Run durable admission locally

Start the v2 Worker and its SQLite Durable Object, then exercise proof of possession, finite capacity, sealed bidding, and single-use redemption in workerd.

Prerequisites

  • Node.js 24 or newer. The reference uses Web Crypto Ed25519 support.
  • Access to the private x429-protocol/x429 repository.
  • A Cloudflare account only when you are ready to deploy; local workerd tests do not need one.
@x429/* packages are private repository workspaces, not public npm installs. The production-profile v2 service is packages/admission-worker; @x429/client, @x429/payment-x402, and @x429/origin are implemented private workspaces. A release operator can build coordinated client-only tarballs with npm run sdk:bundle -- <directory>; that bundle excludes the Worker and console. The Hono middleware remains legacy v1 reference code.

Install and prove the repository

git clone https://github.com/x429-protocol/x429.git
cd x429
npm ci
npm run check

npm run check runs Node tests, exact-payment adapter checks, strict Worker type checks, v2 unit and workerd tests, the controlled client-to-Worker exact-settlement flow, package tarball smoke tests, and the simulator. It does not move real funds.

Configure separate local signing keys

install -d -m 700 .x429/local-secrets
npm run keys:generate -- x429-local-2026-07 \
  --secret-output .x429/local-secrets/issuer.json
npm run keys:generate -- x429-origin-local-2026-07 --origin \
  --secret-output .x429/local-secrets/origin.json
cp packages/admission-worker/.dev.vars.example \
  packages/admission-worker/.dev.vars

The commands print only public metadata. Import the private fields from the exclusive mode-0600 JSON files into .dev.vars or the approved secret manager without displaying them. Keep the two key ids distinct in Wrangler configuration. Never commit those files or place either private key in wrangler.jsonc.

Use a direct secret-manager file import, secret-aware editor, or reviewed file-to-file importer; never cat, echo, shell-substitute, or put private fields in argv. These credential writers are POSIX-only. Native Windows is not supported: use reviewed secret-manager-native tooling that does not invoke them, or WSL with output on a private Linux filesystem—not /mnt/c or another shared mount. Otherwise, do not run them.

Start the v2 admission Worker

npm run worker:dev

The checked-in development configuration listens at http://127.0.0.1:8787, exposes discovery, and uses explicit mock settlement.

curl -i http://127.0.0.1:8787/healthz
curl -i http://127.0.0.1:8787/.well-known/x429.json

Protected routes require a valid Ed25519 client proof; an unsigned curl /v1/infer is expected to fail. Run the integration suite to execute the complete signed flow:

npm run test:worker
npm run test:worker:exact

The suites are designed to fill capacity, obtain durable tickets, reject early and replayed redemption, clear sealed maxima, exercise mock and exact settlement paths, verify standard x402 headers, and redeem one paid permit. Retain a successful run for the release commit. Exact tests use a controlled facilitator stub, not a funded public chain.

Know which profile you are running

CommandProfileUse
npm run worker:devv2 local mockDurable GET/HEAD admission, proof of possession, finite lanes, sealed auction, and no-money settlement.
npm run worker:preflight:stagingv2 exact stagingValidates the copied staging config before source deployment. The example uses Base Sepolia and the official x402.org facilitator.
npm run worker:bootstrap:staging -- --secrets-file PRIVATE_JSONfirst exact deploymentValidates the complete owner-only secret set and publishes the issuance-disabled Worker in one strict deployment. It avoids intermediate versions with only some secrets installed.
npm run worker:preflight:productionv2 exact production candidateRequires Base mainnet official USDC, authenticated CDP facilitator, fixed HTTPS upstream, two independently administered RPC providers agreeing on the Base safe boundary, and distinct administrator and read-only monitor secrets. Passing preflight is not funded-production evidence.

Troubleshooting

ProblemLikely causeFix
npm run check fails on Node version.Node is older than the Web Crypto Ed25519 support expected by the repo.Install Node 24 or newer and retry.
/healthz returns 503.Either signing keypair is absent, reused, mismatched, or malformed.Generate two distinct pairs and populate the local .dev.vars.
A protected request returns 401.The proof is missing, stale, malformed, or does not match the exact target.Sign the v2 canonical request object with the client private key.
A ticket redeems early or twice.A protocol invariant was broken.Block release and reproduce with npm run test:worker.
Exact settlement returns reconciliation pending, a 5xx, or malformed post-signature data.The facilitator may have broadcast, or reported success before both RPC providers proved the same Base safe boundary and exact receipt/events.The required gross budget and recovery WAL already committed before submission. Except for one same-authorization retry of explicit payment_confirmation_persistence_pending, retain the pending record and charged budget; do not resubmit. Use authenticated npm run payment:reconcile with the known transaction, or --discover-transaction for bounded finalized AuthorizationUsed discovery when the hash is genuinely lost. Discovery still performs normal verification. After confirmation call resumeExactPayment() with the same stores and no wallet signer.

Before staging deployment

  1. Copy the staging Wrangler example to its untracked live filename and replace every REPLACE_* value.
  2. Prepare one current-user-owned mode-0600 flat JSON file containing exactly the secret names declared by secrets.required. Include both complete, distinct keypairs, plus any production CDP credentials; never place them in source or Wrangler variables. Do not install first-deployment secrets one at a time.
  3. Include URLs for two independently administered RPC providers and pairwise-distinct 32+ character X429_ADMIN_TOKEN (mutating reconciliation/refund), X429_MONITOR_TOKEN (read-only inventory/export), and X429_POOL_INVENTORY_TOKEN values. The bootstrap command validates names, keypair matching, file security, token separation, and different RPC hostnames before one strict deployment. Different hostnames alone do not prove provider independence.
  4. Have the one deployed exact launch tester run npm run client:identity -- --kid x429-client-<name> --output PRIVATE_FILE, import the new mode-0600 file into a secret manager, and send only the printed thumbprint/public key. Vet that pair and set exactly that thumbprint in X429_ALLOWED_CLIENTS; keep one paid slot, reserve equal to maximum, and one outstanding paid obligation.
  5. Protect one existing GET or HEAD route behind a fixed upstream. Keep the origin private and verify X429-Origin-Assertion with durable nonce consumption.
  6. Map that exact path (or a deliberately bounded terminal /* prefix) to a named finite pool in X429_ROUTE_POOLS. Do not use a global catch-all.
  7. If that route uses custom authentication, tenant, model, or cost-bearing headers, add them to X429_BOUND_HEADERS before issuing tickets. Authorization, cookie, and x-api-key are included automatically.
  8. Distribute client trust pins—issuer, audience, key id, and public key—through an independent channel.
  9. Keep launch timing explicit: Base safe, 20-second payment timeout, 240,000ms chain-observation timeout, 60,000ms poll interval, four attempts, 10-second settlement grace, and a fixed 2-second delivery lead. Deployed exact config rejects an observation timeout below 180,000ms. Prove clients bid only when the latest possible paid slot fits their task deadline.
  10. Choose X429_MAX_FUTURE_WINDOWS so its interval span covers one interval + auction epoch + payment timeout + confirmation timeout + settlement grace + 2 seconds. Preflight rejects a shorter exact horizon; treat runtime auction_horizon_full as capacity exhaustion, not a retry signal.
  11. Force confirmed reconciliation after the original slot and prove resume moves the entitlement into unused future paid capacity without creating a second payment.
  12. Set X429_RELEASE_COMMIT to the full lowercase clean Git commit under review. Keep the template's initial X429_ISSUANCE_DISABLED=true and make the first secret-bearing deployment only with npm run worker:bootstrap:staging -- --secrets-file PRIVATE_JSON. Later issuance-disabled code/config releases use worker:deploy:staging without a secrets file. Then change only the ignored reviewed config to false. Create the separate offline opening-approval key and signed 15-minute evidence envelope described in the private operator runbook. Run worker:verify with explicit disabled/service expectations, the exact release commit, protected resource, canonical config, --opening-evidence, and a new non-overwriting .x429/attestations/staging-open.json proof.
  13. Only after upstream isolation, monitoring, rollback, inventory anchoring, alert delivery, and drain checks pass, open within the proof's ten-minute lifetime using npm run worker:open:staging. The opener re-verifies every signed artifact against the current live head and burns the proof before Wrangler starts; a failure requires fresh evidence. The first tightly capped Base Sepolia open may defer its funded canary once. Every later staging open and every production review requires a verified paid-admission artifact.

There is no funded public-chain evidence or independent security audit in the repository today. Those remain launch gates, not implied results.

A successful admission does not guarantee response delivery. Protected-origin dispatch irrevocably consumes the credential because the application may execute without returning a response. The signed receipt proves consumption while the result may be unknown; later timeout, transport, body-stream, or client-delivery failure is not replayed or automatically refunded.

What to read next