Longer, end-to-end examples that combine the feed subscription
and HTTP/3 submit
surfaces into something you’d actually run. Feeds use @clutchcall/sdk/moqt;
transactions use the HTTP/3 submit API.
Recipe 1 — A feed-driven transaction submitter
Watch the live blockhash and priority-fee feeds, build a transaction against the
freshest blockhash, price it off the live p50, and land it through the BDN with
fan-out. Because the BDN dedups on the signature, a retry is idempotent.
Connect to the feed relay
One client serves both feeds; it auto-reconnects and replays subscriptions.import { MoqtClient } from "@clutchcall/sdk/moqt";
const feeds = await MoqtClient.connect(
"quic://feeds.clutchcall.dev",
process.env.CLUTCHCALL_CREDENTIALS,
);
Track the freshest blockhash and fee
Keep the latest object from each track in memory — the feed pushes a new one
every slot (or every N slots for the fee track).let recent = { blockhash: "", lastValidBlockHeight: 0 };
let fee = { p50: 0, max: 0 };
const dec = (d: Uint8Array) => JSON.parse(new TextDecoder().decode(d));
feeds.subscribeFrame("sol/feed/mainnet", "blockhash", (_t, _p, d) => {
recent = dec(d);
});
feeds.subscribeFrame("sol/feed/mainnet", "priorityFee", (_t, _p, d) => {
fee = dec(d);
});
Build and sign against live state
Use your wallet/keypair and Solana tooling to build a tx with the live
blockhash and a compute-unit price set from the live p50 (replace the
placeholder builder with your own).function buildSignedTx(): Uint8Array {
// ... build a Solana tx using `recent.blockhash`
// and a priority fee around `fee.p50` µ-lamports,
// sign it, and return the raw serialized bytes.
return signedBytes; // Uint8Array
}
Land it through the BDN with a safe retry
Fan-out submits to every edge; the 64-byte-signature dedup makes retries
idempotent, so loop until it lands or the blockhash expires.async function land(tx: Uint8Array): Promise<string> {
for (let i = 0; i < 4; i++) {
const r = await fetch(`https://crypto.clutchcall.dev/bdn/submit?leader=auto`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLUTCHCALL_CREDENTIALS}`,
"Content-Type": "application/octet-stream",
},
body: tx,
});
const { ok, sig } = await r.json();
if (ok) return sig; // dedup: re-sends won't double-land
await new Promise((res) => setTimeout(res, 150));
}
throw new Error("tx did not land before blockhash expiry");
}
const tx = buildSignedTx();
console.log("landed", await land(tx));
For latency-sensitive landing, set fanout_leaders (server-side) above 1 so the
BDN lands on the next leader before it becomes current — front-running the
slot boundary instead of racing it.
Recipe 2 — A private gossip/Geyser feed consumer
Consume a private feed — your own ingest endpoint republished as an
org-scoped MoQT track — and drive a slot-aligned cache. The private namespace is
sol/feed/<orgId>; subscribe with an org-scoped token. The relay holds your
subscribe even before the ingest has published, so this is safe to start at boot.
Subscribe to the private slots track
import { MoqtClient, ConnectionState } from "@clutchcall/sdk/moqt";
const orgId = process.env.ORG_ID!;
const ns = `sol/feed/${orgId}`;
const client = await MoqtClient.connect(
"quic://feeds.clutchcall.dev",
process.env.CLUTCHCALL_CREDENTIALS,
(state, reason) => {
if (state === ConnectionState.Reconnecting) {
console.warn("private feed relay flap:", reason);
}
},
);
let head = { slot: 0, seenAtUs: 0n };
client.subscribeFrame(ns, "slots", (tsUs, _p, data) => {
const { slot } = JSON.parse(new TextDecoder().decode(data));
if (slot > head.slot) head = { slot, seenAtUs: tsUs };
});
Layer the blockhash track on the same client
One connection multiplexes every track — no second dial.let recent = { slot: 0, blockhash: "", lastValidBlockHeight: 0 };
client.subscribeFrame(ns, "blockhash", (_t, _p, data) => {
recent = JSON.parse(new TextDecoder().decode(data));
});
Expose a freshness check
The frame timestamp lets you tell how stale your view is and gate trading
logic on it.function slotFreshnessMs(): number {
const nowUs = BigInt(Date.now()) * 1000n;
return Number((nowUs - head.seenAtUs) / 1000n);
}
setInterval(() => {
console.log(`head slot ${head.slot} · ${slotFreshnessMs()}ms old · ` +
`blockhash ${recent.blockhash.slice(0, 8)}…`);
}, 1000);
Shut down cleanly
process.on("SIGINT", () => {
client.close(); // drops every subscription + the session
process.exit(0);
});
Configuring the private ingest endpoint (your gossip/Geyser gRPC URL and its
auth token, sealed at rest under your org) is a portal/control-plane task, not an
SDK call — the SDK only ever subscribes to the resulting sol/feed/<orgId>
tracks.
Recipe 3 — Combining a feed and a direct TPU land
When you already know the leader you want (e.g. you co-locate next to one), skip
the mesh: watch the slot feed to fire at the right moment, then land straight on
that validator’s TPU with the direct /tpu route.
import { MoqtClient } from "@clutchcall/sdk/moqt";
const client = await MoqtClient.connect(
"quic://feeds.clutchcall.dev",
process.env.CLUTCHCALL_CREDENTIALS,
);
const TARGET = { host: "<validator-host>", port: "<quic-port>" };
async function landDirect(tx: Uint8Array): Promise<string> {
const url = `https://crypto.clutchcall.dev/tpu?host=${TARGET.host}&port=${TARGET.port}`;
const r = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLUTCHCALL_CREDENTIALS}`,
"Content-Type": "application/octet-stream",
},
body: tx,
});
return (await r.json()).sig;
}
// Fire the moment the feed shows our target leader's slot is current.
client.subscribeFrame("sol/feed/mainnet", "slots", async (_ts, _p, data) => {
const { slot } = JSON.parse(new TextDecoder().decode(data));
if (isTargetLeaderSlot(slot)) { // your leader-schedule check
console.log("landed", await landDirect(buildSignedTx()));
}
});
The direct /tpu route does no fan-out and no dedup across edges — if
you call it in a loop you can double-land. Use /bdn/submit (with its
signature-keyed dedup) whenever you retry.