Manual
Nametoll
Nametoll is a named pay desk. A buyer agent is given a name, not a URL and not an API key. The desk resolves that name, asks a TEE whether the spend is under cap, challenges unpaid GETs with HTTP 402, settles HBAR through Blocky402, returns metered units, and appends a bill the public can recompute.
This origin sells live lending-risk snapshots. Price is 100000 tinybars per requested protocol (0.001 HBAR) on hedera:testnet.
The loop
name → TEE allow → pay (Blocky402) → metered units → HCS bill
- Paste or pass a name. The happy path does not ship one.
- Directory returns endpoint, pay-to, price rule, HCS topic, asset
0.0.0.
- Brain returns
allow, maxTinybars, and a public reason. Secrets stay in the enclave.
- Unpaid
GET /desk/snapshot is HTTP 402.
- Pay settles
exact HBAR. The snapshot is billed per delivered protocol.
- The bill is on the HCS topic. Recompute from Mirror Node.
Directory
A parent namespace is the catalog. /desks and GET /desk/catalog?parent= list children, resolve each descriptor, and probe whether that origin is taking payment. GET /desk/offer is this origin's public price and protocol list — not the pay path.
An agent that is handed only the parent:
npm run agent -- <paste-a-parent-name>
It enumerates children, picks by price and protocols, asks the TEE, pays, and prints the receipt. That is how another agent finds a service and pays for it.
Open a desk
Use the desk console or HTTP. Type or paste the name. Choose 1 or 2 protocols. Open desk calls GET /desk/inspect. If the TEE allows, Pay calls POST /desk/pay with the same name and protocol list.
Pay spends the operator buyer key on this origin. It is rate-limited, optionally gated by a shared secret cookie or x-desk-pay-secret, and pinned to PUBLIC_DESK_URL when that is set. Inspect stays open.
HTTP 402
The resource is /desk/snapshot. Amounts are tinybars. Asset is Hedera 0.0.0. Scheme is x402 v2 exact. Facilitator: https://api.testnet.blocky402.com. This process does not hold a facilitator key. Fee-payer comes from live GET /supported.
curl -sD - -H 'Accept: application/json' \
http://127.0.0.1:8787/desk/snapshot
Spend cap
The CRE handler runs in a TEE. Secrets: spend cap, optional buyer allowlist, optional pays-per-hour. Public reasons are under cap, over cap, buyer not allowlisted, and rate limited. A deny or an unavailable enclave blocks settle and merchandise. Successful verdicts are cached per amount, payer, and hour-count for 60s. Failures are not cached. GET /health reports brain.verdictTtlMs.
curl -sS "http://127.0.0.1:8787/desk/brain?tinybars=100000"
Metering
Units are the number of protocols in the request, not response bytes. Catalog on this desk:
| id | label | network |
aave-v3-ethereum | Aave v3 Ethereum | ethereum |
compound-v3-ethereum | Compound v3 Ethereum | ethereum |
1 protocol = 100000 tinybars. 2 protocols = twice that. If an indexer is down, that protocol fail-softs; you are billed for delivered units.
Remainder
Prepaid tinybars are the 402 amount. Owed tinybars are delivered units × price. If the desk delivers fewer units than prepaid, unused remainder is refunded as a seller-signed HBAR transfer. The HCS bill stores prepaid, owed, and refund. There is no second topic.
Ledger
Topic 0.0.10464309. Recipe: GET Mirror Node /api/v1/topics/{topicId}/messages, base64-decode each message, then check units * priceTinybarsPerUnit = tinybars. If prepaidTinybars is present, prepaidTinybars - tinybars = refundTinybars.
Pay attaches the bill only when the settle transaction is on the topic. If Mirror Node is still catching up, the HashScan settle link still stands; the bill block is omitted rather than showing someone else’s receipt.
curl -sS http://127.0.0.1:8787/desk/ledger
Subscribe
Recurring snapshots use Hedera scheduled transactions, not a second 402. The buyer pre-authorizes N transfers with wait_for_expiry. Each slot expires at most 62 days out. When Mirror Node shows executed_timestamp, GET /desk/claim?schedule= delivers one snapshot. The HBAR snapshot 402 stays asset 0.0.0.
HTS is a desk-credit token with a custom fixed HBAR fee to the seller. Blocky402 /supported does not advertise a non-HBAR asset, so the pay path does not switch tokens. GET /desk/hts publishes the token plan. npm run hts -- create broadcasts it. Put the id in HTS_TOKEN_ID.
curl -sS "http://127.0.0.1:8787/desk/subscribe?slots=2&intervalSec=604800"
curl -sS http://127.0.0.1:8787/desk/hts
npm run subscribe -- --plan --slots 2 --interval-sec 120
npm run subscribe -- --slots 2 --interval-sec 120
npm run hts -- probe
npm run hts -- plan
curl -sS "http://127.0.0.1:8787/desk/claim?schedule=<0.0.x>"
HTTP API
| Method | Path | Does |
| GET | /health | Liveness, modules, brain TTL, whether this origin can pay |
| GET | /desk/resolve?name= | Directory descriptor from a live name |
| GET | /desk/catalog?parent= | Children of a parent, each resolved and probed |
| GET | /desk/offer | This origin's price and protocol ids |
| GET | /desk/inspect?name=&protocols= | Descriptor + TEE verdict + unpaid 402 |
| POST | /desk/pay | Settle, snapshot, bill (when matched) |
| GET | /desk/snapshot | Merchandise; 402 if unpaid |
| GET | /desk/brain?tinybars= | Public verdict for an amount |
| GET | /desk/join | Unsigned join() from the same TEE — this origin does not broadcast it |
| GET | /desk/ledger | Topic, bills, recompute recipe |
| GET | /desk/subscribe?slots= | Unsigned scheduled-payment plan |
| GET | /desk/claim?schedule= | Deliver a snapshot after a slot executes |
| GET | /desk/hts | TOLL token plan + Blocky402 asset probe |
curl -sS "http://127.0.0.1:8787/desk/inspect?name=<paste-a-name>&protocols=aave-v3-ethereum"
curl -sS -X POST http://127.0.0.1:8787/desk/pay \
-H 'content-type: application/json' \
-H "x-desk-pay-secret: ${DESK_PAY_SECRET:-}" \
-d '{"name":"<paste-a-name>","protocols":["aave-v3-ethereum"]}'
Agent CLI
Headless buyer. Pass a name or a desk URL. Protocol ids are optional; omit them to request the full catalog. A protocol id that is not in the catalog is how you exercise unused-remainder refund.
npm run buyer -- http://127.0.0.1:8787
npm run buyer -- http://127.0.0.1:8787 aave-v3-ethereum
npm run buyer -- http://127.0.0.1:8787 not-a-real-protocol
npm run buyer -- <paste-a-name>
npm run agent -- <paste-a-parent-name>
npm run directory -- <paste-a-name>
npm run ens:subname -- --plan --parent <parent> --label agent-02
npm run subscribe -- --plan --slots 2 --interval-sec 120
npm run hts -- probe
npm run join -- --check
npm run join
Operators
Do not commit secrets. Copy .env.example locally. Never put a facilitator private key on the resource server. Directory text keys: url, agent-context, agent-endpoint[web]. CRE HTTP inside the TEE uses HTTPClient + TeeRuntime only.
Product pages: /landing, /desks, /app, /docs. / is the product page.