Skip to content

Commit 97a41d5

Browse files
committed
docs: move expiring nonces under protocol transactions
1 parent 6289464 commit 97a41d5

6 files changed

Lines changed: 111 additions & 9 deletions

File tree

src/pages/guide/payments/send-parallel-transactions.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Cards, Card } from 'vocs'
1212

1313
# Send Parallel Transactions
1414

15-
Tempo enables concurrent transaction execution through its [expiring nonce](/guide/tempo-transaction#expiring-nonces) system. Unlike traditional sequential nonces that require transactions to be processed one at a time, expiring nonces allow multiple transactions to be submitted simultaneously without nonce conflicts. Each transaction uses an independent nonce that automatically expires after a set time window, enabling true parallel execution.
15+
Tempo enables concurrent transaction execution through its [expiring nonce](/protocol/transactions/expiring-nonces) system. Unlike traditional sequential nonces that require transactions to be processed one at a time, expiring nonces allow multiple transactions to be submitted simultaneously without nonce conflicts. Each transaction uses an independent nonce that automatically expires after a set time window, enabling true parallel execution.
1616

1717
## Demo
1818

@@ -37,7 +37,7 @@ Ensure that you have set up your project with Wagmi and integrated accounts by f
3737

3838
### Send concurrent transactions with nonce keys
3939

40-
To send multiple transactions in parallel, simply batch them together. [Expiring nonces](/guide/tempo-transaction#expiring-nonces) are attached to each transaction automatically.
40+
To send multiple transactions in parallel, simply batch them together. [Expiring nonces](/protocol/transactions/expiring-nonces) are attached to each transaction automatically.
4141

4242
:::code-group
4343

@@ -82,7 +82,7 @@ console.log('Transaction 2:', receipt2.transactionHash) // [!code focus]
8282
<Cards>
8383
<Card
8484
description="Learn more about expiring nonces that power concurrent transactions."
85-
to="/guide/tempo-transaction#expiring-nonces"
85+
to="/protocol/transactions/expiring-nonces"
8686
icon="lucide:timer"
8787
title="Expiring Nonces"
8888
/>

src/pages/guide/tempo-transaction/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ If you're integrating with Tempo, we **strongly recommend** using Tempo Transact
4949
/>
5050
<Card
5151
description="Create nonces that automatically expire after a set time window."
52-
to="#expiring-nonces"
52+
to="/protocol/transactions/expiring-nonces"
5353
icon="lucide:timer"
5454
title="Expiring Nonces"
5555
/>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
title: Expiring Nonces
3+
description: Use Tempo expiring nonces to submit time-bounded transactions without managing sequential account nonces.
4+
---
5+
6+
import { Cards, Card } from 'vocs'
7+
8+
# Expiring Nonces
9+
10+
Expiring nonces let Tempo Transactions use time-bounded replay protection instead of a sequential account nonce. They are useful when you need to submit independent transactions concurrently, recover cleanly from dropped transactions, or operate relayers that should not coordinate one global nonce stream.
11+
12+
When a transaction uses an expiring nonce, Tempo identifies the transaction by its hash and accepts it only until its `validBefore` timestamp. After the validity window closes, the transaction cannot be included and the nonce entry can be evicted from protocol storage.
13+
14+
## When to use expiring nonces
15+
16+
Use expiring nonces for:
17+
18+
- Parallel user actions where one delayed transaction should not block another.
19+
- Gasless or meta-transaction flows where relayers submit transactions for many users.
20+
- Short-lived automated actions that should fail closed if they are not included quickly.
21+
- Access-key flows where the signature should only be usable for a narrow time window.
22+
23+
Use regular sequential nonces or 2D nonce keys when you need strict ordering within a transaction stream.
24+
25+
## Transaction fields
26+
27+
Set the Tempo Transaction nonce fields as follows:
28+
29+
| Field | Value |
30+
| --- | --- |
31+
| `nonceKey` | `uint256.max` |
32+
| `nonce` | `0` |
33+
| `validBefore` | Unix timestamp in seconds, within the next 30 seconds |
34+
35+
The transaction is valid only while `block.timestamp < validBefore`. Transactions with a `validBefore` timestamp in the past, too close to the current block timestamp, or more than 30 seconds in the future are rejected.
36+
37+
## Foundry example
38+
39+
Use `--tempo.expiring-nonce` and set `--tempo.valid-before` to a timestamp inside the 30-second validity window:
40+
41+
```bash
42+
VALID_BEFORE=$(($(date +%s) + 25))
43+
44+
cast send <CONTRACT_ADDRESS> 'increment()' \
45+
--rpc-url $TEMPO_RPC_URL \
46+
--private-key $PRIVATE_KEY \
47+
--tempo.expiring-nonce \
48+
--tempo.valid-before $VALID_BEFORE
49+
```
50+
51+
For local testing, the same flags work with Anvil in Tempo mode:
52+
53+
```bash
54+
anvil --tempo --hardfork t3
55+
56+
VALID_BEFORE=$(($(date +%s) + 25))
57+
58+
cast send <CONTRACT_ADDRESS> 'increment()' \
59+
--rpc-url http://127.0.0.1:8545 \
60+
--private-key $PRIVATE_KEY \
61+
--tempo.expiring-nonce \
62+
--tempo.valid-before $VALID_BEFORE
63+
```
64+
65+
## Replay protection
66+
67+
Tempo records the transaction hash with its expiry timestamp. If the same transaction hash is seen again before the expiry timestamp, it is rejected as a replay. After expiry, the entry is no longer valid and can be removed from the fixed-size expiring nonce buffer.
68+
69+
This means expiring nonces do not create a permanent account-level nonce queue. Each transaction stands on its own, and independent transactions can be sent at the same time.
70+
71+
## Practical guidance
72+
73+
- Pick a `validBefore` value close to the current time. `now + 20` to `now + 25` seconds leaves enough room for normal submission without hitting the 30-second upper bound.
74+
- Rebuild and re-sign a transaction if the validity window expires before inclusion.
75+
- Do not reuse the exact same signed transaction during its validity window; the protocol treats that as a replay.
76+
- Keep using ordered nonce streams for workflows where transaction B must execute only after transaction A.
77+
78+
## Related docs
79+
80+
<Cards>
81+
<Card
82+
description="Submit multiple independent transactions concurrently with SDK helpers."
83+
to="/guide/payments/send-parallel-transactions"
84+
icon="lucide:zap"
85+
title="Send Parallel Transactions"
86+
/>
87+
<Card
88+
description="Read the full transaction type and nonce field specification."
89+
to="/protocol/transactions/spec-tempo-transaction"
90+
icon="lucide:file-code"
91+
title="Tempo Transaction Spec"
92+
/>
93+
<Card
94+
description="Read the protocol proposal for expiring nonces."
95+
to="https://tips.sh/1009"
96+
icon="lucide:scroll-text"
97+
title="TIP-1009"
98+
/>
99+
</Cards>

src/pages/protocol/transactions/spec-tempo-transaction.mdx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,8 @@ Using signature length for type detection avoids adding explicit type fields whi
905905
### Linear Gas Scaling for Nonce Keys
906906
The progressive pricing model prevents state bloat while keeping initial keys affordable. The 20,000 gas increment approximates the long-term state cost of maintaining each additional nonce mapping.
907907

908-
### No Nonce Expiry
909-
Avoiding expiry simplifies the protocol and prevents edge cases where in-flight transactions become invalid. Wallets handle nonce key allocation to prevent conflicts.
908+
### Nonce Expiry
909+
Ordinary nonce keys do not expire, which keeps ordered transaction streams simple and avoids invalidating in-flight transactions. Expiring nonces are the explicit exception: transactions that set `nonce_key = uint256.max`, `nonce = 0`, and a short `valid_before` window use hash-based replay protection instead of a permanent account nonce entry.
910910

911911
### Backwards Compatibility
912912

@@ -1207,4 +1207,3 @@ The introduction of 7702 delegated accounts already created complex cross-transa
12071207
Because a single transaction can invalidate multiple others by spending balances of multiple accounts
12081208

12091209
**Assessment:** While this transaction type introduces additional pre-execution validation costs, all costs are bounded to reasonable limits. The mempool complexity issues around cross-transaction dependencies already exist in Ethereum due to 7702 and accounts with code, making static validation inherently difficult. So the incremental cost from this transaction type is acceptable given these existing constraints.
1210-

src/pages/quickstart/wallet-developers.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ With Tempo Transactions, you can also:
4949
- Send concurrent transactions with independent nonces ([guide](/guide/payments/send-parallel-transactions))
5050
- Batch multiple calls into a single atomic transaction ([guide](/guide/use-accounts/batch-transactions))
5151
- Sign with passkeys and P256 keys ([guide](/guide/use-accounts/webauthn-p256-signatures))
52-
- Use expiring nonces for cheaper transactions that don't require nonce tracking ([guide](/guide/tempo-transaction#expiring-nonces))
52+
- Use expiring nonces for cheaper transactions that don't require nonce tracking ([guide](/protocol/transactions/expiring-nonces))
5353
:::
5454

5555
### Handle the absence of a native token
@@ -203,7 +203,7 @@ Before launching Tempo support, ensure your wallet:
203203
- [ ] Provides fee token selection in the UI (dropdown or account setting)
204204
- [ ] Pulls token/network assets from Tempo's tokenlist
205205
- [ ] (Recommended) Sponsors fees for your users via [fee sponsorship](/guide/payments/sponsor-user-fees)
206-
- [ ] (Recommended) Uses [expiring nonces](/guide/tempo-transaction#expiring-nonces) for lower-cost transactions that don't require nonce management
206+
- [ ] (Recommended) Uses [expiring nonces](/protocol/transactions/expiring-nonces) for lower-cost transactions that don't require nonce management
207207

208208
## Learning Resources
209209

vocs.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@ export default defineConfig({
613613
text: 'Overview',
614614
link: '/protocol/transactions',
615615
},
616+
{
617+
text: 'Expiring Nonces',
618+
link: '/protocol/transactions/expiring-nonces',
619+
},
616620
{
617621
text: 'Specification',
618622
link: '/protocol/transactions/spec-tempo-transaction',

0 commit comments

Comments
 (0)