
Source Mark
Paid Graph reads that refuse when provenance fails — x402 on Hedera, sources get paid.
Demo
About
SourceMark is a paid read layer for onchain data that refuses to answer when it cannot prove provenance. Agents and apps that act on rates, TVLs, or other indexed metrics need more than a dashboard number: a stale or substituted subgraph answer is not a UI bug, it is a wrong transaction. SourceMark turns that into an HTTP product with real money attached. Callers request a metric over a schema family (for example Messari lending on Ethereum) from a single endpoint. The gateway looks up the family in a data-only registry of pinned The Graph deployment IDs that share a byte-identical schema IPFS hash, fans the same GraphQL query out to every ready source in parallel, and judges each response against live chain head for block lag and age. Sources that fail freshness, report indexing errors, or serve a different deployment than the pin are dropped with a reason. Families declare whether sources must agree (identical) or may differ (peer); identical disagreement refuses the whole read instead of papering over it with a median. Unpaid requests return a real HTTP 402 with x402 payment requirements on Hedera testnet (HBAR via the Blocky402 facilitator). No API key and no signup — the challenge is the onboarding. When a payment header is present, the gateway verifies with the facilitator first and does not settle yet. Only if the provenance gate passes does it settle, answer, and issue a signed receipt naming every contributing deployment, its block, the policy, and the payment. Digests can also be published to a Hedera Consensus Service topic so existence-at-time is not only our database. If the gate fails, the response is 409 REFUSED and settlement is skipped — refusal is free by construction, so the service cannot profit from a guess. On success, revenue is recorded in SourcePayouts on Hedera: a routing fee, per-source shares, and a slashable unvested holdback. Demo source operators opt in with EIP-191 consent over their payout addresses and can claim cleared balances themselves. Anyone can dispute a receipt; the service re-queries The Graph at the recorded blocks. MATCH rejects with no slash. MISMATCH slashes holdback on the ledger and drives onchain openDispute, with arbiter resolveDispute or permissionless resolveAfterDeadline after silence. Buyers who pay in USDC on Base reach the same gate through Bazantic resale. Their rail cannot answer a Hedera x402 challenge, so the gateway uses api-key forward while sources are still paid in HBAR from an operator float — same provenance policy, same onchain split, receipt marked channel:resale. The live multi-page demo on Railway shows 402, paid read, forced refusal, resale, disputes, explore tables, and an SDK page.
How it's made
SourceMark is a TypeScript gateway on Hono (Node 22) with a multi-page static demo (home, demo, explore, sdk), a thin SDK package, and an MCP server plus SKILL.md for agents. The serving path never substitutes fixtures for live Graph data: if sources are unreachable or unpinned, reads refuse. Data layer — The Graph. registry/families.json maps a schema IPFS hash and query templates to pinned deployment IDs. Conformance is checked with The Graph’s network subgraph (byte-identical schemaIpfsHash), not marketing labels. At read time the resolver fans out through the decentralized gateway, reads _meta.deployment and enforces the pin, measures freshness against Ethereum RPC chain head (ANCHOR_MODE=rpc), and aggregates: median for identical families, TVL-weighted for peer families. That peer/identical split mattered: a naive median across Aave V3, V2, Spark, and a wound-down pool produced a rate none of them paid. Payments — Hedera + Blocky402. x402 v2 exact scheme on hedera:testnet via @x402/hedera and the Blocky402 facilitator. Verify and settle are separate calls: verify before Graph work, settle only after the gate. Buyer helpers ship with the product (CLI, loop agent, in-page demo) so the paywall is exercisable, not theoretical. Receipts and consent — viem. Answers and evidence are keccak-hashed over canonical JSON and EIP-191 signed. POST /v1/consent verifies a signature from the registered payout address. Optional HCS publish uses @hashgraph/sdk so digests land on a public topic. Liability — SourcePayouts.sol (Hardhat, Hedera testnet). recordRead locks the split and holdback; claim lets sources withdraw cleared balances; openDispute takes a bond; resolveDispute (arbiter) or resolveAfterDeadline (permissionless after disputeResolveSeconds) upholds or rejects. Dispute decisions are driven by Graph re-derive at receipt blocks, not arbiter opinion alone. A Hedera-specific unit trap mattered in production: msg.value arrives in tinybar while eth_getBalance is weibar; disputeBond must be stored in tinybar and sent as bond×1e10 weibar or openDispute reverts BadBond. Distribution — Bazantic. Registered from OpenAPI as api-key (not x402-mpp) because USDC-on-Base cannot satisfy a Hedera challenge. Same completeRead() path as direct buyers, so refusal cannot be skipped on resale. A multi-service recipe pairs SourceMark with Hedera Mirror Node; public recipe JSON lives in bazantic/. Notable hacks / hard-won details: free refusal via verify-then-settle; operator float ledger when rails do not meet; falsified-receipt demo that corrupts per-source anchors (hash-only tamper still MATCHed on value alignment); gas floors on Hedera resolve txs after under-estimated gas; dedicated DEMO_SOURCE_MNEMONIC payees instead of the public Hardhat phrase. Partners: The Graph (live data + schema identity), Hedera (x402, SourcePayouts, HCS), Bazantic (distribution and Mirror Node recipe).