Bridging M and wM Tokens
This guide explains how to manually bridge $M and Wrapped $M (w$M) tokens across chains using Portal V2 and a block explorer's "Write as Proxy" interface.
Portal V2 is M0's unified cross-chain bridge. It replaces the previous two-portal system (Portal Standard on Wormhole NTT and Portal Lite on Hyperlane) with a single contract on every chain. The same three-step flow (quote, approve, sendToken) works in every direction: from the hub to a spoke, from a spoke back to the hub, and between spokes where cross-spoke transfers are enabled.
$M and w$M, but the same flow applies when the source or destination token is an extension. If wrapping to an extension fails on the destination chain, the recipient receives the underlying $M token instead.Prerequisites
- A Web3 wallet (for example, MetaMask) connected to the source chain.
- The wallet funded with the token you want to bridge.
- Native currency on the source chain to pay for gas and the messaging fee (for example, ETH on Ethereum).
How Portal V2 addressing works
Every chain runs one Portal contract:
HubPortalon Ethereum locks tokens when you bridge out and releases them when you bridge back.SpokePortalon every other chain mints tokens when they arrive and burns them when you bridge away.
You always interact with the Portal on the chain you are sending from. A few things differ from the old system:
- Standard EVM chain IDs. The
destinationChainIdis the destination chain's standard EVM chain ID (for example, Ethereum is1), not a Wormhole chain ID. The Portal's bridge adapter maps it to the underlying provider internally. bytes32addresses. Therecipient,destinationToken, andrefundAddressfields arebytes32, notaddress. Left-pad a 20-byte EVM address to 32 bytes by prefixing it with0xfollowed by 24 zeros (12 bytes), then the 40 hex characters of the address. For example, address0xABCD...1234becomes0x000000000000000000000000ABCD...1234.- A messaging fee. Cross-chain delivery costs a fee that you pass as native value on the
sendTokencall. Read it fromquotefirst.
Supported chains
Portal V2 is live on the chains below. Ethereum is the hub; the rest are spokes. When a step asks for a destinationChainId, use the destination's EVM chain ID from this table.
| Chain | EVM chain ID |
|---|---|
| Ethereum (hub) | 1 |
| Arbitrum | 42161 |
| Base | 8453 |
| Linea | 59144 |
| BNB | 56 |
| HyperEVM | 999 |
| Plume | 98866 |
| Mantra | 5888 |
| Soneium | 1868 |
| Plasma | 9745 |
| Citrea | 4114 |
| 0G | 16661 |
| Fluent | 25363 |
| Moca | 2288 |
| Monad | 143 |
| Rise | 4153 |
Look up each chain's HubPortal / SpokePortal and token addresses on the Deployments page.
Solana is a non-EVM (SVM) chain. It is supported as a spoke, but the addressing and tooling differ. See the Solana docs for Solana-specific steps.
Addresses
Do not hard-code addresses from this guide. Look up the current HubPortal, SpokePortal, $M, and w$M addresses for each chain on the Deployments page.
$M and w$M use 6 decimal places. When entering an amount in a contract call, add 6 zeros. To transfer 10 tokens, enter 10000000.Bridging with Write as Proxy
The flow below is identical whether you are bridging from Ethereum to a spoke, from a spoke to Ethereum, or between two spokes. Perform every step on the source chain's block explorer (for example, Etherscan for Ethereum, Arbiscan for Arbitrum).
Step 1: Open the source-chain Portal in Write as Proxy
Look up the Portal address for your source chain on the Deployments page. On Ethereum this is the HubPortal; on every other chain it is the SpokePortal.
Open that address on the source chain's block explorer, go to the Contract tab, then Write as Proxy, and connect your wallet.
Step 2: Read the fee with quote
On the Read as Proxy tab, call quote:
destinationChainId: the destination chain's standard EVM chain ID (for example,1for Ethereum,42161for Arbitrum).payloadType:0(TokenTransfer).
Note the returned value. This is the messaging fee in the source chain's native currency (in wei). You will pass it as the payable value in Step 4.
Step 3: Approve the Portal to spend your tokens
Open the token you are bridging ($M or w$M) on the source chain's block explorer, go to Write (or Write as Proxy), and call approve:
spender: the Portal address from Step 1.amount: the amount to bridge, in base units (6 decimals; see the note above).
Confirm the transaction and wait for it to be mined.
Step 4: Call sendToken
Return to the Portal's Write as Proxy tab and call sendToken:
payableAmount(the native value sent with the call): the fee returned byquotein Step 2.amount: the amount to bridge, in base units.sourceToken: the address of the token on the source chain ($Morw$M).destinationChainId: the destination chain's standard EVM chain ID.destinationToken: thebytes32address of the token you want to receive on the destination chain.recipient: thebytes32address that receives the tokens on the destination chain.refundAddress: thebytes32address that receives any leftover native fee on the source chain.bridgeAdapterArgs: leave empty (0x) to use the default bridge adapter for the destination chain.
Confirm the transaction. The Portal locks or burns your tokens on the source chain and emits a TokenSent event with a messageId.
Step 5: Wait for delivery
The selected bridge adapter relays the message to the destination chain, where the Portal mints or releases the tokens to your recipient. Delivery time depends on the underlying bridge provider. You can track the destination Portal for a matching TokenReceived event.
refundAddress you provided, so a slightly high quote value is safe.Related
- Portal V2 - Architecture, message types, and security model.
- Deployments - Current Portal and token addresses per chain.
- Integrating with Portal V2 - Developer guide with contract calls and a code example.
- Solana - Bridging to and from Solana.
Integrating with Portal V2
Developer guide for bridging M and Wrapped M tokens across chains with M0 Portal V2, including sendToken and quote signatures and a TypeScript viem example.
Design templates
Compare M0's stablecoin extension models to find the right monetization strategy and deployment chain for your use case.