Bridge

bridge

TypeScript Example

import {
  parseUnits,
  isAddress,
  type Address,
} from "viem";
import { publicClient, walletClient } from "./client"; // Assumes client.ts is in the same folder

// --- ABIs ---

const tellerAbi = [
  /* ... (start of ABI) ... */
  {
    inputs: [
      { internalType: "uint256", name: "shareAmount", type: "uint256" },
      {
        components: [
          { internalType: "uint32", name: "chainSelector", type: "uint32" },
          { internalType: "address", name: "destinationChainReceiver", type: "address" },
          { internalType: "contract ERC20", name: "bridgeFeeToken", type: "address" },
          { internalType: "uint64", name: "messageGas", type: "uint64" },
          { internalType: "bytes", name: "data", type: "bytes" },
        ],
        internalType: "struct BridgeData",
        name: "data",
        type: "tuple",
      },
    ],
    name: "bridge",
    outputs: [{ internalType: "bytes32", name: "messageId", type: "bytes32" }],
    stateMutability: "payable",
    type: "function",
  },
  /* ... (rest of the ABI) ... */
] as const;

// --- Bridge Function ---

async function bridge({
  shareAmount,
  chainSelector,
  recipient,
  tellerAddress
}: {
  shareAmount: bigint;
  chainSelector: number;
  recipient: Address;
  tellerAddress: Address;
}) {
  if (!isAddress(tellerAddress) || tellerAddress === "0x...") {
    console.error("A valid teller contract address is required.");
    return;
  }

  try {
    // 1. Prepare bridge data for contract 
    const bridgeData = prepareBridgeContractArg({chainSelector, destinationChainReceiver});

    // 2. Fetch the fee from the blockchain to calculate expected cost to user
    const previewFee = await getPreviewFee({shareAmount, bridgeData, tellerAddress });
    console.log(`Rate received: ${rate}`);

    // 3. Use `writeContract` to send the transaction
    const hash = await walletClient.writeContract({
      abi: tellerAbi,
      address: tellerAddress,
      functionName: "bridge",
      args: [shareAmount, bridgeData],
      value: previewFee,
    });

    console.log(`Transaction sent! Hash: ${hash}`);
    console.log("Waiting for transaction to be mined...");

    // 5. Wait for the transaction to be included in a block
    const receipt = await publicClient.waitForTransactionReceipt({ hash });

    console.log("Transaction was successfully mined!");
    console.log(`- Block Number: ${receipt.blockNumber}`);
    console.log(
      `- View on Etherscan: https://etherscan.io/tx/${receipt.transactionHash}`,
    );

  } catch (err) {
    console.error("Error sending bulk withdraw transaction:", err);
  }
}

// --- Execution Example ---

/* ... (start of Bridge function) ... */
await bridge({
  shareAmount,
  chainSelector,
  recipient,
  tellerAddress
});
/* ... (rest of Bridge function) ... */

TypeScript Helper Functions

prepareBridgeContractArgs

import { type Address } from "viem";

const NATIVE_TOKEN_FOR_BRIDGE_FEE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

// Prepare the contract arguments for the bridge
const prepareBridgeContractArg ({
  chainSelector, // Identifier of the chain, not a chainId. See above.
  destinationChainReceiver,
  nativeTokenForBridgeFee = NATIVE_TOKEN_FOR_BRIDGE_FEE,
}: {
  bridgeChainIdentifier: number;
  destinationChainReceiver: Address;
  nativeTokenForBridgeFee?: Address;
}) => {
  return {
    chainSelector: chainSelector,
    destinationChainReceiver: destinationChainReceiver,
    bridgeFeeToken: nativeTokenForBridgeFee,
    messageGas: BigInt(300000),
    data: "0x" as never, // cast as never to comply with viem type infrence
  };
};

getPreviewFee

import { publicClient } from "./client";

// Fetch the previewFee for the bridge. 
// Optional: display this to a user in addition to calculation of slippage.
const getPreviewFee = async ({
  shareAmount,
  bridgeData,
  tellerAddress,
}: {
  shareAmount: bigint;
  bridgeData: BridgeData;
  tellerAddress: Address;
}): Promise<bigint> => {

  const previewFee = await client.readContract({
    abi: TellerAbi,
    address: tellerAddress,
    functionName: "previewFee",
    args: [shareAmount, bridgeData],
  });

  return previewFee;
};

Last updated