Skip to main content
This workflow demonstrates combining multiple bridge protocols in a single transaction. Use Stargate for the outbound bridge and CCIP for the return bridge, with DeFi operations executed on each chain via nested callbacks. Route Mechanics: This bundle executes a complex 6-step workflow spanning two chains and two bridge protocols:
  1. Bridge USDT0 from Plasma to Ethereum via Stargate
  2. Check USDT balance on Ethereum after bridge
  3. Swap USDT to syrupUSDT on Ethereum
  4. Bridge syrupUSDT back to Plasma via CCIP
  5. Check syrupUSDT balance on Plasma after bridge
  6. Deposit syrupUSDT into AAVE V3 on Plasma
mixedBridgeProtocols.ts
import { EnsoClient } from "@ensofinance/sdk";

// Chain IDs
const PLASMA_ID = 9745;
const ETHEREUM_ID = 1;

// Common addresses
const WALLET_ADDRESS = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";

// Token addresses - Plasma
const USDT0_PLASMA = "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb";
const SYRUP_USDT_PLASMA = "0xc4374775489cb9c56003bf2c9b12495fc64f0771";
const A_SYRUP_USDT_PLASMA = "0xD4eE376C40EdC83832aAaFc18fC0272660F5e90b";

// Token addresses - Ethereum
const USDT_ETHEREUM = "0xdac17f958d2ee523a2206206994597c13d831ec7";
const SYRUP_USDT_ETHEREUM = "0x356b8d89c1e1239cbbb9de4815c39a1474d5ba7d";

// Protocol addresses
const STARGATE_USDT0_POOL_PLASMA = "0x02ca37966753bdddf11216b73b16c1de756a7cf9";
const CCIP_ROUTER_ETHEREUM = "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D";
const AAVE_V3_PLASMA_POOL = "0x925a2A7214Ed92428B5b1B090F80b25700095e12";

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

const bundle = await client.getBundleData(
  {
    chainId: PLASMA_ID,
    fromAddress: WALLET_ADDRESS,
    routingStrategy: "router",
    receiver: WALLET_ADDRESS,
  },
  [
    {
      // Step 1: Bridge USDT0 from Plasma to Ethereum via Stargate
      protocol: "stargate",
      action: "bridge",
      args: {
        primaryAddress: STARGATE_USDT0_POOL_PLASMA,
        destinationChainId: ETHEREUM_ID,
        tokenIn: USDT0_PLASMA,
        amountIn: "1000000000", // 1000 USDT0
        receiver: WALLET_ADDRESS,
        callback: [
          // Step 2: Check USDT balance on Ethereum
          {
            protocol: "enso",
            action: "balance",
            args: {
              token: USDT_ETHEREUM,
            },
          },
          // Step 3: Swap USDT to syrupUSDT on Ethereum
          {
            protocol: "enso",
            action: "route",
            args: {
              tokenIn: USDT_ETHEREUM,
              tokenOut: SYRUP_USDT_ETHEREUM,
              amountIn: { useOutputOfCallAt: 0 },
            },
          },
          // Step 4: Bridge syrupUSDT back to Plasma via CCIP
          {
            protocol: "ccip",
            action: "bridge",
            args: {
              primaryAddress: CCIP_ROUTER_ETHEREUM,
              destinationChainId: PLASMA_ID,
              tokenIn: SYRUP_USDT_ETHEREUM,
              amountIn: { useOutputOfCallAt: 1 },
              receiver: WALLET_ADDRESS,
              callback: [
                // Step 5: Check syrupUSDT balance on Plasma
                {
                  protocol: "enso",
                  action: "balance",
                  args: {
                    token: SYRUP_USDT_PLASMA,
                  },
                },
                // Step 6: Deposit syrupUSDT to AAVE V3 on Plasma
                {
                  protocol: "aave-v3",
                  action: "deposit",
                  args: {
                    primaryAddress: AAVE_V3_PLASMA_POOL,
                    tokenIn: SYRUP_USDT_PLASMA,
                    tokenOut: A_SYRUP_USDT_PLASMA,
                    amountIn: { useOutputOfCallAt: 0 },
                    receiver: WALLET_ADDRESS,
                  },
                },
              ],
            },
          },
        ],
      },
    },
  ]
);

return bundle;
Important Considerations:
  • Nested callbacks: The CCIP bridge action is itself a callback within the Stargate bridge, creating nested crosschain execution
  • Protocol selection: Stargate for fast outbound bridging, CCIP for secure return with DeFi callback
  • Callback data limits: The inner CCIP callback (~30KB limit) must fit within Stargate’s callback limit (~9.5KB) - plan accordingly
  • Gas estimation: Each bridge hop has its own gas requirements; the Bundle API handles estimation across all chains
  • Finalization timing: CCIP waits for source chain finalization before executing the final callback
Nested callback complexity: When nesting bridge callbacks, the inner callback data must serialize within the outer bridge’s callback limit. For deeply nested workflows, consider Relay for unlimited callback data.

When to Use Mixed Protocols

ScenarioRecommended Approach
Fast outbound, secure returnStargate out → CCIP back
Large callback on returnStargate out → Relay back
Maximum security both waysCCIP both directions
Native token support neededRelay or Stargate

Resources

Updated