> ## 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 — best-route aggregation across Jupiter, Raydium, Orca, Meteora, Pump.fun and 30+ DEXs with optional 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.

## Native SOL and WSOL

```
So11111111111111111111111111111111111111111
```

Use this `tokenIn` / `tokenOut` value when the user is paying with, or receiving, native SOL from their wallet.

Wrapped SOL is the SPL mint `So11111111111111111111111111111111111111112`. Use the WSOL mint only when the user is intentionally swapping an existing WSOL token account.

## Request

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

| Param                                 | Required | Notes                                                                                                                                                                                                                                       |
| ------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chainId`                             | ✓        | `solana:solana`                                                                                                                                                                                                                             |
| `tokenIn` / `tokenOut`                | ✓        | Token mint address. Native SOL sentinel = `So111…111`; WSOL SPL mint = `So111…112`.                                                                                                                                                         |
| `amount` *or* `amountRaw`             | ✓        | Human-readable (`"1.5"`) or raw (`"1500000"` for 6-decimal USDC)                                                                                                                                                                            |
| `walletAddress`                       | ✓        | User's Solana base58 pubkey                                                                                                                                                                                                                 |
| `slippage`                            | –        | `%` value (`0`-`100`) or `auto`. Defaults to `auto`.                                                                                                                                                                                        |
| `prioritizationFeeLamports`           | –        | Jupiter-compatible priority fee budget: `auto`, fixed lamports, or `{"priorityLevelWithMaxLamports":{"priorityLevel":"medium" \| "high" \| "veryHigh","maxLamports":1000000,"global":false}}`                                               |
| `dynamicComputeUnitLimit`             | –        | `true` by default; dynamically sizes the Solana compute limit from the built swap instructions                                                                                                                                              |
| `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. This wallet pays transaction fees, priority fees, Jito tips, and ATA rent. It must sign when different from `walletAddress`. The swap funds still come from `walletAddress`.                                               |
| `closeAuthority`                      | –        | Optional close authority for non-WSOL ATAs Mobula creates during the swap when `payerAddress` is used. Usually set it to the central payer wallet to reclaim rent later.                                                                    |
| `destinationWallet`                   | –        | Solana-only tokenOut recipient. Defaults to `walletAddress`. Do not combine with `finalRecipientWallet`.                                                                                                                                    |
| `swapRecipientAddress`                | –        | Solana-only router-enforced final recipient. MobulaRouter transfers the exact final swap output to this wallet after swap execution and fee/slippage checks. Do not combine with `destinationWallet`. Legacy alias: `finalRecipientWallet`. |
| `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`)                                                                                                                                                                                             |

## Sponsored fees, close authority, and final recipient

Use `payerAddress` when a central wallet should pay Solana fees / ATA rent for the user. Add `closeAuthority` when that central wallet should be able to close non-WSOL ATAs created by Mobula during the swap and recover rent later.

```http theme={null}
GET /api/2/swap/quoting?chainId=solana:solana
  &tokenIn=So11111111111111111111111111111111111111111
  &tokenOut=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
  &amount=0.01
  &walletAddress=USER_WALLET
  &payerAddress=CENTRAL_FEE_PAYER_WALLET
  &closeAuthority=CENTRAL_FEE_PAYER_WALLET
  &swapRecipientAddress=FINAL_OUTPUT_WALLET
  &slippage=auto
  &dynamicComputeUnitLimit=true
```

* `walletAddress` owns the input funds and signs for the swap.
* `payerAddress` pays network fees / rent and must also sign when different from `walletAddress`.
* `closeAuthority` only has an effect when `payerAddress` is provided. It applies to non-WSOL ATAs Mobula creates and leaves open after execution.
* `swapRecipientAddress` receives the final output amount. It does not need to sign.
* `swapRecipientAddress` keeps `walletAddress` as the swap taker/authority, then MobulaRouter transfers the final output after fee and slippage checks.
* `swapRecipientAddress` requires a Mobula on-chain router route. If the selected route cannot use the router, the quote returns an error.

## Response — `data.solana`

```json theme={null}
{
  "data": {
    "amountOutTokens": "245.123",
    "amountInUSD": 200.45,
    "amountOutUSD": 199.87,
    "slippagePercentage": 1,
    "marketImpactPercentage": 0.04,
    "poolFeesPercentage": 0.25,
    "tokenIn":  { "address": "So111…111", "symbol": "SOL",  "decimals": 9 },
    "tokenOut": { "address": "EPjF…",     "symbol": "USDC", "decimals": 6 },
    "requestId": "f8b2…",
    "details": {
      "route": {
        "hops": [
          { "poolAddress": "5Q5…", "exchange": "Raydium", "poolType": "CLMM", "feeBps": 25 }
        ],
        "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'),
);
// The user wallet signs because it owns the input funds.
let signed = await wallet.signTransaction(tx);

// If the quote used payerAddress and it differs from walletAddress,
// the payer must sign too because it pays tx fees / ATA rent.
if (centralFeePayerKeypair) {
  // With a local Keypair:
  signed.sign([centralFeePayerKeypair]);
}

// Or with a wallet adapter / remote signer:
// signed = await centralFeePayerWallet.signTransaction(signed);

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 `dynamicComputeUnitLimit=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.
