Thermal

Private USDC tips for creators — support anonymously, settled gaslessly on Circle's Arc.

Thermal

Created At

ETHGlobal New York 2026

Project Description

Thermal lets you back creators and journalists with private, anonymous USDC support. Public tipping turns who-you-fund into a permanent, searchable record — risky for supporters of dissidents or controversial voices. Thermal breaks that link: you pick an amount and support in one tap, and the fan→creator relationship never touches a public ledger. Creators only ever see an anonymous running total — never a supporter list, not even to us.

Under the hood, balances live in a shielded pool (deposits/withdrawals are the only on-chain footprint; who-pays-whom is not), signed off-chain authorizations are aggregated per creator, and settled in near-instant, gasless USDC transactions on Circle's Arc network. A one-click "Run Demo" replays the full path end-to-end against mock adapters for judges, and the exact same code flips to real on-chain settlement via a single MOCK config switch.

How it's Made

Monorepo, two services.

Frontend (web/): Next.js 15 (App Router) + TypeScript + Tailwind. Dynamic for wallet connect (falls back to a simulated multi-wallet picker in demo mode). The support UI: amount selector (presets + custom) → one shared supportOnce() core that signs a tip authorization (EIP-191 message) and posts it; an in-app "DEMO MODE" badge + scripted Run Demo for a reproducible judge walkthrough. State is in React hooks (no localStorage). Three.js/WebGL thermal-dither background.

Backend (server/): Fastify (Node 22, TS). A frozen shared API contract (onboard / deposit / tip / me/spent / creator balance / withdraw). The core is a ports + adapters architecture: every external service (Unlink privacy accounts, Circle settlement on Arc) is an interface with two implementations — mock and real — selected at one place by a MOCK config flag (assertRealConfig fail-fasts if real keys are missing). A per-creator batcher accumulates verified authorizations and settles them as a single aggregated, gasless USDC transaction. PRIVACY by construction: settlement items deliberately carry NO fanAccountId, so the fan→creator link never reaches the settlement layer; nonce-monotonic anti-replay + signature verification on every tip.

Real-mode rails (studied against Circle's arc-nanopayments / x402-batching and the Unlink admin SDK): viem on Arc testnet (USDC 0x3600…0000, Circle Gateway), real withdraw() via a funded settler. Settlement submission and fan registration are gated behind precise TODOs + DevRel questions rather than faked — so the demo stays honest and the switch to real is non-destructive.

Stack: Next.js 15, React 19, TypeScript, Tailwind, Three.js, Fastify, viem, Dynamic, @unlink-xyz/sdk, Circle Arc (USDC). Notably hacky-but-clean bit: the entire judged demo runs on mock adapters yet exercises the real money-path code, so MOCK=false is the only change needed to go live.

background image mobile

Join the mailing list

Get the latest news and updates