Skip to content

Commit 18fabdd

Browse files
protect: Add "Nonce Management" page to document eth_getTransactionCount behavior. (#573)
1 parent ddd692f commit 18fabdd

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: Nonce Management
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
8+
Normally, a wallet can call `eth_getTransactionCount` to get the next nonce to use for a transaction.
9+
However, since transactions sent to Flashbots Protect are potentially sensitive, even exposing the incremented nonce can leak information about the user's activity.
10+
11+
As such, transactions sent to Flashbots Protect are only included in the `eth_getTransactionCount` results when querying the `"pending"` nonce, and only if the request is signed by the user's private key.
12+
13+
This is done by sending a JSON-RPC request to the Flashbots Protect RPC endpoint with the following parameters:
14+
15+
```json
16+
{
17+
"jsonrpc": "2.0",
18+
"method": "eth_getTransactionCount",
19+
"params": [
20+
"0xYOUR_ADDRESS",
21+
"pending"
22+
],
23+
"id": 1
24+
}
25+
```
26+
27+
The request is then signed and the signature is included in the `X-Flashbots-Signature` header. Without such a signature, the returned nonce will only include transactions sent to the public mempool.
28+
29+
### Authentication
30+
31+
To authenticate your request, sign the payload and include the signed payload in the `X-Flashbots-Signature` header of your request.
32+
33+
```curl
34+
curl -X POST -H "Content-Type: application/json" -H "X-Flashbots-Signature: <public key address>:<signature>" --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}' https://rpc.flashbots.net
35+
```
36+
37+
The private key of the address your want to query must be used to sign the payload.
38+
39+
The signature is calculated by taking the [EIP-191](https://eips.ethereum.org/EIPS/eip-191) hash of the json body encoded as UTF-8 bytes. Here's an example using ethers.js:
40+
41+
<Tabs
42+
defaultValue="ethers.js"
43+
values={[
44+
{ label: 'ethers.js', value: 'ethers.js', },
45+
{ label: 'web3.py', value: 'web3.py' },
46+
{ label: 'go', value: 'go' },
47+
]}
48+
>
49+
<TabItem value="ethers.js">
50+
51+
```ts
52+
import {Wallet, utils} from 'ethers';
53+
54+
const privateKey = '0x1234';
55+
const wallet = new Wallet(privateKey);
56+
const body =
57+
'{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}';
58+
const signature = wallet.address + ':' + wallet.signMessage(utils.id(body));
59+
```
60+
61+
</TabItem>
62+
<TabItem value="web3.py">
63+
64+
```py
65+
from web3 import Web3
66+
from eth_account import Account, messages
67+
68+
body = '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}'
69+
message = messages.encode_defunct(text=Web3.keccak(text=body).hex())
70+
signature = Account.from_key(private_key).address + ':' + Account.sign_message(message, private_key).signature.hex()
71+
```
72+
73+
</TabItem>
74+
<TabItem value="go">
75+
76+
```go
77+
body := `{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}`
78+
hashedBody := crypto.Keccak256Hash([]byte(body)).Hex()
79+
sig, err := crypto.Sign(accounts.TextHash([]byte(hashedBody)), privKey)
80+
signature := crypto.PubkeyToAddress(privKey.PublicKey).Hex() + ":" + hexutil.Encode(sig)
81+
```
82+
83+
</TabItem>
84+
</Tabs>
85+

docs/sidebars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ module.exports = {
5656
'flashbots-protect/mev-share',
5757
'flashbots-protect/gas-fee-refunds',
5858
'flashbots-protect/cancellations',
59+
'flashbots-protect/nonce-management',
5960
'flashbots-protect/stuck_transactions',
6061
'flashbots-protect/large-transactions',
6162
{

0 commit comments

Comments
 (0)