<!--
Sitemap:
- [Interop SDK Documentation](/index): Build multichain TypeScript apps with interoperable addresses, cross-chain quotes, transfer execution, and order tracking across providers.
- [Install Interop SDK](/installation): Install @wonderland/interop-addresses and @wonderland/interop-cross-chain, then choose the package that fits your multichain app.
- [Addresses Module](/addresses/): Parse, encode, and resolve chain-aware addresses that combine an account, chain, and optional ENS name into one unambiguous identifier.
- [Addresses: Getting Started](/addresses/getting-started): Parse an interoperable address and extract its components — go from a human-readable name like vitalik.eth@eip155:1 to address and chain ID.
- [Addresses: Concepts](/addresses/concepts): How EIP-7930, ERC-7828, and CAIP-350 combine address and chain into a single, unambiguous, validated identifier for multichain apps.
- [Parsing an Interoperable Name](/addresses/example): Walkthrough for wallet developers — extract the raw address and chain ID from an interop address so legacy contracts keep working.
- [Addresses: Advanced Usage](/addresses/advanced-usage): Advanced patterns for interoperable addresses — checksums, validation, error handling, and round-trip conversions between formats.
- [Addresses: API Reference](/addresses/api): Function signatures and types for the interop-addresses package — high-level helpers, name-layer methods, and binary-layer primitives.
- [Cross-Chain Module](/cross-chain/): One open source integration for cross-chain actions — compare quotes across providers, execute orders, and track completion.
- [Cross-Chain: Getting Started](/cross-chain/getting-started): Execute a cross-chain token transfer end-to-end — create a provider, fetch a quote, send the transaction, and track the order to completion.
- [Cross-Chain: Concepts](/cross-chain/concepts): The intent-based architecture behind the cross-chain package and how the SDK unifies heterogeneous bridge providers behind a common interface.
- [Supported Providers](/cross-chain/providers): Supported cross-chain providers (Across, Relay, OIF, Bungee, LiFi Intents) and how to configure each via createCrossChainProvider.
- [Across Provider](/cross-chain/across-provider): Configure and use the Across Protocol provider for cross-chain token transfers via the Across bridge infrastructure.
- [Relay Provider](/cross-chain/relay-provider): Configure and use the Relay Protocol provider for cross-chain transfers, including opt-in gasless execution via EIP-3009 signatures.
- [OIF Provider](/cross-chain/oif-provider): Direct integration with any OIF-compliant solver — submission modes, resource locks, and configuration for Open Intents Framework backends.
- [Bungee Provider](/cross-chain/bungee-provider): Cross-chain token transfers via Bungee — onchain transactions, gasless permit2 flow, and tier-based API access for sandbox or production.
- [LiFi Intents Provider](/cross-chain/lifi-intents-provider): Cross-chain transfers through the LI.FI intent solver marketplace, where competing solvers fulfill deposits at the best available rate.
- [Cross-Chain: Full Example](/cross-chain/example): End-to-end example of executing a cross-chain transfer — setup, quote, approval handling, transaction submission, and order tracking.
- [Cross-Chain: Frontend Integration](/cross-chain/frontend-integration): Wire the cross-chain SDK into a React/Next.js app with wagmi v2 — a useCrossChainSwap hook covering quotes, approvals, and submission.
- [Order Tracking](/cross-chain/order-tracking): Track cross-chain orders from initiation to completion via OIF OrderStatus events, with both onchain and offchain observation strategies.
- [Cross-Chain: Advanced Usage](/cross-chain/advanced-usage): Aggregator patterns for cross-chain transfers — multi-provider quote fetching, sorting strategies, timeouts, and built-in order tracking.
- [Cross-Chain: API Reference](/cross-chain/api): Function signatures and types for the interop-cross-chain package — providers, aggregator, approval service, and order tracking.
-->

# 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:

| Tier              | Endpoint                                     | Authentication        | Rate Limit          | Use Case                  |
| ----------------- | -------------------------------------------- | --------------------- | ------------------- | ------------------------- |
| Public Sandbox    | `https://public-backend.bungee.exchange/`    | None                  | Very limited        | Testing only              |
| Dedicated Backend | `https://dedicated-backend.bungee.exchange/` | API Key (`x-api-key`) | 20 RPS (extendable) | Production backends       |
| Frontend / Direct | `https://backend.bungee.exchange/`           | Whitelisted domains   | 100 RPM             | Frontends, 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](https://docs.bungee.exchange/integrate/get-api-access) for how to request a key or whitelist your domains.

## Configuration

| Field                  | Type            | Required | Description                                                                                                                                                                          |
| ---------------------- | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `tier`                 | `BungeeApiTier` | No       | API tier: `"sandbox"`, `"dedicated"`, or `"frontend"` (default: `"sandbox"`)                                                                                                         |
| `baseUrl`              | string          | No       | Custom API base URL. Overrides the URL derived from `tier`                                                                                                                           |
| `providerId`           | string          | No       | Custom provider identifier (default: `"bungee"`)                                                                                                                                     |
| `apiKey`               | string          | No       | API key for dedicated backend (sent via `x-api-key` header)                                                                                                                          |
| `affiliateId`          | string          | No       | Affiliate ID for tracking (sent via `affiliate` header)                                                                                                                              |
| `feeBps`               | string          | No       | Convenience fee in basis points (e.g. `"50"` for 0.5%)                                                                                                                               |
| `feeTakerAddress`      | string          | No       | Address to receive the convenience fee. Required when `feeBps` is set                                                                                                                |
| `submissionModes`      | string\[]        | No       | Transaction submission modes: `"user-transaction"` (onchain) and/or `"gasless"` (permit2). Defaults to `["user-transaction"]`                                                        |
| `slippage`             | string          | No       | Default slippage tolerance (e.g. `"0.5"` for 0.5%)                                                                                                                                   |
| `refuel`               | boolean         | No       | Enable native gas refueling on the destination chain                                                                                                                                 |
| `enableOtherProviders` | boolean         | No       | Include manual routes served by other bridges alongside Bungee's own auto routes                                                                                                     |
| `enableMultipleRoutes` | boolean         | No       | Ask the provider for several route alternatives per quote (e.g. one optimised for max output, another for the fastest fill) instead of only the recommended one. Defaults to `false` |

:::info\[Gasless is opt-in — the default is `["user-transaction"]` only]

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

```typescript
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.
* `enableOtherProviders` opts into Bungee's manual routes. Each manual route is built eagerly via `GET /api/v1/bungee/build-tx` and shipped as a separate `Quote` with an executable `TransactionStep`. Per-route build failures are isolated — the auto route and the remaining manuals are still returned.

## Creating the Provider

### Public Sandbox (Default)

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

const bungeeProvider = createCrossChainProvider("bungee");
```

### Dedicated Backend

```typescript
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

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

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

### With Manual Routes (Other Bridges)

Return Bungee's auto route plus one `Quote` per manual route — i.e. routes served by other bridges accessible through Bungee:

```typescript
const bungeeProvider = createCrossChainProvider("bungee", {
    enableOtherProviders: true,
});

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

// quotes[0]               → Bungee auto route
// quotes[1..N]            → manual routes (one per bridge that has liquidity)
// quote.metadata.bungeeManualRoute → the manual route entry from Bungee
// quote.metadata.bungeeBuildTx     → the build-tx result used to construct the TransactionStep
```

Each manual route is built eagerly via `GET /api/v1/bungee/build-tx` so the quote ships with an executable `TransactionStep`. If one bridge's `build-tx` fails, the auto route and the remaining manual routes are still returned.

### Multiple route alternatives

By default the SDK only asks for the recommended route, so each quote request returns a single `Quote`. If you want the aggregator to compare more options — for example one optimised for the highest output and another for the fastest fill — opt in:

```typescript
const bungeeProvider = createCrossChainProvider("bungee", {
    enableMultipleRoutes: true,
});
```

The flag is named generically on purpose: if another provider adds the same idea of returning more than one route per request, it can reuse the same option.

### With Custom Base URL

Override the tier URL with a custom endpoint:

```typescript
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`:

```typescript
const quote = quotes[0];

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

See the [API reference](/cross-chain/api#quotefees) 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:

```typescript
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:

```typescript
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. The query parameter depends on which route a quote came from:

| Route         | Query parameter          | When the SDK uses it                                                                  |
| ------------- | ------------------------ | ------------------------------------------------------------------------------------- |
| Auto routes   | `?requestHash=<orderId>` | `quote.tracking.orderId = requestHash` is set, so tracking polls by it.               |
| Manual routes | `?txHash=<openTxHash>`   | No Bungee-issued `requestHash` exists — the SDK polls by the on-chain origin tx hash. |

Both paths hit `/api/v1/bungee/status`. The opened-intent parser also queries by `txHash` so it can resolve an order from just the on-chain transaction hash.

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

## Next Step

See a complete working example: [Full Example](/cross-chain/example)

## References

* [Bungee Protocol Documentation](https://docs.bungee.exchange)
* [Bungee API Access](https://docs.bungee.exchange/integrate/get-api-access) — request production API keys
* [API Reference](/cross-chain/api) — full type definitions for quotes, fees, and orders
* [Concepts](/cross-chain/concepts) — how intent-based transfers work
