
DeComp
A GPU compute market where AI agents rent Macs and pay per 5s of GPU time
Demo
About
DeComp is a GPU compute market for AI agents. Providers sell time on their Apple-silicon Macs; agents rent it and pay per five seconds of measured GPU time, using x402 over HTTP and settling every payment on Hedera through the Blocky402 facilitator. The problem. An AI agent that needs a GPU today has to sign up for a cloud account, hold a credit card, and rent by the hour. Meanwhile there are a lot of idle Apple-silicon Macs with capable GPUs and no way to sell five seconds of that time to a machine that only needs five seconds. Neither side can transact without a human in the loop. How a job works. The agent reads an HCS topic where providers have published their prices, and picks the cheapest one that offers the job type. It calls POST /jobs and gets back HTTP 402 with an x402 PAYMENT-REQUIRED challenge: the exact scheme on hedera:testnet, one tick's price, the provider's payTo account, and the facilitator's fee-payer account. The agent builds a Hedera TransferTransaction, signs it, and retries. The provider verifies the payment, starts the job on its GPU, settles through Blocky402, and answers 202 with the job id and the settlement transaction id. While the job runs, each new 5-second tick is a fresh 402 challenge — payment streams alongside the compute, and the provider kills any job whose measured runtime passes its paid time plus a 5-second grace. Stop paying, and compute stops. When the job ends, the agent confirms every settlement on the mirror node and publishes an audit record to a second HCS topic. No private keys exist in this system. Every account — agent, providers, operator, and every connector user — is a Privy wallet plus the Hedera account it keys. Privy has no Hedera chain type, so these are secp256k1 wallets used as raw signers: a Hedera ECDSA signature is plain secp256k1 over the keccak256 digest of a transaction body, which Privy's raw_sign produces directly (normalized to low-s, which Hedera requires). .env holds no Hedera key material at all. Every component consumes one HederaIdentity interface — an account plus a signer — so the same agent, provider, and payment-gate code runs unchanged whether the identity comes from a fixed role, an OAuth-authenticated person, or a self-custodial wallet in a desktop app. What's in the repo: - Agent (apps/agent) — CLI and library: HCS discovery, cheapest-first routing with fallback, tick payments, mirror-node confirmation, audit publishing. - Provider (apps/provider) — Bun server: the x402 gate, per-GPU-second pricing, a metered job queue, HCS self-registration on boot. - Job runner (services/job-runner) — FastAPI sidecar running a fixed job menu (a matmul benchmark, a Mandelbrot render) on MLX or PyTorch MPS as killable subprocesses, metered by wall clock. It refuses to run on CPU. - Claude connector (apps/connector) — a remote MCP server behind its own OAuth 2.1 authorization server. Add DeComp as a custom connector in Claude, sign in once with Privy, and run paid GPU jobs by chatting — no terminal, no key. - Provider bridge (apps/bridge) — a WebSocket relay so a provider behind NAT is reachable with no public IP, domain, or tunnel. It holds no keys and trusts nothing but a connect-time signature checked against the mirror node. - Decomp Node (apps/provider-node) — a macOS desktop app (Electron + React, ships as a .dmg). Log in, and it provisions your Hedera account, starts the GPU runner and provider, publishes your listing, and shows earnings and job history. Hedera is used for four distinct things: HBAR and HTS transfers for settlement; an HCS registry topic for provider discovery and pricing; an HCS audit topic for per-job records; and the mirror node for confirmation and for verifying payer keys. Jobs can be paid in HBAR or in DCC, an HTS compute-credit token. A standalone script (bun run audit:reconstruct) rebuilds every provider's earnings from HCS and the mirror node alone, with no agent code involved — so the audit trail is checkable by anyone against the chain. Status. Live on Hedera testnet with four validation gates that run against the real network: paid jobs end to end, discovery and fallback, metered ticks with billing matching measured time, and a job paid entirely in DCC with its audit record reconstructed from chain data.
How it's made
Stack. TypeScript on Bun throughout (workspaces monorepo, Bun.serve, bun:sqlite, bun test), Python 3.12 + FastAPI for the GPU sidecar, React + Electron for the desktop app, and Hedera testnet for everything on-chain. The x402 layer is built on the official @x402/core and @x402/hedera packages; Hedera access is the @hiero-ledger/sdk plus the public mirror-node REST API. How it fits together. The monorepo splits into four shared packages and five apps. @decomp/privy-hedera turns a Privy wallet into a Hedera signer and exposes one HederaIdentity type — an account id, an x402 payment signer, and a client factory. @decomp/hedera-x402 is the x402 layer: a Bun.serve payment gate, a step-by-step paying client, facilitator wiring, and mirror/token helpers. @decomp/hcs-registry holds the HCS message schemas and chunk-aware mirror readers. Every app consumes HederaIdentity and nothing else, which is why the same agent and provider code runs unchanged behind a CLI role, an OAuth-authenticated connector user, and a self-custodial wallet in a desktop app — the identity seam was the single most useful design decision in the project. Partner tech and what it actually bought us: - Hedera does four separate jobs here, not one. HBAR/HTS transfers settle payments; an HCS topic is the provider registry, so discovery needs no server we run; a second HCS topic is the job audit log; and the mirror node confirms settlements and supplies payer public keys. Because HCS is a durable public log, bun run audit:reconstruct rebuilds every provider's earnings from the chain alone, with no agent code in the loop — the audit trail is verifiable by a third party, which is a property we got essentially for free by putting it on HCS instead of in a database. Sub-cent, seconds-to-finality fees are also what make a 5-second billing tick economically sane at all; per-tick settlement on a chain with dollar fees would be absurd. - x402 gave us metering for free. We didn't build a billing system: the 402-challenge/retry cycle is the meter. Each tick is just another 402, so payment streams alongside compute, and "stop paying" and "stop computing" are the same event. - Blocky402 as facilitator means the agent never holds HBAR for gas or submits anything itself — it signs a transfer whose transaction id sits under the facilitator's fee-payer account, and the facilitator adds its signature and submits. - Privy is why there are no private keys in this repo at all. The genuinely hacky parts: 1. Privy has no Hedera chain type. We use secp256k1 "ethereum" wallets as raw signers, which works because a Hedera ECDSA signature is plain secp256k1 over the keccak256 digest of a transaction body — exactly what Privy's raw_sign produces. Two gotchas: Hedera rejects high-s signatures, so every signature is normalized to low-s; and signatures are verified locally against the account's on-chain key before anything is sent, so a mismatched wallet fails immediately instead of as an opaque INVALID_SIGNATURE twenty seconds later. 2. One signature per consensus node. A Hedera transaction carries a separate body per node, and the SDK asks the signer for each — a default freeze meant seven Privy round-trips per payment. We pin payments to two nodes: two signatures, with a spare node left for the facilitator. Subtlety that cost real debugging time: the client's network map is keyed by address, and one node answers on several, so naively taking two entries can yield the same account twice — two bodies for one node, and the signed payload fails to parse. The node list is deduplicated by account first. 3. We don't trust the facilitator's /verify. On 2026-09-12 Blocky402's hosted testnet /verify returned isValid: true for transfers signed with the wrong key; they only failed at settlement — meaning a provider that trusted it would burn GPU time on payments that could never settle. The provider now checks every debited account's signature against its on-chain key itself, before starting any paid work. 4. HCS registrations outlive the processes that publish them. A provider that went offline hours ago is still in the registry, so list_providers was routing agents to dead nodes. Discovery now probes each candidate's /health with a 3s timeout and drops anyone that doesn't answer. (Deliberately not added to the routing path — that already falls back on connection failure, so a probe there would only add latency to the happy case.) 5. The provider bridge. A relay so anyone with a Mac can be a provider without a public IP, domain, or tunnel. The provider opens one persistent WebSocket outward and proves control of its Hedera account by signing a connect-time challenge, which the bridge verifies against the mirror node. Requests to <bridge>/p/<accountId>/... are relayed over that socket. The bridge holds no keys and trusts nothing but that signature. 6. Sandboxing by subprocess, not Docker — containers can't reach the Metal GPU on macOS. Jobs run as killable subprocesses from a fixed menu with validated parameters and hard runtime limits. The runner refuses to start on CPU, so "GPU job" is enforced, not assumed.