# Trade API

Trade API は Raydium のルーティングエンジンを通じて見積もりを取得し、スワップを実行できます。エンドツーエンドの完全な実装については、 [SDK demo](https://github.com/raydium-io/raydium-sdk-V2-demo).

## フローの概要

Trade API を2ステップで使用します：

1. ルーティングエンジンから見積もりを取得します。
2. その見積もりからトランザクションを構築し、署名して送信します。

## 見積もりを取得

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

正確な入力量でトークンをスワップするための見積もりを返します。

### クエリパラメータ

| Name          | Type     | Required | Description                              |
| ------------- | -------- | -------- | ---------------------------------------- |
| `inputMint`   | `string` | Yes      | スワップ元のトークンミントアドレス                        |
| `outputMint`  | `string` | Yes      | スワップ先のトークンミントアドレス                        |
| `amount`      | `string` | Yes      | トークン小数単位や SOL の場合は lamports などのベース単位での金額 |
| `slippageBps` | `number` | Yes      | 許容スリッページ（ベーシスポイント）、例えば `50 = 0.5%`       |
| `txVersion`   | `string` | Yes      | トランザクションのバージョン： `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"
      }
    ]
  }
}
```

### 見積もりエンドポイント

| Path                     | Description |
| ------------------------ | ----------- |
| `/compute/swap-base-in`  | 正確な入力量を指定   |
| `/compute/swap-base-out` | 正確な出力量を指定   |

## トランザクションを構築

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

見積もりレスポンスから1つ以上のシリアライズされたトランザクションを構築します。

### リクエストボディ

| Name                            | Type      | Required | Description                       |
| ------------------------------- | --------- | -------- | --------------------------------- |
| `swapResponse`                  | `object`  | Yes      | 見積もりエンドポイントが返すレスポンス               |
| `wallet`                        | `string`  | Yes      | ユーザーウォレットの公開鍵                     |
| `txVersion`                     | `string`  | Yes      | トランザクションのバージョン： `V0` または `LEGACY` |
| `wrapSol`                       | `boolean` | No       | 入力側のレッグで SOL を wSOL にラップする        |
| `unwrapSol`                     | `boolean` | No       | 出力側のレッグで wSOL を SOL にアンラップする      |
| `inputAccount`                  | `string`  | No       | 入力トークンアカウント。入力が SOL の場合は省略してください。 |
| `outputAccount`                 | `string`  | No       | 出力トークンアカウント。出力が SOL の場合は省略してください。 |
| `computeUnitPriceMicroLamports` | `string`  | No       | マイクロラマポート単位の優先手数料                 |

### レスポンス例

```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 price を取得したい場合はこのヘルパーを使用してください。

## 完全な例

### インストール

```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 上。
