# Trade API

Trade API 允许您通过 Raydium 的路由引擎获取报价并执行代币交换。有关完整的端到端实现，请参阅 [SDK 示例](https://github.com/raydium-io/raydium-sdk-V2-demo).

## 流程概览

使用 Trade API 分两步进行：

1. 从路由引擎获取报价。
2. 根据该报价构建交易，然后签名并发送。

## 获取报价

`GET https://transaction-v1.raydium.io/compute/swap-base-in`

返回用于以精确输入金额进行代币交换的报价。

### 查询参数

| 名称            | 类型       | 必填 | 说明                                |
| ------------- | -------- | -- | --------------------------------- |
| `inputMint`   | `string` | 是  | 要交换出的代币 mint 地址                   |
| `outputMint`  | `string` | 是  | 要交换入的代币 mint 地址                   |
| `amount`      | `string` | 是  | 以基础单位表示的数量，例如代币小数或 SOL 的 lamports |
| `slippageBps` | `number` | 是  | 以基点表示的滑点容忍度，例如 `50 = 0.5%`        |
| `txVersion`   | `string` | 是  | 交易版本： `v0` 或 `legacy`             |

### 示例响应

```json
{
  "id": "cbbcc7e2-a5fa-4040-a260-b229842c93c7",
  "success": true,
  "version": "V1",
  "data": {
    "swapType": "BaseIn",
    "inputMint": "So11111111111111111111111111111111111111112",
    "inputAmount": "100000000",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "outputAmount": "13738391",
    "otherAmountThreshold": "13669699",
    "slippageBps": 50,
    "priceImpactPct": 0,
    "referrerAmount": "0",
    "routePlan": [
      {
        "poolId": "3nMFwZXwY1s1M5s8vYAHqd4wGs4iSxXE4LRoUMMYqEgF",
        "inputMint": "So11111111111111111111111111111111111111112",
        "outputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
        "feeMint": "So11111111111111111111111111111111111111112",
        "feeRate": 1,
        "feeAmount": "10000",
        "remainingAccounts": [
          "DDe2TojkajtXKYJEMKfjY3Xjdw1XhZqr8UEBNgrg512P",
          "AWeEpV2ASCkVmcpK7htwWCqztmKMNdsmquKMa7y96Wif",
          "22ps6VsrEnCwEfGX4nkFV2xz4ohpvF5aTVtSg5FcwGRn"
        ],
        "lastPoolPriceX64": "6841151606851928973"
      },
      {
        "poolId": "3NeUgARDmFgnKtkJLqUcEUNCfknFCcGsFfMJCtx6bAgx",
        "inputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
        "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "feeMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
        "feeRate": 1,
        "feeAmount": "1376",
        "remainingAccounts": [
          "CxPCSxEmvkTyd6tqpVcZv2QscGrzkZKBmH7R9Bs9wocT",
          "9iD8oCrLQFNd1sbhYZg2awLrsZu4f1AAZG6bHuJkLXEx",
          "32D4WyeYS7irtnGpVS2VYja5H8uUpc8zF24kd15oFD2o"
        ],
        "lastPoolPriceX64": "18455174383562030500"
      }
    ]
  }
}
```

### 报价端点

| 路径                       | 说明        |
| ------------------------ | --------- |
| `/compute/swap-base-in`  | 指定精确的输入金额 |
| `/compute/swap-base-out` | 指定精确的输出金额 |

## 构建交易

`POST https://transaction-v1.raydium.io/transaction/swap-base-in`

根据报价响应构建一个或多个序列化交易。

### 请求体

| 名称                              | 类型        | 必填 | 说明                       |
| ------------------------------- | --------- | -- | ------------------------ |
| `swapResponse`                  | `object`  | 是  | 报价端点返回的响应                |
| `wallet`                        | `string`  | 是  | 用户钱包公钥                   |
| `txVersion`                     | `string`  | 是  | 交易版本： `V0` 或 `LEGACY`    |
| `wrapSol`                       | `boolean` | 否  | 将 SOL 包装为 wSOL 用于输入链路    |
| `unwrapSol`                     | `boolean` | 否  | 将 wSOL 解包为 SOL 用于输出链路    |
| `inputAccount`                  | `string`  | 否  | 输入代币账户，如果输入为 SOL 则省略     |
| `outputAccount`                 | `string`  | 否  | 输出代币账户，如果输出为 SOL 则省略     |
| `computeUnitPriceMicroLamports` | `string`  | 否  | 以 micro-lamports 表示的优先费用 |

### 示例响应

```json
{
  "id": "bca0c725-0037-48ce-8d0a-db39a0f6e020-tx",
  "version": "V1",
  "success": true,
  "data": [
    {
      "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQADEUxrOZd2...[truncated]"
    }
  ]
}
```

## 可选的优先费用辅助工具

`GET https://api-v3.raydium.io/main/auto-fee`

如果您想要建议的 compute unit 价格而不是手动设置优先费用，请使用此辅助工具。

## 完整示例

### 安装

```bash
yarn add @raydium-io/raydium-sdk-v2
```

### 设置

```typescript
import { Transaction, VersionedTransaction } from '@solana/web3.js'
import { NATIVE_MINT } from '@solana/spl-token'
import axios from 'axios'
import { connection, owner, fetchTokenAccountData } from '../config'
import { API_URLS } from '@raydium-io/raydium-sdk-v2'

// config.ts
export const owner: Keypair = Keypair.fromSecretKey(bs58.decode('<YOUR_WALLET_SECRET_KEY>'))
export const connection = new Connection('<YOUR_RPC_URL>')
```

> 测试时请勿使用您的主钱包私钥。

### 获取报价

```typescript
const { data: swapResponse } = await axios.get<SwapCompute>(
  `${API_URLS.SWAP_HOST}/compute/swap-base-in?inputMint=${inputMint}&outputMint=${outputMint}&amount=${amount}&slippageBps=${slippage * 100}&txVersion=${txVersion}`
)
```

### 序列化

```typescript
const { data: swapTransactions } = await axios.post(
  `${API_URLS.SWAP_HOST}/transaction/swap-base-in`,
  {
    computeUnitPriceMicroLamports: String(priorityFee),
    swapResponse,
    txVersion,
    wallet: owner.publicKey.toBase58(),
    wrapSol: isInputSol,
    unwrapSol: isOutputSol,
    inputAccount: isInputSol ? undefined : inputTokenAcc?.toBase58(),
    outputAccount: isOutputSol ? undefined : outputTokenAcc?.toBase58(),
  }
)
```

### 反序列化并发送

```typescript
const allTxBuf = swapTransactions.data.map((tx) => Buffer.from(tx.transaction, 'base64'))
const allTransactions = allTxBuf.map((txBuf) =>
  isV0Tx ? VersionedTransaction.deserialize(txBuf) : Transaction.from(txBuf)
)

for (const tx of allTransactions) {
  const transaction = tx as VersionedTransaction
  transaction.sign([owner])
  const txId = await connection.sendTransaction(transaction, { skipPreflight: true })

  const { lastValidBlockHeight, blockhash } = await connection.getLatestBlockhash({
    commitment: 'finalized',
  })

  await connection.confirmTransaction(
    { blockhash, lastValidBlockHeight, signature: txId },
    'confirmed'
  )
}
```

## 需要帮助？

在以下位置提问 [#dev-chat](https://discord.com/channels/813741812598439958/1009085496279977994) 在 Discord 上。
