交易与账户
交易接入的主路径:写操作(45 Action)、账户 / 订单 / 持仓读方法、交易 WebSocket 主题 与事件投影。行情与历史数据见 行情数据 · 历史与审计。
| 用途 | 入口 |
|---|---|
| 下单 / 撤单 / 改单 / 保证金 / 清算 / 市场管理 | 写操作 |
| 账户 / 订单 / 持仓 / 触发单 / Bootstrap 读方法 | 账户与订单 |
| 强平价 / 订单价值 / 预估占用(全仓·逐仓·多空) | 下单预估与强平价 |
| 账户 / 成交 / 订单 / 触发单实时推送 | WebSocket 交易主题 |
| 事件结构(交易 / 桥 / 返佣) | 事件投影 |
| 签名(Agent / L1 / User-Signed)与鉴权 | 签名与鉴权 |
以下是交易协议的基础约定:签名信封与鉴权体系。
4. 签名信封(SignedActionEnvelope)
所有写操作 body 的 params 格式为:
{
"envelope": {
"chain_id": 1,
"domain_chain_id": 1,
"action_version": 2,
"nonce": 42,
"signer": "0x1111222233334444555566667777888899990000",
"credential": {
"Secp256k1": {
"signature": [95, 83, 94, "...r||s...", 27]
}
},
"action": {
"PlaceOrder": {
"owner": "0x1111222233334444555566667777888899990000",
"symbol": "BTC-USDT",
"side": "Bid",
"limit_price": "97100.00",
"qty": "1.00000",
"tif": "Gtc",
"reduce_only": false
}
}
}
}
4.1 Envelope 字段
| 字段 | 类型 | 说明 |
|---|---|---|
chain_id | u64 | Zepto 链标识(来自 ChainConfig.chain_id)。auth 层校验 envelope.chain_id == 节点 chain_id,不匹配 → ChainIdMismatch。防跨 Zepto 网络重放(如 Mainnet envelope 不可在 Testnet 重放) |
domain_chain_id | u64 | 验签 EIP-712 domain 的 chainId 与 txid 输入。auth 用 envelope.domain_chain_id 重建 digest。L1:须等于 chain_id(生产 42)。User-Signed:= 钱包当前 EVM 链 ID(如 BSC 56) |
action_version | u32 | Wire 协议版本,当前固定 2 |
nonce | u64 | 账户 nonce;须落在 [account.nonce, account.nonce + window) 且未重复(见 §4.3) |
signer | Address20 | 签名者的 master 账户地址(20 字节 hex,0x 前缀)。不参与签名 digest |
credential | SigCredential | 签名凭证 {"Secp256k1": {"signature": [byte, ...]}}。65 字节 secp256k1(r || s || v) |
action | Action | 具体操作(externally-tagged,变体名 = 写 method 名) |
4.2 chain_id 与 domain_chain_id
两个字段语义不同,各自服务于不同的安全边界:
chain_id — Zepto 链网络标识。由链部署方在 ChainConfig.chain_id 中设定。用途:
- auth 层校验
envelope.chain_id == 节点 chain_id,防跨 Zepto 网络重放(Mainnet ↔ Testnet) - 公共交易标识 txid 的输入
domain_chain_id — 写入 envelope 后,同时用于:
- 签名 digest:auth 以
domain_chain_id作为 EIP-712 domain 的chainId(L1 与 User-Signed 皆然) - txid 计算输入
按通道取值:
| 场景 | chain_id | domain_chain_id |
|---|---|---|
| L1 通道(41 个 Action) | Zepto 链 ID(生产 42) | 必须 = chain_id(生产 42) |
| User-Signed(3 个 Action) | Zepto 链 ID(生产 42) | 用户钱包的 EVM 链 ID(如 1、56、42161) |
L1 若误把 User-Signed 习惯的 56 写入 domain_chain_id,而按 chainId=42 签名,验签必失败。
network_tag(又称 source)来自 ChainConfig.signing_network_tag。Auroran 生产为 "zepto-dev" — 见 签名 §2。
链上无只读 RPC 返回
chain_id/network_tag;固定值见 签名 §2。私有节点以genesis.json为准。
4.3 Nonce 管理
链上采用 nonce 窗口:允许 [account.nonce, account.nonce + window) 内乱序到达(Auroran 默认 window = 64;若配置为 window = 1 则退化为「必须恰好等于下界」的旧行为)。
| 规则 | 说明 |
|---|---|
| 有效区间 | account.nonce ≤ envelope.nonce < account.nonce + window |
| 去重 | 窗口内同一 nonce 不可重复提交(nonce_used_mask 位图) |
| 下界推进 | 消费后 sweep 连续低位,account.nonce 前移(中间「洞」可后补) |
| kept-reject | 同样消耗该 nonce |
| 拒绝 | 低于下界、超出窗口、或窗口内重放 → NONCE_REPLAY(-32001),error.data:{"account_nonce": X, "got": Y, "window": W} |
getAccount.nonce 含义:已 sweep 的 下界,不是「下一笔必须恰好等于该值」。窗口 > 1 时,仍可使用 [nonce, nonce + window) 内任意 未消费 值(例如先落 N+1 再补 N)。
对接建议(客户端侧,非链上硬约束):
- 本地为每笔 Action 分配唯一、单调递增 nonce(不跳号、不复用)
- 可在窗口内 并发在途(多笔 HTTP 同时飞行),不必等前一笔 200 再发下一笔
NONCE_REPLAY时用error.data或getAccount重新同步
完整状态机见 做市商对接指南 §4。
4.4 Credential 格式
当前仅支持 secp256k1 单通道签名:
"credential": {
"Secp256k1": {
"signature": [95, 83, 94, "...r||s...", 27]
}
}
signature 是 65 字节 JSON 数组(非 hex 字符串),格式为 r || s || v,其中 v ∈ {27, 28}(recovery id)。r 和 s 各 32 字节大端。与 eth_signTypedData_v4 / ethers 等以太坊工具的字节输出一致(不是 v || r || s)。
4.5 鉴权通道
recover 出的地址 == envelope.signer → master 直签。
recover 出的地址 ≠ envelope.signer → 在 signer 账户的 agents 列表中按地址查找 → agent 委托签名。
| 通道 | 适用场景 | 签名 key |
|---|---|---|
| Master 直签 | Admin / 敏感操作 / 低频用户 | master 的 secp256k1 私钥 |
| Agent 委托 | 程序化做市 / 高频交易 | 已注册的 API-wallet secp256k1 私钥 |
Agent 必须由 master 经 EIP-712 通道(RegisterAgent)预先授权,指定角色子集和过期时间。
4.6 签名算法
所有 45 个 Action 均走 EIP-712 签名,但分两个 算法通道(与下方 §5.1「谁可以签」正交):
| 算法通道 | Action | 签什么 |
|---|---|---|
| L1 | 除下列三外的 41 个(含 PlaceOrder / SetMarginMode / SetLeverage…) | phantom L1Action + msgpack connectionId(禁止以 Action 名为 primaryType) |
| User-Signed | 仅 WithdrawRequest / RegisterAgent / RevokeAgent | 钱包 typed data(primaryType 为 Withdraw / RegisterAgent / RevokeAgent) |
完整接入说明见 签名与鉴权。
L1 通道(41 个交易/管理操作)
适用于除 WithdrawRequest、RegisterAgent、RevokeAgent 外的全部 Action。
L1 通道使用 phantom EIP-712 类型 L1Action(string source,bytes32 connectionId),其构造分 3 步:
Step 1 — 计算 connectionId:
msgpack_bytes = rmp_serde::to_vec_named(action)
connectionId = keccak256(msgpack_bytes || nonce.to_be_bytes(8))
- 对
action对象做 msgpack 序列化(rmp_serdenamed map 模式),得到确定性字节串 - 拼接
nonce的 8 字节大端表示 - 对整体求
keccak256,得到 32 字节connectionId
msgpack 编码细节(确定性保证,跨语言可复现):
i128→ msgpack 定长整数Option::None→ msgpacknil- Enum → msgpack map(外部 tag,key 为变体名字符串)
Address20→ msgpack 20 字节 bin- String → msgpack str
- bool/u32/u64 → 对应 msgpack 类型
Step 2 — EIP-712 domain + struct hash:
domain = keccak256(
typeHash("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
|| enc_string("ZeptoSignTransaction")
|| enc_string("1")
|| enc_uint(domain_chain_id) // L1 须 domain_chain_id == chain_id(生产 42)
|| enc_address(0x0000...0000)
)
struct_hash = keccak256(
typeHash("L1Action(string source,bytes32 connectionId)")
|| enc_string(network_tag)
|| connectionId
)
typeHash(s)=keccak256(utf8_bytes(s))enc_string(s)=keccak256(utf8_bytes(s))enc_uint(v)= 32 字节大端,高位补零enc_address(a)= 左侧补 12 个零字节,右对齐 20 字节地址
Step 3 — EIP-712 最终摘要:
digest = keccak256(0x19 || 0x01 || domain || struct_hash)
Step 4 — 签名:
对上述 32 字节 digest 做 secp256k1 recoverable 签名,得到 65 字节 [r_0..r_31, s_0..s_31, v](r || s || v,v ∈ {27, 28}),填入 credential.Secp256k1.signature。
EIP-712 通道(WithdrawRequest / RegisterAgent / RevokeAgent)
走标准 eth_signTypedData_v4,由钱包直接构造 typed data 并签名。domain 名/版本与 L1 相同(ZeptoSignTransaction),但 domain.chainId = domain_chain_id(钱包 EVM 链),primary type 按 Action 不同。typed data 结构和 domain JSON 见 写操作 - EIP-712 签名。
自研签名:见专章 签名与鉴权(Agent、L1 msgpack、User-Signed)。Action schema 见 write-actions §2。Nonce 见 做市商对接指南 §4。
公共交易标识 txid
响应中的 tx_hash 是公共交易标识(txid),与签名彻底解耦。同一笔交易无论由 master 还是 agent 签名,txid 相同。其计算独立于签名 digest:
txid = SHA-256(
b"zepto-txid-v1" // domain-separation 标签
|| chain_id // u64 BE (8 bytes)
|| domain_chain_id // u64 BE (8 bytes)
|| action_version // u32 BE (4 bytes)
|| nonce // u64 BE (8 bytes)
|| signer // 20 bytes raw address
|| SHA-256(msgpack(action))
)
注意:txid 使用 SHA-256 和 domain_chain_id,而签名 digest 使用 keccak256 和 EIP-712 结构。两者算法不同,不可混淆。
5. 鉴权体系
5.1 Action 鉴权一览
下表「鉴权通道」表示 谁可以签(master / agent / master-only),不是签名算法通道。算法上:除末三行 User-Signed 外,其余均为 L1(见 签名与鉴权 / §4.6)。
| Action | 鉴权(谁可签) | 所需角色 | 算法通道 |
|---|---|---|---|
| PlaceOrder / CancelOrder | master_or_agent_with_role | Trader | L1 |
| BatchPlaceOrder | master_or_agent_with_role | Trader | L1 |
| AmendOrder / BatchModify / MassCancel / ClosePosition / ScheduleCancel | master_or_agent_with_role | Trader | L1 |
| SetLeverage / SetMarginMode / SetIsolatedMargin | master_or_agent_with_role | Trader | L1 |
| PlaceTriggerOrder / CancelTriggerOrder / AmendTriggerOrder / BatchAmendTrigger | master_or_agent_with_role | Trader | L1 |
| PlaceOco / CancelOco | master_or_agent_with_role | Trader | L1 |
| SetReferrer / RegisterReferrer / SetInviterKeepRatio | master_or_agent_with_role | Trader | L1 |
| SetGlobalRebateRatio / SetAccountRebateRatio | master_or_agent_with_role | Admin | L1 |
| SubmitOracleQuote / BatchSubmitOracleQuote | master_or_agent_with_role | Quoter | L1 |
| Liquidate | master_or_agent_with_role | Liquidator | L1 |
| RecordDeposit / CreditDeposit | master_or_agent_with_role | SettlementOperator | L1 |
| WithdrawSettle / WithdrawRefund | master_or_agent_with_role | SettlementOperator | L1 |
| SetSettlementPaused | master_or_agent_with_role | Admin | L1 |
| SetUserFeeRate | master_or_agent_with_role | Admin | L1 |
| CreateMarket / ActivateMarket / HaltMarket / ResumeMarket | master | — | L1 |
| RequestDelist / CompleteDelist | master | — | L1 |
| SetFeeRecipient / AmendMarketConfig / SetEmergencyHalt | master | — | L1 |
| SetAccountRole | master | — | L1 |
| WithdrawRequest | user_signed_master | — | User-Signed |
| RegisterAgent / RevokeAgent | user_signed_master | — | User-Signed |
5.2 角色位掩码
| 角色 | 位值 | 说明 |
|---|---|---|
| Trader | 1 | 下单、撤单、改单、保证金管理 |
| OracleOperator | 2 | 保留 |
| SettlementOperator | 4 | Bridge 充提操作 |
| Admin | 8 | 闸门、费率管理 |
| Liquidator | 16 | 清算执行 |
| Quoter | 32 | 预言机报价提交 |