# Recipes

> End-to-end Solana BDN walkthroughs: a feed-driven transaction submitter and a private gossip/Geyser feed consumer, all over QUIC.

This page has longer, end-to-end examples. They combine the [feed subscription](./sdk-methods#subscribe-to-feeds-with-the-moqt-client)
and [HTTP/3 submit](./sdk-methods#deliver-a-transaction-http-3-submit-api)
surfaces into programs that you can run. Feeds use `clutchcall_connect/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 from the live p50. Land it through the BDN
with fan-out. The BDN dedups on the signature. Thus a retry is idempotent.

  1. **Connect to the feed relay**
One client serves both feeds. It reconnects automatically and replays
    subscriptions.
```ts
import { MoqtClient } from "clutchcall_connect/moqt";

const feeds = await MoqtClient.connect(
  "quic://feeds.firstbyte.fast",
  process.env.CLUTCHCALL_CREDENTIALS,
);
```
  2. **Track the freshest blockhash and fee**
Keep the latest object from each track in memory. The feed pushes a new
    object every slot (or every N slots for the fee track).
```ts
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);
});
```
  3. **Build and sign against live state**
Use your wallet/keypair and Solana tooling to build a tx. Use the live
    blockhash and a compute-unit price set from the live p50. Replace the
    placeholder builder with your own.
```ts
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
}
```
  4. **Land it through the BDN with a safe retry**
Fan-out submits to every edge. The 64-byte-signature dedup makes retries
    idempotent. Thus you can loop until the tx lands or the blockhash expires.
```ts
async function land(tx: Uint8Array): Promise<string> {
  for (let i = 0; i < 4; i++) {
    const r = await fetch(`https://crypto.firstbyte.fast/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));
```

> **TIP:**
> For latency-sensitive landing, set `fanout_leaders` (server-side) above 1. The
> BDN then lands on the **next** leader before that leader becomes current. It
> moves ahead of the slot boundary instead of racing it.

## Recipe 2 — A private gossip/Geyser feed consumer

Consume a **private** feed and drive a slot-aligned cache. A private feed is
your own ingest endpoint, republished as an org-scoped MoQT track. The private
namespace is `sol/feed/<orgId>`. Subscribe with an org-scoped token. The relay
holds your subscribe even before the ingest publishes. Thus it is safe to start
this at boot.

  1. **Subscribe to the private slots track**
```ts
import { MoqtClient, ConnectionState } from "clutchcall_connect/moqt";

const orgId = process.env.ORG_ID!;
const ns = `sol/feed/${orgId}`;

const client = await MoqtClient.connect(
  "quic://feeds.firstbyte.fast",
  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 };
});
```
  2. **Layer the blockhash track on the same client**
One connection multiplexes every track. You do not dial a second time.
```ts
let recent = { slot: 0, blockhash: "", lastValidBlockHeight: 0 };
client.subscribeFrame(ns, "blockhash", (_t, _p, data) => {
  recent = JSON.parse(new TextDecoder().decode(data));
});
```
  3. **Expose a freshness check**
The frame timestamp shows how stale your view is. You can gate trading
    logic on it.
```ts
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);
```
  4. **Shut down cleanly**
```ts
process.on("SIGINT", () => {
  client.close();                // drops every subscription + the session
  process.exit(0);
});
```

> **NOTE:**
> You configure the private ingest endpoint in the portal/control plane, not
> through an SDK call. The endpoint is your gossip/Geyser gRPC URL and its auth
> token, sealed at rest under your org. The SDK only **subscribes** to the
> resulting `sol/feed/<orgId>` tracks.

## Recipe 3 — Combining a feed and a direct TPU land

Sometimes you already know the leader that you want (e.g. you co-locate next to
one). Then 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.

```ts
import { MoqtClient } from "clutchcall_connect/moqt";

const client = await MoqtClient.connect(
  "quic://feeds.firstbyte.fast",
  process.env.CLUTCHCALL_CREDENTIALS,
);

const TARGET = { host: "<validator-host>", port: "<quic-port>" };

async function landDirect(tx: Uint8Array): Promise<string> {
  const url = `https://crypto.firstbyte.fast/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()));
  }
});
```

> **WARNING:**
> 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.
