Search projects, hackathons, sponsors and tech

    ← All projects

    ProofStream

    ProofStream turns live DEX data into portable Merkle receipts anyone can verify.

    Demo

    About

    ProofStream is a verification layer for blockchain data APIs. It fetches live DEX activity from The Graph, including recent swaps, pool activity, and wallet-origin activity across supported networks. The raw GraphQL response is converted into readable records and sealed into a Merkle tree using the MerkleForge Framework. Users can select any activity record and generate a compact cryptographic receipt containing the record, dataset root, and Merkle proof. The receipt is verified locally in the browser without downloading the complete dataset or trusting the application’s backend. If the selected record is modified, verification fails immediately. ProofStream includes editable GraphQL and JSON views, human-readable activity cards, token information, tamper testing, developer-level proof details, and downloadable JSON and PDF receipts. Graph API keys are used only in browser memory and are never stored. The project demonstrates how wallets, dashboards, AI agents, light clients, and data providers can make indexed blockchain responses independently verifiable. ProofStream proves that a record belongs to a specific sealed dataset; it does not claim that the upstream indexer or blockchain data source is independently correct.

    How it's made

    ProofStream is built as a TypeScript and Rust workspace. Its interactive web application uses React 19, TypeScript, and Vite, while its proof engine is built with Rust and the MerkleForge Framework. The browser connects directly to The Graph Gateway through editable GraphQL queries. I created schema-aware presets for Uniswap V3, Aerodrome, SushiSwap, ApeSwap, Trader Joe, and compatible deployments across multiple networks. ProofStream also integrates Messari’s standardized DEX AMM schema, allowing SushiSwap, ApeSwap, and Trader Joe to share the same GraphQL query and normalization pipeline. Only the live Subgraph deployment ID changes between these protocols. Users can request recent swaps, activity from a particular pool, or records associated with a wallet address. The Graph is a load-bearing part of the project: it supplies the live indexed blockchain data that ProofStream converts into verifiable receipts. The application does not rely on mocked or static data for its live demonstration. After receiving a GraphQL response, ProofStream normalizes each swap into a deterministic, human-readable row containing the protocol, schema version, token pair, token addresses, amounts, USD value, transaction hash, wallet origin, pool, and block number. These exact normalized rows become the leaves of a Merkle tree. Deterministic normalization is essential because even a small change to a committed field must produce a different hash. The proof layer uses domain-separated Keccak-256 hashing. Leaf data and internal nodes receive different prefixes before hashing, preventing the two node types from being interpreted interchangeably. ProofStream combines the leaf hashes into a binary Merkle tree, produces one dataset root, and generates a compact sibling path for the selected row. The browser then performs stateless verification using only the selected row, its index, the helper hashes, and the expected root. It does not need the complete dataset or access to the source database. If a user changes an amount, address, token pair, or any other committed value, the browser computes a different root and rejects the receipt. The Rust implementation uses `merkle-core`, `merkleforge-hash`, and `merkle-variants` from MerkleForge. It constructs a `BinaryMerkleTree<Keccak256>` and produces a serializable proof packet. I implemented the same proof algorithm in TypeScript so judges and developers can run the complete verification flow in a browser without installing Rust, operating a backend, or trusting a server-side verification result. The interface separates the workflow into Query, Dataset, and Receipt views. Users can inspect and edit the GraphQL request and raw JSON response, while the same data is translated into readable activity cards. Receipts can be downloaded as structured JSON for software integrations or as a plain-language PDF generated with jsPDF. Token metadata and artwork improve readability but are deliberately excluded from the canonical data used for hashing. For privacy, Graph API keys remain only in React memory while the page is open. They are sent directly to The Graph in the request authorization header and are never written to local storage, session storage, the repository, or a ProofStream database. A particularly useful part of the implementation is that ProofStream preserves both representations of the data: the original API response remains inspectable, while the normalized version becomes cryptographically strict. Users can edit the JSON, rebuild the dataset, modify a selected claim, and immediately observe how each change affects the Merkle root and verification result.