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.
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, androuteIdOf(inbox)returns the same route ID. - Vault
bridgeGateway(),metalChainId(),outbox()andmetalInbox()match the configured message routes. Each inbox uses the intended light client and source chain. - Gateway
pool()matches the pool, and poolbridgeGateway()names this gateway. - Vault
supportedToken(token)is true. GatewayassetRouteOf(routeId, token)names the intended pool asset, andforeignTokenOf(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.
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 satisfy0 < 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 asclaimDeposit(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 aBridgeMint 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:
- A successful receipt contains the pool’s
BridgeMintedfor the exact asset, deposit ID, amount and note commitment. bridgeDepositMinted(depositId)is true, and the note appears in the pool’s commitment tree. Save its index and update the note’s membership witness.- Pool bridge liability and route reserve increase by the amount, and route pending decreases by the amount, accounting for any concurrent activity.
- The receipt block is canonical and final on Metal.
Recover a rejected deposit
A Failed verdict queues a refund message from the Metal gateway. Save itsDepositRefunded(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.