---
name: Bungee
description: Use when building token swap and cross-chain bridging integrations, quoting routes across DEXs and bridges, executing transactions on multiple chains (EVM, Solana, Tron, Sui, Bitcoin), handling deposit flows for non-connected wallets, or tracking transaction status across chains. Agents should reach for Socket when users need to move assets between chains or swap tokens with optimized routing.
metadata:
    mintlify-proj: bungee
    version: "1.0"
---

# Socket Skill

## Product summary

Socket is a unified routing engine for same-chain token swaps and cross-chain asset movement. It abstracts away the complexity of routing across 50+ chains, multiple liquidity sources (DEXs, bridges, solvers), and payment methods. Agents use Socket to quote routes, execute transactions, create deposit addresses for non-connected wallets, and track completion status.

**Key endpoints:**
- `GET /v3/swap/quote` — request routes with pricing
- `POST /v3/swap/quote/{quoteId}/activate` — activate deposit routes
- `GET /v3/swap/status` — poll transaction status
- `GET /v3/swap/supported-chains` — list supported networks
- `GET /v3/swap/token-list` — search tokens

**Base URLs:**
- Production (API key): `https://dedicated-backend.socket.tech`
- Testing (no auth): `https://public-backend.socket.tech`
- Frontend (domain whitelist): `https://backend.socket.tech`

**Auth headers:**
- `x-api-key: YOUR_API_KEY` (production backend)
- `affiliate: YOUR_AFFILIATE_ID` (required for all endpoints)

**Primary docs:** https://docs.socket.tech/integrate/introduction

## When to use

Reach for Socket when:
- A user wants to swap tokens on the same chain (DEX routing)
- A user needs to move assets across chains (bridge routing)
- You need to accept deposits from users without requiring a connected wallet (deposit addresses)
- You need to execute transactions on non-EVM chains (Solana, Tron, Sui, Bitcoin)
- You need to track transaction completion across chains
- You're building a wallet, exchange, protocol, or payment flow that requires asset movement
- You need to quote multiple routes and let users pick the best one (by speed, output, or cost)

Do not use Socket for: wallet creation, key management, price feeds unrelated to swaps, or staking/lending operations.

## Quick reference

### Quote request parameters (userOps=tx)

| Parameter | Required | Type | Notes |
|-----------|----------|------|-------|
| `userOps` | Yes | `tx`, `deposit`, `cex-withdraw` | Route type; `tx` for direct swaps |
| `originChainId` | Yes | string | Source chain ID (e.g., `42161` for Arbitrum) |
| `destinationChainId` | Yes | string | Destination chain ID |
| `inputToken` | Yes | string | Token address on origin chain |
| `outputToken` | Yes | string | Token address on destination chain |
| `inputAmount` | Yes | string | Amount in token base units (no decimals) |
| `userAddress` | Yes | string | Wallet address submitting the transaction |
| `receiverAddress` | Yes | string | Destination recipient address |
| `slippage` | No | string | Slippage tolerance (e.g., `0.5` for 0.5%) |
| `refundAddress` | No | string | Fallback address for failed routes (required for `deposit` and `cex-withdraw`) |
| `contractCaller` | No | string | Intermediate contract address if routing through a contract |
| `feeBps` | No | string | Affiliate fee in basis points (0–10000); requires `feeTakerAddress` |
| `feeTakerAddress` | No | string | Address receiving affiliate fees; requires `feeBps` |
| `destinationPayload` | No | string | Hex-encoded calldata to execute on destination; requires `destinationGasLimit` |
| `destinationGasLimit` | No | string | Gas limit for destination payload execution |
| `simulatedQuotesRequired` | No | `true`, `false` | Simulate DEX routes on-chain; drop reverting quotes |
| `incognito` | No | `true`, `false` | Quote only privacy-capable providers |

### Route tags (for ranking)

| Tag | Meaning |
|-----|---------|
| `SUGGESTED` | Socket's recommended route |
| `FASTEST` | Shortest estimated time |
| `MAX_OUTPUT` | Highest output amount |
| `MIN_INPUT` | Lowest input amount required |

### Status polling values

| Status | Terminal | Meaning |
|--------|----------|---------|
| `PENDING` | No | Quote/route not yet started |
| `IN_PROGRESS` | No | Source tx confirmed; destination pending |
| `COMPLETED` | Yes | Funds delivered to receiver |
| `FAILED` | Yes | Route failed or cancelled |
| `EXPIRED` | Yes | Quote window expired |
| `REFUNDED` | Yes | Funds refunded to refund address |

### Transaction submission by chain

| `txData.kind` | Chain | How to submit |
|---------------|-------|---------------|
| `evm_tx` | EVM | `signer.sendTransaction({ to, data, value })` |
| `svm_instructions` | Solana | Compile v0 message from instructions + lookupTables, sign, broadcast |
| `svm_versioned_tx` | Solana | Deserialize VersionedTransaction, sign, broadcast |
| `sui` | Sui | Rebuild from transactionBytes, set gas/sender, sign, execute |
| `tron_tx` | Tron | `tronWeb.trx.triggerSmartContract({ to, data, value })` |
| `btc_deposit` | Bitcoin | Send satoshis to depositAddress as native BTC tx |

### Native token address

Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native gas tokens (ETH, MATIC, etc.) across all chains.

## Decision guidance

### When to use userOps=tx vs userOps=deposit

| Scenario | Use `tx` | Use `deposit` |
|----------|----------|---------------|
| User has connected wallet | ✓ | — |
| User sending from exchange | — | ✓ |
| User on non-EVM chain (Solana, Bitcoin) | — | ✓ |
| You need immediate execution | ✓ | — |
| User can't sign in your app | — | ✓ |
| Funding from CEX withdrawal | — | Use `cex-withdraw` |

### When to use simulatedQuotesRequired=true

| Condition | Use `true` | Use `false` |
|-----------|-----------|-----------|
| Same-chain DEX swaps only | ✓ | — |
| Cross-chain routes | — | ✓ (simulation only on origin leg) |
| You want to filter reverting quotes | ✓ | — |
| You need speed over safety | — | ✓ |

### When to use contractCaller

| Scenario | Pass `contractCaller` |
|----------|----------------------|
| User submits directly from wallet | No |
| Intermediate contract calls AllowanceHolder | Yes (set to contract address) |
| Router contract executes the swap | Yes |
| Aggregator contract routes the tx | Yes |

## Workflow

### Standard swap flow (userOps=tx)

1. **Get a quote:** Call `GET /v3/swap/quote?userOps=tx&originChainId=...&destinationChainId=...&inputToken=...&outputToken=...&inputAmount=...&userAddress=...&receiverAddress=...`
2. **Select a route:** Rank routes by `routeTags` (SUGGESTED, FASTEST, MAX_OUTPUT, MIN_INPUT) or compare `output.valueInUsd`, `estimatedTime`, `gasFee`. Discard routes past `expiresAt`.
3. **Check approval:** If `route.approval` is present, check the user's current allowance on-chain. Only send an approval tx if current allowance < `approval.amount`. Approve `approval.spenderAddress` (usually AllowanceHolder, not the final DEX/bridge).
4. **Submit transaction:** Submit `route.txData.object` from `userAddress` using the method specified by `txData.kind` (evm_tx, svm_instructions, etc.). Do not rebuild calldata client-side.
5. **Poll status:** Call `GET /v3/swap/status?quoteId={quoteId}` every 5–10 seconds until you see a terminal status (COMPLETED, FAILED, EXPIRED, REFUNDED).
6. **Verify completion:** Check `status === COMPLETED` and confirm output token arrived at `receiverAddress`.

### Deposit flow (userOps=deposit)

1. **Get a deposit quote:** Call `GET /v3/swap/quote?userOps=deposit&originChainId=...&destinationChainId=...&inputToken=...&outputToken=...&inputAmount=...&receiverAddress=...&refundAddress=...`
2. **Check activationRequired:** If `route.activationRequired === true`, call `POST /v3/swap/quote/{quoteId}/activate` to get `txData` and `depositData`. If `false`, skip to step 3.
3. **Show deposit instructions:** Surface `depositData` (address, token, amount, memo) to the user via QR code, copy-paste, or direct transfer.
4. **User sends funds:** User transfers the specified token and amount to the deposit address from any wallet or exchange.
5. **Poll status:** Call `GET /v3/swap/status?quoteId={quoteId}` every 5–10 seconds until terminal status.
6. **Verify completion:** Check `status === COMPLETED` and confirm output token arrived at `receiverAddress`.

### Handling contractCaller (intermediate contract execution)

1. **Identify the intermediate contract:** Determine the contract address that will call `AllowanceHolder.exec` on behalf of the user.
2. **Pass contractCaller:** Include `contractCaller=<contract_address>` in the quote request.
3. **Submit from the contract:** Submit `txData.object` from the intermediate contract, not directly from `userAddress`.
4. **Verify caller:** Without `contractCaller`, the transaction reverts with `CallerNotSignedUser`.

## Common gotchas

- **Expired quotes:** Always check `expiresAt` before submitting. Do not send quotes past expiration — they will fail on-chain.
- **Approval not checked on-chain:** The quote response includes `approval` whenever a route *could* need it, but does not read your current allowance. Check on-chain and only approve when needed to avoid unnecessary transactions.
- **Native token address:** Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native gas tokens. Do not use chain-specific addresses like `0x0000...`.
- **Do not rebuild calldata:** Always submit `txData.object` exactly as returned. Rebuilding calldata client-side will cause the transaction to fail or behave unexpectedly.
- **contractCaller required for intermediate contracts:** If your integration routes through a contract (not the user's wallet), you must pass `contractCaller` or the transaction reverts with `CallerNotSignedUser`.
- **receiverAddress must be valid on destination chain:** Ensure the receiver address is a valid address on the destination chain, not the origin chain.
- **Deposit activation step:** Routes with `activationRequired: true` are previews — you must call `/activate` before showing deposit instructions to the user.
- **Slippage format:** Slippage is a decimal string (e.g., `0.5` for 0.5%), not basis points. Supports up to 3 decimal places.
- **Missing refundAddress for deposit/cex-withdraw:** Both `userOps=deposit` and `userOps=cex-withdraw` require `refundAddress` — the quote will fail without it.
- **Destination payload requires gas limit:** If you set `destinationPayload`, you must also set `destinationGasLimit`. The reverse is also true.
- **Fee parameters must be paired:** `feeBps` and `feeTakerAddress` must both be present or both absent. Providing only one causes a 400 error.
- **Empty route list:** A quote response with an empty `routes` array means providers failed to quote, the route is unsupported, or filters excluded all providers. Check `includeQuoteRejections=true` to see rejection reasons.
- **API key exposure:** Keep `x-api-key` server-side. Never expose it in frontend code or client bundles.
- **Solana sponsor address:** For gasless Solana swaps, pass `solanaSponsorAddress` on the quote. The sponsor covers tx fees and ATA rent.

## Verification checklist

Before submitting work:

- [ ] Quote request includes all required parameters (`userOps`, `originChainId`, `destinationChainId`, `inputToken`, `outputToken`, `inputAmount`, `userAddress`, `receiverAddress`)
- [ ] Route is not expired (`expiresAt` is in the future)
- [ ] If `route.approval` is present, approval transaction is sent before submitting `txData`
- [ ] `txData.object` is submitted exactly as returned (no client-side rebuilding)
- [ ] `txData.kind` matches the chain family (evm_tx for EVM, svm_* for Solana, etc.)
- [ ] Status polling uses the correct `quoteId` from the quote response
- [ ] Status polling continues until a terminal status (COMPLETED, FAILED, EXPIRED, REFUNDED)
- [ ] If using `contractCaller`, it is passed in the quote request and the contract is the actual caller
- [ ] If using `destinationPayload`, both `destinationPayload` and `destinationGasLimit` are set
- [ ] If using `userOps=deposit`, `activationRequired` is checked and `/activate` is called if needed
- [ ] If using `userOps=deposit` or `cex-withdraw`, `refundAddress` is provided
- [ ] `receiverAddress` is a valid address on the destination chain
- [ ] API key is not exposed in frontend code (production backend only)
- [ ] `affiliate` header is included in all requests

## Resources

**Comprehensive page navigation:** https://docs.socket.tech/llms.txt

**Critical documentation pages:**
- [Socket API Integration Guide](https://docs.socket.tech/integrate/integration-guides/socket-api) — full end-to-end integration with all parameters and chain-specific submission methods
- [Deposit Addresses Guide](https://docs.socket.tech/integrate/integration-guides/deposit-addresses) — deposit flow for non-connected wallets and non-EVM chains
- [Get API Access](https://docs.socket.tech/integrate/get-api-access) — endpoint selection, authentication, and rate limits

**Migration guides (if updating existing code):**
- [Bungee v1 → Socket v3](https://docs.socket.tech/integrate/migration-guide)
- [Socket v2 → Socket v3](https://docs.socket.tech/integrate/migration-guide-v2)

---

> For additional documentation and navigation, see: https://docs.socket.tech/llms.txt