Get Started with Gateway
Overview
Wormhole Gateway is a Cosmos SDK chain that provides a way to bridge non-native assets into the Cosmos ecosystem and serves as a source for unified liquidity across Cosmos chains. Because IBC is used to bridge assets from Gateway to Cosmos chains, liquidity fragmentation is avoided, and liquidity for foreign assets bridged via Wormhole into Cosmos is unified across Cosmos chains. In addition to facilitating asset transfers, Wormhole Gateway allows Wormhole to ensure proper accounting with the Global Accountant.
Integration
Integrating with Wormhole Gateway is straightforward and can be achieved with just a few lines of code as follows:
- For Transfers from an external chain to any supported Cosmos Chain, see Into Cosmos
- For Transfers from any supported Cosmos Chain to an external chain, see Out of Comsos
- For Transfers between any supported Cosmos Chains, see between Cosmos chains
Into Cosmos
To bridge assets into a Cosmos chain, an asset transfer is initiated on the foreign chain with a payload that is understood by the Gateway, or more specifically, the IBC Shim Contract. Once received on the Gateway, the asset's CW20 representation is sent to the destination chain through IBC using the well-established ICS20 protocol.
The following example uses the Wormhole SDK to prepare a bridge transfer from an external chain into Cosmos.
import * as wh from '@certusone/wormhole-sdk';
const transferDetails = {
gateway_transfer: {
// This is a simple transfer with no additional payload
chain: 4000, // Chain ID of the Cosmos destination chain
recipient: 'INSERT_COSMOS_RECIPIENT_ADDRESS', // Base64 encoded bech32
fee: 0, // Fee for transfer (0 for now)
nonce: 0,
},
};
// The address of the ibc-translator contract on the Gateway
const ibcTranslatorAddress =
'wormhole14ejqjyq8um4p3xfqj74yld5waqljf88fz25yxnma0cngspxe3les00fpjx';
// Convert the transfer details to a Uint8Array for sending
const payload = new Uint8Array(Buffer.from(JSON.stringify(transferDetails)));
// Send transfer transaction on Ethereum
const txReceipt = await wh.transferFromEth(
wh.consts.TESTNET.eth.token_bridge, // Source chain token bridge address
wallet, // Signer for eth tx
'INSERT_TOKEN_ADDRESS', // Address of token being transferred
10000000n, // Amount of token in its base units
wh.consts.CHAINS.wormchain, // Chain ID of destimation chain
ibcTranslatorAddress,
0, // Relayer fee, 0 for now
{}, // Transaction overrides (gas fees, etc...)
payload // The payload Gateway uses to route transfers
);
Out of Cosmos
To bridge assets out of the Cosmos ecosystem or between Cosmos chains, an IBC transfer is initiated on the source chain to the Gateway with a payload containing details about the transfer in the memo
field.
The following example demonstrates using CosmJS to create an IBC transfer:
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const client = await SigningStargateClient.connectWithSigner(
simapp.tendermintUrl,
wallet,
defaultSigningClientOptions
);
const memo = JSON.stringify({
gateway_ibc_token_bridge_payload: {
gateway_transfer: {
chain: 0, // Chain ID of receiver
recipient: 'INSERT_RECEIVER_ADDRESS',
fee: 0, // Fee to cover transfer
nonce: 0,
},
},
});
const ibcTranslatorAddress =
'wormhole14ejqjyq8um4p3xfqj74yld5waqljf88fz25yxnma0cngspxe3les00fpjx';
const result = await client.sendIbcTokens(
faucet.address0, // Sender address
ibcTranslatorAddress, // Receiver address
coin(INSERT_AMOUNT, 'INSERT_COIN'), // Amount and coin
'transfer', // Source port
'channel-2186', // Source channel
timeoutHeight,
timeoutTimestamp,
0, // Fee to cover transaction
memo // Formatted payload with details about transfer
);
Between Cosmos Chains
From an implementation perspective, transfers between Cosmos chains behave exactly the same as bridging out of Cosmos. The exception is that the chain ID passed is a Cosmos chain.
Data Structures
GatewayIbcTokenBridgePayload
The core data structure of Gateway token transfers is the GatewayIbcTokenBridgePayload,
which contains details about the transfer that the Gateway uses to perform the transfer.
pub enum GatewayIbcTokenBridgePayload {
GatewayTransfer {
chain: u16,
recipient: Binary,
fee: u128,
nonce: u32,
},
GatewayTransferWithPayload {
chain: u16,
contract: Binary,
payload: Binary,
nonce: u32,
},
}
When sending a GatewayIbcTokenBridge
payload, it must be serialized as JSON. The binary values are base64
encoded for proper JSON encoding. The recipient
for Cosmos chains are base64
encoded bech32
addresses. For example, if the recipient
is wormhole1f3jshdsmzl03v03w2hswqcfmwqf2j5csw223ls
, the encoding will be the direct base64
encoding of d29ybWhvbGUxZjNqc2hkc216bDAzdjAzdzJoc3dxY2Ztd3FmMmo1Y3N3MjIzbHM=
.
The chain
values map to Wormhole chain IDs. The fee
and nonce
are Wormhole-specific parameters, both unused today. For incoming IBC messages from Cosmos chains, the receiver
field will be base64 encoded in the Simple.recipient
field, and the channel-id
will be included as the equivalent Wormhole chain ID.