Every signed action carries a nonce. The exchange accepts a nonce only if it is greater than the last nonce seen for that signer.
Rules
- Use milliseconds since the Unix epoch.
- Nonces must increase monotonically per signer, not per action type.
- Two actions with the same nonce cannot both be accepted.
- Nonces older than 24 hours are rejected.
- A nonce that is too far in the future (more than 10 seconds) is rejected.
One key, one process
If two processes sign with the same key, they will collide. Give each bot its own API wallet, or serialize nonce creation through a single signer service.
Recommended pattern
let lastNonce = 0;
function nextNonce() {
const now = Date.now();
lastNonce = Math.max(now, lastNonce + 1);
return lastNonce;
}For high-throughput systems, use a monotonic counter seeded from the server time and persist it across restarts. Do not use Date.now() alone if two requests can be created in the same millisecond.
API wallet lifecycle
- Approve. The master signs
approveAgentwith the API wallet address and a name. - Use. The API wallet signs orders and cancels. The exchange resolves the account from the approval.
- Revoke. The master signs
approveAgentwith a zero address, or uses the app. - Prune. Unused API wallets are pruned after 30 days of inactivity. Funds are never at risk from pruning; only the permission is removed.
Sub-accounts and vaults
Sub-accounts and vaults do not have keys. The master signs and sets vaultAddress to the sub-account or vault address. Nonces are still ordered per master signer, not per sub-account.
Errors
| Error | Cause |
|---|---|
Nonce too low | A previous action already used this nonce |
Nonce too high | Clock skew greater than 10 seconds |
Duplicate nonce | Two actions submitted with the same nonce |
API wallet not approved | Missing or revoked approval |