Observed since 20 Oct, 22:05 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Client-side transaction builder for the 0Block DEX router. Builds unsigned v0 swap transactions entirely offline — tenant-wrapped or direct — with shared address lookup tables, gateway tips, and on-chain fee-event decoding for accounting.
The SDK for 0Block's two products — independent, composable:
| Product | What it does | Needs the other? |
|---|---|---|
| DEX Smart Router | Build swap transactions on-chain-routed across 60+ venues — through your tenant wrapper (your fee applies) or directly (0Block fee only) | No — submit through any RPC |
| Landing Service | Land any fully-signed Solana transaction: tip-gated submission forwarded to staked infrastructure and current/next leader TPUs | No — accepts any transaction |
Used together they form a complete trade pipeline: build with the router SDK, sign externally, land through the service.
Router highlights:
Keypair ever touches the SDK.npm install @0block.io/sdk
Requires Node ≥ 20 server-side; browser builds work with any modern bundler.
The mode is fixed at initialization:
import { createContext } from "@0block.io/sdk";
// Tenant mode — swaps route through your tenant wrapper program.
// Your tenant fee (set on-chain) and the 0Block fee apply.
const ctx = createContext({
tenant: {
wrapperProgramId: "<your tenant wrapper program id>",
tenantFeeVault: "<your tenant fee vault>",
},
});
// Direct mode — swaps invoke the 0Block router directly.
// Only the 0Block platform fee applies.
const ctx = createContext();
import { connectionFetcher, resolvePumpfunMarketContext } from "@0block.io/sdk";
const fetcher = connectionFetcher(connection);
const market = await resolvePumpfunMarketContext(fetcher, { mint });
// `market` is plain strings — push it to clients over your existing
// stream together with quotes and a FINALIZED blockhash.
import {
buildLookupTableAddresses,
buildInitLookupTableInstructions,
} from "@0block.io/sdk";
const addresses = buildLookupTableAddresses({ context: ctx, market });
const { tableAddress, transactions } = buildInitLookupTableInstructions({
authority: opsKey,
recentSlot,
addresses,
});
// Send each batch as one transaction, in order. Wait ~1 slot before first use.
import { applyPreset, buildPumpfunSwapTransaction } from "@0block.io/sdk";
const { minReturn, tip, computeBudget } = applyPreset(
{ slippagePct: 20, prioritySol: 0.001, bribeSol: 0.001 },
{ expectedOut: quote.expectedOut, tipAccount: streamed.tipAccount }
);
const built = buildPumpfunSwapTransaction({
context: ctx,
market,
user: wallet.address,
side: "buy",
amountIn: 10_000_000n, // 0.01 SOL
minReturn,
recentBlockhash: streamed.finalizedBlockhash,
lookupTables: streamed.lookupTables,
tip,
computeBudget,
});
// built.messageBytes → sign with the user's key (exactly one signature)
// built.orderId → correlate the fill via SwapResultEvent
// built.estimatedSize → wire size, pre-checked against the 1232-byte limit
Attach the signature and get wire bytes with serializeWithSignatures(built, [sig]),
then submit through the 0Block gateway.
import { decodeSwapResultEvents } from "@0block.io/sdk";
const events = decodeSwapResultEvents(tx.meta.logMessages);
// [{ orderId, status, commissions: { feeMint, totalFeeAmount,
// items: [{ kind: "platform" | "tenant", bps, amount, tenantProgram }] } }]
Land any transaction — router-built or otherwise. Three rules: include the tip (a plain transfer to an allowlisted account, kept as a static message key, never behind a lookup table), use a finalized blockhash, and confirm by polling (no websocket).
import { createLandingClient, withLandingTip } from "@0block.io/sdk";
// Any instructions at all — no router required:
const ixs = withLandingTip(myInstructions, payer, {
account: tipAccount, // allowlisted tip account
lamports: 1_000_000n, // ≥ the service minimum
});
// ...compile with a FINALIZED blockhash, sign...
const landing = createLandingClient({
url: "https://<landing-endpoint>",
apiKey: process.env.ZEROBLOCK_API_KEY,
});
const { signature, slot } = await landing.submitAndConfirm(wireBytes, readConnection, {
lastValidBlockHeight,
});
Router-built transactions already carry the tip when you pass tip to
buildPumpfunSwapTransaction — hand their signed wire bytes straight to
landing.sendTransaction.
| Runs | Function | Purpose |
|---|---|---|
| anywhere | createContext | Resolve tenant vs direct mode from init params |
| backend | resolvePumpfunMarketContext | Chain-derived accounts for a mint, as streamable strings |
| backend | buildLookupTableAddresses / buildInitLookupTableInstructions | Create the shared static-accounts table |
| client | applyPreset | Slippage % / priority SOL / bribe SOL → build params |
| client | buildPumpfunSwapTransaction | Complete unsigned v0 transaction (offline) |
| client | serializeWithSignatures | Attach external signatures → wire bytes |
| indexer | decodeSwapResultEvents | SwapResultEvent → normalized commission breakdown |
Lower-level building blocks (buildPumpfunSwapInstruction, PDA derivations,
wSOL wrap/unwrap helpers, tip and compute-budget builders, vendored IDLs) are
exported as well.
(payer, order_id): a duplicate order
id fails at account creation and the whole swap reverts. Mint orderId on
your backend (non-zero u128, one per business order — reuse it across
retries) and pass it to buildPumpfunSwapTransaction; the SDK refuses to
build tenant swaps without one. Direct mode has no marker; a random id is
generated when omitted.wrapper_config PDA signs the router CPI, and the router's
TenantConfig.tenant_authority must equal that PDA
(deriveWrapperConfig(wrapperProgramId)). Otherwise swaps fail
UnauthorizedTenant.TenantConfig account
in the tenant_cfg slot even on direct calls (ignored for fees). The router
operator provisions a standing "direct" config; override its key with
directTenantConfigKey if needed.confirmed hash may be unknown there.wrapSol / unwrapWsol if your users manage wSOL themselves.npm install
npm test # compiles, then runs the offline smoke test (no network, no keys)
The vendored IDLs under src/idl/ are generated from the on-chain programs'
Anchor builds. Regenerate them after any program change — account ordering and
discriminators must match on-chain reality.
UNLICENSED — all rights reserved. Contact 0block.io for usage terms.
Download counts and popularity will appear here as the collector receives them.
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:05 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:eddf732f8c8eee1b03edb9c0f0f2df29606c82b79dc871895e4aa79c579caf8e