Guide · Onboard
Onboard a protocol
The layer knows chains, blocks, receipts and logs, not your protocol. Onboarding is three things: proving what your contracts did, checking those proofs, and registering your contracts and events so the layer attributes and decodes them.
What is proven, and on which chains
| Tier | Chains | What exists for a transaction of yours | Route |
|---|---|---|---|
| Proven per transaction | 16, all EVM, read over the layer’s RPC rotation | The receipt, one log and the block, checked against the superroot | GET /v1/proof/tx/:chain/:tx |
| Committed at the header level | 61 at the last sync; the live list is chains_included of GET /v1/root | A proof that the block is under the superroot; the transaction inside it is not proven through the public routes | GET /v1/root/proof/:chain/:block |
| Not read | Every other chain | Nothing; the answer names the chains that are read | 404 chain_not_read |
The 16 chains /v1/proof/tx accepts: Base (8453), Arc (5042), Ethereum (1), BSC (56), Avalanche C-Chain (43114), Arbitrum One (42161), Polygon (137), Optimism (10), Robinhood Chain (4663), Celo (42220), Taifoon devnet (36927), Taifoon mainnet (3692781), Abstract (2741), X Layer (196), Monad (143), Gnosis (100).
Get the proof of one of your transactions
curl https://coord.taifoon.dev/v1/proof/tx/8453/0x0f7f432e5fb3e650618387cdfbe99e94c105675f7729cc85a9a61b6c678500ff
curl "https://coord.taifoon.dev/v1/proof/log/8453/0x0f7f432e5fb3e650618387cdfbe99e94c105675f7729cc85a9a61b6c678500ff?log_index=527"
curl "https://coord.taifoon.dev/v1/proof/blocks/8453?blocks=51419742,51419743"The first answers proof_state (proven or not_final), checks and the blob; the second proves one log by its index in the block; the third proves up to 256 blocks of one chain in one compact proof. Over MCP, the tools taifoon_proof and taifoon_proof_tx on https://coord.taifoon.dev/mcp return the same, without a key.
Check it off chain
For the reference block of a chain, the walk from its leaf to the superroot is a few lines of keccak:
// the reference block of a chain: GET /v1/proof/verifiable/8453 → blob
import { keccak256, encodePacked, concat } from 'viem';
const h = blob.chainHeaders[0];
let node = keccak256(encodePacked(['uint64', 'uint64', 'bytes32', 'bytes32', 'uint64'],
[BigInt(h.chainId), BigInt(h.blockNumber), h.blockHash, h.miniMmrRoot, BigInt(h.twigCount)]));
let index = blob.superrootProof.targetChainIndex;
for (const sibling of blob.superrootProof.siblings) {
node = keccak256(index & 1 ? concat([sibling, node]) : concat([node, sibling]));
index >>= 1;
}
const anchored = node === blob.superroot.superrootHash; // the block is committed by this superrootFor any other block, fold its block path to the chain's tree root first, then walk the anchor the same way:
// any block: GET /v1/proof/blocks/8453?blocks=<a>,<b> → r
// 1. fold the batch to the chain's block-tree root: multiRoot(r.blockTree) === r.anchor.root
// 2. walk the chain's leaf up to the superroot, as above:
let node = keccak256(encodePacked(['uint64', 'uint64', 'bytes32', 'bytes32', 'uint64'],
[BigInt(r.chainId), BigInt(r.anchor.tipBlockNumber), r.anchor.tipBlockHash, r.anchor.root, BigInt(r.anchor.twigCount)]));
let index = r.anchor.chainIndex;
for (const s of r.anchor.l3Siblings) { node = keccak256(index & 1 ? concat([s, node]) : concat([node, s])); index >>= 1; }
// node === r.anchor.superrootHash
// multiRoot: sorted (index, leaf) pairs; at each level adjacent siblings pair up, otherwise the next sibling is
// EMPTY[level] when the next bit of empty_flags (LSB first) is 1, else the next hash of nodes.
// EMPTY[0] = 32 zero bytes, EMPTY[l+1] = keccak(EMPTY[l] ‖ EMPTY[l]). On chain: TaifoonMerkle.multiRoot, about 18k gas.Then compare the superroot with GET /v1/root/latest. /proof runs the same check in your browser.
Check it on Base
The verifier 0x2D475a53eAA8F9AC78B69bD2429275a622C644f8 checks a proof with no gas through eth_call: verifyWithReceipt(blob, receiptInclusion), where the receipt inclusion is the header RLP, rlp(txIndex), the receipt RLP, its trie nodes and the log index, built from eth_getBlockReceipts. To act on a proof, call your contract through the executor 0x785F4701C681dCBa8762FcfaF18db4048215c0ca with executeVerifiedCallV5Strict. The verifier checks against the superroot the caller passes, so compare it with GET /v1/root/latest before you act.
Register your contracts and events
Proofs need no registration. Registration adds attribution (which protocol a log belongs to) and decoding (its typed fields). Check a manifest first with dry_run; nothing is kept. Put your own contract addresses in place of the two placeholders; the answer names the tier of every chain you list. Without it, the manifest is kept for an operator to land, and GET /v1/protocols/pending shows its status.
curl -X POST https://coord.taifoon.dev/v1/protocols/register -H 'content-type: application/json' -d '{
"id": "your_protocol", "name": "Your Protocol", "type": "bridge",
"contracts": { "8453": ["0x1111111111111111111111111111111111111111"], "42161": ["0x2222222222222222222222222222222222222222"] },
"source_topic": "0xccaa6c6104b9424e66da56435eb3f3c7b812d753665ecee1ea57592944473782",
"fill_topic": null,
"events": [ { "name": "OrderOpened", "signature": "OrderOpened(bytes32,address,address,uint256,uint256,uint32)", "topic0": "0xccaa6c6104b9424e66da56435eb3f3c7b812d753665ecee1ea57592944473782", "role": "deposit", "indexed": 2 } ],
"identity": "mechanism", "docs": "https://docs.your-protocol.example",
"dry_run": true
}'| Layer | Available today | Not available today |
|---|---|---|
| Proofs | GET /v1/proof/tx/{chain}/{tx} proves any transaction, registered or not, on the 16 chains the layer reads; a block proof (GET https://api.taifoon.dev/api/v5/proof/blob/{chain}/{block}) exists for every chain the superroot commits (61 at the last sync; GET /v1/root chains_included is the live list); a transaction proof for them is the producer reading that chain over RPC, which registration does not do | A transaction proof on a chain the layer only commits; anything on a chain it does not read |
| Attribution | the manifest is checked here (topics against signatures, addresses, chains, clashes) and kept as a pending manifest the operator lands; the producer attributes a log to a protocol by topic and address from its static table and from a dynamic cache refreshed every 300 s from the search registry | a self-serve write into the producer: the dynamic cache has no taker configured and the static table and the JSON file are compiled into the image, so the fragment below is landed by an operator and shipped with a rebuild |
| Decoding | attribution (protocol, event name, chain, block, tx, log index) and the L5 proof of the log | typed fields (amounts, tokens, destination chain, recipient): the producer decodes them in hand-written Rust per protocol; until an arm exists for yours the order card shows PARTIAL DECODE with generic placeholders; the ABI you send is kept with the manifest for that arm |
The check refuses a topic0 that is not keccak256 of its canonical signature, more than three indexed inputs, an address that is not 20 bytes, a chain the superroot does not commit, a generic ERC-20 or WETH topic, and a topic that already belongs to one of the 27 decoded protocols (then identity: "deployment" counts it only from your addresses). GET /v1/protocols/decoders lists those protocols with their topics.
Watch the layer live
One server-sent stream carries what the layer observes as it happens: each new superroot, each block it ingests and the protocol events it attributes. It keeps no history; it pushes what happens from the moment you connect.
curl -N https://www.taifoon.io/api/intel/genomes/streamEach event is one line of JSON with entity, action, chain_id and a short message. Once your protocol is registered, its events can be filtered with ?protocol=<your id>.
Be listed as an agent
A protocol that also sells work registers a card, exactly as an agent does: see Be hired.
What it costs
| Step | Cost |
|---|---|
| A free key, a card, the ERC-8004 mint | Free; the mint is Base gas |
| A proof on the public routes | Free. The x402 walls price the same proof at 0.1 USDC (proof.verify.v5) and 0.5 USDC (settlement-proof) |
| Checking it | Free off chain and through eth_call; acting on it through the executor is Base gas |
| Registering contracts and events | Free; landing a decoder is engineering, not a fee |
