Skip to content

Commit e1d0ca2

Browse files
Merge pull request #1133 from multiversx/iterate-keys
Add documentation for the iterate-keys endpoint
2 parents 4860f4f + 64eaaa6 commit e1d0ca2

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
id: iterate-keys
3+
title: Iterate keys
4+
---
5+
6+
[comment]: # (mx-abstract)
7+
8+
## Overview
9+
10+
Retrieving all storage keys for an account can be resource-intensive if the account has many entries. The `/address/iterate-keys` endpoint allows clients to efficiently iterate through all key-value pairs in an account's data trie, fetching them in batches and resuming from a checkpoint using an iterator state. This is especially useful for large accounts or when paginating through storage.
11+
12+
If you need to ensure consistency across multiple requests (e.g., if the account might change), use the `?blockNonce={blockNonce}` query parameter to lock iteration to a specific trie root.
13+
14+
:::warning
15+
This endpoint will only work if the node's `config.toml` file has the following setting enabled:
16+
17+
```
18+
[TrieLeavesRetrieverConfig]
19+
Enabled = true
20+
```
21+
:::
22+
23+
[comment]: # (mx-context-auto)
24+
25+
## Endpoint details
26+
27+
- **Method:** POST
28+
- **Path:** `/address/iterate-keys`
29+
- **Optional:** `/address/iterate-keys?blockNonce={blockNonce}`
30+
31+
### Request body
32+
33+
| Field | Type | Description |
34+
| -------------- | ------ | --------------------------------------------------------------------------------------------------|
35+
| `address` | string | Address of the account whose storage keys you want to iterate. |
36+
| `numKeys` | int | Number of keys to retrieve in this batch. If 0, retrieves as many as possible until timeout. |
37+
| `iteratorState`| array | Set to empty array for the first request, or use the value from the previous response to resume. |
38+
39+
#### Example - First request
40+
41+
```json
42+
{
43+
"address": "erd1...",
44+
"numKeys": 100,
45+
"iteratorState": []
46+
}
47+
```
48+
49+
#### Example - Subsequent request
50+
51+
```json
52+
{
53+
"address": "erd1...",
54+
"numKeys": 100,
55+
"iteratorState": [
56+
"QTyP0ZbUPao3dJiNhdduVDc2GlJO5XNSljRJS2lpF00EBg==",
57+
"F6Wc4zEhjoS2cpcmb4h4tH+8hNHwbez/mskIzpKr7ooF",
58+
"qE7Onkq+OYx9bCx2OPRl5GUIE3iqqA0I+hC7E35+2EwG",
59+
"eNu9LmbWHS5cjjaONCn3oc22+9H/hc2rvjHdJVLb9p8H",
60+
"9ikE6F470N3x4UxfSnXpqM6ATHUpdAAk7TwNEziXD5QI",
61+
"pymZnCzkTZ91cKFLTUlY0S5du5deg3CJXcR/jZR9gDUJ",
62+
"dK7SeJcCggBlkhKoQpfLbbQ1RkwRgDENK8YhjUu71HcK",
63+
"pYbrJttg/Cqzxko2IyqVWLeEiY1ScLYjPiVdqNX1PFcL",
64+
"vTuXGEd5YBqLX/bwG9rOhb+Ect25N5IIEgHR8TMklL4M",
65+
"MXbChMP5migm07zByj85+h3EZorzDwj4A0lRcNBIV1QO",
66+
"wq+g7t7WX/6bEcxZhGvQlIfgJxzY/gK2BR/IDjBVYw8P"
67+
]
68+
}
69+
```
70+
71+
72+
### Response body
73+
74+
| Field | Type | Description |
75+
|-------------------------|---------------------|-----------------------------------------------------------------------------|
76+
| `data.blockInfo` | object | Information about the block (nonce, hash, rootHash). |
77+
| `data.newIteratorState` | array \| null | Array of strings if more data remains, or null if iteration is complete. |
78+
| `data.pairs` | object | Key-value pairs (hex-encoded) retrieved in this batch. |
79+
| `error` | string | Error message, if any. |
80+
| `code` | string | Status code, e.g., "successful". |
81+
82+
#### Example response (more data to fetch)
83+
84+
```json
85+
{
86+
"data": {
87+
"blockInfo": {
88+
"nonce": 141738,
89+
"hash": "f7fd9ee6a3a24ab63c30f2a7c9df360d8e1d367aed52b43ec527bfd6aa8eae35",
90+
"rootHash": "96bb085e08cec47a45df37ed07abd6ed2e22fdeeb5192a6a2bb624cb8c18b3e1"
91+
},
92+
"newIteratorState": [
93+
"JZWO0TF7sEredrzrZQ3aSj40w29valylR4GHv65qiBoADw==",
94+
"WrN0877/4OOj2muLRNNhXbSB7wBpSKVqHJRhiinqOuQB",
95+
"4WECDX5h4NSKqdG4KOJgOdlbmbKMOYDc0GmUPH7ALoUC",
96+
"j+j5EIMbiE6VXkRRarus5AMImhC4eo6HIb7SBNga9VMD",
97+
"kR1nAJ1HXgc1OKnuJOu2U4qlGVx90zTiiFzvvyTBZ2AE",
98+
"F6Wc4zEhjoS2cpcmb4h4tH+8hNHwbez/mskIzpKr7ooF",
99+
"qE7Onkq+OYx9bCx2OPRl5GUIE3iqqA0I+hC7E35+2EwG",
100+
"eNu9LmbWHS5cjjaONCn3oc22+9H/hc2rvjHdJVLb9p8H",
101+
"9ikE6F470N3x4UxfSnXpqM6ATHUpdAAk7TwNEziXD5QI",
102+
"pymZnCzkTZ91cKFLTUlY0S5du5deg3CJXcR/jZR9gDUJ",
103+
"dK7SeJcCggBlkhKoQpfLbbQ1RkwRgDENK8YhjUu71HcK",
104+
"pYbrJttg/Cqzxko2IyqVWLeEiY1ScLYjPiVdqNX1PFcL",
105+
"vTuXGEd5YBqLX/bwG9rOhb+Ect25N5IIEgHR8TMklL4M",
106+
"MXbChMP5migm07zByj85+h3EZorzDwj4A0lRcNBIV1QO",
107+
"wq+g7t7WX/6bEcxZhGvQlIfgJxzY/gK2BR/IDjBVYw8P"
108+
],
109+
"pairs": {
110+
"454c524f4e4465736474415745534f4d452d313632623032": "0403",
111+
"454c524f4e4465736474415745534f4d452d383831343636": "0403"
112+
// ... more key-value pairs ...
113+
}
114+
},
115+
"error": "",
116+
"code": "successful"
117+
}
118+
```
119+
120+
#### Example response (iteration complete)
121+
122+
```json
123+
{
124+
"data": {
125+
"blockInfo": {
126+
"nonce": 112594,
127+
"hash": "f26e9d8c00d7a56c071989d14544e0c3431eb33956854ce780374d8c08b4aa9f",
128+
"rootHash": "75c50f6913d4badb9635235f9dafc7eb14ce14406f8c59d05838ff25021c009f"
129+
},
130+
"newIteratorState": null,
131+
"pairs": {
132+
"454c524f4e446573647446554e4749424c452d326562313837": "0401"
133+
}
134+
},
135+
"error": "",
136+
"code": "successful"
137+
}
138+
```
139+
140+
[comment]: # (mx-context-auto)
141+
142+
## Usage notes
143+
144+
- The `pairs` object contains hex-encoded keys and values. Decode as needed.
145+
- Always pass `newIteratorState` as-is in your next request's `iteratorState` field to continue iteration.
146+
- When `newIteratorState` is null, all keys have been retrieved.
147+
- If `iteratorState` is an empty array (`[]`) in the request, iteration starts from the beginning of the trie.
148+
- If `numKeys` is 0, the server will return as many keys as possible until all are retrieved or until the `TrieOperationsDeadlineMilliseconds` timeout is reached.
149+
- If retrieving `numKeys` takes more time than the configured timeout, the request will return the keys collected up to that point.
150+
- Use `?blockNonce={blockNonce}` to ensure all requests iterate the same trie root, even if the account changes between requests.
151+
152+
[comment]: # (mx-context-auto)
153+
154+
## Example usage
155+
156+
1. **Initial request:**
157+
- Send a POST with `iteratorState` as an empty array and desired `numKeys` (or 0 for maximum batch).
158+
2. **Subsequent requests:**
159+
- Use the `newIteratorState` from the previous response to fetch the next batch. Pass it as-is.
160+
- Optionally, provide `blockNonce` to ensure consistency if the account may change.
161+
3. **Finish:**
162+
- When `newIteratorState` is null, you have retrieved all keys.

sidebars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ const sidebars = {
279279
"sdk-and-tools/rest-api/versions-and-changelog",
280280
],
281281
},
282+
"sdk-and-tools/rest-api/iterate-keys",
282283
],
283284
},
284285
],

0 commit comments

Comments
 (0)