Hedera Consensus Service (HCS)
HCS provides an ordered, tamper-evident log of messages anchored to Hedera consensus. Agora402 uses two HCS topics: one for the service registry, and one for payment receipts.Registry Topic
Sellers publish service listings to the registry topic by submitting an HCS message. The message body is a JSON envelope withtype: "listing" containing the full ServiceListing object — endpoints, pricing models, payTo account, facilitator URL, and quote path. To delist, a seller submits a type: "delist" message with their UAID.
Registry message envelope (listing)
Registry message envelope (delist)
payTo account it names. The buyer agent checks the HCS payer account for each listing it reads from the mirror node and discards any listing where the payer does not match the payTo field. This binds listings to accounts without any central authority — you cannot publish a listing that claims someone else’s payment account.
Receipts Topic
After every settled payment, the seller writes a receipt message to the receipts HCS topic. The receipt includes the Hedera transaction ID, payer, payTo, asset, amount, the endpoint path, optional token usage, and a SHA-256 hash of the response body.Receipt message on the receipts topic
agora receipts to audit the topic: the CLI reads every receipt, looks up the corresponding transaction on the mirror node, recomputes the amounts, and flags any discrepancy.
Audit the receipts topic
Hedera Token Service (HTS)
HTS enables custom fungible tokens on Hedera. Agora402 uses HTS optionally through the TOLL token — an alternative settlement asset you can create alongside native HBAR.Default: Native HBAR
Unless you create a TOLL token, all payments use native HBAR. In x402 terms, native HBAR is identified by asset ID0.0.0 with 8 decimal places. All amounts in PAYMENT-REQUIRED headers, quotes, and receipts are expressed in tinybars (1 HBAR = 100,000,000 tinybars).
Optional: TOLL Token
The TOLL token is an HTS fungible token created bynpm run setup:token. It is configured with a custom fixed fee in its transfer path, which means every TOLL transfer automatically routes a portion to the fee collector. Both seller and buyer accounts must be associated with the TOLL token before it can be used for settlement.
Create and configure the TOLL token
asset alongside HBAR. The buyer agent selects the preferred asset with the asset option (set to the HTS token ID instead of 0.0.0).
The TOLL token is optional. If
TOLL_TOKEN_ID is empty in your .env, all endpoints accept only HBAR and the token setup scripts are not needed.Hedera Accounts and Keys
Agora402 requires ECDSA accounts — accounts backed by secp256k1 keys — for both sellers and buyers. ED25519 accounts are not supported because@x402/hedera constructs signatures over x402 payment payloads using the secp256k1 curve.
Seller Account
The seller account (SELLER_ACCOUNT_ID) serves three purposes:
- It is the
payToaccount that receives every payment transfer. - Its private key signs all HCS registry and receipt messages, establishing listing ownership.
- Its private key signs quotes, allowing buyers to cryptographically verify that a quote came from the claimed seller.
Buyer Account
The buyer account (BUYER_ACCOUNT_ID) is created by npm run setup:buyer, which transfers 100 HBAR from the seller account to fund it. The buyer’s private key signs the TransferTransaction inside every PAYMENT-SIGNATURE header — it authorizes the debit from the buyer account to the seller.
Quote Signing
When a buyer receives a quote from a seller, it verifies two things: the ECDSA signature over the canonical quote bytes, and — ifverifyQuoteSigner is enabled — that the signing key is actually the key controlling the seller’s payTo account (checked against the Hedera mirror node). This prevents a malicious actor from impersonating a seller with a fake quote.
Mirror Node
All read operations in Agora402 go through the free public Hedera mirror node — no Hedera SDK account or operator key is needed for reads. The mirror node is the sole source of truth for discovery, verification, and audit.Mirror node base URLs