Skip to main content

Background

Signed requests need replay protection: an order or withdrawal signature should not let someone execute the same action repeatedly. Most signed exchange requests include a nonce for this purpose. Polymarket deposit reports instead sign the transaction hash and have no nonce. Unlike Ethereum’s sequential transaction counter, Notional uses timestamp-based nonces with a rolling window, allowing requests to arrive out of order.

API wallets

API wallets, also called agent wallets, are separate signing keys approved by an account owner. They can sign eligible actions, such as orders and cancels, on behalf of that account. Withdrawals and API-wallet approvals require the account owner’s signature. Use the account owner’s address as user for account queries and WebSocket subscriptions. Use Approve API Wallet to register a signing key and Get API wallets to list an account’s approvals. Get address role accepts an API-wallet address and can identify the account owner of an active approval. Owner-only actions still require the owner’s signature.

API wallet lifecycle

Approvals are identified by agentName:
  • Approving a new address with an existing name replaces the previous wallet under that name.
  • Omitting the name or using an empty string selects the single unnamed wallet. Approving a new unnamed wallet replaces the previous unnamed wallet.
  • To revoke a wallet, send approveAgent with the zero address as agentAddress and the existing wallet’s name. Use an empty name for the unnamed wallet.
A replaced or revoked key can no longer act for the account. If an approval record has an expiresAt timestamp, it also stops authorizing the key once that time is reached. The extraAgents response can still include expired records. Generate a fresh wallet when rotating keys. Revoking or replacing an approval does not reset that signer’s nonce history.

Notional nonces

Notional retains the 20 highest nonces per signer. A new request’s nonce must be unused and, once the set is full, greater than the smallest retained nonce. This allows some out-of-order arrival without requiring every request to use exactly the previous nonce plus one. Nonces are tracked by the address whose private key signs the request. Requests signed directly by the owner use the owner’s nonce set; requests signed by an API wallet use that wallet’s set. Orders, cancels, and other actions signed by the same key share this set. Use a Unix-millisecond integer within [T - 2 days, T + 1 day], where T is the server’s current time when validating the request. Keep the client’s clock synchronized. expiresAfter is an optional signed request deadline. See request deadlines.

Suggestions for automated trading

  1. Use a separate API wallet per trading process or frontend session. This gives each signer its own nonce set and avoids collisions between independent clients.
  2. Allocate nonces with a monotonic counter. For each request, atomically choose max(current Unix milliseconds, previous nonce + 1). Concurrent Date.now() calls alone can produce duplicates. If processes share a signer, coordinate the counter across them and preserve it across restarts.
  3. Allocate one nonce per signed request. A batch of orders or cancels uses one request nonce, rather than a separate nonce for each item. Sign and submit the same nonce.
  4. Keep delayed requests within the rolling window. Once 20 higher nonces have been recorded, an older request falls below the retained set and is rejected. The window is measured in requests, so it does not guarantee a fixed amount of time for out-of-order arrival.
Retry handling is endpoint-specific. Cancel requests reject reused nonces, including identical retries. After an uncertain cancel response, check current order state before signing another cancel with a new nonce. See Signing for signing requirements, formats, and common mistakes.