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

# Swap 与 Bridge

> 通过统一 API 跨链交换资产

<img src="https://mintcdn.com/blockradar/FrE2zfJ4u32QicMn/images/swap.jpg?fit=max&auto=format&n=FrE2zfJ4u32QicMn&q=85&s=a3cb4d76aa3218dd5b8cf2c816d55b93" alt="Swap 与 Bridge" width="2880" height="1620" data-path="images/swap.jpg" />

<Note>
  简而言之<br />
  Blockradar 的 Swap API 让您可以通过单一的统一 endpoint 在同一条链上交换资产（swap），或在不同链之间转移资产（bridge）。
</Note>

## 前提条件

在使用 Swap API 之前，请确保您已具备：

<Steps>
  <Step title="API 密钥">
    从 [Blockradar Dashboard](https://dashboard.blockradar.co) 获取您的 API 密钥。前往 **Developers** 进行生成。
  </Step>

  <Step title="已创建钱包">
    通过 [Create Wallet API](/en/api-reference/wallets/create-wallet) 或 dashboard 创建钱包。您将需要 `walletId` 来执行 swap 操作。
  </Step>

  <Step title="资产 ID">
    在 dashboard 的 **Assets** 中或通过 [Get Assets API](/en/api-reference/miscellaneous/get-assets) 获取源资产和目标资产的 `assetId`。
  </Step>

  <Step title="充足余额">
    确保您的钱包持有足够的源资产余额，以覆盖 swap 金额及网络手续费。
  </Step>
</Steps>

## 工作原理

Blockradar 会根据您选择的资产自动判断该交易是 **swap** 还是 **bridge**：

<CardGroup cols={2}>
  <Card title="Swap" icon="repeat">
    在**同一区块链**上交换不同资产。

    *示例：Base 上的 USDC → USDT*
  </Card>

  <Card title="Bridge" icon="bridge">
    在**不同区块链**之间转移资产。

    *示例：BSC 上的 USDC → Optimism 上的 USDC*
  </Card>
</CardGroup>

<Tip>
  您无需指定是 swap 还是 bridge——API 会根据您提供的 `fromAssetId` 和 `toAssetId` 自动处理。
</Tip>

## 支持的资产与链

Swap API 在 Blockradar 支持的链上支持主要稳定币：

| Stablecoin | 描述             |
| ---------- | -------------- |
| USDT       | Tether USD     |
| USDC       | USD Coin       |
| DAI        | Dai Stablecoin |
| BUSD       | Binance USD    |
| cNGN       | 奈拉稳定币          |
| EURC       | Euro Coin      |
| IDRX       | 印尼盾稳定币         |
| JPYC       | 日元稳定币          |

<Warning>
  资产可用性因链而异。请始终使用 [Get Assets API](/en/api-reference/miscellaneous/get-assets) 获取目标链上当前支持的资产列表及其 `assetId` 值。
</Warning>

<Note>
  请参阅[集成](/en/essentials/integrations)了解支持的网络与稳定币完整列表。
</Note>

## Master Wallet 与 Child Address

Swap API 在两个层级上提供：

<CardGroup cols={2}>
  <Card title="Master Wallet" icon="wallet">
    直接从您的 master wallet 执行 swap。适合资金管理操作。
  </Card>

  <Card title="Child Address" icon="address-card">
    从单个 child address 执行 swap。非常适合面向特定用户的操作。
  </Card>
</CardGroup>

### Endpoints

| 操作   | Master Wallet                               | Child Address                                                     |
| ---- | ------------------------------------------- | ----------------------------------------------------------------- |
| 获取报价 | `POST /v1/wallets/{walletId}/swaps/quote`   | `POST /v1/wallets/{walletId}/addresses/{addressId}/swaps/quote`   |
| 执行   | `POST /v1/wallets/{walletId}/swaps/execute` | `POST /v1/wallets/{walletId}/addresses/{addressId}/swaps/execute` |

## 第 1 步：获取报价

在执行 swap 之前，始终获取报价以向用户展示预期结果。

### 请求参数

| 参数                 | 类型     | 是否必填 | 描述                                                    |
| ------------------ | ------ | ---- | ----------------------------------------------------- |
| `fromAssetId`      | string | 是    | 用于交换的源 asset ID                                       |
| `toAssetId`        | string | 是    | 用于交换的目标 asset ID                                      |
| `amount`           | string | 是    | 交换金额                                                  |
| `order`            | string | 否    | 报价偏好：`FASTEST`、`CHEAPEST`、`RECOMMENDED`、`NO_SLIPPAGE` |
| `recipientAddress` | string | 否    | 外部钱包地址（用于发送至非 Blockradar 钱包）                          |

### 报价示例

<CodeGroup>
  ```bash Curl theme={null}
  curl --request POST \
    --url https://api.blockradar.co/v1/wallets/{walletId}/swaps/quote \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
      "fromAssetId": "asset_usdc_base_mainnet",
      "toAssetId": "asset_usdt_bsc_mainnet",
      "amount": "100",
      "order": "RECOMMENDED"
    }'
  ```

  ```javascript JavaScript theme={null}
  const quote = await fetch(
    `https://api.blockradar.co/v1/wallets/${walletId}/swaps/quote`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        fromAssetId: 'asset_usdc_base_mainnet',
        toAssetId: 'asset_usdt_bsc_mainnet',
        amount: '100',
        order: 'RECOMMENDED'
      })
    }
  ).then(r => r.json());

  console.log('Quote:', quote.data);
  ```
</CodeGroup>

### 报价响应

```json theme={null}
{
  "message": "Swap quote fetched successfully",
  "statusCode": 200,
  "data": {
    "amount": "99.45",
    "minAmount": "98.95",
    "rate": "0.9945",
    "impact": "0.12",
    "slippage": "0.5",
    "networkFee": "0.002",
    "networkFeeInUSD": "0.15",
    "estimatedArrivalTime": 180
  }
}
```

### 理解报价字段

| 字段                     | 描述                             |
| ---------------------- | ------------------------------ |
| `amount`               | swap 完成后您预计将收到的金额              |
| `minAmount`            | 最低保证金额（已计入 slippage）           |
| `rate`                 | 实际兑换汇率 (toAmount / fromAmount) |
| `impact`               | 价格影响百分比                        |
| `slippage`             | 允许的最大价格波动百分比                   |
| `networkFee`           | 以原生代币单位计的 gas 费                |
| `networkFeeInUSD`      | 折算为 USD 的 gas 费                |
| `estimatedArrivalTime` | 预计完成时间（秒）                      |

<Tip>
  在用户确认 swap 之前，至少应展示：**预计收到的金额**、**预计到账时间**和**手续费**。
</Tip>

## 第 2 步：执行 Swap

用户确认报价后，执行 swap。

### 请求参数

| 参数                 | 类型     | 是否必填 | 描述                                                    |
| ------------------ | ------ | ---- | ----------------------------------------------------- |
| `fromAssetId`      | string | 是    | 用于交换的源 asset ID                                       |
| `toAssetId`        | string | 是    | 用于交换的目标 asset ID                                      |
| `amount`           | string | 是    | 交换金额                                                  |
| `order`            | string | 否    | 报价偏好：`FASTEST`、`CHEAPEST`、`RECOMMENDED`、`NO_SLIPPAGE` |
| `recipientAddress` | string | 否    | 外部钱包地址（用于发送至非 Blockradar 钱包）                          |
| `reference`        | string | 否    | 您的内部追踪 ID                                             |
| `metadata`         | object | 否    | 通过 webhooks 传递的自定义数据                                  |

### 执行示例

<CodeGroup>
  ```bash Curl theme={null}
  curl --request POST \
    --url https://api.blockradar.co/v1/wallets/{walletId}/swaps/execute \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
      "fromAssetId": "asset_usdc_base_mainnet",
      "toAssetId": "asset_usdt_bsc_mainnet",
      "amount": "100",
      "order": "RECOMMENDED",
      "reference": "swap-order-12345",
      "metadata": {
        "userId": "user_abc123",
        "orderId": "order_xyz789"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const swap = await fetch(
    `https://api.blockradar.co/v1/wallets/${walletId}/swaps/execute`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        fromAssetId: 'asset_usdc_base_mainnet',
        toAssetId: 'asset_usdt_bsc_mainnet',
        amount: '100',
        order: 'RECOMMENDED',
        reference: 'swap-order-12345',
        metadata: {
          userId: 'user_abc123',
          orderId: 'order_xyz789'
        }
      })
    }
  ).then(r => r.json());

  console.log('Swap initiated:', swap.data);
  ```
</CodeGroup>

### 执行响应

```json theme={null}
{
  "message": "Swap transaction created successfully",
  "statusCode": 200,
  "data": {
    "id": "swap-uuid-123",
    "type": "SWAP",
    "status": "PENDING",
    "fromAsset": {
      "symbol": "USDC",
      "amount": "100",
      "blockchain": "base"
    },
    "toAsset": {
      "symbol": "USDT",
      "amount": "99.45",
      "blockchain": "bsc"
    },
    "reference": "swap-order-12345",
    "metadata": {
      "userId": "user_abc123",
      "orderId": "order_xyz789"
    },
    "createdAt": "2024-01-15T10:30:00Z"
  }
}
```

<Warning>
  Swap 操作是异步的。初始响应显示 `PENDING` 状态。请监听 `swap.success` 或 `swap.failed` webhook 以确认完成。
</Warning>

## 订单类型

根据您的使用场景选择合适的订单类型：

| 订单类型          | 描述       | 适用场景        |
| ------------- | -------- | ----------- |
| `FASTEST`     | 优先速度而非成本 | 时间敏感的交易     |
| `CHEAPEST`    | 最小化手续费   | 成本敏感的操作     |
| `RECOMMENDED` | 平衡方案（默认） | 大多数使用场景     |
| `NO_SLIPPAGE` | 精确金额或失败  | 对金额精度有要求的场景 |

## Webhook 事件

通过 webhooks 监控 swap 完成情况：

| 事件             | 描述        |
| -------------- | --------- |
| `swap.success` | swap 成功完成 |
| `swap.failed`  | swap 失败   |

### Webhook 负载

```json theme={null}
{
  "event": "swap.success",
  "data": {
    "id": "swap-uuid-123",
    "type": "SWAP",
    "status": "SUCCESS",
    "fromAsset": {
      "symbol": "USDC",
      "amount": "100",
      "blockchain": "base",
      "hash": "0xabc..."
    },
    "toAsset": {
      "symbol": "USDT",
      "amount": "99.45",
      "blockchain": "bsc",
      "hash": "0xdef..."
    },
    "reference": "swap-order-12345",
    "metadata": {
      "userId": "user_abc123",
      "orderId": "order_xyz789"
    },
    "completedAt": "2024-01-15T10:33:00Z"
  }
}
```

## 完整流程示例

以下是展示报价 → 确认 → 执行流程的完整实现：

```javascript theme={null}
async function executeSwap(walletId, fromAssetId, toAssetId, amount) {
  const apiKey = process.env.BLOCKRADAR_API_KEY;
  const baseUrl = 'https://api.blockradar.co/v1';

  // Step 1: Get quote
  const quote = await fetch(
    `${baseUrl}/wallets/${walletId}/swaps/quote`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        fromAssetId,
        toAssetId,
        amount,
        order: 'RECOMMENDED'
      })
    }
  ).then(r => r.json());

  // Step 2: Display quote to user
  console.log(`You will receive: ${quote.data.amount}`);
  console.log(`Minimum amount: ${quote.data.minAmount}`);
  console.log(`Network fee: $${quote.data.networkFeeInUSD}`);
  console.log(`Estimated time: ${quote.data.estimatedArrivalTime}s`);

  // Step 3: Execute swap (after user confirmation)
  const swap = await fetch(
    `${baseUrl}/wallets/${walletId}/swaps/execute`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        fromAssetId,
        toAssetId,
        amount,
        order: 'RECOMMENDED',
        reference: `swap-${Date.now()}`
      })
    }
  ).then(r => r.json());

  console.log('Swap initiated:', swap.data.id);
  console.log('Status:', swap.data.status);

  // Step 4: Listen for webhook to confirm completion
  return swap.data;
}

// Usage
executeSwap(
  'wallet-uuid',
  'asset_usdc_base_mainnet',
  'asset_usdt_bsc_mainnet',
  '100'
);
```

## 错误响应

<AccordionGroup>
  <Accordion title="余额不足">
    ```json theme={null}
    {
      "message": "Insufficient balance for swap",
      "statusCode": 400,
      "error": "INSUFFICIENT_BALANCE",
      "data": {
        "required": "100",
        "available": "50.25",
        "asset": "USDC"
      }
    }
    ```
  </Accordion>

  <Accordion title="无效的 Asset ID">
    ```json theme={null}
    {
      "message": "Asset not found",
      "statusCode": 404,
      "error": "ASSET_NOT_FOUND",
      "data": {
        "assetId": "invalid_asset_id"
      }
    }
    ```
  </Accordion>

  <Accordion title="Swap 路径不可用">
    ```json theme={null}
    {
      "message": "No swap route available for this pair",
      "statusCode": 400,
      "error": "NO_ROUTE_AVAILABLE",
      "data": {
        "fromAsset": "USDC",
        "toAsset": "CUSTOM_TOKEN"
      }
    }
    ```
  </Accordion>

  <Accordion title="金额过低">
    ```json theme={null}
    {
      "message": "Amount below minimum swap threshold",
      "statusCode": 400,
      "error": "AMOUNT_TOO_LOW",
      "data": {
        "minimum": "10",
        "provided": "1"
      }
    }
    ```
  </Accordion>

  <Accordion title="Slippage 超限">
    ```json theme={null}
    {
      "message": "Price moved beyond slippage tolerance",
      "statusCode": 400,
      "error": "SLIPPAGE_EXCEEDED",
      "data": {
        "expectedAmount": "99.45",
        "actualAmount": "97.00",
        "slippageTolerance": "0.5%"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## 最佳实践

### 用户体验

* **始终展示报价**：在执行前展示金额、手续费和预计时间
* **处理 slippage**：告知用户可能存在的价格波动
* **展示进度**：使用 webhooks 向用户更新 swap 状态

### 安全性

* **校验金额**：确保 swap 金额在可接受的范围内
* **使用 references**：用唯一的 reference ID 追踪 swap
* **监控 webhooks**：始终通过 webhooks 验证 swap 完成情况

### 性能

* **缓存 asset IDs**：将 asset IDs 缓存在本地，避免重复查询
* **使用合适的订单类型**：对时间敏感选用 `FASTEST`，对成本敏感选用 `CHEAPEST`
* **实现重试**：使用指数退避处理临时性故障

## API 参考

| Endpoint                                                                  | 描述                         |
| ------------------------------------------------------------------------- | -------------------------- |
| [Master Wallet Get Quote](/en/api-reference/swap/master-wallet-get-quote) | 从 master wallet 获取 swap 报价 |
| [Master Wallet Execute](/en/api-reference/swap/master-wallet-execute)     | 从 master wallet 执行 swap    |
| [Child Address Get Quote](/en/api-reference/swap/child-address-get-quote) | 从 child address 获取 swap 报价 |
| [Child Address Execute](/en/api-reference/swap/child-address-execute)     | 从 child address 执行 swap    |

## 支持

* **邮箱**：[support@blockradar.co](mailto:support@blockradar.co)
* **文档**：[API 参考](/en/api-reference/swap/master-wallet-get-quote)
* **博客**：[如何使用 Blockradar 进行 swap 或 bridge 资产](https://www.blockradar.co/blog/how-to-swap-or-bridge-assets-with-blockradar-a-follow-along-guide)

<Note>
  Swap API 为同链 swap 与跨链 bridge 提供统一接口。在迁移到生产环境之前，请先在 testnets 上使用小额测试金额进行验证。
</Note>
