訂單生命週期¶
網路與相容性
| 資源 | 值 |
|---|---|
| API 基礎 URL | https://api.sera.cx/api/v1 |
| 鏈 | Ethereum 主網(chainId 1) |
| Sera 合約 | 0xB5C50C5D5f038404F85970b7f5B7259C4AC0E198 |
| Vault 合約 | 0xC7d4Fd2638e6630C8C61329878676b88A8A24D43 |
| SOR 合約 | 0xa7A0cf7cd6f043fCA23f29d8ae5aae6b46e11c18 |
簽名原語。 所有交易型變更都是針對 Sera domain 的 EIP-712 類型化資料簽名。走 permit 路徑的充值使用 ERC-2612 Permit 擴充功能 — USDC、EURC 以及許多現代穩定幣支援,但並非所有 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 步驟一:檢查伺服器時間¶
在建立簽名之前,與伺服器時鐘同步以避免到期問題:
所有已簽名訂單都必須帶 expiration,而且 API 會強制執行 now < expiration <= now + 365 天 - 300 秒。請使用伺服器時間,而不是只依賴瀏覽器或本地系統時鐘。
步驟二:查詢可用代幣¶
取得支援的代幣清單以找到您需要的合約地址:
步驟三:掛限價單¶
建構並簽署 EIP-712 Order,然後提交。完整簽名流程見 身份驗證 與 做市商指南 → 下達單筆限價單。範例節錄:
import time, uuid, requests
# 產生唯一訂單 ID
order_id = str(uuid.uuid4())
executor_id = requests.get("https://api.sera.cx/api/v1/health").json()["executor_id"]
raw = int(uuid.UUID(order_id))
group_id = raw >> 16
uuid_int = str((executor_id << 252) | (raw << 124) | (group_id << 12))
# 構造訂單。from_address 是市場基礎代幣,to_address 是報價代幣。
# 最終支出哪一邊由 side 決定。
order = {
"owner_address": wallet_address,
"side": "bid", # 用 USDC 買 EURC
"amount": "1000.0", # 1000 EURC
"price": "1.085", # 每 EURC 1.085 USDC
"order_type": "limit",
"from_address": EURC_ADDRESS, # 市場基礎代幣,也是您要買入的代幣
"to_address": USDC_ADDRESS, # 市場報價代幣,在 bid 中是您支出的代幣
"order_id": order_id,
"uuid_int": uuid_int,
"expiration": int(time.time()) + 86_400,
}
# 使用 EIP-712 簽名(完整簽名細節見 身份驗證)
signature = sign_order(signer, order)
result = requests.post(
"https://api.sera.cx/api/v1/orders",
json={**order, "signature": signature},
timeout=10,
).json()
print("Order placed:", result["order_id"])
import { v4 as uuidv4 } from "uuid";
// 產生唯一訂單 ID
const orderId = uuidv4();
const { executor_id: executorId } = await fetch("https://api.sera.cx/api/v1/health")
.then(r => r.json());
const raw = BigInt("0x" + orderId.replace(/-/g, ""));
const groupId = raw >> 16n;
const uuidInt = ((BigInt(executorId) << 252n) | (raw << 124n) | (groupId << 12n)).toString();
// 構造訂單。from_address 是市場基礎代幣,to_address 是報價代幣。
// 最終支出哪一邊由 side 決定。
const order = {
owner_address: walletAddress,
side: "bid", // 用 USDC 買 EURC
amount: "1000.0", // 1000 EURC
price: "1.085", // 每 EURC 1.085 USDC
order_type: "limit",
from_address: EURC_ADDRESS, // 市場基礎代幣,也是您要買入的代幣
to_address: USDC_ADDRESS, // 市場報價代幣,在 bid 中是您支出的代幣
order_id: orderId,
uuid_int: uuidInt,
expiration: Math.floor(Date.now() / 1000) + 86_400,
};
// 使用 EIP-712 簽名(完整簽名細節見 身份驗證)
const signature = await signOrder(signer, order);
const response = await fetch("https://api.sera.cx/api/v1/orders", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...order, signature }),
});
const result = await response.json();
console.log("Order placed:", result.order_id);
步驟四:監控訂單狀態¶
使用您的 API key 輪詢訂單狀態:
status = requests.get(
f"https://api.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.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.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.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 欄位自行轉換。
步驟六:取消訂單(可選)¶
如果您想取消未成交或部分成交的訂單:
# 簽署 CancelOrder 訊息
cancel_signature = sign_cancel_order(signer, wallet_address, int(status["uuid_int"]))
cancel_res = requests.post(
"https://api.sera.cx/api/v1/orders/cancel",
json={
"owner_address": wallet_address,
"order_id": order_id,
"uuid_int": status["uuid_int"],
"signature": cancel_signature,
},
timeout=10,
).json()
print("Cancelled:", cancel_res)
// 簽署 CancelOrder 訊息
const cancelSignature = await signCancelOrder(signer, walletAddress, BigInt(status.uuid_int));
const cancelRes = await fetch("https://api.sera.cx/api/v1/orders/cancel", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
owner_address: walletAddress,
order_id: orderId,
uuid_int: status.uuid_int,
signature: cancelSignature,
}),
});
console.log("Cancelled:", await cancelRes.json());
Note
下單後通常會有約 5 分鐘的撤單冷卻期;命中冷卻會回傳 429。請在冷卻後重試,或先查詢訂單狀態再重新提交。
步驟七:提取(可選)¶
將資金從 Vault 轉回錢包時,請使用即時提取流程:
- 呼叫
POST /withdraw取得執行者聯簽。 - 呼叫
POST /withdraw/build取得未簽名的executeInstantWithdrawDualSig交易。 - 在本地簽署該交易,然後透過
POST /withdraw/send廣播。
如果 API 不可用,您可以使用鏈上的 emergencyWithdraw() 流程。
虛擬流動性訂單¶
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 判斷使用者資金變化。文件回應 schema 之外的欄位不屬於公共 API 契約。