@zbase-protocol/core
v0.2.0
Published
Chain-agnostic ZK privacy core for x402 AI agent payments. Poseidon hashing, Merkle trees, Groth16 proof generation, account/secrets management. Used by @zbase-protocol/svm and @zbase-protocol/mcp.
Maintainers
Readme
@zbase-protocol/core
Chain-agnostic ZK privacy primitives for x402 AI agent payments.
🧪 Status: testnet. Currently live against Base Sepolia via the hosted facilitator at zbase.app. The SDK code itself is chain-agnostic, but Base mainnet also requires a deployed mainnet pool, env-wired contract addresses, mainnet ASP initialization, shared Upstash storage, and a launch-ready postman signer.
Privacy model (honest)
Before you integrate, know exactly what this gives your users.
Provides today (live on Base Sepolia):
- Sender/receiver unlinkability. The recipient address has no on-chain link to the depositor's wallet. The link is broken by a Groth16 proof of pool membership + a nullifier that marks the note spent.
- Compliance-gated privacy. Only deposits from clean addresses (ASP-approved subset) can withdraw. This is the Vitalik-Buterin-coauthored design, not Tornado Cash.
Does NOT provide today:
- Amount hiding.
_valueis emitted in plaintext on bothDepositedand the withdrawal/settle event. Anyone watching the chain sees deposit amounts and withdrawal amounts — only the link between them is broken. - Timing-correlation defense. The decoy scheduler (
scripts/decoy-scheduler.ts) exists but is not running in prod. A single withdrawal in a quiet window is trivially attributable. - Amount-frequency-attack defense. A
$99.99deposit followed by a$99.99settle is correlatable.
Roadmap (scaffolded, not deployed):
- UTXO notes (
circuits/note_spend.circom,createNote/splitNote/mergeNotesin this SDK) → true amount hiding. Needs trusted setup ceremony. - Threshold-signed ASP (
ThresholdEntrypoint.sol) → distributed compliance trust. - Decoy scheduler in prod → defeats FIFO temporal de-anon.
Anonymity-set size is the privacy metric, not TVL. The pool can hold 0 USDC and still provide full anonymity to new deposits — the commitment Merkle tree grows on every deposit and never shrinks on withdrawal. Low TVL only blocks other users' withdrawals, not your privacy.
Full deep-dive: zbase.gitbook.io/threat-model.
zBase is built on Vitalik Buterin's Privacy Pools research (Apache 2.0, audited reference implementation by 0xbow). This package contains the chain-agnostic primitives shared across all chain implementations.
Install
npm install @zbase-protocol/coreQuickstart
import {
generateDepositSecrets,
computeCommitment,
computeNullifierHash,
} from "@zbase-protocol/core";
// 1. Generate fresh nullifier + secret for a deposit
const secrets = generateDepositSecrets();
// 2. Compute the commitment hash (what goes on-chain)
// value is atomic USDC (6 decimals): 1_000_000 = 1 USDC
const commitment = computeCommitment(
1_000_000n,
secrets.nullifier,
secrets.secret
);
// 3. Settle a private payment via a trusted facilitator
const response = await fetch("https://zbase.app/api/facilitator/settle", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
paymentDetails: {
scheme: "exact",
networkId: "eip155:84532", // Base Sepolia
payTo: "0xProviderAddress",
maxAmountRequired: "500000", // 0.5 USDC
},
zbaseDeposit: { ...secrets, value: "990000", label: "...", commitment: "..." },
}),
});For a full end-to-end test (deposit → settle → withdraw) on Base Sepolia, see scripts/integration-sdk-vs-facilitator.mjs.
Security note: the current hosted facilitator generates proofs server-side, so
settlePrivately()/direct /settle calls send note spend secrets to the
configured baseUrl. Use HTTPS and only point at a deployment you operate or
trust. The exported client rejects insecure non-local HTTP URLs by default.
What's exported
| Area | Symbols |
|---|---|
| Account / secrets | generateDepositSecrets, computeCommitment, computePrecommitment, computeNullifierHash, computeLabel, feToBE32, SNARK_SCALAR_FIELD, createAccount, serializeAccount, deserializeAccount |
| ZK proofs | generateWithdrawalProof, verifyProofLocally (Groth16 via snarkjs) |
| Merkle tree | buildMerkleTree, generateMerkleProof, getTreeDepth (LeanIMT) |
| UTXO notes (scaffold) | createNote, commitmentOf, nullifierHashOf, splitNote, mergeNotes, planSpend, serializeNote, deserializeNote, generateViewingKey, encryptNote, decryptNote, scanNotes |
| ERC-5564 stealth | generateMetaAddress, parseMetaAddress, deriveStealthAddress, scanForPayments, computeStealthPrivateKey, STEALTH_SCHEME_ID |
| Privacy scanner | analyzeTransfers |
Full TypeScript types exported alongside. 38 named exports total.
Status of the hosted facilitator
The default facilitator at https://zbase.app runs on Base Sepolia today.
Base mainnet is supported by the SDK type surface (network: "eip155:8453") but
is not a safe toggle until the production contract stack is deployed and the
hosted facilitator passes its mainnet preflight. Check live status:
curl https://zbase.app/api/facilitator/supportedHow to test
Three paths, depending on persona:
- Browser: zbase.app/test — connect wallet, get Sepolia USDC, deposit + withdraw privately
- Agent (curl): pure HTTP, no SDK required. See
/api/skillfor AI coding agents - SDK: this package. See
scripts/integration-sdk-vs-facilitator.mjsin the repo for a runnable smoke test
Links
- 🌐 zbase.app
- 📖 Documentation (GitBook)
- 🐙 GitHub
- 🐦 @zbase__
- 🐰 Companion:
@zbase-protocol/svm(Solana) — repo-local and paused for Base mainnet launch - 🤖 Companion:
@zbase-protocol/mcp(Claude Desktop / Cursor) — repo-local until published
License
Apache 2.0. Built on Vitalik Buterin's Privacy Pools research and the 0xbow reference implementation.
