Skip to main content
The workflow shows how to access Reservoir minting infrastructure from remote chains through automated bridging sequences. Route Mechanics: This bundle orchestrates a complete crosschain yield strategy through multiple atomic operations:
  • Bridge USDCe from Berachain to Ethereum using Stargate protocol
  • Check USDCebalance on Ethereum after successful bridge completion
  • Mint rUSD using the bridged USDCethrough Reservoir’s minting contract
  • Bridge newly minted rUSD back to Berachain via Stargate bridge
  • Check rUSD balance on Berachain after the bridge returns
mintOnBeraFromMainnet.ts
// Chain IDs
const BERACHAIN_ID = 80094;
const ETHEREUM_ID = 1;

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

// Token addresses
const USDCE_BERACHAIN = "0x549943e04f40284185054145c6E4e9568C1D3241";
const USDC_ETHEREUM = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const RUSD_ETHEREUM = "0x09D4214C03D01F49544C0448DBE3A27f768F2b34";

// Protocol addresses
const RESERVOIR_MINTING_CONTRACT =
  "0x4809010926aec940b550D34a46A52739f996D75D";

const client = new EnsoClient({
  apiKey: process.env.ENSO_API_KEY || "your-api-key-here",
});

const usdcBeraToEthPools = await client.getLayerZeroPool({
  chainId: BERACHAIN_ID,
  token: USDCE_BERACHAIN,
  destinationChainId: ETHEREUM_ID + "",
});

const rusdEthToBeraPools = await client.getLayerZeroPool({
  chainId: ETHEREUM_ID,
  token: RUSD_ETHEREUM,
  destinationChainId: BERACHAIN_ID + "",
});

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

const bundle = await client.getBundleData(
  {
    chainId: BERACHAIN_ID,
    fromAddress: WALLET_ADDRESS,
    spender: WALLET_ADDRESS,
    routingStrategy: "router",
  },
  [
    {
      protocol: "stargate",
      action: "bridge",
      args: {
        primaryAddress: usdcBeraToEthPools[0].pool,
        destinationChainId: ETHEREUM_ID,
        tokenIn: USDCE_BERACHAIN,
        amountIn: parseUnits("1000", 6).toString(), // 1000 USDC
        receiver: WALLET_ADDRESS,
        callback: [
          // Step 1: Check USDCebalance on Ethereum after bridge
          {
            protocol: "enso",
            action: "balance",
            args: {
              token: USDC_ETHEREUM,
            },
          },
          // Step 2: Mint rUSD using bridged USDC
          {
            protocol: "reservoir",
            action: "deposit",
            args: {
              primaryAddress: RESERVOIR_MINTING_CONTRACT,
              tokenIn: USDC_ETHEREUM,
              tokenOut: RUSD_ETHEREUM,
              amountIn: { useOutputOfCallAt: 0 }, // Use USDCefrom balance check
              receiver: WALLET_ADDRESS,
            },
          },
          // Step 3: Bridge newly minted rUSD back to Berachain
          {
            protocol: "stargate",
            action: "bridge",
            args: {
              primaryAddress: rusdEthToBeraPools[0].pool,
              destinationChainId: BERACHAIN_ID,
              tokenIn: RUSD_ETHEREUM,
              amountIn: { useOutputOfCallAt: 1 }, // Use e-rUSD from minting
              receiver: WALLET_ADDRESS,
            },
          },
        ],
      },
    },
  ]
);

return bundle;
Important considerations
  • This bundle executes multiple crosschain operations atomically - if any step fails, the entire transaction reverts
  • LayerZero bridge fees apply for both USDCe and rUSD transfers between chains
  • Gas costs for Ethereum minting and Berachain vault deposit are calculated upfront
  • Bridge timing may vary based on network congestion on both chains

Resources:

Updated