> ## Documentation Index
> Fetch the complete documentation index at: https://injectivelabs-docs-ai-sdk.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# IBC

## Messages

## MsgTransfer

This message is used to send coins from the sender's Bank module on Injective to the receiver's Bank module on another Cosmos chain through IBC, which is Cosmos's Inter-Blockchain Communication Protocol.
Note that Injective only supports mainnet transfers across IBC for most networks.

Application to application communication in IBC is conducted over channels, which route between an application module on one chain, and the corresponding application module on another one. More info on IBC channels can be found at [https://tutorials.cosmos.network/academy/3-ibc/3-channels.html](https://tutorials.cosmos.network/academy/3-ibc/3-channels.html).
A list of canonical channel Ids for mainnet transfers to and from Injective can be found in the [Injective Lists repository](https://github.com/InjectiveLabs/injective-lists).
Also noteworthy is that the application module on each chain has a portId to designate the type of module on each end.
For example, `transfer` is the portId designating the transfer of ICS-20 tokens between bank modules.

In this example, we will transfer ATOM from Injective to CosmosHub

<Callout type="info">
  For token metadata (symbols, decimals, channel mappings), please use
  [Injective Lists](https://github.com/InjectiveLabs/injective-lists) which
  provides up-to-date token information in JSON format.
</Callout>

```ts theme={null}
import { toChainFormat, toBigNumber } from "@injectivelabs/utils";
import { ChainId, CosmosChainId } from "@injectivelabs/ts-types";
import { MsgTransfer } from "@injectivelabs/sdk-ts/core/modules";
import { getNetworkEndpoints, Network } from "@injectivelabs/networks";
import { ChainGrpcBankApi } from "@injectivelabs/sdk-ts/client/chain";
import { MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts/core/tx";
import { makeTimeoutTimestampInNs } from "@injectivelabs/sdk-ts/utils";
import { ChainRestTendermintApi } from "@injectivelabs/sdk-ts/client/chain";

const injectiveChainId = CosmosChainId["Injective"];
const destinationChainId = CosmosChainId["Cosmoshub"];

const endpointsForNetwork = getNetworkEndpoints(Network.Mainnet);

/**
 * For IBC transfers, you need:
 * 1. The IBC denom hash for the token on Injective
 * 2. The channel ID for the destination chain
 *
 * You can find this information in the Injective Lists repository:
 * https://github.com/InjectiveLabs/injective-lists
 */
const injectiveToCosmosHubChannelId = "channel-1";

/**
 * The IBC denom for ATOM on Injective
 * Format: ibc/{hash} where hash is derived from the channel and base denom
 */
const atomIbcDenom =
  "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9";

/* format amount for transfer (0.001 ATOM with 6 decimals) */
const amount = {
  denom: atomIbcDenom,
  amount: toChainFormat(0.001, 6).toFixed(),
};

const injectiveAddress = "inj...";
const destinationAddress = "cosmos...";
const port = "transfer";
const timeoutTimestamp = makeTimeoutTimestampInNs();

/* get the latestBlock from the origin chain */
const tendermintRestApi = new ChainRestTendermintApi(endpointsForNetwork.rest);

/* Block details from the origin chain */
const latestBlock = await tendermintRestApi.fetchLatestBlock();
const latestHeight = latestBlock.header.height;
const timeoutHeight = toBigNumber(latestHeight).plus(
  30 // default block timeout height
);

/* create message in proto format */
const msg = MsgTransfer.fromJSON({
  port,
  memo: `IBC transfer from ${injectiveChainId} to ${destinationChainId}`,
  sender: injectiveAddress,
  receiver: destinationAddress,
  channelId: injectiveToCosmosHubChannelId,
  timeout: timeoutTimestamp,
  height: {
    revisionHeight: timeoutHeight.toNumber(),
    revisionNumber: parseInt(latestBlock.header.version.block, 10),
  },
  amount,
});

const privateKey = "0x...";

/* broadcast transaction */
const txHash = await new MsgBroadcasterWithPk({
  privateKey,
  network: Network.Mainnet,
}).broadcast({
  msgs: msg,
});

console.log(txHash);
```
