Search projects, hackathons, sponsors and tech

    ← All projects

    horofox

    An agent that cannot afford to answer you — until it earns the fee itself.

    Demo

    About

    CONTINUITY TRACK — DISCLOSURE UP FRONT. This project did not start from zero on day one, and the commit history says so plainly. The repository's first commit is 2026-08-31, four days before ETHOnline opened (2026-09-04 05:00 UTC). As of submission, 23 of 41 commits predate the event and 18 were made during it. The pre-event work is the trading agent and the self-funding ledger. Everything that makes this an ETHOnline submission was built during the event and is visible in `git log` from 2026-09-04 onward: the x402 payment layer on Hedera, the live paid production endpoint, the settled on-chain payments, and the demo. A commit dated 2026-09-04 in this repo is itself the written disclosure of the above. Nothing is hidden from the log; please read it. Every agent-payment project I could find solves one half of the problem: spending. Budgets, caps, allowances — how to stop an agent from spending too much. But an agent that can only spend is an agent on an allowance. Somebody else funds it. horofox closes the other half: it earns the money it spends, and until it has earned, it cannot answer you. The loop, end to end: 1. A user asks a question. The agent checks its own quota ledger, finds zero credits, and refuses. That refusal is the production code path, not a mock. 2. It earns. Every trade the agent routes carries a Hyperliquid builder code, and 0.1% of that flow accrues to us on-chain. No token minted, no fee invented — Hyperliquid pays it at the protocol level, so no rival can waive it to zero to squeeze us out. 3. The fee converts into inference credit through an idempotent ledger. Settle twice and the second call grants zero, because the ledger already counted that money. 4. To answer, the agent needs market data it does not have — so it buys it. x402 v2, exact scheme, on Hedera. It meets a 402, reads the requirements from the PAYMENT-REQUIRED header, signs a Hedera transaction and settles. The facilitator co-signs and pays the gas, so the agent never has to hold HBAR. 5. Now it answers, and one credit is consumed. This is live, not a mock. Real USDC has moved on Hedera testnet from the agent's account (0.0.10503338) into the service's (0.0.10503359), settling against the production endpoint at horofox.com — which returns a real, payable 402 to anyone who calls it. The data itself is worth paying for: Hyperliquid HIP-3 dexes carry tokenized equities, indices and pre-IPO markets that most price APIs do not list at all. These are perpetual futures, not shares — the service says so in its own llms.txt rather than letting an agent assume otherwise. One part of the loop is simulated, and the demo prints that on screen while it runs: registering a builder code requires a 100 USDC deposit in a Hyperliquid perps account, which has not been made, so the fee figure is injected into the real code path. Everything else — the refusal, the conversion, the payment, the answer — actually happens.

    How it's made

    Next.js (App Router) on Cloudflare Workers via OpenNext, TypeScript throughout, no database — every ledger is a JSON file behind a storage layer that degrades honestly when the filesystem is read-only. Payments — x402 v2 on Hedera. The official Hedera PoC uses the Express middleware from @x402/express, which does not work on the Next App Router, so the server side calls the framework-agnostic entry point directly: x402HTTPResourceServer.processHTTPRequest, with a small adapter that turns a Next Request into the shape the core expects. Scheme is exact via @x402/hedera; the facilitator is x402.org/facilitator on testnet and Blocky402 on mainnet, switchable by env var. v2 carries the payment requirements in the PAYMENT-REQUIRED header as base64 rather than in the body, and the header key casing is implementation-defined, so the lookup is case-insensitive and the decoded requirements are mirrored into the body so a human with curl can still debug it. The buying side (lib/x402/client.ts) is the half nobody else built. It wraps fetch with @x402/fetch, but the budget gate lives outside the payment library: before signing, the agent asks its own ledger whether it can afford this call. If the answer is no, the original 402 is returned unchanged rather than a synthesised error, so the caller cannot mistake a refusal for a payment. Each stage — requesting, payment_required, signing, settling, paid, refused — is emitted as an event, which is what the demo renders. Earning — Hyperliquid builder codes. Orders carry a builder code and 0.1% of perp flow accrues on-chain; lib/hl/revenue.ts reads the cumulative figure from the Hyperliquid info API. lib/selffund.ts converts it into inference credit and is idempotent by ledger: it records the cumulative amount already settled, so a second call grants nothing. Concurrent settlements are serialized through a promise chain — I found this with a probe that ran two settlements at once and got two full grants, which only stayed correct by last-write-wins luck. That probe is now a test. Discovery — an agent has to find the service before it can pay for it. /.well-known/x402, llms.txt, openapi.json and an MCP stdio server are all generated from one catalog module, so they cannot drift apart; a test asserts they agree. The llms.txt discloses the things a model should surface rather than hide: these are perps and not shares, pre-IPO markets price an implied valuation, and six of the ten HIP-3 dexes are dormant. Verification — 34 test scripts, run as a sweep. Two real bugs surfaced while wiring the loop for this submission. First, when the free quota was exhausted the endpoint returned a bare 402 telling the caller to pay over x402 while giving them nothing to pay against — an agent literally could not settle. Second, in paid mode the free allowance was consumed and then a 402 was returned anyway, so the documented "try before you pay" never worked. Three tests had encoded the buggy behaviour as correct; those were fixed too. The demo (npm run demo) labels every step [REAL] or [SIMULATED] on screen as it runs, because a demo that dresses up a mock as a settlement is worse than one that admits its gap.