跳轉至

快速開始

網路與相容性

資源 值
API 基礎 URL https://api.testnet.sera.cx/api/v1
鏈 Sepolia(chainId 11155111)
Sera 合約 0x83475A1bD98a8DC2DCd507A747e4DC85da241D6e
Vault 合約 0x3c7945840bAE0d7e7f3824Ebccef1962629250F0
SOR 合約 0x83c1368110B640A729f3810De5FBe94b99aa5668

簽名原語。 所有交易型變更都是針對 Sera domain 的 EIP-712 類型化資料簽名。走 permit 路徑的充值使用 ERC-2612 Permit 擴充功能 — USDC、EURC、EURT 以及多數現代穩定幣支援,但並非所有 ERC-20 都支援;簽名前請呼叫 GET /permit/metadata 檢查。API key 管理使用 EIP-712 ManageApiKey payload。

已驗證客戶端。 Python eth_account >= 0.10 + requests;TypeScript ethers v6(signer.signTypedData)。已驗證支援 EIP-712 類型化資料的瀏覽器錢包:MetaMask、Rabby、Frame、Coinbase Wallet、Trust、Rainbow。Safe 多簽透過 EIP-1271 支援(訊息於鏈上驗證,而非透過 ecrecover)。

地址大小寫。 讀取類端點(/balances、/orders、/fills)將 owner_address 視為大小寫敏感 — 請傳入小寫形式。EIP-712 簽名 payload 接受 EIP-55 校驗和地址。

本指南將帶您完成與 Sera 的首次互動 — 從查詢可用代幣到執行您的第一筆兌換。

前置條件

  • 一個 Ethereum 錢包(例如 MetaMask)
  • 一些測試網 ETH 用於支付 Gas(使用 Sepolia 水龍頭)
  • 用於交易的測試網穩定幣 — 登錄表中的所有代幣(USDC、EURC、GBPA、XSGD …)都可以從 Sera 測試網水龍頭免費領取(詳見下方)。

Sera 測試網代幣水龍頭

測試網代幣登錄表 中的每種穩定幣都可以從 Sepolia 上的 Sera 水龍頭合約免費鑄造:

水龍頭: 0x4FAc3BB8B77547E2Da7ed903baDBeD2f46cBe65a

在 testnet.sera.cx 的「領取測試代幣」流程中使用,或直接呼叫水龍頭合約並傳入您想要的代幣地址。若沒有對應測試代幣的非零餘額,下方步驟都無法運行。

步驟一:瀏覽可用代幣

查詢代幣登錄表以查看可用的穩定幣:

curl https://api.testnet.sera.cx/api/v1/tokens
import requests

response = requests.get("https://api.testnet.sera.cx/api/v1/tokens")
tokens = response.json()["tokens"]
print(tokens)
const response = await fetch("https://api.testnet.sera.cx/api/v1/tokens");
const { tokens } = await response.json();
console.log(tokens);

步驟二:取得兌換報價

取得兩種代幣之間的兌換報價:

curl -X POST https://api.testnet.sera.cx/api/v1/swap/quote \
  -H "Content-Type: application/json" \
  -d '{
    "from_token": "0x965d4b4546716e416e950bc30467d128455d2d0e",
    "to_token": "0xef64d15ed6c371545eb6dcd6c026c17dfb6c440f",
    "from_amount": "1000000000",
    "owner_address": "0xYOUR_ADDRESS",
    "recipient": "0xYOUR_ADDRESS",
    "expiration": 1735689600,
    "gas_mode": "receive_less"
  }'
import time, requests

quote = requests.post(
    "https://api.testnet.sera.cx/api/v1/swap/quote",
    json={
        "from_token":     "0x965d4b4546716e416e950bc30467d128455d2d0e",  # USDC
        "to_token":       "0xef64d15ed6c371545eb6dcd6c026c17dfb6c440f",  # EURC
        "from_amount":    "1000000000",                                  # 1000 USDC(6 位小數)
        "owner_address":  "0xYOUR_ADDRESS",
        "recipient":      "0xYOUR_ADDRESS",
        "expiration":     int(time.time()) + 3600,
        "gas_mode":       "receive_less",
    },
    timeout=10,
).json()
print(quote)
const response = await fetch("https://api.testnet.sera.cx/api/v1/swap/quote", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    from_token:    "0x965d4b4546716e416e950bc30467d128455d2d0e",   // USDC
    to_token:      "0xef64d15ed6c371545eb6dcd6c026c17dfb6c440f",   // EURC
    from_amount:   "1000000000",                                    // 1000 USDC(6 位小數)
    owner_address: "0xYOUR_ADDRESS",
    recipient:     "0xYOUR_ADDRESS",
    expiration:    Math.floor(Date.now() / 1000) + 3600,
    gas_mode:      "receive_less",
  }),
});
const quote = await response.json();
console.log(quote);

回應中包含 uuid 與 route_params — 這些是您將以錢包簽名的參數。

步驟三:簽名並執行兌換

使用 EIP-712 typed-data 簽名簽署 route_params,然後提交:

from eth_account import Account
from eth_account.messages import encode_typed_data

# `domain` 與 `INTENT_TYPES` 在 身份驗證 頁面有記載
signable  = encode_typed_data(domain, INTENT_TYPES, quote["route_params"])
signature = Account.from_key(PRIVATE_KEY).sign_message(signable).signature.hex()

submit_body = {"uuid": quote["uuid"], "signature": "0x" + signature.removeprefix("0x")}
permit = quote.get("permit") or {}
if permit.get("permit_required") and permit.get("permit_supported"):
    typed = permit["eip712"]
    permit_message = encode_typed_data(typed["domain"], typed["types"], typed["message"])
    permit_signature = Account.from_key(PRIVATE_KEY).sign_message(permit_message).signature.hex()
    submit_body["permit_signature"] = "0x" + permit_signature.removeprefix("0x")
    submit_body["permit_deadline"] = int(typed["message"]["deadline"])
elif permit.get("permit_required") and int(permit["current_allowance_raw"]) < int(permit["value_raw"]):
    raise RuntimeError("Approve the quoted spender, confirm the transaction, then request a fresh quote")

submit = requests.post(
    "https://api.testnet.sera.cx/api/v1/swap",
    json=submit_body,
    timeout=10,
).json()
// `domain` 與 `INTENT_TYPES` 在 身份驗證 頁面有記載
const signature = await signer.signTypedData(domain, INTENT_TYPES, quote.route_params);

const submitBody: { uuid: string; signature: string; permit_signature?: string; permit_deadline?: number } = {
  uuid: quote.uuid, signature,
};
const permit = quote.permit;
if (permit?.permit_required && permit.permit_supported) {
  const typed = permit.eip712;
  submitBody.permit_signature = await signer.signTypedData(typed.domain, typed.types, typed.message);
  submitBody.permit_deadline = Number(typed.message.deadline);
} else if (permit?.permit_required && BigInt(permit.current_allowance_raw) < BigInt(permit.value_raw)) {
  throw new Error("Approve the quoted spender, confirm the transaction, then request a fresh quote");
}

const result = await fetch("https://api.testnet.sera.cx/api/v1/swap", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(submitBody),
});

一個報價授權一次執行。請保存報價 uuid 與完整簽名請求。超時或 503 導致回應未知時,重試完全相同的請求以恢復已保存結果。POST /swap 回傳 trade_id 後,攜帶 API Key 查詢 GET /orders/{trade_id}。報價 uuid 與結果中的 trade_id 是不同標識,不能用報價 ID 查詢訂單。首筆結果未知時不要創建第二筆兌換。

詳細簽名說明請參閱 身份驗證。

步驟四:檢查您的餘額

建立 API Key 以查詢您的餘額與訂單歷史。/balances 端點會同時回傳您的錢包餘額(錢包中的代幣)與 Vault 餘額(用於限價單交易的已充值代幣),以及任何被掛單凍結的部分。

餘額中的 vault_available 是帳務金額,不保證可花。請檢查 vault_spendable 與恢復欄位,包括零餘額的恢復記錄。提供充值、即時提款或餘額同步前讀取 /config 能力。可用時使用餘額同步,不要為餘額更新延遲重複充值。

balances = requests.get(
    "https://api.testnet.sera.cx/api/v1/balances",
    params={"owner_address": "0xYOUR_ADDRESS"},
    headers={"Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET"},
    timeout=10,
).json()["balances"]

for bal in balances:
    print(f"{bal['symbol']}:")
    print(f"  錢包:           {bal['wallet_balance']}")
    print(f"  Vault 可用: {bal['vault_available']}")
    print(f"  Vault 可花: {bal.get('vault_spendable')} ({bal.get('spendability_status')})")
    print(f"  Vault 凍結: {bal['vault_frozen']}")
const response = await fetch(
  "https://api.testnet.sera.cx/api/v1/balances?owner_address=0xYOUR_ADDRESS",
  { headers: { "Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET" } },
);
const { balances } = await response.json();

for (const bal of balances) {
  console.log(`${bal.symbol}:`);
  console.log(`  錢包:           ${bal.wallet_balance}`);
  console.log(`  Vault 可用: ${bal.vault_available}`);
  console.log(`  Vault 可花: ${bal.vault_spendable} (${bal.spendability_status})`);
  console.log(`  Vault 凍結: ${bal.vault_frozen}`);
}

使用網頁應用

您也可以直接透過 Sera 網頁介面進行交易:

  1. 造訪 testnet.sera.cx
  2. 連接您的錢包
  3. 選擇貨幣對
  4. 下限價單或執行即時兌換
  5. 在儀表板中監控您的訂單

下一步

不支援 permit 的代幣額度不足時,請使用授權與交易廣播,等待確認後重新報價,再執行簽名步驟。按目標輸出金額兌換請使用 Exact Output 流程。

普通 Swap 重試請保留完整簽名請求,並遵循提交身份與重試。相同請求成功重試可回傳原結果。