> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhino.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# TON Contracts

> This guide explains how to interact with the rhino.fi Bridge contract on TON.

### Setup

For this example we'll use `@ton/ton` and `@ton/crypto` to interact with the contract, but you can replace it with any TON library of your choice.

Make sure to install it first:

<CodeGroup>
  ```bash yarn theme={null}
  yarn add @ton/ton @ton/crypto
  ```

  ```bash npm theme={null}
  npm install @ton/ton @ton/crypto
  ```
</CodeGroup>

## Interacting with the Contract

To execute a bridge transaction, send a transfer with the following payload:

<Info>
  The `commitmentId` required by the contract corresponds to the `quoteId` returned by the API.

  To obtain the `commitmentId`, first request a quote from the API, then commit it. The response will include the `quoteId`, which should be used as the `commitmentId` in the contract call.

  See [the API bridge example](/api-integration/bridge#6-full-example) for details.
</Info>

<CodeGroup>
  ```javascript @ton/ton theme={null}
  import {beginCell, toNano, Address, TonClient, internal, WalletContractV4} from '@ton/ton'
  import {mnemonicToPrivateKey} from '@ton/crypto';
  import getBridgeConfigs from './getBridgeConfigs'

  const getJettonWalletAddress = async (tonWalletAddress, jettonMasterAddress, publicProvider) => {
    const jettonMaster = publicProvider.open(JettonMaster.create(jettonMasterAddress))

    return jettonMaster.getWalletAddress(tonWalletAddress)
  }

  export const callTonBridgeContract = async (
    {
      commitmentId,
      amount,
      token,
      tonWalletAddress,
    }) => {
    // See API Integration -> Fetch Bridge Configs for the full implementation
    const configs = await getBridgeConfigs()
    const chainConfig = configs[chain]

    // Replace with your wallet implementation
    const tonClient = new TonClient({
      endpoint: chainConfig.rpc,
    })
    const key = await mnemonicToPrivateKey(TON_MNEMONIC);
    const workchain = 0;
    const wallet = WalletContractV4.create({
      workchain,
      publicKey: keyPair.publicKey,
    })
    const walletProvider = tonClient.open(wallet)
    const tokenConfig = chainConfig.tokens[token]
    const amountWithDecimals = +amount * 10 ** tokenConfig.decimals
    const tokenAddress = tokenConfig.address
    const bridgeContractAddress = chainConfig.contractAddress

    const jettonWalletContract = await getJettonWalletAddress(
      Address.parse(tonWalletAddress),
      Address.parse(tokenAddress),
      tonClient
    )
    const sourceAddress = Address.parse(tonWalletAddress)
    const destinationAddress = Address.parse(bridgeContractAddress)

    const forwardPayload = beginCell()
      .storeUint(BigInt(`0x${commitmentId}`), 96)
      .endCell()

    const forwardAmount = 0.02

    const body = beginCell()
      .storeUint(0xf8a7ea5, 32) // opcode for jetton transfer
      .storeUint(0, 64) // query id
      .storeCoins(BigInt(amountWithDecimals)) // jetton amount, amount * 10^9
      .storeAddress(destinationAddress) // TON wallet destination address
      .storeAddress(sourceAddress) // response excess destination
      .storeBit(0) // no custom payload
      .storeCoins(toNano(forwardAmount)) // forward amount (if >0, will send notification message)
      .storeBit(1) // we store forwardPayload as a reference
      .storeRef(forwardPayload)
      .endCell()

    const seqno: number = await walletProvider.getSeqno();

    return await walletProvider.sendTransfer({
      seqno,
      secretKey: key.secretKey,
      timeout: Math.floor(Date.now() / 1000) + 360,
      messages: [
        internal({
          to: jettonWalletContract.toString(),
          value: toNano(0.1),
          body: body,
        }),
      ],
    })
  }
  ```
</CodeGroup>
