HCS Registry
HCS Registry
The registry is a single HCS topic shared by all sellers. To list a service, the seller submits a signed JSON message of type
listing to that topic, containing a full ServiceListing object — endpoints, pricing models, base URL, quote path, receipt topic, and UAID.Buyers read the topic through the Hedera mirror node (a public, unauthenticated API). The mirror node returns every message in sequence order, along with the Hedera account that paid for each message submission. This payer account is the trust anchor.Trust model: a listing is only accepted by the buyer if the HCS message’s payerAccountId matches the payTo field inside the listing itself. Since you must own a Hedera account’s private key to pay for an HCS message, this proves the listing was published by the entity that will receive payments — without any registry operator or off-chain authority.To delist, the seller submits a message of type delist with its UAID. The buyer’s registry reader applies delists in sequence and drops any listing that has been removed by its controlling account.Agent Identity (HCS-14 UAID)
Agent Identity (HCS-14 UAID)
Every seller and buyer in Agora402 carries an HCS-14 Universal Agent Identifier (UAID) — a globally unique, deterministic string that identifies an agent independently of its deployment details.The identifier is derived as:The six fields hashed are:
name, nativeId, protocol, registry, skills, and version — sorted alphabetically in the canonical JSON. Endpoints, topics, base URLs, and private keys are deliberately excluded, so the UAID is stable across redeploys, IP changes, and key rotations.The parameters appended after the hash provide human-readable context:Trust: quote signatures and HCS message payers are verified against the
payTo account on the mirror node. Because the UAID includes the nativeId (the CAIP-10 Hedera account), a buyer can confirm that the agent signing a quote controls the account that will receive payment — without any PKI or certificate authority.x402 Pay-per-Request
x402 Pay-per-Request
x402 is an open HTTP payment protocol that uses the
402 Payment Required status code. Instead of a subscription or a pre-issued API key, every billable request triggers a payment negotiation inline inside the HTTP exchange.The Agora402 flow using the exact scheme on Hedera:- The buyer sends the request (e.g.,
POST /v1/infer). - The seller’s
@x402/expressmiddleware intercepts and returns a402response with aPAYMENT-REQUIREDheader containing:scheme=exact— the buyer must pay exactly this amountnetwork=hedera:testnet— the CAIP-2 network identifierasset=0.0.0— native HBAR (or an HTS token ID)amount— atomic units (tinybars for HBAR)payTo— the seller’s account IDextra.feePayer— Blocky402’s fee-payer account
- The
@x402/fetchclient on the buyer runs spend controls (asset allowlist, per-call cap) and session policies (remaining budget check). If any control rejects the payment option, the request fails immediately without charging the buyer. @x402/hederabuilds aTransferTransaction: buyer → seller foramount, with Blocky402 as thetransactionFeePayerAccountId. The buyer signs this transaction with its own key and retries the original request with aPAYMENT-SIGNATUREheader.- The seller middleware calls Blocky402
/verify, which decodes the transaction, validates the signature and amounts, and reports the payer. - On a successful handler response (2xx), the middleware calls Blocky402
/settle. Blocky402 co-signs as fee payer, submits to Hedera, and returns the finalized transaction ID in thePAYMENT-RESPONSEheader.
Quote Negotiation
Quote Negotiation
The quote handshake is a free, pre-payment negotiation step that lets the buyer lock in a price and optionally counter below list.Request — buyer sends If the offer falls below the seller’s floor, the seller responds with
POST /a2a/quote:endpointId— which endpoint to priceestimate— a work estimate (token counts, units, etc.) used to run the pricing modelmaxAmount— the buyer’s ceiling in atomic units; acts as a counter-offer if below list priceasset—0.0.0for HBAR or an HTS token ID
Quote:409 Conflict and returns minimumAmount and listPrice so the buyer can decide whether to retry at a higher offer or abandon.The buyer verifies the ECDSA signature over the canonical quote body and, if verifyQuoteSigner is enabled, checks via the mirror node that signerPublicKey is the key of the payTo account. A quote is single-use: the seller marks it consumed on settlement so it cannot be replayed.Pricing Models
Pricing Models
The Per-token — a base charge plus per-thousand rates for input and budgeted output tokens:For a request with 12 input tokens and 256 budgeted output tokens:
The same
PricingModel type is a discriminated union of three models. All amounts are decimal strings of atomic units (tinybars for HBAR) — no floating-point arithmetic ever touches money. The priceFor(model, estimate) function uses only BigInt internally and rounds up per 1,000 tokens.Flat — a fixed price per request, regardless of input size:50000 + ceil(12 × 10000 / 1000) + ceil(256 × 20000 / 1000) = 50000 + 120 + 5120 = 55240 tinybarsPer-unit — a charge per discrete unit (e.g., one API query, one second of compute):priceFor function runs on both the buyer and the seller. The buyer computes the list price locally to rank sellers before quoting; the seller recomputes it when pricing the quote. Because the function is deterministic and BigInt-only, both sides always agree.Token estimation uses a simple heuristic: ceil(text.length / 4) characters per token — the same function on both sides, so estimates are reproducible without calling the LLM.HCS Receipts and Audit
HCS Receipts and Audit
After every successful settlement, the seller’s The
onAfterSettle hook writes a Receipt to a dedicated HCS topic. Receipts include:Auditing with
agora receipts:ReceiptLedger.audit() method fetches every receipt from the HCS topic, then fetches the corresponding settlement transaction from the mirror node. For each receipt it checks:- The on-chain transfer matches
payer,payTo,asset, andamount. - The receipt was written by the expected seller account.
- The transaction result is
SUCCESS.
FAIL flag. Honest sellers pass every check; a seller that inflates amounts or misattributes payers will be caught automatically.Budget Controls
Budget Controls
The You can also pass
BuyerAgent enforces two independent spending limits configured at construction time.Per-call cap (maxPerCall) — the maximum amount the buyer will pay for a single request, in atomic units of the preferred asset. This is enforced by the @x402/fetch spend controls before the transaction is even signed. If the 402 asks for more than maxPerCall, the request fails immediately — no signature is produced and no funds leave the buyer’s account.Session budget (sessionBudget) — the total the agent may spend across all calls in the current process lifetime. A registered policy on the x402 client computes remaining = sessionBudget − totalSpent before each payment. If no accepted payment option is affordable within the remaining budget, the request fails with a clear error message rather than silently overspending.Both limits are denominated in the same atomic units as the pricing models. Use the parseAmount(human, decimals) helper to convert human-readable HBAR strings (e.g., "0.05") to tinybars (e.g., 5000000n) when configuring the agent.--max-call and --budget (in HBAR) to the agora CLI:Assets: HBAR and TOLL Token
Assets: HBAR and TOLL Token
Agora402 supports two settlement assets.Native HBAR — the default. Asset ID is Replace
0.0.0 (a sentinel that maps to the native HBAR transfer in a Hedera TransferTransaction). HBAR has 8 decimal places; 1 HBAR = 100,000,000 tinybars. No token association is required.TOLL HTS Token — an optional HTS token created by npm run setup:token. The TOLL token carries a custom fixed fee in its transfer path, so every token transfer automatically routes a portion to a fee-collection account. This is useful for platform monetisation or liquidity incentives. The buyer must associate their account with the token before they can receive it (the setup script does this automatically).Settlement asset in the ServiceListing:"asset": "0.0.0" with your TOLL token ID (e.g., "0.0.33333") and update symbol and decimals to match. The buyer selects options matching its configured asset preference, so a listing can offer both HBAR and TOLL options for the same endpoint — the buyer automatically picks the one it can pay with.