Skip to content

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.