# Nonce & Replay Protection

Every Lynx write request carries a `nonce` (a millisecond Unix timestamp) and an `expires_after` field. Together with the per-signer nonce tracking on-chain, they prevent replay attacks.

## Rules At A Glance

| Rule               | Detail                                                                                                                                                                         |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Type**           | `uint64`. Use `Date.now()` (millisecond timestamp).                                                                                                                            |
| **Tracking scope** | **Per-signer** — each Agent Key has its own nonce space, separate from your main private key and from other Agents.                                                            |
| **Storage**        | The chain keeps the **100 highest** nonces per signer.                                                                                                                         |
| **Validity**       | A new nonce must be **greater than the smallest stored nonce** and **must not have been used before**.                                                                         |
| **Time window**    | Valid range: `(T − 2 days, T + 1 day)` where `T` is the block time (ms).                                                                                                       |
| **Concurrency**    | Different Agent Keys have independent nonce spaces — concurrent traffic from many bots scales naturally. Within a single Agent, ensure each request uses a unique millisecond. |
| **Lookup**         | None required. Use the current millisecond timestamp.                                                                                                                          |

{% hint style="info" %}
**Recommended `expires_after`:** `nonce + 600_000` (10 minutes). It bounds how stale a signed but unsubmitted transaction can be, which is useful if your network path is slow.
{% endhint %}

## Agent Revocation And Nonce Floor

All signed Lynx transactions are publicly visible on-chain after inclusion. If an Agent is revoked and its nonce state is then cleared, an attacker can read the Agent's historical signed transactions from the chain and replay them:

```
1. Agent A signs "buy 10 BTC @ 67,500" (nonce=t1) → executed, on-chain, public.
2. Agent A is revoked → nonce state cleared.
3. Agent A is re-authorized → nonce state empty again.
4. Anyone reads the original signed transaction from step 1 → re-submits verbatim.
5. System validation: Agent A signature valid ✓, nonce t1 unused (cleared!) ✓ → executed again.
```

{% hint style="warning" %}
The attacker did not need to steal a private key — only to read public on-chain data. This is the inherent risk of nonce state clearance in a public-chain environment.
{% endhint %}

**Solution — Nonce Floor:** When an Agent is revoked, the chain records `revoked_at` (a timestamp). If the same Agent address is later re-authorized, `nonce_min = revoked_at` is automatically set. Any nonce `≤ revoked_at` is rejected — all historical signatures are invalidated.

| Event                              | nonce\_min                                                       |
| ---------------------------------- | ---------------------------------------------------------------- |
| Agent first authorized             | `0` (any valid timestamp accepted)                               |
| Agent revoked                      | Record `revoked_at` (not cleared, just marked)                   |
| Agent re-authorized (same address) | `nonce_min = revoked_at` (all pre-revocation signatures invalid) |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lynxtrade.world/authentication/nonce-and-replay-protection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
