兌換交易¶
兌換為希望立即以最佳可用價格交換代幣的交易者提供即時執行。與限價單不同,兌換是 Fill-or-Kill — 要麼全額執行,要麼被拒絕。
兌換流程¶
sequenceDiagram
participant User
participant API as Sera API
participant Chain as Ethereum
User->>API: POST /swap/quote
API-->>User: Quote (uuid, route_params)
User->>User: Sign route_params (EIP-712)
User->>API: POST /swap (uuid + signature)
API->>Chain: Settlement
Chain-->>API: Confirmation
API-->>User: Success (trade_id) 步驟一:請求報價¶
const response = await fetch('https://api.sera.cx/api/v1/swap/quote', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
from_token: '0x1920...F88', // USDC address
to_token: '0xd3Bd...779', // EURC address
from_amount: '1000000000', // 1000 USDC (6 decimals)
owner_address: '0xYOUR_WALLET',
recipient: '0xYOUR_WALLET', // 接收輸出代幣的地址(可以是另一個錢包)
expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour
gas_mode: 'receive_less'
})
});
const quote = await response.json();
// quote.uuid — Unique quote identifier
// quote.route_params — EIP-712 parameters to sign
// quote.fee_breakdown — Gas 費用詳情 (gas_cost_usd, gas_cost_from_token)
報價參數¶
| 參數 | 類型 | 說明 |
|---|---|---|
from_token | address | 輸入代幣的 ERC-20 地址 |
to_token | address | 輸出代幣的 ERC-20 地址 |
from_amount | string | 以原始代幣單位表示的金額(例如 "1000000000" 代表 1000 USDC) |
owner_address | address | 您的錢包地址 |
recipient | address | 輸出代幣的接收地址;可以是任何地址——設定為其他錢包即可將兌換輸出傳送給第三方。 |
expiration | integer | Unix 時間戳截止時間 |
gas_mode | string | "receive_less" 或 "pay_more" |
報價回應¶
回應包含:
uuid— 此報價的唯一識別碼(提交時使用)route_params— 要簽署的 EIP-712 Intent 結構欄位fee_breakdown— Gas 費用詳情:gas_cost_usd和gas_cost_from_tokenexpires_at— 報價到期時間(報價為一次性使用)
步驟二:簽署報價¶
使用錢包透過 EIP-712 類型資料簽名對 route_params 進行簽署:
import { ethers } from 'ethers';
// The EIP-712 domain (get from /api/v1/tokens or contract)
const domain = {
name: 'Sera',
version: '1',
chainId: 11155111, // Sepolia
verifyingContract: '0x...' // Sera contract address
};
// The Intent type
const types = {
Intent: [
{ name: 'inputToken', type: 'address' },
{ name: 'outputToken', type: 'address' },
{ name: 'maxInputAmount', type: 'uint256' },
{ name: 'minOutputAmount', type: 'uint256' },
{ name: 'recipient', type: 'address' },
{ name: 'initialDepositAmount', type: 'uint256' },
{ name: 'uuid', type: 'uint256' },
{ name: 'deadline', type: 'uint48' },
]
};
const signature = await signer.signTypedData(domain, types, quote.route_params);
步驟三:執行兌換¶
提交已簽署的報價:
const result = await fetch('https://api.sera.cx/api/v1/swap', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
uuid: quote.uuid,
signature: signature
})
});
const swap = await result.json();
// swap.success — Whether the swap was accepted
// swap.trade_id — Unique trade identifier for tracking
Gas 模式¶
與限價單(需要以真實 ETH 支付 Gas)不同,兌換的 Gas 費用由伺服器自動計入報價中。您無需持有 ETH 即可執行兌換 — Gas 被吸收到代幣金額中。
請求報價時,您可以選擇 Gas 費用的應用方式:
| 模式 | 行為 |
|---|---|
receive_less | Gas 費用從輸出中扣除。您花費的金額恰好是 from_amount,但收到的金額略少。 |
pay_more | Gas 費用加到輸入中。您收到完整的報價金額,但花費略多。 |
報價回應中的 fee_breakdown 顯示確切的 Gas 費用,不會有意外。伺服器會計算調整後的金額 — 您的前端只需按原樣簽署 route_params 即可。
多段路由¶
Sera 會自動為您的兌換找到最佳路徑。如果直接交易對不存在,或多跳路徑能提供更好的定價,兌換會透過中間貨幣透明地進行路由。
例如,GBP → SGD 的兌換可能執行為:
- GBP → USD
- USD → SGD
這是原子性的 — 要麼所有段都成功,要麼全部不執行。
為什麼 MEV 不是問題¶
Sera 的兌換並不是像公共 AMM 兌換那樣執行的。報價生成、路由和撮合都在 Sera 的 Web2 引擎中鏈下完成,而 Ethereum 只作為最終結算層使用。
這意味著使用者不會把一筆開放式市價兌換訂單暴露到公共 mempool 中進行價格發現。相反,您會先請求報價,再簽署精確的 route_params,然後結算要麼在已簽署的邊界內執行,要麼直接失敗。
已簽署的 Intent 包含 maxInputAmount、minOutputAmount、一次性 uuid 和 deadline。由於交易並不是在公共 mempool 中被發現和重新定價,常見的夾擊攻擊路徑並不存在。
錯誤處理¶
| HTTP 狀態碼 | 含義 |
|---|---|
| 200 | 兌換已接受並正在處理 |
| 400 | 請求參數無效 |
| 410 | 報價已過期(請重新請求報價) |
| 429 | 超過速率限制(等待後重試) |
| 503 | 服務暫時不可用 |