跳轉至

訂單生命週期

網路與相容性

資源 值
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 上限價單的完整生命週期 — 從下單到領取收益。

概覽

sequenceDiagram
    participant User
    participant API as Sera API
    participant Chain as Ethereum

    User->>API: POST /orders (signed order)
    API-->>User: order_id
    Note over API: Order is matched<br/>when counterparty found
    API->>Chain: Settlement on-chain
    User->>API: GET /orders/{id}
    API-->>User: Status: settled
    Note over User: Proceeds available<br/>in vault balance

步驟一:檢查伺服器時間

在建立簽名之前,與伺服器時鐘同步以避免到期問題:

import requests

time_res = requests.get("https://api.testnet.sera.cx/api/v1/system/time")
server_time = time_res.json()["timestamp"]
print(f"Server time: {server_time}")
const timeRes = await fetch("https://api.testnet.sera.cx/api/v1/system/time");
const { timestamp } = await timeRes.json();
console.log("Server time:", timestamp);

所有已簽名訂單都必須帶 expiration,而且 API 會強制執行 now < expiration <= now + 365 天 - 300 秒。請使用伺服器時間,而不是只依賴瀏覽器或本地系統時鐘。

步驟二:查詢可用代幣

取得支援的代幣清單以找到您需要的合約地址:

tokens = requests.get("https://api.testnet.sera.cx/api/v1/tokens").json()["tokens"]

# 查找 USDC 和 EURC 地址
usdc = next(t for t in tokens if t["symbol"] == "USDC")
eurc = next(t for t in tokens if t["symbol"] == "EURC")
const tokensRes = await fetch("https://api.testnet.sera.cx/api/v1/tokens");
const { tokens } = await tokensRes.json();

// 查找 USDC 和 EURC 地址
const usdc = tokens.find((t: any) => t.symbol === "USDC");
const eurc = tokens.find((t: any) => t.symbol === "EURC");

步驟三:掛限價單

先完成做市商指南的配置和單筆幫助函數,包括市場選擇。BASE、QUOTE 來自市場返回值。幫助函數預覽並使用規範字段簽名,在發送前保存完整請求,出錯時停止。以下價格 1 是 quote/base 單位的演示值,請按當前市場選擇價格。

placed = place_order("bid", BASE, QUOTE, Decimal("1000"),
                     Decimal("1"), int(time.time()) + 3600)
order_id = placed["order_id"]
const placed = await placeOrder("bid", BASE, QUOTE, "1000", "1",
                                Math.floor(Date.now() / 1000) + 3600);
const orderId = placed.order_id;

步驟四:監控訂單狀態

使用您的 API key 輪詢訂單狀態:

status = requests.get(
    f"https://api.testnet.sera.cx/api/v1/orders/{order_id}",
    headers={"Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET"},
    timeout=10,
).json()
print("Status:", status["status"])
# 外部狀態:"pending"、"matched"、"settled"、"cancelled"、"failed"
print("Filled:", status["filled_amount"])
print("Signed uuid_int:", status["uuid_int"])
const statusRes = await fetch(
  `https://api.testnet.sera.cx/api/v1/orders/${orderId}`,
  { headers: { "Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET" } },
);
const status = await statusRes.json();
console.log("Status:", status.status);
// 外部狀態:"pending"、"matched"、"settled"、"cancelled"、"failed"
console.log("Filled:", status.filled_amount);
console.log("Signed uuid_int:", status.uuid_int);

步驟五:查詢餘額

訂單結算後,收益會出現在您的 Vault 餘額中:

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

for bal in balances:
    print(f"{bal['symbol']}: vault_raw={bal['vault_available']}, "
          f"frozen_raw={bal['vault_frozen']}, decimals={bal['decimals']}")
const balanceRes = await fetch(
  `https://api.testnet.sera.cx/api/v1/balances?owner_address=${walletAddress}`,
  { headers: { "Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET" } },
);

const { balances } = await balanceRes.json();
for (const bal of balances) {
  console.log(`${bal.symbol}: vault_raw=${bal.vault_available}, ` +
              `frozen_raw=${bal.vault_frozen}, decimals=${bal.decimals}`);
}

GET /balances 現在回傳原始 uint256 十進位字串。顯示給使用者前,請搭配每一行的 decimals 欄位自行轉換。

步驟六:取消訂單(可選)

如果您想取消未成交或部分成交的訂單:

# Reuse cancel_order from the Market Maker Guide.
cancel_order(order_id, int(status["uuid_int"]))
# Query this order again to confirm its current state.
// Reuse cancelOrder from the Market Maker Guide.
await cancelOrder(orderId, BigInt(status.uuid_int));
// Query this order again to confirm its current state.

Note

下單後有可配置的撤單冷卻期(默認 300 秒)。命中冷卻返回 429,當前實現沒有高頻賬戶豁免。限流也返回 429,應結合響應判斷。

步驟七:提取(可選)

將資金從 Vault 轉回錢包時,請使用即時提取流程:

  1. 呼叫 POST /withdraw 取得執行者聯簽。
  2. 呼叫 POST /withdraw/build 取得未簽名的 executeInstantWithdrawDualSig 交易。
  3. 在本地簽署該交易,然後透過 POST /withdraw/send 廣播。

API 不可用時,可按請求、等待期、執行窗口及餘額規則使用鏈上緊急提款流程。

虛擬流動性訂單

VL 訂單的生命週期與標準限價單相同,但共用預算管理。當某個 VL 同胞訂單成交時,撮合引擎會自動修改或取消其餘同胞訂單,以維持在預算內。

主要差異:

  • 掛單 — 使用 POST /orders/vl/batch 取代 POST /orders
  • 取消 — 使用 POST /orders/vl/cancel 取消整批,或使用 POST /orders/cancel 取消單筆同胞訂單
  • 預算追蹤 — 系統在所有同胞訂單間追蹤共用的凍結餘額;任一同胞成交會減少其他同胞可用預算

完整指南請參見 虛擬流動性。

訂單狀態摘要

狀態 含義 可取消?
pending 已提交、掛單中或部分成交 是
matched 所有腿在撮合引擎中已交叉,鏈上結算進行中 否
settled 已完全成交且鏈上確認 否
cancelled 已在完全成交前取消 否
failed 被拒絕或結算 revert 通常否;查看 error 與 error_code

pending 可以表示尚未成交、部分成交後仍有剩餘數量,或已提交但尚未進入鏈上結算的訂單。前端應結合 filled_amount、remaining_amount、settlement_summary、/fills 以及 settlement_economics 判斷使用者資金變化。公共 API 不暴露協議價差收入或交易對手轉帳拆分。