> For the complete documentation index, see [llms.txt](https://docs.kumbaya.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kumbaya.xyz/developers/dex-integration/quoting.md).

# Quoting prices

You have three ways to get a swap quote on Kumbaya, depending on whether you want to run the routing logic yourself or have Kumbaya do it for you.

| Approach                              | When to use                            | Trade-off                                 |
| ------------------------------------- | -------------------------------------- | ----------------------------------------- |
| **`QuoterV2` directly (RPC)**         | Single-pool quotes, you know the route | Fast, simple. No multi-hop optimization.  |
| **`@kumbaya_xyz/smart-order-router`** | Multi-hop optimal routing, client-side | Heavier. Needs RPC + indexer access.      |
| **Exchange API `/api/v1/quote`**      | Most integrations - let us route       | One HTTPS call. Cached. Returns calldata. |

## Option 1: `QuoterV2` directly

For a single pool - fee tier and tokens known up front - the simplest path is calling `QuoterV2.quoteExactInputSingle()` via RPC.

```ts
import { createPublicClient, http, parseUnits } from 'viem'

const QUOTER_V2 = '0x1F1a8dC7E138C34b503Ca080962aC10B75384a27' // mainnet
const RPC = 'https://mainnet.megaeth.com/rpc'

const quoterAbi = [{
  type: 'function',
  name: 'quoteExactInputSingle',
  stateMutability: 'nonpayable',
  inputs: [{ type: 'tuple', name: 'params', components: [
    { type: 'address', name: 'tokenIn' },
    { type: 'address', name: 'tokenOut' },
    { type: 'uint256', name: 'amountIn' },
    { type: 'uint24',  name: 'fee' },
    { type: 'uint160', name: 'sqrtPriceLimitX96' },
  ]}],
  outputs: [
    { type: 'uint256', name: 'amountOut' },
    { type: 'uint160', name: 'sqrtPriceX96After' },
    { type: 'uint32',  name: 'initializedTicksCrossed' },
    { type: 'uint256', name: 'gasEstimate' },
  ],
}] as const

const client = createPublicClient({ transport: http(RPC) })

const quote = await client.simulateContract({
  address: QUOTER_V2,
  abi: quoterAbi,
  functionName: 'quoteExactInputSingle',
  args: [{
    tokenIn:  '0x4200000000000000000000000000000000000006', // WETH
    tokenOut: '0xYOUR_TOKEN',
    amountIn: parseUnits('1', 18),
    fee:      3000,    // 0.3% - pick the right tier
    sqrtPriceLimitX96: 0n,
  }],
})

console.log('Out:', quote.result[0])
console.log('Gas estimate:', quote.result[3])
```

Notes:

* `QuoterV2` does a real on-chain simulation, so the result is exact (modulo the obvious caveat that price can move before your tx lands).
* It's a `nonpayable` function despite being read-only - that's a Uniswap V3 quirk. Use `simulateContract` (viem) or `staticCall` (ethers) rather than `readContract`.
* For exact output, use `quoteExactOutputSingle` (same shape, swap `amountIn` → `amountOut`).
* For multi-hop, use `quoteExactInput(bytes path, uint256 amountIn)` with a packed path - but at that point you probably want option 2 or 3.

## Option 2: Smart Order Router (client-side)

For multi-hop and split routes, use [`@kumbaya_xyz/smart-order-router`](/developers/sdks/smart-order-router.md). It enumerates pools, scores routes, and accounts for gas:

```bash
npm install @kumbaya_xyz/smart-order-router @kumbaya_xyz/sdk-core ethers@^5
```

> Smart Order Router is built on **ethers v5** (`BaseProvider` from `@ethersproject/providers`). It does not currently support ethers v6 or viem providers.

```ts
import { AlphaRouter } from '@kumbaya_xyz/smart-order-router'
import { CurrencyAmount, Token, ChainId, TradeType, Percent } from '@kumbaya_xyz/sdk-core'
import { providers } from 'ethers'   // ethers v5

const provider = new providers.JsonRpcProvider('https://mainnet.megaeth.com/rpc')

const router = new AlphaRouter({
  chainId: ChainId.MEGAETH,
  provider,
})

const tokenIn  = new Token(ChainId.MEGAETH, '0x4200000000000000000000000000000000000006', 18, 'WETH')
const tokenOut = new Token(ChainId.MEGAETH, '0xYOUR_TOKEN', 18, 'TOKEN')

const route = await router.route(
  CurrencyAmount.fromRawAmount(tokenIn, '1000000000000000000'), // 1 WETH
  tokenOut,
  TradeType.EXACT_INPUT,
  {
    recipient: '0xYourWalletAddress',
    slippageTolerance: new Percent(50, 10_000), // 0.5%
    deadline: Math.floor(Date.now() / 1000) + 600,
  },
)

console.log('Quote:',  route?.quote.toExact())
console.log('Calldata:', route?.methodParameters?.calldata)
console.log('Value:',    route?.methodParameters?.value)
```

The returned `methodParameters` are ready to send to `SwapRouter02` or `UniversalRouter` (configurable on the `route` call). See [**Executing swaps**](/developers/dex-integration/swapping.md).

## Option 3: Exchange API

If you don't want to run the SOR client-side, hit the hosted endpoint:

```
GET https://exchange.kumbaya.xyz/api/v1/quote?
    chainId=4326
    &tokenInAddress=0x4200000000000000000000000000000000000006
    &tokenOutAddress=0xYOUR_TOKEN
    &amount=1000000000000000000
    &slippageBps=50
    &recipient=0xYourWalletAddress
    &type=exactIn                                  # default; or 'exactOut'
    &routerType=swap-router-02                     # default; or 'universal'
```

Response includes:

* `quote` and `quoteGasAdjusted` (human-readable decimal strings)
* `gasUseEstimate`, `gasUseEstimateUSD`
* `methodParameters: { to, value, calldata }` - ready to submit as a transaction
* `route` - the path the SOR picked

> The GET endpoint takes `amount` and `type` (`exactIn` / `exactOut`); the POST partner endpoint takes `fromAmount` and uses a decimal `slippage` instead. They're not interchangeable. See [**Quote endpoints**](/developers/apis/exchange-api/quote.md).

See [**Executing swaps**](/developers/dex-integration/swapping.md) for what to do with the returned calldata.

## Picking between them

* **Quick prototype, single pool:** `QuoterV2` direct.
* **Production frontend or bot, full routing:** Exchange API. Less to maintain, server-side caching.
* **Custom routing logic, alternative venues, or you want to inspect routes:** Smart Order Router locally.
