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

# 路由指令

> AMM 路由指令的權威參考，涵蓋在主網啟用的六個變體——包括精確輸入/精確輸出交換及 wSOL 工具函式。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/products/routing/instructions)
</Info>

## 指令概覽

| 標籤 | 識別碼                          | 精確 | 變體     |
| -- | ---------------------------- | -- | ------ |
| 0  | `SwapBaseInWithUserAccount`  | 輸入 | Legacy |
| 1  | `SwapBaseOutWithUserAccount` | 輸出 | Legacy |
| 5  | `CreateSyncNative`           | —  | 工具     |
| 6  | `CloseTokenAccount`          | —  | 工具     |
| 8  | `SwapBaseIn`                 | 輸入 | 當前     |
| 9  | `SwapBaseOut`                | 輸出 | 當前     |

**說明：**

* **精確：** 呼叫者固定的金額類型（輸入 = 精確輸入 `amount_in`；輸出 = 精確輸出 `amount_out`）。
* **變體：** Legacy 指令即使路由中無 CLMM 跳躍也需要非空的 `limit_prices` 雙端佇列。當前指令（8 / 9）將空的 `limit_prices` 視為「無檢查」，這是新程式碼的推薦方式。

所有交換變體都通過**使用者控制的 ATA** 路由中間代幣——使用者擁有輸入 ATA、每個中間 ATA 及輸出 ATA。若為新的整合，請使用**標籤 8（`SwapBaseIn`）**或**標籤 9（`SwapBaseOut`）**，除非你有特別的理由呼叫 Legacy 變體。

## 當前交換指令（推薦）

這些是新程式碼應該使用的進入點。引數結構與 Legacy 變體相同，但 `limit_prices` 可以為空。

### `SwapBaseIn`（標籤 8）

精確輸入多跳躍交換。呼叫者固定 `amount_in`；路由器逐跳執行並確保最終金額達到或超過 `minimum_amount_out`。

**引數**

```
amount_in:            u64
minimum_amount_out:   u64
limit_prices:         VecDeque<u128>  // 可選；空雙端佇列表示無按跳躍 CLMM 價格檢查
```

**帳戶**

```
[
  <user_input_ata> W S,         // 簽署者；餘額 >= amount_in
  <user_intermediate_ata_1> W,  // 每個中間跳躍一個
  ... <user_intermediate_ata_N> W,
  <user_output_ata> W,
  <token_program>,

  <pool_program_hop_1>,         // 識別第 1 跳躍屬於哪個 AMM 系列
  <pool_state_hop_1> W,
  ... <hop 1 計畫所需的其他帳戶>,

  <pool_program_hop_2>,
  <pool_state_hop_2> W,
  ... <hop 2 帳戶>,

  ... [按跳躍數重複]
]
```

每個跳躍的確切帳戶清單取決於底層 AMM 計畫（AMM v4 / CPMM / CLMM / Stable）。路由器依次 CPI 進入每個計畫，並驗證計畫 ID 符合四個支援計畫之一。

**前置條件**

* 呼叫者使用 `user_input_ata` 簽署。
* `user_input_ata.amount >= amount_in`。
* 每個中間使用者 ATA 存在且由呼叫者擁有。
* 如果任何跳躍是 CLMM 且你想要價格界限強制執行，請為每個 CLMM 跳躍提供一個 `limit_prices` 項目。

**後置條件**

* `user_input_ata` 餘額減少 `amount_in`。
* `user_output_ata` 餘額增加 ≥ `minimum_amount_out`。
* 每個中間 ATA 保持零淨變化（路由消耗上一個跳躍產生的任何內容）。

**常見錯誤**

* `ExceededSlippage` — 最終輸出 \< `minimum_amount_out`。
* `InvalidInput` — 空路由、畸形帳戶或不支援的 `pool_program`。
* `SqrtPriceX64` — CLMM 跳躍的價格超出提供的 `limit_prices` 界限（僅當 `limit_prices` 非空時）。

***

### `SwapBaseOut`（標籤 9）

精確輸出多跳躍交換。呼叫者固定 `amount_out`；路由器確保實際輸入不超過 `maximum_amount_in`。

**引數**

```
maximum_amount_in:   u64
amount_out:          u64
limit_prices:        VecDeque<u128>  // 可選；空雙端佇列表示無按跳躍 CLMM 價格檢查
```

**帳戶** — 結構同標籤 8。

**前置條件**

* 呼叫者使用 `user_input_ata` 簽署；餘額 `>= maximum_amount_in`（最壞情況）。
* 每個中間 ATA 及輸出 ATA 存在。

**後置條件**

* `user_input_ata` 減少所需的實際金額（≤ `maximum_amount_in`）。
* `user_output_ata` 增加正好 `amount_out`。

**常見錯誤**

* `ExceededSlippage` — 所需輸入超過 `maximum_amount_in`。
* `InvalidInput`、`SqrtPriceX64` — 如標籤 8。

***

## Legacy 交換指令

這些較舊的變體在實際計畫上仍可呼叫，出於完整性在此記錄。對於新程式碼，優先使用標籤 8 / 標籤 9；下面兩個 Legacy 變體即使不涉及 CLMM 跳躍也需要非空的 `limit_prices` 雙端佇列，這使其使用起來不夠便利。

### `SwapBaseInWithUserAccount`（標籤 0）

精確輸入多跳躍交換，形狀與標籤 8 相同但有更嚴格的 `limit_prices` 要求。

**引數**

```
amount_in:           u64
minimum_amount_out:  u64
limit_prices:        VecDeque<u128>  // 必須、非空
```

**帳戶** — 形狀同 `SwapBaseIn`（標籤 8）。所有中間插槽必須是由呼叫者擁有的 ATA。

**前置條件**

* 呼叫者使用 `user_input_ata` 簽署。
* `user_input_ata.amount >= amount_in`。
* 所有中間使用者 ATA 存在且由呼叫者擁有。
* `limit_prices` 非空（每個 CLMM 跳躍一個項目；如無 CLMM 跳躍，用佔位符值填充）。

**後置條件**

* `user_input_ata` 餘額減少 `amount_in`。
* `user_output_ata` 餘額增加 ≥ `minimum_amount_out`。

**常見錯誤**

* `ExceededSlippage`。
* `InvalidInput` — 此 Legacy 變體拒絕空的 `limit_prices`。
* `SqrtPriceX64`。

***

### `SwapBaseOutWithUserAccount`（標籤 1）

精確輸出交換，是 `SwapBaseOut`（標籤 9）的 Legacy 對應。

**引數**

```
maximum_amount_in:   u64
amount_out:          u64
limit_prices:        VecDeque<u128>  // 必須、非空
```

**帳戶** — 形狀同標籤 0 / 標籤 9。

**前置條件**

* 呼叫者使用 `user_input_ata` 簽署。
* `user_input_ata.amount >= maximum_amount_in`。
* 所有中間使用者 ATA 存在且由呼叫者擁有。
* `limit_prices` 非空。

**後置條件**

* `user_input_ata` 減少所需的實際金額（≤ `maximum_amount_in`）。
* `user_output_ata` 增加正好 `amount_out`。

**常見錯誤**

* `ExceededSlippage`。
* `InvalidInput`。
* `SqrtPriceX64`。

***

## 工具指令

### `CreateSyncNative`（標籤 5）

在一個步驟中建立（若缺少）並同步 wSOL ATA。在交換時包裝 SOL 時很便利。

**引數**

```
amount: u64    // 要包裝的 SOL（lamports）
```

**帳戶**

```
[
  <user_wsol_ata> W,            // wSOL 的 ATA；若缺少則建立
  <user_native_account> W S,    // 簽署者；SOL 從此處扣除
  <wsol_mint>,
  <system_program>,
  <token_program>,
  <associated_token_program>,
]
```

**效果**

* 若 `user_wsol_ata` 不存在則建立它。
* 從簽署者的原生 SOL 餘額轉移 `amount` lamports 到 ATA。
* 在 ATA 上呼叫 `SyncNative` 使其代幣餘額反映新的 lamports。

**常見錯誤**

* `InvalidOwner` — `user_wsol_ata` 的擁有者不是簽署者。

***

### `CloseTokenAccount`（標籤 6）

關閉代幣帳戶並將其租金返還給目的地錢包。與 `CreateSyncNative` 配對：在 wSOL 交換後，呼叫 `CloseTokenAccount` 以回收支援 wSOL ATA 的租金。

**引數** — 無。

**帳戶**

```
[
  <token_account_to_close> W,
  <destination_for_rent> W,
  <owner> S,
  <token_program>,
]
```

**效果**

* 關閉 `token_account_to_close`。
* 將租金豁免的 lamport 餘額（主網上標準 SPL Token 帳戶約 0.00203928 SOL）轉移到 `destination_for_rent`。
* 代幣帳戶必須具有零代幣餘額。

**常見錯誤**

* `InvalidOwner` — 呼叫者不是 ATA 擁有者。
* 代幣帳戶餘額非零。

***

## 後續步驟

* [`products/routing/code-demos`](/zh-Hant/products/routing/code-demos) — 用 TypeScript 構建這些指令。
* [`products/routing/accounts`](/zh-Hant/products/routing/accounts) — 按 AMM 分派鍵及按跳躍帳戶佈局。
* [`reference/error-codes`](/zh-Hant/reference/error-codes) — 完整 `RouteError` 清單。
