Skip to content

Developer Guides

Everything you need to integrate zBase, by role. Each guide is task-oriented and assumes you can read TypeScript and use a terminal. If you just want to see a payment work first, start with Pay privately in 5 minutes.

Pick your path

You are... Read You get
An agent / buyer paying APIs Pay privately from an agent (SDK) One call: probe → 402 → settle privately → deliver.
A facilitator / integrator Integrate zBase as your facilitator Swap your x402 facilitator URL; keep standard sellers.
A provider / seller receiving pay Receive payments (stealth) Get paid to a fresh address with no customer link.
Building your own note logic Privacy Pool notes · Merkle tree & proofs Note encoding, proofs, state tree.
Running a backend (no local note state) Wallet backend API Hosted facilitator endpoints.

60-second technical quickstart (buyer)

npm install @zbase-protocol/core
import { createFacilitatorClient } from "@zbase-protocol/core";

const zbase = createFacilitatorClient({
  baseUrl: "https://zbase.app",     // pin the facilitator you trust (it sees spend secrets)
  network: "eip155:8453",           // Base mainnet
});

// One call runs the whole loop: free-probe → 402 → private settle → retry w/ payment header → data.
const res = await zbase.payAndFetch(
  "https://api.seller.com/endpoint",
  { method: "GET" },
  {
    deposit: myNote,                        // a pool note (see Privacy Pool notes)
    onNoteRotate: (next) => db.save(next),  // persist the change note
    acceptNotPrivate: true,                 // open pilot: settle even though set < 30
  },
);

console.log(res.status, res.response);      // seller's data
console.log(res.fundingTxHash);             // public pool withdrawal that funded the payer

The result contract you must handle (money-safety)

The note is spent only on a settled payment, and settlement is idempotent on the note, so a lost or ambiguous response can never charge you twice. payAndFetch returns a tri-state, not a boolean — handle all three:

Outcome Shape What it means What to do
Delivered res.paid === true, res.status 2xx Paid and the seller returned data. Use res.response; persist res.nextDeposit.
Proven unspent payAndFetch throws The withdrawal did not happen (e.g. 402 rejected pre-spend). Note untouched. Safe to retry with the same note.
Uncertain res.paid === false, res.uncertain === true The note may be spent (dropped/ambiguous settle). Retry the same call (idempotent). Never pay from a different note.

The one mistake that double-pays

Never treat "no clear success" as "unspent." The SDK enforces this — it only throws note unspent when the note is provably unspent. Full detail: Handling failures safely.

What the facilitator can see, and what it cannot do

Today the facilitator does server-side proving, so it sees your note's spend secrets (nullifier + secret) at settle time. Pin baseUrl to a host you trust. What it cannot do:

  • It cannot redirect your payment. The recipient is bound into the Groth16 proof's public signals; a facilitator that rewrites the recipient invalidates the proof, so a valid relay cannot be redirected. (See Trust model.)
  • It cannot forge a withdrawal. The verifier is on-chain; without the trusted-setup toxic waste a forged proof is infeasible.

Client-side proving — generating the proof on your machine so the facilitator never sees the secrets — is on the roadmap.

Seller compatibility

zBase sends both x402 transport headers — X-PAYMENT (x402 v1) and Payment-Signature (x402 v2 transport). Precisely: any seller whose facilitator verifies a standard exact EIP-3009 payload — the Coinbase-CDP default — delivers unchanged and never learns zBase was involved. Sellers on a bespoke facilitator (a proprietary signed-offer / SIWX handshake instead of the standard payload) are not supported; the SDK free-probes and refuses those for $0 before spending. See How zBase compares.

Test the public API live

The read-only facilitator endpoints (capabilities, live anonymity set, health, exposure preview) are firable from the Live API playground. The money endpoints are documented there too, as reference — build those calls with the SDK above, not by hand.