Venum SDK
@venumdev/sdk is the typed TypeScript client for the Venum Solana execution API. It covers every public endpoint, ships zero runtime dependencies, and works in Node 22+ and modern browsers.
- npm:
@venumdev/sdk - GitHub:
venumhq/solana-venum-sdk
Why use the SDK
- Typed everything — response interfaces for every endpoint, discriminated unions for every SSE event
- Two stream modes — callback (
streamPrices(...)) and async iterator (for await (const msg of venum.iteratePrices(...))) - AbortSignal everywhere — every method, REST and SSE
- Automatic retry with jittered backoff and
Retry-After. Opt out globally or per-request. Never retries non-idempotent calls (submitSwap,send) or auth failures (401,403) - One-shot swap helper —
venum.swap({...signer, waitFor: 'confirmed'})collapses build → sign → submit → wait into a single call - Amount helpers —
toBaseUnits,fromBaseUnits,solToLamports, etc. - Env fallback in Node — reads
VENUM_API_KEYandVENUM_API_URLif omitted - Zero runtime deps — platform
fetchandTextDecoder
Install
pnpm add @venumdev/sdk
# or
npm install @venumdev/sdkQuick start
import { VenumClient, solToLamports } from '@venumdev/sdk'
const venum = new VenumClient({ apiKey: process.env.VENUM_API_KEY })
const sol = await venum.price('SOL')
console.log(sol.priceUsd, sol.bestBid, sol.bestAsk)
const quote = await venum.quote({
inputMint: 'SOL',
outputMint: 'USDC',
amount: solToLamports(1),
slippageBps: 50,
})
console.log(quote.topRoutes[0])In Node, apiKey and baseUrl fall back to VENUM_API_KEY and VENUM_API_URL from process.env when omitted. Explicit options always win. In the browser, only explicit options are used.
Cancellation
Every method accepts an AbortSignal. Aborting cancels the in-flight request, any pending retry, and (for streams) the reader plus future reconnects.
const ctrl = new AbortController()
setTimeout(() => ctrl.abort(), 2000)
await venum.quote(req, { signal: ctrl.signal })
// One-shot timeout
await venum.quote(req, { signal: AbortSignal.timeout(2000) })Retry
Enabled by default with sensible values:
| Rule | Behavior |
|---|---|
401, 403 | Never retried. Surfaces immediately so you can prompt sign-in / upgrade. |
404, 400 | Never retried (resource / caller error). |
429 | Retried, honoring Retry-After. After exhausting retries, throws VenumApiError with status: 429. |
502, 503, 504 | Retried with jittered exponential backoff. |
| Network errors | Retried. |
submitSwap, send | Never retried (non-idempotent — a double-submit could land twice). |
Per-request override: await venum.quote(req, { retry: false }) or { retry: { retries: 5 } }.
Disable globally: new VenumClient({ retry: false }).
Streams
Both callback and async iterator modes deliver the same typed messages.
Callback mode
const ctrl = new AbortController()
await venum.streamPrices(['SOL', 'JITOSOL'], {
signal: ctrl.signal,
onError: (msg) => console.warn('reconnecting:', msg),
onEvent: (msg) => {
switch (msg.type) {
case 'ready': console.log('ready at', msg.ts); break
case 'price': console.log(msg.price.token, msg.price.priceUsd); break
case 'heartbeat': /* periodic keep-alive */ break
}
},
})Iterator mode
const ctrl = new AbortController()
for await (const msg of venum.iteratePrices(['SOL'], { signal: ctrl.signal })) {
if (msg.type === 'price') console.log(msg.price.priceUsd)
}Swap flow
One-shot helper
import { VenumClient, solToLamports } from '@venumdev/sdk'
import { Keypair, VersionedTransaction } from '@solana/web3.js'
import { Buffer } from 'node:buffer'
const venum = new VenumClient()
const wallet = Keypair.fromSecretKey(/* ... */)
const result = await venum.swap({
inputMint: 'SOL',
outputMint: 'USDC',
amount: solToLamports(0.1),
slippageBps: 50,
signer: {
publicKey: wallet.publicKey.toBase58(),
sign: (unsignedBase64) => {
const tx = VersionedTransaction.deserialize(Buffer.from(unsignedBase64, 'base64'))
tx.sign([wallet])
return Buffer.from(tx.serialize()).toString('base64')
},
},
waitFor: 'confirmed',
})
console.log(result.signature, result.landed?.slot)Manual flow (full control)
const build = await venum.buildSwap({
inputMint: 'SOL',
outputMint: 'USDC',
amount: solToLamports(0.1),
userPublicKey: wallet.publicKey.toBase58(),
slippageBps: 50,
})
const tx = VersionedTransaction.deserialize(Buffer.from(build.transaction, 'base64'))
tx.sign([wallet])
const submit = await venum.submitSwap({
quoteId: build.quoteId,
signedTransaction: Buffer.from(tx.serialize()).toString('base64'),
})
const landed = await venum.waitForTx(submit.signature, { events: ['confirmed'] })Compatibility
The SDK has no Solana SDK dependency. It only exchanges base64-encoded VersionedTransaction bytes, which makes it compatible with:
@solana/web3.js(classic) —VersionedTransaction.deserialize/.serialize+.sign([kp])@solana/kit(new) —getTransactionDecoder/signTransaction/getBase64EncodedWireTransaction- wallet-standard adapters — wrap the wallet's
signTransactioninto aSwapSigner
Errors
import { VenumApiError, VenumNetworkError } from '@venumdev/sdk'
try {
await venum.quote(req)
} catch (err) {
if (err instanceof VenumApiError) {
if (err.status === 401) {
// prompt sign-in
} else if (err.status === 403) {
// upgrade plan
} else if (err.status === 429) {
// rate-limited after retries
}
} else if (err instanceof VenumNetworkError) {
// err.url, err.cause
} else if ((err as Error).name === 'AbortError') {
// caller cancelled
}
}Amount helpers
import { toBaseUnits, fromBaseUnits, fromBaseUnitsString, solToLamports, lamportsToSol } from '@venumdev/sdk'
toBaseUnits(1.5, 9) // "1500000000"
toBaseUnits('0.000001', 9) // "1000"
fromBaseUnitsString('1500000000', 9) // "1.5" (exact, no precision loss)
fromBaseUnits('1500000000', 9) // 1.5 (may lose precision for huge balances)
solToLamports(2.5) // "2500000000"
lamportsToSol(1_500_000_000) // 1.5Amounts up to Number.MAX_SAFE_INTEGER (2^53) fit in JS number, but a wallet with 9M+ SOL at 9 decimals overflows. Strings are lossless. Use BigInt(raw) when you need to do math.
Browser usage
The SDK works in any modern browser — same fetch, same streams. Do not ship an API key to clients. Set up a backend-for-frontend that proxies requests to api.venum.dev, injects the key server-side, and rate-limits per origin or IP. Background and rationale: venum.dev/solana-free-rpc.
See also
- Venum CLI — terminal interface, also re-exports the SDK as a library
- Solana Venum MCP — MCP server for AI agents
- Quoting, Swap Building, Transaction Submission
- API Reference — every endpoint with request/response schemas
