Search projects, hackathons, sponsors and tech

    ← All projects

    Tally

    A shop's revenue becomes a bond: Chainlink prices it privately, Hedera issues and repays it.

    Demo

    About

    Tally turns a small business's real revenue into a short-term, fixed-rate bond. It's underwritten in private, priced in public, and pays itself back. THE PROBLEM Many small shops have a year of steady card sales but no bank credit history. They can't borrow against the one thing that actually predicts repayment: their revenue. When they do get credit, underwriting is manual, opaque and one-off, and a good repayment record never follows them to their next lender. HOW TALLY WORKS Connect revenue. A business registers and connects its Stripe account through Stripe Connect. Tally reads its real charges directly; the business never types in a number. Underwrite. Tally boils the sales history down to three facts: revenue over the last 90 days, how many days of history exist, and how much daily sales swing (volatility). A fixed, transparent policy decides. It needs at least 30 days of history, at least $3,000 of 90-day revenue, and volatility under a cap. The coupon (interest) rate starts at 4% and rises with volatility. The same policy runs live on Chainlink's network as a CRE workflow. Nine independent Chainlink nodes read the revenue through an authenticated API and agree on the verdict, and only the verdict is reported, never the raw revenue. Issue. An approved business gets a real fixed-rate bond, issued on Hedera testnet through Hedera's Asset Tokenization Studio, with its units minted to Tally's custodian account. Pay itself back. Each coupon payment is a Hedera Scheduled Transaction that waits for its due date. The Hedera network executes the payment by itself, with no bot, no cron job and nobody pressing a button, and sends real HBAR to the bondholder. Tally then uses the network's own timestamp to record whether each payment was on time, and writes that result on-chain. Resell. A secondary market lets bondholders list and sell their bonds. The bond token enforces compliance itself: a buyer who hasn't passed KYC is rejected on-chain by the token contract, not by our website. Build a public credit record. Every bond's lifecycle (issued, coupon paid on time or late, resold, redeemed) is indexed by a subgraph on The Graph, so any future lender can look up an issuer's repayment history before lending again.

    How it's made

    Tally is a pnpm + Turborepo TypeScript monorepo: A Next.js 15 web app, deployed on Vercel, with its data in Postgres (Neon). Four shared packages: seam (shared types and fixed-point money), underwriting (revenue snapshot and pricing policy), ats-client (Hedera Asset Tokenization Studio) and scheduler (Hedera Scheduled Transactions). Solidity contracts built with Foundry, a subgraph, and a Chainlink CRE workflow. Money is never a float. Every amount is a 6-decimal fixed-point bigint end to end, from Stripe charges through underwriting to the bond's face value. HEDERA — three services, each doing real work: Asset Tokenization Studio issues a genuine fixed-rate bond, not a token we made up. Compliance comes built in: KYC, whitelists and transfer restrictions are enforced inside the token itself, so when an account without KYC tried to buy on our secondary market, the token contract rejected it on-chain. Scheduled Transactions with setWaitForExpiry(true) are the whole settlement engine. Each coupon payment executes by itself at its due date, with no keeper bot or cron job. Hedera won't schedule more than about 60 days ahead, so Tally stores the full coupon calendar at issuance and a background job schedules each coupon once it comes within range. The Mirror Node is our source of truth. Whether a payment was on time comes from the network's own consensus timestamp, and the secondary-market order book is rebuilt from contract event logs rather than a database table. THE HACKIEST PART — signing Hedera ATS transactions from a server: The ATS SDK only signs inside a web browser: it checks for window, then needs a MetaMask-style window.ethereum. It fails in plain Node.js, and faking window only moves the error somewhere else. So Tally launches a real headless Chromium with Playwright, injects a minimal EIP-1193 wallet backed by an ethers wallet holding the custodian key, and loads an esbuild bundle of the SDK from http://localhost. It has to be localhost, because the SDK calls crypto.randomUUID(), which only works on a secure origin. Getting the SDK to bundle for the browser took four tricks: stubbing server-only logging and custodial-wallet modules it imports whether or not they're used pointing the Hedera SDK import at its browser build by absolute file path, because esbuild ignores the browser field when exports is present defining global as globalThis working around an SDK quirk where a 0.0.x account ID resolves to a different EVM address than the one actually holding the tokens CHAINLINK CRE — decentralised credit decisions: The underwriting workflow is written in TypeScript with the CRE SDK and deployed live to Chainlink's private registry. Every minute it fetches a business's revenue snapshot using a secret held by CRE, applies the same policy as our underwriting package, and reports only approve/decline and the coupon rate, never the raw revenue. Nine independent nodes compute the verdict and reach consensus, so the credit decision doesn't depend on trusting our server. It's built to keep revenue inside a trusted execution environment (TEE) once Chainlink enables confidential execution for our private-beta workflow. THE GRAPH — a public credit record: A subgraph indexes each bond's lifecycle events (issued, coupon, resale, redeemed, defaulted) into per-issuer standings: bonds issued, coupons on time and coupons late. Repayment history becomes a public, queryable record that follows the business to its next lender. Subgraph Studio can't index Hedera, so we also deploy the contracts to Ethereum Sepolia and index that copy. STRIPE: Stripe Connect OAuth reads each business's charges from its own Stripe account. Charges are de-duplicated by ID, so revenue is never counted twice. For testing, Stripe Test Clocks create genuinely backdated paid invoices through Stripe's own API instead of fake database rows. SECURITY: Any route that moves value (issuing a bond, arming coupons, listing or filling orders) refuses requests that come through a proxy or tunnel unless they carry an admin token, and the hosted site refuses them entirely. The revenue endpoint Chainlink reads checks its secret token in constant time.