Agents that pay per request β and keep receipts that prove it. The
official @x402/* packages move the money β HBAR or USDC, the buyer's
choice per request; every other flow
stops at the facilitator's word that it moved. Here the agent checks the
chain itself, the server cryptographically commits to the bytes it
served, and every run files a receipt β settlement, delivered
content, human consent, each panel independently verifiable, up to a
block-proof receipt stamped VERIFIED by cryptography alone. The whole
trail lands on a public HCS audit log that npm run audit re-verifies
with no one's cooperation. Prototype, testnet only (enforced in code).
System map: docs/architecture.md.
flowchart LR
A["π€ agent"] -- "pays a 402<br/>HBAR / USDC" --> S["server"]
S -- "data + signed<br/>sha-256 of the bytes" --> A
A -- "verifies<br/>on-chain" --> M["public mirror"]
A -- "files" --> R["π§Ύ receipt<br/>every panel provable"]
A -- "attests" --> H["HCS audit log"]
H -- "npm run audit<br/>anyone, forever" --> V["β re-verified"]
[agent] 5 Β· 200 β data: {"product":"spot-price","mock":false,"symbol":"HBAR","price":0.068036,"currency":"USD","source":"hedera-network-exchange-rate","rateExpiresAt":1785502800}
[agent] settlement claims transaction 0.0.6502504@1785501679.860897624
[agent] 6 Β· VERIFYING β the mirror node, not the facilitator's word
[agent] Paid in full β the chain confirms the exact amount landed.
[agent] charged: quoted 0.05000000 β (5,000,000 tinybar) β settled 0.05000000 β (5,000,000 tinybar) β exact; network fee paid by the sponsor, not the agent
[agent] hashscan: https://hashscan.io/testnet/transaction/1785501684.589679895
[agent] 6Β½ Β· content COMMITTED β 0.0.9651303 signed sha-256 79377a6fb9028868β¦ against this settlement (key mirror-checked)
[agent] 7 Β· receipt written to receipt.html
[agent] 8 Β· verdict attested to HCS topic 0.0.9855803
The settlement on HashScan β
real data (the chain's own exchange rate), exact amount, committed content,
attested β anyone can re-run the check from the transaction id. Every commitment on the public audit
topic re-verifies from
public data alone: npm run audit.
The receipt is the product, and there are two β one per rung of the trust ladder above the facilitator's word (where every other x402 flow stops):
- the mirror receipt β every paid run, checked against the public mirror: independent and re-checkable by anyone, still operator-attested, so it is honestly stamped UNVERIFIED;
- the block-proof receipt β merkle root recomputed, threshold signature
verified, before a single field is believed: the only receipt this repo
stamps VERIFIED. The proof is a real Hiero block-stream proof β
the wiring just isn't on testnet yet (HIP-1056), so today it runs on a
committed real previewnet block; the cryptography is live either way.
One click in the hub, or
npm run provenance(no keys, no env, no network).
Same verdict pipeline, different rung; each panel on either is an independently verifiable claim in its own trust register β never borrowing authority from the one above it.
- Settlement β quoted vs settled to the atomic unit, the transaction id, live proof links; stamped for HOW it was read (mirror record vs block proof β "verified" is reserved for cryptography).
- Delivered content β
SERVER COMMITTED: the server signed sha-256 of the exact bytes against this settlement; it can never deny what it served. Re-hash the content and check. - Human approval β who signed which one-time challenge, re-verified against their on-chain key.
- The proof's working (block receipts) β source block, anchor, and the checks that held before a single field was believed.
Block receipts are beta, and say so on their face: HIP-1056 block streams haven't reached testnet, so the proof runs on a committed real previewnet block (its true consensus date shows). The amber caveat is printed on the receipt itself β the artifact never pretends. And the library is testnet-ready today: the block source is injected (src/stream.ts), so the day streams land, live x402 settlements gain VERIFIED receipts by swapping the source β zero code changes to the pipeline, the receipts, or the stamps.
"Impossible to use or drain a user's funds without their explicit consent" β here that is mechanism, not policy:
- Exact-amount signing β one transfer per run, precisely the advertised amount, nothing else.
- Spend cap before the signature β over-cap quotes are refused, in the quote's own asset, before anything is signed.
- Human gates β button approval, or a wallet-signed single-use challenge verified against the approver's on-chain key.
- Key isolation β three processes, three keys, none shared; the server holds no payment keys.
- Testnet gate in code (src/config.ts) β mainnet is a code change, not a config change.
And the agent verifies every spend after the fact β consent going in, proof coming out. The gates, on screen β real runs, verbatim (the first two cost nothing: both refusals fire before anything is signed):
| Surface | Where | Public proof |
|---|---|---|
| HBAR transfers, fee-payer sponsored | demo/agent.ts + facilitator | settled run |
| HTS payments (official testnet USDC) | /data/fx + hub asset picker |
token 0.0.429274 |
| Mirror-node REST (settlement, keys, topics) | src/verify.ts, demo/audit.ts | the raw record a verdict reads |
| HCS attestation log | src/attestation.ts | live topic 0.0.9855803 Β· npm run audit |
| Network exchange rate | /data/spot-price serves it live |
the endpoint |
| HIP-1056 block streams | src/stream.ts | npm run provenance β offline, keyless |
| HIP-820 wallet signing (HashPack) | hub wallet-approval mode | the consent panel on any wallet-approved receipt |
One paid request, by the numbers:
- 2 on-chain transactions β the fee-payer-sponsored transfer (HBAR or USDC, switchable per request from the hub) and its HCS attestation;
- 4 Hedera services in one flow β transfer/HTS settlement, a consensus topic, the mirror REST API, and the network's own exchange-rate feed (which is also the data being sold);
- 4+ mirror lookups, all free β the agent's key check, the settlement record, the content-signer's key, the approver's key in wallet mode;
- up to 3 signatures verified post-settlement β the settlement itself against the chain, the server's content commitment, and the human's consent β each against on-chain keys, none on anyone's word.
Fees are fixed and sub-cent, finality is seconds, the mirror is free: one modest paid API at 10 req/s is ~1.7M Hedera transactions a day, each with a verifiable receipt.
Runs entirely on published packages β no forks β and upstreamed what it
learned as shipped versions in the Hiero ecosystem: all open
source, all Apache-2.0, installable by any Hedera builder today:
byTransactionId
(payment-requests v0.1.2) Β·
mirror-fetch
(receipts v0.2.0) Β· true block-stream transaction ids
(streams-node v0.2.0) Β·
x402 challenges as a hiero-checkout
entry β the same priced resource is a 402 for agents AND a checkout QR for
humans, judged by the same rule:
flowchart LR
C["@x402/core Β· hedera Β· hono<br/>official x402 β moves the money"] --> X["hiero-x402<br/>(this repo)"]
subgraph HIERO["Hiero ecosystem β open source, Apache-2.0"]
P["hiero-payment-requests"]
R["hiero-receipts"]
SN["streams-node"]
CK["hiero-checkout"]
end
P -- "match Β· byTransactionId" --> X
R -- "fromMirror Β· toHTML" --> X
SN -- "block-stream proofs" --> X
X -. "fed back: byTransactionId" .-> P
X -. "fed back: mirror-fetch" .-> R
X -. "fed back: true tx ids" .-> SN
X -. "fed back: x402 checkout entry" .-> CK
Two funded ECDSA testnet accounts: facilitator (sponsors fees) and agent (pays); the server holds no payment keys. Testnet HBAR is free from the Hedera Portal faucet; testnet USDC for the token route comes from Circle's faucet (pick Hedera Testnet β auto-association does the rest).
npm install # @hiero-hackers packages need a read:packages token
cp .env.example .env # fill in the two accounts
npm run demo # facilitator (:4020) + server (:4021) β hub at :4021/ui
npm run e2e # the agent: 402 β sign β 200 β VERIFY β receipt.htmlThe hub at :4021/ui is the demo β every control below is on it. All
knobs, one page: docs/configuration.md.
npm run verify β typecheck, lint, format, tests, coverage floored at
100% statements and branches, all offline. Ground rules:
CONTRIBUTING.md Β· security posture:
SECURITY.md Β· the research that decided everything:
research/.
Apache-2.0








