Skip to main content

Bungee Provider

The Bungee Protocol provider enables cross-chain token transfers using the Bungee bridge infrastructure, supporting both onchain transactions (native ETH or via BungeeInbox, default) and gasless permit2 flows (ERC20).

Status: Active (mainnet)

API Access

Bungee offers three integration tiers, each with a different base URL and authentication method:

TierEndpointAuthenticationRate LimitUse Case
Public Sandboxhttps://public-backend.bungee.exchange/NoneVery limitedTesting only
Dedicated Backendhttps://dedicated-backend.bungee.exchange/API Key (x-api-key)20 RPS (extendable)Production backends
Frontend / Directhttps://backend.bungee.exchange/Whitelisted domains100 RPMFrontends, dApps, wallets

The SDK uses the public sandbox by default — createCrossChainProvider("bungee") works with no setup but is rate-limited and intended for integration testing only. For production, upgrade to Dedicated (server-to-server) or Frontend (browser) and pass the matching tier in the config.

See Bungee's API access docs for how to request a key or whitelist your domains.

Configuration

FieldTypeRequiredDescription
tierBungeeApiTierNoAPI tier: "sandbox", "dedicated", or "frontend" (default: "sandbox")
baseUrlstringNoCustom API base URL. Overrides the URL derived from tier
providerIdstringNoCustom provider identifier (default: "bungee")
apiKeystringNoAPI key for dedicated backend (sent via x-api-key header)
affiliateIdstringNoAffiliate ID for tracking (sent via affiliate header)
feeBpsstringNoConvenience fee in basis points (e.g. "50" for 0.5%)
feeTakerAddressstringNoAddress to receive the convenience fee. Required when feeBps is set
submissionModesstring[]NoTransaction submission modes: "user-transaction" (onchain) and/or "gasless" (permit2). Defaults to ["user-transaction"]
slippagestringNoDefault slippage tolerance (e.g. "0.5" for 0.5%)
refuelbooleanNoEnable native gas refueling on the destination chain
Gasless is opt-in — the default is ["user-transaction"] only

submissionModes defaults to ["user-transaction"]. To enable the gasless permit2 flow, explicitly opt in:

createCrossChainProvider("bungee", {
submissionModes: ["user-transaction", "gasless"],
});

When both modes are configured, quotes are fetched in parallel and the aggregator handles either order type seamlessly, so opting in has no extra cost. For Bungee, adding "gasless" enables the permit2 signature flow for ERC-20 tokens — the user signs a permit2 message instead of sending an onchain transaction.

Notes:

  • baseUrl overrides the URL derived from tier.
  • feeBps and feeTakerAddress must be set together. The fee is deducted from the output amount.
  • slippage sets the default tolerance for all quotes. If not set, Bungee uses its own default.
  • refuel tops up native gas on the destination chain so the user can transact immediately after bridging.

Creating the Provider

Public Sandbox (Default)

import { createCrossChainProvider } from "@wonderland/interop-cross-chain";

const bungeeProvider = createCrossChainProvider("bungee");

Dedicated Backend

import { BungeeApiTier, createCrossChainProvider } from "@wonderland/interop-cross-chain";

const bungeeProvider = createCrossChainProvider("bungee", {
tier: BungeeApiTier.Dedicated,
apiKey: "your-api-key",
affiliateId: "your-affiliate-id",
});

Custom Base URL

import { createCrossChainProvider } from "@wonderland/interop-cross-chain";

const bungeeProvider = createCrossChainProvider("bungee", {
baseUrl: "https://my-proxy.example.com",
});

Getting Quotes

Default (Onchain)

ERC20 transfers use the onchain BungeeInbox flow by default. The quote returns a transaction step:

const quotes = await bungeeProvider.getQuotes({
user: "0xYourAddress",
input: {
chainId: 10, // Optimism
assetAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", // USDC
amount: "1000000", // 1 USDC
},
output: {
chainId: 8453, // Base
assetAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
},
});

const quote = quotes[0];

With submissionModes (Gasless)

Use the gasless permit2 signature flow instead of onchain transactions. The quote returns a signature step:

const bungeeProvider = createCrossChainProvider("bungee", {
submissionModes: ["gasless"],
});

const quotes = await bungeeProvider.getQuotes({
user: "0xYourAddress",
input: {
chainId: 8453, // Base
assetAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
amount: "1000000",
},
output: {
chainId: 10, // Optimism
assetAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", // USDC
},
});

const quote = quotes[0];

With Convenience Fee

Charge an affiliate fee deducted from the output amount:

const bungeeProvider = createCrossChainProvider("bungee", {
feeBps: "50", // 0.5%
feeTakerAddress: "0xYourFeeReceiverAddress",
});

const quotes = await bungeeProvider.getQuotes({
user: "0xYourAddress",
input: {
chainId: 10,
assetAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
amount: "1000000",
},
output: {
chainId: 8453,
assetAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
},
});

const quote = quotes[0];
// quote.metadata.bungeeAutoRoute.affiliateFee contains the fee details

With Slippage

Set a custom slippage tolerance for quotes:

const bungeeProvider = createCrossChainProvider("bungee", {
slippage: "0.5", // 0.5% tolerance
});

With Refuel

Enable native gas refueling so the user receives a small amount of native token on the destination chain:

const bungeeProvider = createCrossChainProvider("bungee", {
refuel: true,
});

With Custom Base URL

Override the tier URL with a custom endpoint:

const bungeeProvider = createCrossChainProvider("bungee", {
tier: BungeeApiTier.Dedicated,
baseUrl: "https://public-backend.bungee.exchange", // overrides dedicated URL
});

Fees

After getting a quote, you can inspect the standardized fee breakdown via quote.fees:

const quote = quotes[0];

console.log(quote.fees?.originGas); // origin chain gas estimate

See the API reference for the full QuoteFees type.

Executing Transactions

Bungee quotes can return either a transaction step (onchain via BungeeInbox, default) or a signature step (permit2/gasless via submissionModes: ["gasless"]). Use getSignatureSteps and getTransactionSteps to handle both:

import { getSignatureSteps, getTransactionSteps } from "@wonderland/interop-cross-chain";

const sigSteps = getSignatureSteps(quote.order);
const txSteps = getTransactionSteps(quote.order);

if (sigSteps.length > 0) {
// Permit2 flow: sign + submit
const step = sigSteps[0];
const { signatureType, ...typedData } = step.signaturePayload;
const signature = await walletClient.signTypedData(typedData);
await bungeeProvider.submitOrder(quote, signature);
} else if (txSteps.length > 0) {
// Onchain flow: send transaction directly
const step = txSteps[0];
await walletClient.sendTransaction({
to: step.transaction.to,
data: step.transaction.data,
value: step.transaction.value ? BigInt(step.transaction.value) : undefined,
});
}

Approvals

Access approval information from the order checks:

const allowances = quote.order.checks?.allowances ?? [];
for (const { spender, tokenAddress, required } of allowances) {
// Approve token spend if needed
}

Tracking

Bungee uses API-based tracking. The SDK polls the status endpoint at a 5-second interval:

GET /api/v1/bungee/status?requestHash=<orderId>

No extra RPC URLs are needed — tracking is handled entirely through the Bungee API.

Next Step

See a complete working example: Execute Intent

References