Dynamo speaks x402: HTTP 402 with a machine-readable challenge, answered by an X-PAYMENT header. Two schemes ride the same challenge:
exact — discrete work at a quoted price: the buyer ticks the priceagainst a stream, binds the payment to the seller's request nonce, and presents a consume receipt. Request-bound, replay-rejected, idempotent.
dynamo-allowance — streaming access: the buyer presents the offlineallowance credential; the seller meters actual work against it.
Everything the seller checks is verifiable offline against a pinned engine signer — no payment-network call in the request path.
import { Dynamo, usd, units, x402 } from "@dynamoprotocol/sdk";
const dynamo = await Dynamo.open({
coreUrl: process.env.DYNAMO_CORE_URL!,
token: process.env.OWNER_API_TOKEN!,
});
const seller = "0x00000000000000000000000000000000000000D4";
const sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));
// BUYER side: a capped stream aimed at the seller.
const budget = await dynamo.openBudget({ funding: "none", cap: usd("5") });
const stream = await budget.stream({ to: seller, rate: units(1_000_000n), cap: units(2_000_000n) });
await sleep(1_100);
// SELLER side: the 402 challenge for a priced resource.
const challenge = x402.issueChallenge({
resource: "https://api.example.test/report",
payTo: seller,
maxAmountRequired: 250_000n,
requestRef: "req-docs-1",
});
// BUYER: answer with the exact scheme — ticks the price, binds the receipt.
const answer = await x402.answerChallenge(challenge, stream, { prefer: "exact" });
if (answer.headerName !== "X-PAYMENT") throw new Error("payment rides X-PAYMENT");
// SELLER: verify ENTIRELY offline against the PINNED engine signer — the
// address your budget reported at open; operators pin it in config.
const verified = await x402.verifyPayment(answer.headerValue, {
expectedSigner: budget.engineSigner as `0x${string}`,
serviceNode: seller,
nowSeconds: BigInt(Math.floor(Date.now() / 1000)),
expectedRequestRef: "req-docs-1",
requiredUnits: 250_000n,
});
if (!verified.valid) throw new Error(`payment must verify: ${verified.reason}`);
if (verified.scheme !== "exact") throw new Error("expected the exact scheme");
// The allowance is AIMED: a different service node replaying the same
// payment is refused with a named reason — never served.
const replayed = await x402.verifyPayment(answer.headerValue, {
expectedSigner: budget.engineSigner as `0x${string}`,
serviceNode: "0x00000000000000000000000000000000000000aa",
nowSeconds: BigInt(Math.floor(Date.now() / 1000)),
});
if (replayed.valid) throw new Error("a payment aimed at another node must be refused");
await stream.revoke();
await budget.close();
const session = await budget.aggregate();
if (!session.reconciled) throw new Error("engine and settlement layer disagree");
For buyers, x402.x402Fetch(fetch, stream) wraps any fetch: on a 402 it answers the challenge from the stream and retries ONCE; a second 402 propagates — fail closed, no payment loops.
The seller-side checks are not optional garnish; they are the conformance suite's A.2b section: replay rejection, idempotent consume records, voucher monotonicity, exposure bounds (refuse new unsettled work past a bound — a free pre-check), and finality-aware access for high prices.
"Conformance-tested" is a specific, runnable claim (R4):
export DYNAMO_CORE_URL=https://your-instance-url # funds the test streams
export OWNER_API_TOKEN=your-owner-api-token
npx @dynamoprotocol/conformance-kit --target https://your-seller.example
The kit runs the full catalog — challenge shape, both schemes, denial ordering, A.2b merchant protection — against any endpoint that speaks 402 + X-PAYMENT, and writes a machine-readable report with its own digest, so a sign-off can be pinned and re-verified. The gateway plugins pass the identical catalog live.