Skip to main content
This example shows single-contract minting on Ethereum followed by automated token distribution to Katana through bridging. The pattern shows multi-chain token access without requiring separate minting deployments on each destination chain. **Route Mechanics: ** This bundle facilitates stablecoin diversification across chains through a the following process:
  • Convert USDC to rUSD on Ethereum using Enso’s routing aggregation
  • Bridge the newly minted rUSD from Ethereum to Katana chain via Stargate
  • Check rUSD balance on Katana after bridge completion
  • Swap rUSD for vault-bridged USDC (vbUSDC) on Katana
The strategy enables users to access Katana’s DeFi ecosystem while starting with familiar USDC on Ethereum and relying on Reservoir Stablecoin.
const KATANA_ID = 747474;
const ETHEREUM_ID = 1;

// Common addresses
const WALLET_ADDRESS = "0x93621DCA56fE26Cdee86e4F6B18E116e9758Ff11"; // User wallet

// Token addresses
const rUSD_ETHEREUM = "0x09D4214C03D01F49544C0448DBE3A27f768F2b34";
const rUSD_KATANA = "0x09D4214C03D01F49544C0448DBE3A27f768F2b34";
const USDC_ETHEREUM = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const VBUSDC_KATANA = "0x203A662b0BD271A6ed5a60EdFbd04bFce608FD36";

const client = new EnsoClient({
  apiKey: process.env.ENSO_API_KEY!,
});

// LayerZero pool addresses
const wsrEthToKatanaPools = await client.getLayerZeroPool({
  chainId: ETHEREUM_ID,
  token: rUSD_ETHEREUM,
  destinationChainId: KATANA_ID,
  destinationToken: rUSD_KATANA,
});

// LayerZero pool addresses
const rUsdKatanaToEthRUsd = await client.getLayerZeroPool({
  chainId: ETHEREUM_ID,
  token: rUSD_ETHEREUM,
  destinationChainId: KATANA_ID,
  destinationToken: rUSD_KATANA,
});

console.log(JSON.stringify(wsrEthToKatanaPools), !wsrEthToKatanaPools.length);

if (!wsrEthToKatanaPools.length) {
  throw new Error("Required pools not available");
}

const bundle = await client.getBundleData(
  {
    chainId: ETHEREUM_ID,
    fromAddress: WALLET_ADDRESS,
    spender: WALLET_ADDRESS,
    routingStrategy: "router",
  },
  [
    // mint wsrUSD on Ethereum
    {
      protocol: "enso",
      action: "route",
      args: {
        amountIn: parseUnits("1000", 6).toString(), // 1000 USDC
        tokenIn: USDC_ETHEREUM,
        receiver: WALLET_ADDRESS,
        tokenOut: rUSD_ETHEREUM,
      },
    },

    {
      protocol: "stargate",
      action: "bridge",
      args: {
        primaryAddress: wsrEthToKatanaPools[0].pool as Address,
        destinationChainId: KATANA_ID,
        tokenIn: rUSD_ETHEREUM,
        amountIn: { useOutputOfCallAt: 0 },
        receiver: WALLET_ADDRESS,
        callback: [
          // Step 1: Check wsrUSD balance on Katana after bridge
          {
            protocol: "enso",
            action: "balance",
            args: {
              token: rUSD_KATANA,
            },
          },
          // Step 2: Swap wsrUSD to vbUSDC
          {
            protocol: "enso",
            action: "route",
            args: {
              tokenIn: rUSD_KATANA,
              tokenOut: VBUSDC_KATANA,
              amountIn: { useOutputOfCallAt: 0 }, // Use wsrUSD_KATANA from balance check
              receiver: WALLET_ADDRESS,
            },
          },
        ],
      },
    },
  ]
);
Important Considerations
  • Bridge operations execute sequentially - Katana operations only proceed after successful Ethereum minting
  • LayerZero bridge fees apply for transfers between Ethereum and Katana
  • Gas costs for both chains are paid from the originating Ethereum transaction

Resources:

Updated