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

# Stableswap on Solana

> Integrate the Solana stableswap program directly — swap instruction, pair-state fees, and router proofs for custom pricing.

On Solana, Swaps' stableswap protocol is a single on-chain program, deployed
on mainnet:

```
ghosty4ZU1Qk1HN7Ymz4pZ15QfspzJZgSYFkdKN6ZLK
```

It swaps between 6-decimal stable mints:

| Token | Mint                                           |
| ----- | ---------------------------------------------- |
| USDC  | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |
| USDT  | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` |
| PYUSD | `2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo` |
| xoUSD | `xoUSDq85Rjsb6SbUwJyreFgeWQvxdkT7R3c3g7s6p5Y`  |

<Info>
  Integration is permissionless at **default rates** read from `pair_state`.
  **Custom pricing** is delivered through Swaps-signed router proofs (covered
  below) — [reach out to us](https://console.swaps.xyz) to get set up.
</Info>

## Fees and `pair_state`

Each tradeable pair has a `pair_state` PDA holding directional fees, refreshed
continuously by the Swaps pricing keeper:

* **Seeds:** `["pair_state", mint_x, mint_y]` where `mint_x < mint_y`
  (lexicographic pubkey sort — the lower-sorted mint is canonical X).
* **Fields:** `mint_x`, `mint_y`, `x_to_y_fee_bps`, `y_to_x_fee_bps`,
  `last_updated_slot`, `bump`.

Read the `pair_state` for your pair to quote the default rate for each
direction.

## The `swap` instruction

```text theme={null}
swap(amount_in: u64, minimum_amount_out: u64)
```

Accounts, in order:

| #  | Account                       | Notes                                               |
| -- | ----------------------------- | --------------------------------------------------- |
| 1  | `user`                        | Signer                                              |
| 2  | `exchange_state`              | Program state PDA                                   |
| 3  | `mint_in`                     | Input mint                                          |
| 4  | `mint_out`                    | Output mint                                         |
| 5  | `token_state_in`              | Token state PDA for the input mint                  |
| 6  | `token_state_out`             | Token state PDA for the output mint                 |
| 7  | `token_vault_in`              | Program vault for the input mint (writable)         |
| 8  | `token_vault_out`             | Program vault for the output mint (writable)        |
| 9  | `user_token_account_in`       | User's input token account (writable)               |
| 10 | `recipient_token_account_out` | Recipient's output token account (writable)         |
| 11 | `pair_state`                  | Pair fee state PDA                                  |
| 12 | `instructions`                | Instructions sysvar (used to read the router proof) |
| 13 | `system_program`              |                                                     |
| 14 | `associated_token_program`    |                                                     |
| 15 | `token_program_in`            | Token program of the input mint                     |
| 16 | `token_program_out`           | Token program of the output mint                    |

An address lookup table is available to keep transactions compact:

```
9gMXVHfEV9L4vnQEHG879VwfYrcupBwKe9kRBFsLQoYg
```

## Custom pricing — the router proof

Without a proof, swaps execute at the default `pair_state` rates. A **router
proof** — an Ed25519 signature produced by the Swaps router key — overrides the
rate for a specific swap. This is how partners receive custom pricing.

The proof is supplied as an Ed25519 signature-verification precompile
instruction that **must be at transaction instruction index 0**; the program
reads it through the Instructions sysvar. The signed message is 118 bytes:

| Field      | Size     | Encoding          |
| ---------- | -------- | ----------------- |
| `"swap"`   | 4 bytes  | ASCII             |
| `user`     | 32 bytes | Pubkey            |
| `mintIn`   | 32 bytes | Pubkey            |
| `mintOut`  | 32 bytes | Pubkey            |
| `amountIn` | 8 bytes  | u64 little-endian |
| `expiry`   | 8 bytes  | i64 little-endian |
| `rateBps`  | 2 bytes  | u16 little-endian |

The `stableswap-sdk` npm package's `buildRouterProofMessage` and
`buildRouterProofInstruction` helpers are the reference implementation for this
encoding. Proofs are signed by Swaps — contact us to set up custom pricing.

## Errors

| Error                   | Cause                                        |
| ----------------------- | -------------------------------------------- |
| `Frozen`                | Exchange is currently frozen                 |
| `ZeroAmount`            | Amount must be greater than zero             |
| `InsufficientLiquidity` | Insufficient liquidity in the output vault   |
| `SlippageExceeded`      | Output is less than `minimum_amount_out`     |
| `InvalidPairState`      | Wrong `pair_state` account for the mints     |
| `InvalidProof`          | Router proof signature or message is invalid |
| `ProofExpired`          | Router proof `expiry` has passed             |

## Related

* [Stableswap on EVM](/protocol-reference/stableswap-evm) — the same protocol
  behind the GhostExchange interface.
* [Stableswaps via the API](/guides/stableswaps) — the same liquidity through
  a single `getAction` call.
