Signing
The EIP-712 domains, why they are bound to the genesis, the type strings of every public operation, and where the canonical test vectors are.
Every write to Vordium is signed. Most operations are EIP-712 typed data; a few money moves are plain text messages (EIP-191). The chain recovers the signer from the signature, so a body names its signer and the chain checks that the recovered key is allowed to sign it.
The domains
There are two EIP-712 domains. Both have five fields:
EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)| Domain | name | version | verifyingContract | Used for |
|---|---|---|---|---|
| VordCore | VordCore | 1 | 0x0000000000000000000000000000000000001002 | orders, cancels, TWAP, TP/SL, agents, withdrawals |
| VordexSession | VordexSession | 1 | 0x0000000000000000000000000000000000001002 | opening and ending a session (trading key) |
chainId is the network's chain id, and the salt binds every signature to the chain's genesis:
salt = keccak256( tag ‖ genesis sha256 as 32 raw bytes )
tag = 0x564f524449554d5f564f5244434f524501 for VordCore
0x564f524449554d5f564f5244455853455353494f4e01 for VordexSessionEach tag is the ASCII text of the domain's tag followed by the byte 0x01, written here as hex; the genesis hash goes
in as its 32 bytes, not as text. A signature
made for one chain therefore never verifies on another, even one with the same chain id. Read the genesis from the
node you send to (GET /status, field genesis_sha256) and check it against the network spec before signing.
The resulting domain separators, derived from each network's own chain id and genesis:
| Fact | Mainnet | Testnet |
|---|---|---|
| Chain id | 101101 | 101102 |
| Genesis (sha256) | 2c1c0679fa6ab8358f1d3e8d294a8d1c73ac2e2caf9079f1216abedc3d9fdf4f | 8b5d414c5cd5d18bc468b64f87ac8e2c2b5ff494c769d5e09dcf50ce75a59792 |
| VordCore separator | 0x68b86feeb9a9d9d471c3355da4719f2ce6a2330fbde6dad54d815783dacab34b | 0x9f769846fed7e1af2c35b499ada9facb6fe3485e160b8c3adfc60dac07acbe4b |
| VordexSession separator | 0x519818aadee0cf7503a73f7087eef99d936b37b242e79ee9a825942596d3ad6e | 0x15c1c1c529defc3b0389b1e35696c79664d8eba423f68bf7906535c68cd62f92 |
Signatures
A signature is 65 bytes, r ‖ s ‖ v, as hex. Orders may also be signed as 64 bytes (r ‖ s); the chain finds the
recovery id itself.
Orders and trading
PlaceOrder(address owner,uint32 pairId,uint8 side,uint128 size,uint64 price,uint32 leverageBps,uint8 orderType,bool reduceOnly,bool postOnly,uint64 triggerPrice8dec,uint8 triggerDir,uint64 clientNonce)
CancelOrder(address owner,uint64 orderId)
ModifyOrderV2(address owner,uint64 orderId,uint64 newPrice,uint128 newSize,uint64 clientNonce)
CancelAllOrders(address owner,uint32 pairId,uint64 nonce)
BatchOrders(address owner,uint64 nonce,BatchAction[] actions)BatchAction(uint8 kind,uint32 pairId,uint8 side,uint128 size,uint64 price,uint32 leverageBps,uint8 orderType,bool reduceOnly,bool postOnly,uint64 clientNonce,uint64 orderId)
ScheduleCancel(address owner,uint64 cancelAtMs,uint64 nonce)
SetMmp(address owner,uint64 windowMs,uint32 maxFills,uint128 maxFilledNotional6dec,uint128 maxNetSize18dec,uint64 freezeMs,uint64 nonce)
SetTpSl(address owner,uint32 pairId,uint64 positionId,uint64 takeProfit8dec,uint64 stopLoss8dec)
PlaceTwap(address owner,uint32 pairId,uint8 side,uint128 totalSize18dec,uint32 numSlices,uint64 durationMs,uint32 leverageBps,uint32 slippageBps,bool randomize,uint64 triggerPrice8dec,uint8 triggerDir,uint64 minPrice8dec,uint64 maxPrice8dec,uint64 clientNonce)
CancelTwap(address owner,uint64 twapId,uint64 clientNonce)side: 0 buy, 1 sell. orderType: 0 Market, 1 Limit. price is the price × 10⁸ (kept to 6 decimals); a market order
signs 0. size is the size × 10¹⁸. triggerPrice8dec and triggerDir are 0. In a batch, kind is 0 place,
1 cancel, 2 cancel by client nonce. owner is the account; an order may be signed by the account or by a live session
key of the account. TWAP placement and cancellation take the account's own key only.
Sessions
SessionCreate(address sessionKey,uint256 expiresAt,uint256 nonce) — VordexSession domain
SessionRevoke(address owner,uint256 nonce) — VordexSession domainSessionCreate is signed by the account, which the chain recovers; it names the session key. expiresAt is in
seconds; the nonce must be above the account's last session nonce. An account holds one session: end the one it holds
with SessionRevoke before opening another for a different key.
Agent operations
RegisterAgentV2(address owner,address agent,string name,string mandate,uint64 expiresMs,uint64 nonce)
SetAgentName(address owner,address agent,string name,uint64 nonce)
SetAgentPolicyV1(address owner,address agent,uint32 capsBitmask,uint8 sideMode,uint128 maxTotalExposure6dec,uint32 maxLeverageBps,uint128 dailyLossLimit6dec,uint128 dailyFeeCap6dec,uint32 opsPerWindow,uint32 opsWindowMs,uint32 activeFromMsOfDay,uint32 activeToMsOfDay,uint32 oracleBandBps,bool lockAutoClear,uint64 expiresMs,bool enabled,uint64 nonce)
SetAgentMarketLimit(address owner,address agent,uint32 pair,bool allowed,uint128 maxOrder18dec,uint128 maxPosition18dec,uint32 maxLeverageBps,uint64 nonce)
ClearAgentLock(address owner,address agent,uint64 lockSinceMs,uint64 nonce)
RevokeAgent(address owner,address agent,uint64 nonce)They are sent to POST /submit with every field under its wire name (expires_ms, caps_bitmask, …), 128-bit amounts
as decimal strings. The Python SDK builds the exact body (vordium.agent_ops.sign_owner_op).
Withdrawals
WithdrawIntentV4(address account,uint32 vaultId,bytes32 recipient,uint256 amount,uint256 nonce,uint8 routeKind,uint32 destinationDomain,uint256 maxFee,uint64 deadline)Signed by the account's own key only (Bridge).
Text messages
Fund moves into the pool and staking, referral messages and the validator unjail request are EIP-191 text messages.
Each names the chain and its genesis on their own lines (Chain: <id>, then Genesis: <64 lower-case hex>), so they
too are bound to one chain.
Canonical test vectors
The network publishes vectors for every agent operation — the typed data, the digest, the signature from a public test
key and the exact /submit body:
- agent-ops-vectors-2c1c0679.json in the public node repository, with its README;
- the agent operations guide, docs/agents.md.
The Python SDK's test suite reproduces them byte for byte.
Network facts last checked against the network 2026-10-22 13:00:37 UTC · mainnet spec v28 · testnet spec v8