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

# Solana Swap Quoting

> Quote and execute swaps on Solana with native SOL / WSOL address rules, priority fees, Jito tips, and multi-lander racing.

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

## SOL addresses in swap requests

```
So11111111111111111111111111111111111111111
```

Use `So11111111111111111111111111111111111111111` when the user holds native SOL in their wallet and wants to swap from or receive native SOL.

Wrapped SOL is a real SPL mint and uses `So11111111111111111111111111111111111111112`. Use the wrapped SOL mint only when the user is explicitly swapping WSOL token-account balance, not their native lamports balance.

## Request

```http theme={null}
GET /api/2/swap/quoting?chainId=solana:solana
  &tokenIn=So11111111111111111111111111111111111111111
  &tokenOut=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
  &amount=1
  &walletAddress=8ZmF…
  &slippage=auto
  &prioritizationFeeLamports=auto
  &computeUnitLimit=true
  &jitoTipLamports=10000
  &feePercentage=0.5
  &feeWallet=8ZmF…
```

| Param                                 | Required | Notes                                                                                                                                                                                         |
| ------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chainId`                             | ✓        | `solana:solana`                                                                                                                                                                               |
| `tokenIn` / `tokenOut`                | ✓        | Token address. Native SOL sentinel = `So11111111111111111111111111111111111111111`. Wrapped SOL SPL mint = `So11111111111111111111111111111111111111112`.                                     |
| `amount` *or* `amountRaw`             | ✓        | Human-readable (`"1.5"`) or raw (`"1500000"` for 6-decimal USDC)                                                                                                                              |
| `walletAddress`                       | ✓        | User's Solana base58 pubkey. It signs/funds the swap and receives `tokenOut` unless `destinationWallet` or `finalRecipientWallet` is provided.                                                |
| `slippage`                            | –        | `auto` or fixed percentage 0-100. Default: `auto`.                                                                                                                                            |
| `prioritizationFeeLamports`           | –        | Jupiter-compatible priority fee budget: `auto`, fixed lamports, or `{"priorityLevelWithMaxLamports":{"priorityLevel":"medium" \| "high" \| "veryHigh","maxLamports":1000000,"global":false}}` |
| `computeUnitLimit`                    | –        | `true` by default; dynamically sizes the Solana compute limit from the built swap instructions. You can also pass a fixed integer.                                                            |
| `jitoTipLamports`                     | –        | Add a Jito tip transfer to one of the official tip accounts                                                                                                                                   |
| `multiLander`                         | –        | `true` returns N candidates over a durable nonce — see [Multi-lander](#multi-lander)                                                                                                          |
| `landerTipLamports`                   | –        | Per-lander tip when `multiLander=true`                                                                                                                                                        |
| `payerAddress`                        | –        | Fee abstraction — separate fee payer from `walletAddress`                                                                                                                                     |
| `destinationWallet`                   | –        | Sends output to another wallet when supported. Mutually exclusive with `finalRecipientWallet`.                                                                                                |
| `finalRecipientWallet`                | –        | Router-enforced final output recipient. The router sends the exact post-swap output to this wallet after swap, fees, and slippage checks. Mutually exclusive with `destinationWallet`.        |
| `feePercentage`                       | –        | Caller referral fee 0-99% (taken from input or output SOL)                                                                                                                                    |
| `feeWallet`                           | –        | Required when `feePercentage > 0` (and for `minFeesNative` / `feeToken`)                                                                                                                      |
| `minFeesNative`                       | –        | Minimum referral fee in SOL, e.g. `0.05`. Floors the referral fee — `max(amountIn × feePercentage/100, minFeesNative)` — enforced on-chain by MobulaRouter when the fee asset is native SOL.  |
| `feeToken`                            | –        | Mint of a token to charge a flat **minimum** fee in (with `minFeesTokenRaw`). Transferred to `feeWallet` via a dedicated instruction, **independent of the route**.                           |
| `minFeesTokenRaw`                     | –        | Raw amount (smallest unit) of `feeToken` to charge. Tx reverts if the user's balance is insufficient.                                                                                         |
| `onlyRouters`                         | –        | Comma-list of `jupiter,naos,kyberswap,lifi`                                                                                                                                                   |
| `excludedProtocols` / `onlyProtocols` | –        | DEX-level filter (e.g. `raydium,orca,pump-amm`)                                                                                                                                               |

### Recipient controls

By default, `walletAddress` receives the output token. Use `destinationWallet` for a simple recipient override when supported by the route. Use `finalRecipientWallet` when the Mobula Solana router must transfer the exact final output amount after swap execution, fees, and slippage checks.

`destinationWallet` and `finalRecipientWallet` are mutually exclusive. `payerAddress` only changes the Solana fee payer/signing wallet; it does not redirect the swap output.

## Response — `data.solana`

```json theme={null}
{
  "data": {
    "amountOutTokens": "245.123",
    "amountInUSD": 200.45,
    "amountOutUSD": 199.87,
    "slippagePercentage": 3.5,
    "marketImpactPercentage": 0.04,
    "poolFeesPercentage": 0.25,
    "tokenIn":  { "address": "So11111111111111111111111111111111111111111", "symbol": "SOL",  "decimals": 9 },
    "tokenOut": { "address": "EPjF…",     "symbol": "USDC", "decimals": 6 },
    "requestId": "f8b2…",
    "details": {
      "route": {
        "hops": [
          {
            "poolAddress": "5Q5…",
            "exchange": "Raydium",
            "poolType": "CLMM",
            "amountInRaw": "1000000000",
            "amountOutRaw": "245100000",
            "feePercentage": 0.25,
            "feeBps": 25,
            "feeSource": "pool",
            "marketImpactPercentage": 0.04,
            "priceImpactPercentage": 0.04,
            "volume24hUSD": 1234567.89,
            "ranking": 1
          }
        ],
        "totalFeePercentage": 0.25,
        "aggregator": "jupiter"
      }
    },
    "fee": { "amount": "0.001", "percentage": 0.5, "wallet": "8ZmF…", "deductedFrom": "input" },
    "solana": {
      "transaction": {
        "serialized": "base64-encoded-VersionedTransaction-bytes",
        "variant": "versioned"
      },
      "lastValidBlockHeight": 269450123
    },
    "evm": null,
    "ton": null
  }
}
```

### `data.solana` fields

| Field                    | Type                      | Description                                                                                                      |
| ------------------------ | ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `transaction.serialized` | base64                    | Full Solana transaction. Deserialize with `VersionedTransaction.deserialize` (or `Transaction.from` for legacy). |
| `transaction.variant`    | `'versioned' \| 'legacy'` | Discriminator — almost always `'versioned'` in practice.                                                         |
| `lastValidBlockHeight`   | number                    | Blockhash expiry — your client should broadcast before the chain ticks past this.                                |

## Multi-lander

Set `multiLander=true` to receive N candidate transactions sharing a durable nonce. Race them across Jito / Nozomi / 0slot for fastest landing — only one can commit.

```json theme={null}
{
  "data": {
    "candidates": [
      { "lander": "jito",     "serialized": "base64…", "tipAccount": "Cw8C…", "tipLamports": 1000 },
      { "lander": "nozomi",   "serialized": "base64…", "tipAccount": "TpdX…", "tipLamports": 1000 },
      { "lander": "zeroslot", "serialized": "base64…", "tipAccount": "6fQa…", "tipLamports": 1000 }
    ],
    "nonceAccount": "Hgs…",
    "nonceAuthority": "BvW…",
    "solana": null,
    "evm": null,
    "ton": null
  }
}
```

Sign every candidate, POST them all to `/swap/send` in batch mode (`candidates: [{lander, signedTransaction}, …]`).

## Signing

```ts theme={null}
import { VersionedTransaction } from '@solana/web3.js';

const tx = VersionedTransaction.deserialize(
  Buffer.from(quote.data.solana.transaction.serialized, 'base64'),
);
// Sign via wallet (Phantom / Privy / Backpack / etc.).
const signed = await wallet.signTransaction(tx);
const signedBase64 = Buffer.from(signed.serialize()).toString('base64');

await fetch('/api/2/swap/send', {
  method: 'POST',
  body: JSON.stringify({ chainId: 'solana:solana', signedTransaction: signedBase64 }),
});
```

## Supported aggregators

Jupiter, KyberSwap, NAOS, Li.Fi — pick one or several via `onlyRouters`. Per-DEX filtering (Raydium, Orca, Meteora DLMM/Damm, Pump AMM, Whirlpool, …) via `onlyProtocols` / `excludedProtocols`.

## Limits

* **Blockhash expiry** — `lastValidBlockHeight` is \~150 slots (60s). Re-quote if the user takes longer than that to sign.
* **Priority budget** — use `prioritizationFeeLamports` with `computeUnitLimit=true` so the CU price is derived from the final compute limit. When bundling with Jito, set `jitoTipLamports` separately.
* **Address forms** — Solana addresses are case-sensitive base58. Don't lowercase.
