
Ledger-of-Work
Agents buy multi-step web work over x402 on Hedera, metered, with a receipt anyone can verify.
Demo
About
When software pays software, the buyer gets bytes and no way to check them. No invoice, nothing tying the data to a real retrieval, and the money has already moved. A person would notice a number that looks wrong. An agent has no such instinct — which is how a $7M prediction-market resolution came down to a screenshot in a Discord channel that nobody could verify. Ledger of Work sells completed web work to agents over x402 on Hedera — logging in, searching, paginating, extracting — and hands back a receipt anyone can check without trusting us. PRICED BY THE WORK, NOT THE REQUEST Ten records cost the same as three, because they sit on one page. A hundred costs five times more, because it is ten pages. The meter charges for pages traversed and steps taken, against a price book published before you buy. THE RECEIPT IS THE PRODUCT Every job commits the answer, the rendered page, a screenshot, and — where the source allows it — a zkTLS proof from an independent attestor who watched the TLS session and signed what the site actually returned. That proof is the one thing on the receipt we could not forge, because we do not hold the attestor's key. CHECK IT YOURSELF IN A MINUTE Open the verifier, enter topic 0.0.10413059, sequence 18, seller 0.0.10410493, and drop in the four files from samples/ in the repo. Fourteen checks, all green. Now swap result-proof.json for result-proof.tampered.json — one character different. Thirteen checks still pass: the payment settled, the price follows the book, the page, screenshot and proof are all intact. One goes red. VOID. That page never contacts our servers. It reads the public Hedera mirror node from your browser, so it works if you assume we are lying. WHAT IS ON CHAIN RIGHT NOW 57 receipts. 53 paid jobs across five capabilities, from three separate accounts, four settled in an HTS token, seven carrying attestor proofs. Four charged nothing, because a job that delivers nothing is not billed. AN AGENT NEEDS NOTHING FROM US TO START It reads an open HCS directory with no submit key, resolves an HCS-14 identity and an A2A agent card, and negotiates over A2A message/send: state a budget and the seller offers a smaller job at the same published rate — never a discount, because the verifier re-checks the price against the book and a discount would fail its own audit. Then it pays and verifies. One command, starting from nothing but a topic id.
How it's made
A pnpm TypeScript monorepo: six packages, eight apps, 501 tests, none of which touch the network. Partner technologies, and what each actually bought us. Hedera Consensus Service is the receipt log — ordered, timestamped, append-only, and cheap enough that a fifth-of-a-cent job can afford to write to it, which is the property that makes per-job receipts viable at all. The mirror node REST API is what makes verification trustless: the verifier reads it directly from a browser, so a sceptic never has to ask us for anything. Blocky402 settles the x402 payments. HTS carries settlement in a token so an agent holding a stablecoin need not hold HBAR. Scheduled Transactions (HIP-423) give recurring payment, and setWaitForExpiry(true) is the difference between a standing order and every transfer firing at once. HCS-14 gives the service a name derived from what it is rather than where it is hosted. The genuinely hacky parts. Hedera only has x402's `exact` scheme — there is no `upto` — so work-based pricing is built from it: a pure plan() prices the job before any work, the buyer signs that one number, and the seller absorbs every overrun. The verifier therefore checks the quote against the published price book rather than the bill. Receipts must fit 1024 bytes because the mirror REST API does not reassemble chunked messages, which is why the receipt stores hashes rather than payloads and fails at build time naming the field to drop. transactionId.accountId must be the facilitator's feePayer, not the buyer's, or settlement returns InvalidSignature with no explanation — that one cost a day. Reclaim's attestor-core needs setCryptoImplementation because @reclaimprotocol/tls ships an empty crypto object in Node. Playwright drives the browser behind a policy we wrote after realising an allowlist was doing security by accident: robots.txt is now fetched and obeyed per request to RFC 9309 (a bare "Disallow:" means no restrictions, which whitehouse.gov serves), and an SSRF guard checks every address a hostname resolves to, judges IPv4-in-IPv6 by IPv4 rules, refuses zero-padded octets, and re-checks the URL after redirects. The proof tests run against a real captured attestor signature, because a hand-built fixture cannot tell a valid signature from a forged one and every test would pass.