Skip to main content
What you’ll be able to do
  • Deposit an asset on another chain and receive shielded funds on Metal.
  • Recover a rejected deposit through the refund process.
To bridge funds into Metal, the depositor transfers a supported token to a vault, a smart contract on the source chain that holds the deposited tokens. Those tokens back the recipient’s shielded funds on Metal. The vault records a message containing the deposit details. A relayer submits that message for verification on Metal, where the gateway bridge contract records a claim, a pending record of the deposit. After any required screening passes, the recipient authorizes minting with a proof, and Metal’s shielded pool creates a shielded note that the recipient can spend on Metal.

Confirm the route and proving prerequisites

Obtain an authenticated route configuration from the bridge provider. It must identify both chain IDs and RPC endpoints, the source vault and token, Metal gateway and pool, route ID, mapped pool asset, inboxes and light clients in both directions, and public contract artifacts. The depositor needs source tokens, and each signing account needs funds for transaction fees on its chain. Use the vault and gateway reference for exact read methods and return fields. Before depositing, compare these values and record the blocks used for the reads:
  • Gateway routeOf(routeId) matches the source vault, source chain and Metal inbox, and routeIdOf(inbox) returns the same route ID.
  • Vault bridgeGateway(), metalChainId(), outbox() and metalInbox() match the configured message routes. Each inbox uses the intended light client and source chain.
  • Gateway pool() matches the pool, and pool bridgeGateway() names this gateway.
  • Vault supportedToken(token) is true. Gateway assetRouteOf(routeId, token) names the intended pool asset, and foreignTokenOf(routeId, asset) returns that source token.
  • The deposit fits cap - reserve - pending, and the amount in the token’s smallest units matches the deposit instruction. The bridge preserves those units across the route.
Route capacity can change before the claim arrives, so confirm capacity with the provider for a large deposit. If the route is full when the claim arrives, the source tokens remain in the vault while claim delivery waits for capacity. Obtain the provider’s public note and key tools, the pool’s matching BridgeMint circuit artifact, and Barretenberg proof-generation instructions. Prepare a current sanctions nonmembership witness and private storage for note recovery. The proof requires the owner’s authorization and the exact note opening. Read screeningAuthority() and, when it is nonzero, arrange screening with that authority before depositing. Verify both message directions, including the refund path back to the vault. The Metal checkpoint verifier accepts only epoch zero, as explained in sending messages.

Prepare the note and deposit

Use the note tools to construct a note for the mapped pool asset and deposit amount in the token’s smallest units. Generate and privately save the owner’s recovery data, note opening and commitment before approving any tokens. The commitment must be nonzero and below the BN254 field modulus. The amount must satisfy 0 < amount < 2^128 and fit the source balance. Approve the source vault to spend that amount of the supported ERC-20 token. Verify the approval transaction and allowance before calling deposit(token, amount, noteCommitment). Use the deposit ABI with a source-chain wallet client. Save each signed transaction and its hash before broadcasting. The vault requires exact token delivery and rejects fee-on-transfer deposits. In the successful deposit receipt, decode DepositReceived from the vault and MessageSent from its outbox. Save the actual deposit ID and outbox nonce. Check the depositor, token, amount and note commitment, then read depositOf(depositId) at that block. Verify the depositor-to-vault token transfer and the vault’s balance increase. Apply the source chain’s finality policy and check the receipt’s canonical block before delivering the claim.

Deliver the claim and check screening

Follow receiving messages to prove the source outbox message under an accepted checkpoint and execute it on Metal. The source sender must be the configured vault, and the receiving contract must be the Metal gateway. Decode the payload as claimDeposit(depositId, token, amount, noteCommitment) and compare every field to the saved deposit before relaying. Require a successful Metal receipt containing the inbox’s execution event and the gateway’s DepositClaimed. Read claimOf(depositId) and match asset, amount, note commitment, route ID and source token. Confirm the route’s pending amount increased by the deposit. Its reserve increases only after minting. When reconciling aggregate route balances, use the transaction’s events and account for concurrent changes in state reads. When screening is enabled, wait for DepositScreened from the configured gateway and read verdictOf(depositId). 1 means Passed and permits minting. 0 means Unset, so keep waiting. 2 means Failed and permanently prevents minting this claim. Only the configured authority’s account may call screen to set this verdict, which cannot be changed afterward.

Prove and mint the shielded note

After obtaining the deposit ID, use the public proving tools to create a BridgeMint proof for the exact recorded claim. Its ordered inputs are listed in the bridge mint reference. They bind Metal chain ID, pool contract address, note commitment, amount, pool asset, deposit ID and the current sanctions root. Verify the proof locally against the pool’s current circuit before submission. Read the sanctions root and circuit configuration again before submitting. If either changed, refresh the required witness or artifact and regenerate the proof. Bridge minting accepts only the current sanctions root. Retain the private note opening and owner keys, while keeping proofs and transaction records separate from secret recovery material. Simulate and submit gateway mint(depositId, sanctionsRoot, mintProof) from any Metal signing account. The signing account’s balance in the gas token pays the transaction fee. Save the signed transaction and hash before broadcast, then verify:
  1. A successful receipt contains the pool’s BridgeMinted for the exact asset, deposit ID, amount and note commitment.
  2. bridgeDepositMinted(depositId) is true, and the note appears in the pool’s commitment tree. Save its index and update the note’s membership witness.
  3. Pool bridge liability and route reserve increase by the amount, and route pending decreases by the amount, accounting for any concurrent activity.
  4. The receipt block is canonical and final on Metal.
After these checks, mark the shielded note available in the wallet’s private records. Verify that a second mint of the same deposit fails without appending another note or increasing liability.

Recover a rejected deposit

A Failed verdict queues a refund message from the Metal gateway. Save its DepositRefunded(depositId, routeId, outboxNonce) event and confirm that pending has decreased. The tokens remain in the source vault until that refund instruction is delivered. Follow sending messages to relay the exact refundDeposit(depositId) call to the source vault. Authenticate the gateway as source sender and the vault as receiving contract. In the source-chain execution receipt, verify the vault’s DepositRefunded event, depositOf(depositId).refunded == true, and the token transfer from vault to the original depositor. Confirm the depositor received the amount and check source-chain finality before marking the refund complete. A failed transfer leaves delivery retryable. Preserve the original refund message and resolve the transfer condition before retrying. Refunds require the screening authority’s Failed verdict, so this path is available only on routes with screening enabled.

Resume without depositing twice

Track each deposit by source chain, vault and deposit ID. Retain both message nonces, signed transaction attempts, checkpoint evidence, claim and verdict state, and the eventual mint or refund transaction. If a response is lost, look up the saved transaction hash and read the corresponding onchain state to resume the existing deposit. Test the route’s rejection of duplicate claims, duplicate mints and invalid proofs, and verify rollback on cap or screening failure. With the screening authority’s agreement, use a separate disposable deposit to test the Failed verdict and complete refund delivery.