The Internet Computer, verified on Base, Arc, Robinhood and Taifoon mainnet

What went live
LIVE. A light client for the Internet Computer's ICP ledger is deployed on Base, Arc, Robinhood Chain and Taifoon mainnet. It sits at the same address on all four, 0x518A7cddF565A2c36D9e58C18CE1e2a19EEd5F5C, and on each chain it has verified a certificate signed by the Internet Computer's NNS subnet: the ledger tip at block 38,756,677, hash 0x7b4fb99df5d03d11eb86eee3199a28f9009615af2b8d4799ddac939d2852c25e.
- Base (8453): deployment 0x664468d2…8a45, certificate verified 0x661e96c7…68c1
- Arc (5042): deployment 0x0c8c9cf9…907a, certificate verified 0x5d2a5c1c…7b84
- Robinhood Chain (4663): deployment 0xcde884aa…bd13, certificate verified 0xc259af06…1421
- Taifoon mainnet (3692781): deployment
0x5b5680ae97d36c987832af4c86959ca248bce6b5326288979fd692fb02fe4ca7, certificate verified0x08dde16d8b0289577b5c4c664c2b91d0cb446ed59e31c4fd5aa110d83e73f2f4(no public explorer yet; read them fromhttps://mainnet.taifoon.dev)
Deploying cost about 1.49M gas on each chain; verifying the certificate cost about 294k. The source is published on Sourcify as an exact match.
What it checks
The Internet Computer signs the root of its state tree with a threshold BLS12-381 key held by the NNS subnet. The ICP ledger canister puts the hash of its latest block into that tree as its certified data. So a certificate is a short proof: a signature over a root, and the hashes needed to show that the ledger's tip hash sits under that root.
The contract redoes all of it on the EVM:
- the BLS12-381 pairing, through the EIP-2537 precompiles that Base, Arc, Robinhood Chain and Taifoon mainnet all have;
- the hash-to-curve of the signed message, in Solidity, under the Internet Computer's domain tag;
- the state-tree witness, hash by hash, from the ledger's certified data and from the time leaf to the same root;
- and then, from a certified tip, the chain of ledger blocks behind it: each block's hash is the SHA-256 of its bytes, and its bytes begin with its parent's hash, so a run of blocks is proven with
proveAncestors.
Once a ledger block is proven, a transfer inside it is a fact the chain can act on. That is what the deposit gate will use.
The gates and the custody canister, also live
LIVE. The same evening the rest went up. A deposit gate sits on each chain: 0x0B55d43D956b70edC19B45c196db3843F231f7eF on Base, Arc and Robinhood Chain, and 0xbe50518009bf0D04716c1b69E4b4d3138A7B8590 on Taifoon mainnet. Each comes with its own wrapped ICP token (0xa3B2eB502006369581eDD898d22ca559e64f8c07; 0xF9245Ab96Dfd49c67b5efE855936F2283835a0fe on Taifoon mainnet), minted only by the gate against a ledger deposit the light client has proven. The gates are owned by the Taifoon council, a 3-of-5 multisig: the same one at the same address on Base, Arc and Robinhood Chain (recreated on Arc the same day), and its twin with the same five owners on Taifoon mainnet. The addresses are in the deployment record.
Behind them, on the Internet Computer, the custody canister dkafq-4aaaa-aaaaj-a6ysq-cai holds the deposited ICP and releases it only against a burn that every configured RPC endpoint of that chain reports in a finalized block. Three guardians, threshold two; releases are unpaused; all four gates are configured.
Gate deploys: Base 0x1f3cdabc…f8a4, Arc 0x074fafdd…9198, Robinhood 0xa5f07066…1840, Taifoon mainnet 0xd4b7354ff205d04c347863c317853750ed6ddfaaf9beae5127c99b42f75f5227.
Ready to use: what works right now
- Deposit. Read your deposit account on the gate:
depositAccount(yourAddress)returns the ICP ledger account to send to. Send ICP there from any ICP wallet. The custodian sweeps it into the pool and the gate credits you. - Prove. Submit the ledger tip after your deposit (
submitTip), then the run of blocks down to your deposit (proveAncestors). Anyone can; the proof carries the authority. - Mint.
claim(block, yourAddress)mints wrapped ICP, less one ledger fee, once per block. The council opened minting on all four gates; each readsmintPaused() == false, shown live on /bridge. - Redeem.
redeem(amount, icpAccount)burns and the canister pays the ICP out, minus the ledger fee; minimum 0.1 ICP, fixed for good.
The first trip, step by step
LIVE. On 3 October 2026 we sent ICP through the route on Base and back, using only the public path described above. A quarter of an ICP in, 0.2499 wrapped ICP minted, 0.2 redeemed, 0.1999 ICP paid back. Here is each step, what it proves, and where to check it.
1. Deposit. We asked the Base gate for the deposit account of our address and sent 0.25 ICP to it from an ordinary ICP wallet. The transfer landed in ICP ledger block 38,769,510, hash 0x3e6821b04f4e2d25f319375f6f767e6078b7ae234ef795096425163fb5eeeac3. The custody canister derives the same account on its own; the two were compared before a single token moved.
2. Sweep. The canister moved the deposit into its custody pool (ledger block 38,769,512) and credited the Base gate with 0.2499 ICP of backing. Releases for a gate can never exceed what was swept in for it.
3. Certificate. We fetched the ledger tip seven blocks later (38,769,517, hash 0xd35a3e089bc6e6d21997213f607d881988f9726025b6c9247a119db13d4f4f8e) with the Internet Computer's certificate, and submitted it with submitTip. The contract checked the NNS signature on chain: 0x40251727…a0a6, 259,565 gas. Proof.
4. Ancestors. Eight ledger blocks, from the deposit up to that tip, each one beginning with the hash of the one before. proveAncestors walked them and marked the deposit block as part of the ledger: 0xd19db902…269e, 215,843 gas. Proof.
5. Claim. claim read the transfer out of the proven block, saw that it paid our deposit account, and minted 0.2499 wrapped ICP (the deposit less one ledger fee): 0x3b021547…c1b8, 316,669 gas. Proof. The same block can never be claimed twice.
6. Redeem. We burned 0.2 wrapped ICP and named an ICP account to be paid: 0x86f28de0…5060, Base block 52,115,007. Proof.
7. Release. The canister paid 0.1999 ICP in ledger block 38,769,768, but only after Base had finalized the burn, about twenty minutes later, and both of the endpoints it asks had reported the same event.
The three calls that mint (steps 3 to 5) cost about 792,000 gas together.
Each proof link is the coordination layer's answer for that transaction: the Base block that holds it, the path from that block to the superroot, and Base's finality commitment. It proves the block, and that the transaction is in it; it does not carry a separate event layer for these calls. For the Internet Computer side, https://api.taifoon.dev/api/icp/certified-tip serves the latest verified tip with its certificate, and https://api.taifoon.dev/api/icp/block-proof/ serves a recent block linked to that tip, together with ready calldata for submitTip and proveAncestors. The ledger keeps only about its newest thousand blocks at hand, so prove a deposit soon after you make it.
What the trip caught
The first release was refused, and it was right to be. One of the two Base endpoints the canister was set to ask does not answer receipt lookups without a paid token, so only one endpoint could report the burn where two are required. Nothing was at risk; the canister simply would not pay. The guardians replaced that endpoint with a two-of-three vote, and the same release then passed on the first call. The endpoints for the other three chains were checked for the same fault and answer both questions the canister asks. We would rather find this with a quarter of an ICP than have you find it.
The same trip on Arc and Robinhood Chain
LIVE. The same day we ran it on the other two chains, 0.12 ICP each, 0.1 redeemed. This time nothing was built by hand: the two proof calls were sent exactly as https://api.taifoon.dev/api/icp/block-proof/ serves them, which is the path you would take.
Arc (5042). Deposit in ICP ledger block 38,770,056. Certificate 0x8a811b4c…3a55, ancestors 0x4ef8fa65…27cb, claim of 0.1199 0x48ad836c…9cb0, redeem 0x017a63a6…3597. The release paid in ledger block 38,770,071 on the first call, seconds after the burn: Arc's blocks are final at once. Proofs: certificate, ancestors, claim, redeem.
Robinhood Chain (4663). Deposit in ICP ledger block 38,770,074. Certificate 0x18e433ff…7835, ancestors 0x4040e882…543d, claim of 0.1199 0xe80e475e…3713, redeem 0xbed74d30…efc3. The release paid in ledger block 38,770,225, about 25 minutes after the burn, once Robinhood Chain had finalized it. Proofs: certificate, ancestors, claim, redeem.
On all three chains the mint followed the deposit within two minutes. The way back is as fast as the chain's finality: seconds on Arc, about 20 minutes on Base, about 25 on Robinhood Chain.
What the trips caught on our own side: when they ran, the coordination layer had not stored the block headers they landed in. Its collectors were following both chains at the tip but skipping blocks under load, and it said so instead of answering. We added a way to refill missing headers, gave both chains a second RPC, and found that Arc was missing from the list of chains folded into the root. All of it is fixed, and every step on all three chains now has a proof, linked above.
It is a route on the bridge now
LIVE. On /bridge, pick Internet Computer as FROM or TO, with Base, Arc or Robinhood Chain on the other side. The asset switches to ICP, the route shows in the same table as every other bridge with its measured cost and time, and the panel under it reads your deposit account from the gate. The wrapped token is tICP ("Taifoon ICP"), 8 decimals, at 0xa3B2eB502006369581eDD898d22ca559e64f8c07 on all three chains. Taifoon mainnet has a gate too, but no trip has run there yet, so the bridge does not offer it.
BUILDING. The same light client as a Solana program, using Solana's BLS12-381 syscalls, is built and tested on the runtime. Not deployed.
One honest limit: the ICP ledger does not certify block numbers, only hashes. The contract proves that a block is on the ledger, not which number it carries.
Try it
Read the latest certified tip and when the Internet Computer signed it (nanoseconds since 1970):
cast call --rpc-url https://mainnet.base.org 0x518A7cddF565A2c36D9e58C18CE1e2a19EEd5F5C 'latestTip()(bytes32)'cast call --rpc-url https://mainnet.base.org 0x518A7cddF565A2c36D9e58C18CE1e2a19EEd5F5C 'latestTime()(uint64)'Ask whether a ledger block hash is proven:
cast call --rpc-url https://rpc.mainnet.arc.io 0x518A7cddF565A2c36D9e58C18CE1e2a19EEd5F5C \ 'isLedgerBlock(bytes32)(bool)' 0x7b4fb99df5d03d11eb86eee3199a28f9009615af2b8d4799ddac939d2852c25eYour deposit account on Base, from any address:
cast call --rpc-url https://mainnet.base.org 0x0B55d43D956b70edC19B45c196db3843F231f7eF 'depositAccount(address)(bytes32)' <your address>Submit a newer certificate yourself: query the ledger canister ryjl3-tyaaa-aaaaa-aaaba-cai for query_encoded_blocks, take the certificate from the reply, and call submitTip with the certified data, the two witnesses and the signature as a G1 point in EIP-2537 encoding. Anyone may; the certificate carries the authority. The same works on Taifoon mainnet at https://mainnet.taifoon.dev.
Why this matters
Every bridge to the Internet Computer today, including the one that issues the ICP token on Ethereum, Base and Arbitrum, verifies the other side through RPC providers that have to agree, and is upgradable by a small set of keys. A light client is the other way round: the chain checks the Internet Computer's own signature, and nobody stands in between. The outbound direction, releasing ICP for a burn, still needs a custodian; that part is built and stated as what it trusts, and is not live.
