> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# EVM Swap Quoting

> Quote and execute swaps on Ethereum, Base, Arbitrum, BNB Chain, Polygon, Optimism, Avalanche and 30+ EVM chains via MobulaRouter — best-route across Uniswap V2/V3/V4, Curve, Balancer, PancakeSwap, Aerodrome, Velodrome, Sushi and 200+ DEXs.

Single endpoint, same shape as Solana / TON. The EVM-specific calldata sits under `data.evm`. See the [Swap Quoting](./swap-quoting) page for the full input parameters.

## Native sentinel

```
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
```

Standard EIP-7528 placeholder — use this `tokenIn` / `tokenOut` for the chain's native token (ETH on Ethereum/L2s, BNB on BNB Chain, MATIC on Polygon, AVAX on Avalanche, …). The router wraps/unwraps automatically.

## Supported chains

| Chain                                                                                                                                                                                                                              | `chainId`   | Native |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------ |
| Ethereum                                                                                                                                                                                                                           | `evm:1`     | ETH    |
| Optimism                                                                                                                                                                                                                           | `evm:10`    | ETH    |
| BNB Chain                                                                                                                                                                                                                          | `evm:56`    | BNB    |
| Polygon                                                                                                                                                                                                                            | `evm:137`   | POL    |
| Base                                                                                                                                                                                                                               | `evm:8453`  | ETH    |
| Arbitrum                                                                                                                                                                                                                           | `evm:42161` | ETH    |
| Avalanche                                                                                                                                                                                                                          | `evm:43114` | AVAX   |
| Linea, zkSync, Scroll, Mantle, Blast, Mode, Manta, Taiko, Sei, Cronos, Fantom, Gnosis, Celo, Moonbeam, Kava, Metis, opBNB, Polygon zkEVM, Merlin, BOB, Cyber, Fuse, IoTeX, Conflux, Astar zkEVM, ZKFair, XLayer, ZetaChain, Klaytn | `evm:N`     | varies |

Full list of integer chain IDs: see [`MOBULA_CHAIN_MAP`](https://github.com/MobulaFi/mobula-monorepo/blob/main/packages/chains/src/index.ts) in the chains package.

## Request

```http theme={null}
GET /api/2/swap/quoting?chainId=evm:8453
  &tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
  &tokenOut=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  &amount=0.1
  &walletAddress=0x…
  &slippage=1
  &feePercentages=0.6,0.25
  &feeWallets=0xPartnerA…,0xPartnerB…
```

| Param                                 | Required | Notes                                                                                                                                                                                                          |
| ------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chainId`                             | ✓        | `evm:<integer>` (e.g. `evm:8453` for Base)                                                                                                                                                                     |
| `tokenIn` / `tokenOut`                | ✓        | Token contract address (lowercased OR checksummed). Native = `0xEee…`                                                                                                                                          |
| `amount` *or* `amountRaw`             | ✓        | Human (`"0.1"`) or raw wei (`"100000000000000000"`)                                                                                                                                                            |
| `walletAddress`                       | ✓        | Taker address: supplies `tokenIn`, signs, and pays gas                                                                                                                                                         |
| `recipientAddress`                    | –        | Address that receives `tokenOut`; defaults to `walletAddress`                                                                                                                                                  |
| `slippage`                            | –        | % (0-100, default 1)                                                                                                                                                                                           |
| `feePercentages`                      | –        | Caller referral fees (CSV or array, max 4), parallel to `feeWallets` — entry *i* is paid to wallet *i*. Charged in the pair's quote asset: input on buys, output on sells; no quote side (meme↔meme) = no fee. |
| `feeWallets`                          | –        | Wallets receiving the referral fees, parallel to `feePercentages`                                                                                                                                              |
| `feePercentage` / `feeWallet`         | –        | **Deprecated** singular pair — still accepted; plural wins when both are sent                                                                                                                                  |
| `onlyRouters`                         | –        | Comma-list of `kyberswap,lifi,naos`                                                                                                                                                                            |
| `excludedProtocols` / `onlyProtocols` | –        | DEX-level filter                                                                                                                                                                                               |
| `sellEntireBalance`                   | –        | `true` sells the wallet's complete ERC-20 `tokenIn` balance at execution; the quoted amount remains an estimate                                                                                                |

## Send output to another address

Set `recipientAddress` when the taker and output recipient differ. `walletAddress` still supplies `tokenIn`, signs the transaction, pays gas, and owns any required token allowance; MobulaRouter sends the final `tokenOut` amount to `recipientAddress`.

```http theme={null}
GET /api/2/swap/quoting?chainId=evm:8453
  &tokenIn=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  &tokenOut=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
  &amount=10
  &walletAddress=0xTAKER…
  &recipientAddress=0xRECIPIENT…
  &slippage=1
```

This works with Mobula routes and supported aggregator routes. Use a valid, non-zero EVM address. For native-token output, a contract recipient must be able to receive the chain's native currency.

## Sell the entire ERC-20 balance

Set `sellEntireBalance=true` for deposit or relay flows where the exact balance is not known when requesting the quote. You must still provide exactly one of `amount` or `amountRaw`: it is used to select the route and calculate the absolute minimum output, while MobulaRouter reads and sells the `walletAddress` balance at execution time.

```http theme={null}
GET /api/2/swap/quoting?chainId=evm:988
  &tokenIn=0xeaf7ac0fdf150cdd89340fb762d83848de6a7b83
  &tokenOut=0x779ded0c9e1022225f8e0630b35a9b54be713736
  &amount=1
  &walletAddress=0x…
  &slippage=1
  &sellEntireBalance=true
```

* `tokenIn` must be an ERC-20 token. Native-token input is rejected.
* Use a realistic estimate: if the execution-time balance differs materially, the route and absolute minimum output are still based on the quoted amount.
* The allowance granted to `approvalAddress` must cover the complete balance present at execution.
* The target chain must run MobulaRouter v2.19.0 or later, and the API must find a Mobula route. `onlyRouters`, `onlyProtocols`, and aggregator fallback are incompatible; the API returns an error rather than silently selling only the estimated amount.

## Response — `data.evm`

```json theme={null}
{
  "data": {
    "amountOutTokens": "245.123",
    "amountInUSD": 250.45,
    "amountOutUSD": 249.87,
    "slippagePercentage": 1,
    "marketImpactPercentage": 0.04,
    "poolFeesPercentage": 0.3,
    "tokenIn":  { "address": "0xEee…EEeE", "symbol": "ETH",  "decimals": 18 },
    "tokenOut": { "address": "0x8335…",    "symbol": "USDC", "decimals": 6  },
    "requestId": "f8b2…",
    "details": {
      "route": {
        "hops": [
          { "poolAddress": "0x4C36…", "exchange": "Uniswap V3", "poolType": "v3", "feeBps": 5 }
        ],
        "totalFeePercentage": 0.05,
        "aggregator": "kyberswap"
      }
    },
    "fee": { "amount": "0.00085", "percentage": 0.85, "wallet": "0xPartnerA…", "deductedFrom": "input" },
    "fees": [
      { "amount": "0.0006", "percentage": 0.6, "wallet": "0xPartnerA…", "deductedFrom": "input" },
      { "amount": "0.00025", "percentage": 0.25, "wallet": "0xPartnerB…", "deductedFrom": "input" }
    ],
    "evm": {
      "transaction": {
        "to":       "0xMobulaRouter…",
        "from":     "0xUserWallet…",
        "data":     "0xCALLDATA…",
        "value":    "100000000000000000",
        "gasLimit": "350000",
        "chainId":  8453,
        "approvalAddress": "0xMobulaRouter…",
        "approvals": [{ "token": "0xUSDC…", "spender": "0xMobulaRouter…" }]
      }
    },
    "solana": null,
    "ton": null
  }
}
```

### `data.evm.transaction` fields

| Field                                                | Type                  | Description                                                           |
| ---------------------------------------------------- | --------------------- | --------------------------------------------------------------------- |
| `to`                                                 | `0x…`                 | MobulaRouter contract on the target chain                             |
| `from`                                               | `0x…`                 | Echo of `walletAddress`                                               |
| `data`                                               | `0x…`                 | Encoded call to MobulaRouter — pass through verbatim to your wallet   |
| `value`                                              | string wei            | Native token to attach (= `amountIn` for native-in swaps, else `0`)   |
| `gasLimit`                                           | string?               | Suggested gas (your wallet may simulate to refine)                    |
| `gasPrice` / `maxFeePerGas` / `maxPriorityFeePerGas` | string? wei           | Filled per chain (legacy or EIP-1559)                                 |
| `nonce`                                              | number?               | Optional — wallet picks if omitted                                    |
| `chainId`                                            | number                | EIP-155 chain id matching `chainId` query param                       |
| `approvalAddress`                                    | `0x…`?                | Where the user must `approve()` the sell token (defaults to `to`)     |
| `approvals`                                          | `{token, spender}[]`? | Pre-flight approval list — execute these before `eth_sendTransaction` |

## Signing

```ts theme={null}
// 1. Execute pre-flight approvals if any (one approve() per (token,spender)).
for (const { token, spender } of quote.data.evm.transaction.approvals ?? []) {
  await wallet.writeContract({ address: token, abi: ERC20, functionName: 'approve', args: [spender, MAX] });
}

// 2. Send the swap tx.
const txHash = await wallet.request({
  method: 'eth_sendTransaction',
  params: [{
    to:    quote.data.evm.transaction.to,
    data:  quote.data.evm.transaction.data,
    value: quote.data.evm.transaction.value,
    gas:   quote.data.evm.transaction.gasLimit,
  }],
});
```

The wallet broadcasts directly — **no `/swap/send` call needed for EVM** (the call goes straight from the user's wallet to their RPC).

## Routing

All EVM swaps go through **MobulaRouter**, deployed identically on each supported chain. Under the hood it dispatches to the best aggregator (KyberSwap, NAOS, Li.Fi) — pick one explicitly via `onlyRouters` or let the API choose. DEX filtering (Uniswap V2/V3/V4, Curve, Balancer, PancakeSwap, Aerodrome, Velodrome, Sushi, …) via `onlyProtocols` / `excludedProtocols`.

## Limits

* **Approvals required** for any non-native sell token. Always check `approvals[]` and execute first.
* **Gas estimation** — `gasLimit` is a router-level upper bound. Wallets typically simulate to tighten.
* **Address case** — both lowercased and EIP-55 checksummed accepted on input.
