Skip to main content
Every PINT includes a nonce field that prevents replay attacks. The maintains a server-side nonce registry per wallet, ensuring each PINT can only be processed once.

How Nonces Work

Each wallet address has a monotonically increasing nonce counter maintained by the SIS. When a PINT is submitted for token exchange, the nonce in the PINT must be strictly greater than the wallet’s last-used nonce.
Wallet: 0xE23c...
Last nonce: 41

PINT with nonce 42  →  ✅ Accepted (42 > 41). Last nonce updated to 42.
PINT with nonce 42  →  ❌ Rejected (42 = 42). Error: PINT-409-001
PINT with nonce 40  →  ❌ Rejected (40 < 42). Error: PINT-409-001
PINT with nonce 50  →  ✅ Accepted (50 > 42). Last nonce updated to 50.

Rules

Nonces must increase. Each PINT’s nonce must be strictly greater than the wallet’s current last_nonce. Equal or lower values are rejected with 409 Conflict and error code PINT-409-001. Gaps are allowed. You don’t need to use sequential nonces. Jumping from nonce 5 to nonce 8 is valid. This supports concurrent signing workflows where multiple PINTs may be prepared in parallel but submitted in unpredictable order. Atomic validation. The nonce check and update happen atomically — there’s no window for race conditions when multiple PINT exchanges are submitted simultaneously for the same wallet. Per-wallet scope. Nonce counters are scoped to individual wallet addresses. Different wallets have independent nonce sequences.

Client Implementation

When constructing a PINT, your client should:
  1. Track the last-used nonce locally (or retrieve the current nonce from the PINT list endpoint)
  2. Set the PINT’s nonce to a value greater than the last-used nonce
  3. If the exchange returns PINT-409-001, increment the nonce and retry
A simple approach is to use Unix millisecond timestamps as nonces — they’re naturally monotonically increasing and allow concurrent operations without coordination:
const pint = {
  wallet: "0xE23c9A70BC749EBddd8c78a864fd911D04E9e992",
  nonce: Date.now(), // Millisecond timestamp as nonce
  // ...
};
The nonce is a uint256 in the EIP-712 schema. Make sure your implementation handles large integers correctly — JavaScript’s Number type will lose precision above 2^53. Use BigInt in JavaScript/TypeScript.