# 3. Interchain Message

## OP bridge deposit

Transfer coin from Initia to Minitia via OP bridge.

{% tabs %}
{% tab title="CLI" %}

```bash
> initiad tx ophost initiate-token-deposit [bridge_id] [addr] 1000000uinit ''\
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  Coin,
  LCDClient,
  MnemonicKey,
  MsgInitiateTokenDeposit,
  Wallet,
} from '@initia/initia.js';

async function initiateTokenDeposit() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const msgs = [
    new MsgInitiateTokenDeposit(
      key.accAddress, // sender
      3, // bridge id
      'init1gegp28h8n7lv85ydltycenmw8dndn9umnn697q', // reciever
      new Coin('uinit', 1) // coin
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

initiateTokenDeposit();

```

{% endtab %}
{% endtabs %}

***

## OP bridge withdraw

Withdraw coin from Minitia to Initia via OP bridge.&#x20;

There is a *finalization period* that must be passed after the `withdraw` transaction has been executed before you can execute `finalize-token-withdrawal`.

{% tabs %}
{% tab title="CLI" %}

```bash
> minitiad tx opchild withdraw [addr] [amount]\
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices [l2_gas_price] \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  Coin,
  LCDClient,
  MnemonicKey,
  MsgInitiateTokenWithdrawal,
  Wallet,
} from '@initia/initia.js';

async function initiateTokenWithdraw() {
  const lcd = new LCDClient('[l2-rest-url]', {
    gasPrices: '0.15unova', // gas price in your l2 denom
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const msgs = [
    new MsgInitiateTokenWithdrawal(
      key.accAddress, // sender
      'init1gegp28h8n7lv85ydltycenmw8dndn9umnn697q', // reciever
      new Coin('l2/...', 1) // coin
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

initiateTokenWithdraw();

```

{% endtab %}
{% endtabs %}

***

## OP bridge finalize token withdrawal

Finalization period has to pass after `withdraw` transaction has been executed in order to execute `finalize-token-withdrawal` transaction to receive coins on Initia Layer 1.

The data required in below example can be fetched from Executor API of each Minitia.

{% tabs %}
{% tab title="CLI" %}

```bash
> initiad tx ophost finalize-token-withdrawal [path/to/withdrawal-info.json] \
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  Coin,
  LCDClient,
  MnemonicKey,
  MsgFinalizeTokenWithdrawal,
  Wallet,
} from '@initia/initia.js';
import * as crypto from 'crypto';

async function finalizeTokenWithdrawal() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const msgs = [
    new MsgFinalizeTokenWithdrawal(
      3, // bridge id
      492, // output index
      [], // merkle proof
      key.accAddress, // sender
      'init1wgl839zxdh5c89mvc4ps97wyx6ejjygxs4qmcx', // receiver
      1, // sequence
      new Coin('uinit', 100000), // amount
      sha3_256(492), // version
      'YNWpXXUHHtPVmDVHTCEb6WzJFNGGc7FnqeIskFS+lsU=', // state root
      'Tegv5DHAE6gZJJy9Yn4wY1mV3sqOzh7da8BC4mf/vE4=', // storage root
      'oY7lpEEBdRmaV3lXkNlwTK2S9W4xPX7jHm93Ao4zfa0=' // latest block hash
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

finalizeTokenWithdrawal();


function sha3_256(version: number) {
  const hash = crypto.createHash('SHA3-256');
  let hex = version.toString(16);
  if (hex.length % 2 === 1) {
    hex = '0' + hex;
  }
  const val = Buffer.from(hex, 'hex');
  return hash.update(val).digest().toString('base64');
}
```

{% endtab %}
{% endtabs %}

***

## IBC token transfer

Transfer tokens to other chains / Minitias via IBC transfer.

{% tabs %}
{% tab title="CLI" %}

```bash
> initiad tx ibc-transfer transfer \
  transfer [src-channel] [addr] 1000000uinit \
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  Coin,
  Height,
  LCDClient,
  MnemonicKey,
  MsgTransfer,
  Wallet,
} from '@initia/initia.js';

async function ibcTokenTransfer() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const msgs = [
    new MsgTransfer(
      'transfer', // port
      'channel-1', // src channel
      new Coin('uinit', 1234), // amount
      key.accAddress, // sender
      key.accAddress, // receiver
      // you have to provide one of timeout
      new Height(0, 0), // timeout height
      ((new Date().valueOf() + 100000) * 1000000).toString() // timeout timestamp
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

ibcTokenTransfer();
```

{% endtab %}
{% endtabs %}

***

## IBC NFT transfer

Transfer NFTs to other chains / Minitias via IBC NFT transfer.

{% tabs %}
{% tab title="CLI" %}

```bash
> initiad tx ibc-nft-transfer nft-transfer \
  nft-transfer [src-channel] [receiver] [class-id] [token-id],...[token-id] \
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  Coin,
  Height,
  LCDClient,
  MnemonicKey,
  MsgNftTransfer,
  Wallet,
} from '@initia/initia.js';

async function ibcNftTrnasfer() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const msgs = [
    new MsgNftTransfer(
      'nft-transfer', // port
      'channel-3', // channel id
      'move/bfe696257ce629b8cfc03c44c4b732973705cf00fa87279e9440547215850a71', // class id
      [tokenid], // token ids
      key.accAddress, // sender
      key.accAddress, // receiver
      // you have to provide one of timeout
      new Height(0, 0), // timeout height
      ((new Date().valueOf() + 100000) * 1000000).toString() // timeout timestamp
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

ibcNftTrnasfer();
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://initia.gitbook.io/initia/kBNuZF5MglV9d3zOOUeW/initia-developer-tutorials/3.-interchain-message.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
