@net-protocol/storage 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -0
- package/dist/index.d.mts +523 -0
- package/dist/index.d.ts +523 -0
- package/dist/index.js +2120 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2079 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +73 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2120 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var wagmi = require('wagmi');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var core = require('@net-protocol/core');
|
|
6
|
+
var viem = require('viem');
|
|
7
|
+
var pako = require('pako');
|
|
8
|
+
var actions = require('viem/actions');
|
|
9
|
+
var useAsyncEffect = require('use-async-effect');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var pako__default = /*#__PURE__*/_interopDefault(pako);
|
|
14
|
+
var useAsyncEffect__default = /*#__PURE__*/_interopDefault(useAsyncEffect);
|
|
15
|
+
|
|
16
|
+
// src/hooks/useStorage.ts
|
|
17
|
+
|
|
18
|
+
// src/abis/storage.json
|
|
19
|
+
var storage_default = [
|
|
20
|
+
{
|
|
21
|
+
type: "function",
|
|
22
|
+
name: "bulkGet",
|
|
23
|
+
inputs: [
|
|
24
|
+
{
|
|
25
|
+
name: "params",
|
|
26
|
+
type: "tuple[]",
|
|
27
|
+
internalType: "struct Storage.BulkGetParams[]",
|
|
28
|
+
components: [
|
|
29
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
30
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
outputs: [
|
|
35
|
+
{
|
|
36
|
+
name: "results",
|
|
37
|
+
type: "tuple[]",
|
|
38
|
+
internalType: "struct Storage.BulkGetResult[]",
|
|
39
|
+
components: [
|
|
40
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
41
|
+
{ name: "value", type: "bytes", internalType: "bytes" }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
stateMutability: "view"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: "function",
|
|
49
|
+
name: "bulkGetTotalWrites",
|
|
50
|
+
inputs: [
|
|
51
|
+
{
|
|
52
|
+
name: "params",
|
|
53
|
+
type: "tuple[]",
|
|
54
|
+
internalType: "struct Storage.BulkGetParams[]",
|
|
55
|
+
components: [
|
|
56
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
57
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
outputs: [
|
|
62
|
+
{ name: "results", type: "uint256[]", internalType: "uint256[]" }
|
|
63
|
+
],
|
|
64
|
+
stateMutability: "view"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "function",
|
|
68
|
+
name: "bulkGetValueAtIndex",
|
|
69
|
+
inputs: [
|
|
70
|
+
{
|
|
71
|
+
name: "params",
|
|
72
|
+
type: "tuple[]",
|
|
73
|
+
internalType: "struct Storage.BulkGetValueAtIndexParams[]",
|
|
74
|
+
components: [
|
|
75
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
76
|
+
{
|
|
77
|
+
name: "operator",
|
|
78
|
+
type: "address",
|
|
79
|
+
internalType: "address"
|
|
80
|
+
},
|
|
81
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
outputs: [
|
|
86
|
+
{
|
|
87
|
+
name: "results",
|
|
88
|
+
type: "tuple[]",
|
|
89
|
+
internalType: "struct Storage.BulkGetResult[]",
|
|
90
|
+
components: [
|
|
91
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
92
|
+
{ name: "value", type: "bytes", internalType: "bytes" }
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
stateMutability: "view"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: "function",
|
|
100
|
+
name: "bulkPut",
|
|
101
|
+
inputs: [
|
|
102
|
+
{
|
|
103
|
+
name: "params",
|
|
104
|
+
type: "tuple[]",
|
|
105
|
+
internalType: "struct Storage.BulkPutParams[]",
|
|
106
|
+
components: [
|
|
107
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
108
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
109
|
+
{ name: "value", type: "bytes", internalType: "bytes" }
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
outputs: [],
|
|
114
|
+
stateMutability: "nonpayable"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: "function",
|
|
118
|
+
name: "get",
|
|
119
|
+
inputs: [
|
|
120
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
121
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
122
|
+
],
|
|
123
|
+
outputs: [
|
|
124
|
+
{ name: "", type: "string", internalType: "string" },
|
|
125
|
+
{ name: "", type: "bytes", internalType: "bytes" }
|
|
126
|
+
],
|
|
127
|
+
stateMutability: "view"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: "function",
|
|
131
|
+
name: "getTotalWrites",
|
|
132
|
+
inputs: [
|
|
133
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
134
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
135
|
+
],
|
|
136
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
137
|
+
stateMutability: "view"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: "function",
|
|
141
|
+
name: "getValueAtIndex",
|
|
142
|
+
inputs: [
|
|
143
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
144
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
145
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
146
|
+
],
|
|
147
|
+
outputs: [
|
|
148
|
+
{ name: "", type: "string", internalType: "string" },
|
|
149
|
+
{ name: "", type: "bytes", internalType: "bytes" }
|
|
150
|
+
],
|
|
151
|
+
stateMutability: "view"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: "function",
|
|
155
|
+
name: "put",
|
|
156
|
+
inputs: [
|
|
157
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
158
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
159
|
+
{ name: "value", type: "bytes", internalType: "bytes" }
|
|
160
|
+
],
|
|
161
|
+
outputs: [],
|
|
162
|
+
stateMutability: "nonpayable"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: "event",
|
|
166
|
+
name: "Stored",
|
|
167
|
+
inputs: [
|
|
168
|
+
{
|
|
169
|
+
name: "key",
|
|
170
|
+
type: "bytes32",
|
|
171
|
+
indexed: true,
|
|
172
|
+
internalType: "bytes32"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "operator",
|
|
176
|
+
type: "address",
|
|
177
|
+
indexed: true,
|
|
178
|
+
internalType: "address"
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
anonymous: false
|
|
182
|
+
}
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
// src/abis/chunked-storage.json
|
|
186
|
+
var chunked_storage_default = [
|
|
187
|
+
{
|
|
188
|
+
type: "function",
|
|
189
|
+
name: "get",
|
|
190
|
+
inputs: [
|
|
191
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
192
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
193
|
+
],
|
|
194
|
+
outputs: [
|
|
195
|
+
{ name: "", type: "string", internalType: "string" },
|
|
196
|
+
{ name: "", type: "bytes", internalType: "bytes" }
|
|
197
|
+
],
|
|
198
|
+
stateMutability: "view"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
type: "function",
|
|
202
|
+
name: "getChunk",
|
|
203
|
+
inputs: [
|
|
204
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
205
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
206
|
+
{ name: "chunkIndex", type: "uint8", internalType: "uint8" }
|
|
207
|
+
],
|
|
208
|
+
outputs: [
|
|
209
|
+
{ name: "chunkData", type: "bytes", internalType: "bytes" }
|
|
210
|
+
],
|
|
211
|
+
stateMutability: "view"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
type: "function",
|
|
215
|
+
name: "getChunks",
|
|
216
|
+
inputs: [
|
|
217
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
218
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
219
|
+
{ name: "startIndex", type: "uint8", internalType: "uint8" },
|
|
220
|
+
{ name: "endIndex", type: "uint8", internalType: "uint8" }
|
|
221
|
+
],
|
|
222
|
+
outputs: [
|
|
223
|
+
{ name: "chunks", type: "bytes[]", internalType: "bytes[]" }
|
|
224
|
+
],
|
|
225
|
+
stateMutability: "view"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
type: "function",
|
|
229
|
+
name: "getMetadata",
|
|
230
|
+
inputs: [
|
|
231
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
232
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
233
|
+
],
|
|
234
|
+
outputs: [
|
|
235
|
+
{ name: "chunkCount", type: "uint8", internalType: "uint8" },
|
|
236
|
+
{ name: "originalText", type: "string", internalType: "string" }
|
|
237
|
+
],
|
|
238
|
+
stateMutability: "view"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
type: "function",
|
|
242
|
+
name: "put",
|
|
243
|
+
inputs: [
|
|
244
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
245
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
246
|
+
{ name: "chunks", type: "bytes[]", internalType: "bytes[]" }
|
|
247
|
+
],
|
|
248
|
+
outputs: [],
|
|
249
|
+
stateMutability: "nonpayable"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
type: "event",
|
|
253
|
+
name: "ChunkedStoragePut",
|
|
254
|
+
inputs: [
|
|
255
|
+
{
|
|
256
|
+
name: "originalKey",
|
|
257
|
+
type: "bytes32",
|
|
258
|
+
indexed: true,
|
|
259
|
+
internalType: "bytes32"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "sender",
|
|
263
|
+
type: "address",
|
|
264
|
+
indexed: true,
|
|
265
|
+
internalType: "address"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "hashedKey",
|
|
269
|
+
type: "bytes32",
|
|
270
|
+
indexed: false,
|
|
271
|
+
internalType: "bytes32"
|
|
272
|
+
}
|
|
273
|
+
],
|
|
274
|
+
anonymous: false
|
|
275
|
+
},
|
|
276
|
+
{ type: "error", name: "DataTooLarge", inputs: [] }
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
// src/abis/chunked-storage-reader.json
|
|
280
|
+
var chunked_storage_reader_default = [
|
|
281
|
+
{
|
|
282
|
+
type: "function",
|
|
283
|
+
name: "get",
|
|
284
|
+
inputs: [
|
|
285
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
286
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
287
|
+
],
|
|
288
|
+
outputs: [
|
|
289
|
+
{ name: "", type: "string", internalType: "string" },
|
|
290
|
+
{ name: "", type: "bytes", internalType: "bytes" }
|
|
291
|
+
],
|
|
292
|
+
stateMutability: "view"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
type: "function",
|
|
296
|
+
name: "getChunk",
|
|
297
|
+
inputs: [
|
|
298
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
299
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
300
|
+
{ name: "chunkIndex", type: "uint8", internalType: "uint8" }
|
|
301
|
+
],
|
|
302
|
+
outputs: [
|
|
303
|
+
{ name: "chunkData", type: "bytes", internalType: "bytes" }
|
|
304
|
+
],
|
|
305
|
+
stateMutability: "view"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
type: "function",
|
|
309
|
+
name: "getChunkAtIndex",
|
|
310
|
+
inputs: [
|
|
311
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
312
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
313
|
+
{ name: "chunkIndex", type: "uint8", internalType: "uint8" },
|
|
314
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
315
|
+
],
|
|
316
|
+
outputs: [
|
|
317
|
+
{ name: "chunkData", type: "bytes", internalType: "bytes" }
|
|
318
|
+
],
|
|
319
|
+
stateMutability: "view"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
type: "function",
|
|
323
|
+
name: "getChunks",
|
|
324
|
+
inputs: [
|
|
325
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
326
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
327
|
+
{ name: "startIndex", type: "uint8", internalType: "uint8" },
|
|
328
|
+
{ name: "endIndex", type: "uint8", internalType: "uint8" }
|
|
329
|
+
],
|
|
330
|
+
outputs: [
|
|
331
|
+
{ name: "chunks", type: "bytes[]", internalType: "bytes[]" }
|
|
332
|
+
],
|
|
333
|
+
stateMutability: "view"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
type: "function",
|
|
337
|
+
name: "getChunksAtIndex",
|
|
338
|
+
inputs: [
|
|
339
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
340
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
341
|
+
{ name: "startIndex", type: "uint8", internalType: "uint8" },
|
|
342
|
+
{ name: "endIndex", type: "uint8", internalType: "uint8" },
|
|
343
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
344
|
+
],
|
|
345
|
+
outputs: [
|
|
346
|
+
{ name: "chunks", type: "bytes[]", internalType: "bytes[]" }
|
|
347
|
+
],
|
|
348
|
+
stateMutability: "view"
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
type: "function",
|
|
352
|
+
name: "getMetadata",
|
|
353
|
+
inputs: [
|
|
354
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
355
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
356
|
+
],
|
|
357
|
+
outputs: [
|
|
358
|
+
{ name: "chunkCount", type: "uint8", internalType: "uint8" },
|
|
359
|
+
{ name: "originalText", type: "string", internalType: "string" }
|
|
360
|
+
],
|
|
361
|
+
stateMutability: "view"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
type: "function",
|
|
365
|
+
name: "getMetadataAtIndex",
|
|
366
|
+
inputs: [
|
|
367
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
368
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
369
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
370
|
+
],
|
|
371
|
+
outputs: [
|
|
372
|
+
{ name: "chunkCount", type: "uint8", internalType: "uint8" },
|
|
373
|
+
{ name: "originalText", type: "string", internalType: "string" }
|
|
374
|
+
],
|
|
375
|
+
stateMutability: "view"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
type: "function",
|
|
379
|
+
name: "getTotalWrites",
|
|
380
|
+
inputs: [
|
|
381
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
382
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
383
|
+
],
|
|
384
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
385
|
+
stateMutability: "view"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
type: "function",
|
|
389
|
+
name: "getValueAtIndex",
|
|
390
|
+
inputs: [
|
|
391
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
392
|
+
{ name: "operator", type: "address", internalType: "address" },
|
|
393
|
+
{ name: "idx", type: "uint256", internalType: "uint256" }
|
|
394
|
+
],
|
|
395
|
+
outputs: [
|
|
396
|
+
{ name: "", type: "string", internalType: "string" },
|
|
397
|
+
{ name: "", type: "bytes", internalType: "bytes" }
|
|
398
|
+
],
|
|
399
|
+
stateMutability: "view"
|
|
400
|
+
}
|
|
401
|
+
];
|
|
402
|
+
|
|
403
|
+
// src/abis/storage-router.json
|
|
404
|
+
var storage_router_default = [
|
|
405
|
+
{
|
|
406
|
+
type: "function",
|
|
407
|
+
name: "get",
|
|
408
|
+
inputs: [
|
|
409
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" },
|
|
410
|
+
{ name: "operator", type: "address", internalType: "address" }
|
|
411
|
+
],
|
|
412
|
+
outputs: [
|
|
413
|
+
{ name: "isChunkedStorage", type: "bool", internalType: "bool" },
|
|
414
|
+
{ name: "text", type: "string", internalType: "string" },
|
|
415
|
+
{ name: "data", type: "bytes", internalType: "bytes" }
|
|
416
|
+
],
|
|
417
|
+
stateMutability: "view"
|
|
418
|
+
},
|
|
419
|
+
{ type: "error", name: "StoredDataNotFound", inputs: [] }
|
|
420
|
+
];
|
|
421
|
+
|
|
422
|
+
// src/abis/safe-storage-reader.json
|
|
423
|
+
var safe_storage_reader_default = [
|
|
424
|
+
{
|
|
425
|
+
type: "function",
|
|
426
|
+
name: "bulkGet",
|
|
427
|
+
inputs: [
|
|
428
|
+
{
|
|
429
|
+
name: "params",
|
|
430
|
+
type: "tuple[]",
|
|
431
|
+
internalType: "struct IStorage.BulkGetParams[]",
|
|
432
|
+
components: [
|
|
433
|
+
{
|
|
434
|
+
name: "key",
|
|
435
|
+
type: "bytes32",
|
|
436
|
+
internalType: "bytes32"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
name: "operator",
|
|
440
|
+
type: "address",
|
|
441
|
+
internalType: "address"
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
}
|
|
445
|
+
],
|
|
446
|
+
outputs: [
|
|
447
|
+
{
|
|
448
|
+
name: "results",
|
|
449
|
+
type: "tuple[]",
|
|
450
|
+
internalType: "struct IStorage.BulkGetResult[]",
|
|
451
|
+
components: [
|
|
452
|
+
{
|
|
453
|
+
name: "text",
|
|
454
|
+
type: "string",
|
|
455
|
+
internalType: "string"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: "value",
|
|
459
|
+
type: "bytes",
|
|
460
|
+
internalType: "bytes"
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
],
|
|
465
|
+
stateMutability: "view"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
type: "function",
|
|
469
|
+
name: "bulkGetValueAtIndex",
|
|
470
|
+
inputs: [
|
|
471
|
+
{
|
|
472
|
+
name: "params",
|
|
473
|
+
type: "tuple[]",
|
|
474
|
+
internalType: "struct IStorage.BulkGetValueAtIndexParams[]",
|
|
475
|
+
components: [
|
|
476
|
+
{
|
|
477
|
+
name: "key",
|
|
478
|
+
type: "bytes32",
|
|
479
|
+
internalType: "bytes32"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
name: "operator",
|
|
483
|
+
type: "address",
|
|
484
|
+
internalType: "address"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
name: "idx",
|
|
488
|
+
type: "uint256",
|
|
489
|
+
internalType: "uint256"
|
|
490
|
+
}
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
],
|
|
494
|
+
outputs: [
|
|
495
|
+
{
|
|
496
|
+
name: "results",
|
|
497
|
+
type: "tuple[]",
|
|
498
|
+
internalType: "struct IStorage.BulkGetResult[]",
|
|
499
|
+
components: [
|
|
500
|
+
{
|
|
501
|
+
name: "text",
|
|
502
|
+
type: "string",
|
|
503
|
+
internalType: "string"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
name: "value",
|
|
507
|
+
type: "bytes",
|
|
508
|
+
internalType: "bytes"
|
|
509
|
+
}
|
|
510
|
+
]
|
|
511
|
+
}
|
|
512
|
+
],
|
|
513
|
+
stateMutability: "view"
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
type: "function",
|
|
517
|
+
name: "get",
|
|
518
|
+
inputs: [
|
|
519
|
+
{
|
|
520
|
+
name: "key",
|
|
521
|
+
type: "bytes32",
|
|
522
|
+
internalType: "bytes32"
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
name: "operator",
|
|
526
|
+
type: "address",
|
|
527
|
+
internalType: "address"
|
|
528
|
+
}
|
|
529
|
+
],
|
|
530
|
+
outputs: [
|
|
531
|
+
{
|
|
532
|
+
name: "",
|
|
533
|
+
type: "string",
|
|
534
|
+
internalType: "string"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: "",
|
|
538
|
+
type: "bytes",
|
|
539
|
+
internalType: "bytes"
|
|
540
|
+
}
|
|
541
|
+
],
|
|
542
|
+
stateMutability: "view"
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
type: "function",
|
|
546
|
+
name: "getValueAtIndex",
|
|
547
|
+
inputs: [
|
|
548
|
+
{
|
|
549
|
+
name: "key",
|
|
550
|
+
type: "bytes32",
|
|
551
|
+
internalType: "bytes32"
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
name: "operator",
|
|
555
|
+
type: "address",
|
|
556
|
+
internalType: "address"
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
name: "idx",
|
|
560
|
+
type: "uint256",
|
|
561
|
+
internalType: "uint256"
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
outputs: [
|
|
565
|
+
{
|
|
566
|
+
name: "",
|
|
567
|
+
type: "string",
|
|
568
|
+
internalType: "string"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
name: "",
|
|
572
|
+
type: "bytes",
|
|
573
|
+
internalType: "bytes"
|
|
574
|
+
}
|
|
575
|
+
],
|
|
576
|
+
stateMutability: "view"
|
|
577
|
+
}
|
|
578
|
+
];
|
|
579
|
+
|
|
580
|
+
// src/constants.ts
|
|
581
|
+
var STORAGE_CONTRACT = {
|
|
582
|
+
abi: storage_default,
|
|
583
|
+
address: "0x00000000db40fcb9f4466330982372e27fd7bbf5"
|
|
584
|
+
};
|
|
585
|
+
var CHUNKED_STORAGE_CONTRACT = {
|
|
586
|
+
abi: chunked_storage_default,
|
|
587
|
+
address: "0x000000A822F09aF21b1951B65223F54ea392E6C6"
|
|
588
|
+
};
|
|
589
|
+
var CHUNKED_STORAGE_READER_CONTRACT = {
|
|
590
|
+
abi: chunked_storage_reader_default,
|
|
591
|
+
address: "0x00000005210a7532787419658f6162f771be62f8"
|
|
592
|
+
};
|
|
593
|
+
var STORAGE_ROUTER_CONTRACT = {
|
|
594
|
+
abi: storage_router_default,
|
|
595
|
+
address: "0x000000C0bbc2Ca04B85E77D18053e7c38bB97939"
|
|
596
|
+
};
|
|
597
|
+
var SAFE_STORAGE_READER_CONTRACT = {
|
|
598
|
+
abi: safe_storage_reader_default,
|
|
599
|
+
address: "0x0000000d03bad401fae4935dc9cbbf8084347214"
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
// src/utils/xmlUtils.ts
|
|
603
|
+
function parseNetReferences(metadata) {
|
|
604
|
+
const regex = /<net\s+k="([^"]+)"\s+v="([^"]+)"(?:\s+i="([^"]+)")?(?:\s+o="([^"]+)")?(?:\s+s="([^"]+)")?\s*\/>/g;
|
|
605
|
+
const references = [];
|
|
606
|
+
let match;
|
|
607
|
+
while ((match = regex.exec(metadata)) !== null) {
|
|
608
|
+
references.push({
|
|
609
|
+
hash: match[1],
|
|
610
|
+
version: match[2],
|
|
611
|
+
index: match[3] ? parseInt(match[3], 10) : void 0,
|
|
612
|
+
operator: match[4]?.toLowerCase(),
|
|
613
|
+
source: match[5]
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
return references;
|
|
617
|
+
}
|
|
618
|
+
function containsXmlReferences(data) {
|
|
619
|
+
return /<net\s+k="[^"]+"\s+v="[^"]+"(?:\s+i="[^"]+")?(?:\s+o="[^"]+")?(?:\s+s="[^"]+")?\s*\/>/.test(
|
|
620
|
+
data
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
function detectStorageType(metadata) {
|
|
624
|
+
return containsXmlReferences(metadata) ? "xml" : "regular";
|
|
625
|
+
}
|
|
626
|
+
function resolveOperator(reference, defaultOperator) {
|
|
627
|
+
return reference.operator?.toLowerCase() || defaultOperator.toLowerCase();
|
|
628
|
+
}
|
|
629
|
+
function getReferenceKey(reference, defaultOperator) {
|
|
630
|
+
const operator = resolveOperator(reference, defaultOperator);
|
|
631
|
+
const index = reference.index !== void 0 ? `-${reference.index}` : "";
|
|
632
|
+
return `${reference.hash}-${operator}${index}`;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/utils/chunkUtils.ts
|
|
636
|
+
var CHUNK_SIZE = 20 * 1e3;
|
|
637
|
+
function chunkDataForStorage(data) {
|
|
638
|
+
try {
|
|
639
|
+
const dataHex = viem.stringToHex(data);
|
|
640
|
+
const compressedBytes = pako__default.default.gzip(dataHex);
|
|
641
|
+
const dataBytes = "0x" + Buffer.from(compressedBytes).toString("hex");
|
|
642
|
+
const chunks = [];
|
|
643
|
+
const hexWithoutPrefix = dataBytes.slice(2);
|
|
644
|
+
for (let i = 0; i < hexWithoutPrefix.length; i += CHUNK_SIZE * 2) {
|
|
645
|
+
const chunk = hexWithoutPrefix.slice(i, i + CHUNK_SIZE * 2);
|
|
646
|
+
chunks.push("0x" + chunk);
|
|
647
|
+
}
|
|
648
|
+
if (chunks.length === 0) {
|
|
649
|
+
chunks.push("0x");
|
|
650
|
+
}
|
|
651
|
+
return chunks;
|
|
652
|
+
} catch (error) {
|
|
653
|
+
console.error("[chunkDataForStorage] Compression failed:", error);
|
|
654
|
+
throw new Error("Failed to compress data for storage");
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function shouldSuggestXmlStorage(data) {
|
|
658
|
+
return data.length > CHUNK_SIZE || containsXmlReferences(data);
|
|
659
|
+
}
|
|
660
|
+
function getChunkCount(data) {
|
|
661
|
+
const dataBytes = viem.stringToHex(data);
|
|
662
|
+
const hexWithoutPrefix = dataBytes.slice(2);
|
|
663
|
+
return Math.max(1, Math.ceil(hexWithoutPrefix.length / (CHUNK_SIZE * 2)));
|
|
664
|
+
}
|
|
665
|
+
function assembleChunks(chunks) {
|
|
666
|
+
try {
|
|
667
|
+
let assembled = chunks[0] || "0x";
|
|
668
|
+
for (let i = 1; i < chunks.length; i++) {
|
|
669
|
+
const chunk = chunks[i];
|
|
670
|
+
if (chunk && chunk !== "0x") {
|
|
671
|
+
assembled += chunk.slice(2);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const bytes = viem.hexToBytes(assembled);
|
|
675
|
+
try {
|
|
676
|
+
const decompressed = pako__default.default.ungzip(bytes);
|
|
677
|
+
const hexString = Buffer.from(decompressed).toString("utf8");
|
|
678
|
+
const result = viem.hexToString(hexString);
|
|
679
|
+
return result;
|
|
680
|
+
} catch (error) {
|
|
681
|
+
return void 0;
|
|
682
|
+
}
|
|
683
|
+
} catch (error) {
|
|
684
|
+
console.error("[assembleChunks] Failed to assemble chunks:", error);
|
|
685
|
+
throw new Error("Failed to decompress chunked data");
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function isBinaryString(str) {
|
|
689
|
+
return str.split("").some((char) => char.charCodeAt(0) > 127);
|
|
690
|
+
}
|
|
691
|
+
function formatStorageKeyForDisplay(storageKey) {
|
|
692
|
+
if (storageKey.startsWith("0x") && storageKey.length === 66 && /^0x[0-9a-fA-F]{64}$/.test(storageKey)) {
|
|
693
|
+
try {
|
|
694
|
+
const decoded = viem.fromHex(storageKey, "string");
|
|
695
|
+
const trimmed = decoded.replace(/\0/g, "");
|
|
696
|
+
if (!isBinaryString(trimmed) && trimmed.trim().length > 0) {
|
|
697
|
+
return {
|
|
698
|
+
displayText: trimmed,
|
|
699
|
+
isDecoded: true
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
} catch {
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return {
|
|
706
|
+
displayText: storageKey,
|
|
707
|
+
isDecoded: false
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function getStorageKeyBytes(input, keyFormat) {
|
|
711
|
+
if (keyFormat === "bytes32") {
|
|
712
|
+
return input.toLowerCase();
|
|
713
|
+
}
|
|
714
|
+
if (keyFormat === "raw") {
|
|
715
|
+
return input.length > 32 ? core.keccak256HashString(input.toLowerCase()) : core.toBytes32(input.toLowerCase());
|
|
716
|
+
}
|
|
717
|
+
if (input.startsWith("0x") && input.length === 66 && // 0x + 64 hex chars = bytes32
|
|
718
|
+
/^0x[0-9a-fA-F]{64}$/.test(input)) {
|
|
719
|
+
return input.toLowerCase();
|
|
720
|
+
}
|
|
721
|
+
return input.length > 32 ? core.keccak256HashString(input.toLowerCase()) : core.toBytes32(input.toLowerCase());
|
|
722
|
+
}
|
|
723
|
+
function encodeStorageKeyForUrl(key) {
|
|
724
|
+
return encodeURIComponent(key);
|
|
725
|
+
}
|
|
726
|
+
function generateStorageEmbedTag(params) {
|
|
727
|
+
const operator = params.operatorAddress.toLowerCase();
|
|
728
|
+
const indexAttr = params.versionIndex !== void 0 ? ` i="${params.versionIndex}"` : "";
|
|
729
|
+
const sourceAttr = params.isRegularStorage ? ` s="d"` : "";
|
|
730
|
+
return `<net k="${params.storageKeyBytes}" v="0.0.1"${indexAttr} o="${operator}"${sourceAttr} />`;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// src/hooks/useStorage.ts
|
|
734
|
+
var BATCH_SIZE = 2;
|
|
735
|
+
function useStorage({
|
|
736
|
+
chainId,
|
|
737
|
+
key,
|
|
738
|
+
operatorAddress,
|
|
739
|
+
enabled = true,
|
|
740
|
+
index,
|
|
741
|
+
keyFormat,
|
|
742
|
+
useRouter = false,
|
|
743
|
+
outputFormat = "hex"
|
|
744
|
+
}) {
|
|
745
|
+
const isLatestVersion = index === void 0;
|
|
746
|
+
const shouldUseRouter = useRouter === true && isLatestVersion;
|
|
747
|
+
const outputAsString = outputFormat === "string";
|
|
748
|
+
const storageKeyBytes = key ? getStorageKeyBytes(key, keyFormat) : void 0;
|
|
749
|
+
const formatData = (text, dataHex) => {
|
|
750
|
+
if (outputAsString) {
|
|
751
|
+
return [text, viem.hexToString(dataHex)];
|
|
752
|
+
}
|
|
753
|
+
return [text, dataHex];
|
|
754
|
+
};
|
|
755
|
+
const [routerData, setRouterData] = react.useState();
|
|
756
|
+
const [routerChunkLoading, setRouterChunkLoading] = react.useState(false);
|
|
757
|
+
const [routerChunkError, setRouterChunkError] = react.useState();
|
|
758
|
+
const routerHook = wagmi.useReadContract({
|
|
759
|
+
abi: STORAGE_ROUTER_CONTRACT.abi,
|
|
760
|
+
address: STORAGE_ROUTER_CONTRACT.address,
|
|
761
|
+
functionName: "get",
|
|
762
|
+
args: storageKeyBytes && operatorAddress ? [storageKeyBytes, operatorAddress] : void 0,
|
|
763
|
+
chainId,
|
|
764
|
+
query: {
|
|
765
|
+
enabled: shouldUseRouter && enabled && !!key && !!operatorAddress
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
react.useEffect(() => {
|
|
769
|
+
async function processRouterResult() {
|
|
770
|
+
if (!routerHook.data || routerHook.isLoading || routerHook.error) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
const [isChunkedStorage, text, data] = routerHook.data;
|
|
774
|
+
if (!isChunkedStorage) {
|
|
775
|
+
const formatted = formatData(text, data);
|
|
776
|
+
setRouterData(formatted);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
setRouterChunkLoading(true);
|
|
780
|
+
setRouterChunkError(void 0);
|
|
781
|
+
try {
|
|
782
|
+
const [chunkCount] = viem.decodeAbiParameters([{ type: "uint8" }], data);
|
|
783
|
+
if (chunkCount === 0) {
|
|
784
|
+
setRouterData(void 0);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
const client = core.getPublicClient({ chainId });
|
|
788
|
+
if (!client) {
|
|
789
|
+
throw new Error(`Chain not found for chainId: ${chainId}`);
|
|
790
|
+
}
|
|
791
|
+
const allChunks = [];
|
|
792
|
+
for (let start = 0; start < Number(chunkCount); start += BATCH_SIZE) {
|
|
793
|
+
const end = Math.min(start + BATCH_SIZE, Number(chunkCount));
|
|
794
|
+
const batch = await actions.readContract(client, {
|
|
795
|
+
abi: CHUNKED_STORAGE_CONTRACT.abi,
|
|
796
|
+
address: CHUNKED_STORAGE_CONTRACT.address,
|
|
797
|
+
functionName: "getChunks",
|
|
798
|
+
args: [storageKeyBytes, operatorAddress, start, end]
|
|
799
|
+
});
|
|
800
|
+
allChunks.push(...batch);
|
|
801
|
+
}
|
|
802
|
+
const assembledString = assembleChunks(allChunks);
|
|
803
|
+
if (assembledString === void 0) {
|
|
804
|
+
setRouterData(void 0);
|
|
805
|
+
} else {
|
|
806
|
+
if (outputAsString) {
|
|
807
|
+
setRouterData([text, assembledString]);
|
|
808
|
+
} else {
|
|
809
|
+
const hexData = viem.stringToHex(assembledString);
|
|
810
|
+
setRouterData([text, hexData]);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
} catch (error) {
|
|
814
|
+
setRouterChunkError(error);
|
|
815
|
+
} finally {
|
|
816
|
+
setRouterChunkLoading(false);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
processRouterResult();
|
|
820
|
+
}, [
|
|
821
|
+
routerHook.data,
|
|
822
|
+
routerHook.isLoading,
|
|
823
|
+
routerHook.error,
|
|
824
|
+
operatorAddress,
|
|
825
|
+
chainId,
|
|
826
|
+
storageKeyBytes,
|
|
827
|
+
outputAsString
|
|
828
|
+
]);
|
|
829
|
+
const {
|
|
830
|
+
data: latestData,
|
|
831
|
+
isLoading: latestLoading,
|
|
832
|
+
error: latestError
|
|
833
|
+
} = wagmi.useReadContract({
|
|
834
|
+
abi: STORAGE_CONTRACT.abi,
|
|
835
|
+
address: STORAGE_CONTRACT.address,
|
|
836
|
+
functionName: "get",
|
|
837
|
+
args: key && operatorAddress ? [getStorageKeyBytes(key, keyFormat), operatorAddress] : void 0,
|
|
838
|
+
chainId,
|
|
839
|
+
query: {
|
|
840
|
+
enabled: !shouldUseRouter && enabled && !!operatorAddress && !!key && isLatestVersion
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
const [historicalData, setHistoricalData] = react.useState(
|
|
844
|
+
void 0
|
|
845
|
+
);
|
|
846
|
+
const [historicalLoading, setHistoricalLoading] = react.useState(false);
|
|
847
|
+
const [historicalError, setHistoricalError] = react.useState();
|
|
848
|
+
react.useEffect(() => {
|
|
849
|
+
async function fetchHistoricalVersion() {
|
|
850
|
+
if (isLatestVersion || !key || !operatorAddress || !enabled) {
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
setHistoricalLoading(true);
|
|
854
|
+
setHistoricalError(void 0);
|
|
855
|
+
setHistoricalData(void 0);
|
|
856
|
+
try {
|
|
857
|
+
const client = core.getPublicClient({ chainId });
|
|
858
|
+
if (!client) {
|
|
859
|
+
throw new Error(`Chain not found for chainId: ${chainId}`);
|
|
860
|
+
}
|
|
861
|
+
const storageKeyBytes2 = getStorageKeyBytes(
|
|
862
|
+
key,
|
|
863
|
+
keyFormat
|
|
864
|
+
);
|
|
865
|
+
try {
|
|
866
|
+
const metadata = await actions.readContract(client, {
|
|
867
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
868
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
869
|
+
functionName: "getMetadataAtIndex",
|
|
870
|
+
args: [storageKeyBytes2, operatorAddress, index]
|
|
871
|
+
});
|
|
872
|
+
const [chunkCount, text2] = metadata;
|
|
873
|
+
if (chunkCount > 0) {
|
|
874
|
+
const chunks = await actions.readContract(client, {
|
|
875
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
876
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
877
|
+
functionName: "getChunksAtIndex",
|
|
878
|
+
args: [storageKeyBytes2, operatorAddress, 0, chunkCount, index]
|
|
879
|
+
});
|
|
880
|
+
const assembledData = assembleChunks(chunks);
|
|
881
|
+
if (assembledData !== void 0) {
|
|
882
|
+
const hexData = viem.stringToHex(assembledData);
|
|
883
|
+
setHistoricalData(formatData(text2, hexData));
|
|
884
|
+
setHistoricalLoading(false);
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
} catch (chunkedError) {
|
|
889
|
+
}
|
|
890
|
+
const result = await actions.readContract(client, {
|
|
891
|
+
abi: STORAGE_CONTRACT.abi,
|
|
892
|
+
address: STORAGE_CONTRACT.address,
|
|
893
|
+
functionName: "getValueAtIndex",
|
|
894
|
+
args: [storageKeyBytes2, operatorAddress, index]
|
|
895
|
+
});
|
|
896
|
+
const [text, data] = result;
|
|
897
|
+
setHistoricalData(formatData(text, data));
|
|
898
|
+
} catch (error) {
|
|
899
|
+
console.error(
|
|
900
|
+
"[useStorage] Failed to fetch historical version:",
|
|
901
|
+
error
|
|
902
|
+
);
|
|
903
|
+
setHistoricalError(error);
|
|
904
|
+
} finally {
|
|
905
|
+
setHistoricalLoading(false);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
fetchHistoricalVersion();
|
|
909
|
+
}, [chainId, key, operatorAddress, index, enabled, isLatestVersion, outputAsString]);
|
|
910
|
+
if (!isLatestVersion) {
|
|
911
|
+
return {
|
|
912
|
+
data: historicalData,
|
|
913
|
+
isLoading: historicalLoading,
|
|
914
|
+
error: historicalError
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
if (shouldUseRouter) {
|
|
918
|
+
return {
|
|
919
|
+
data: routerData,
|
|
920
|
+
isLoading: routerHook.isLoading || routerChunkLoading,
|
|
921
|
+
error: routerHook.error || routerChunkError
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
const formattedDirectData = latestData ? formatData(latestData[0], latestData[1]) : void 0;
|
|
925
|
+
return {
|
|
926
|
+
data: formattedDirectData,
|
|
927
|
+
isLoading: latestLoading,
|
|
928
|
+
error: latestError
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
function useStorageForOperator({
|
|
932
|
+
chainId,
|
|
933
|
+
operatorAddress
|
|
934
|
+
}) {
|
|
935
|
+
const netContract = core.getNetContract(chainId);
|
|
936
|
+
const { data: totalCount, isLoading: isLoadingCount } = wagmi.useReadContract({
|
|
937
|
+
abi: netContract.abi,
|
|
938
|
+
address: netContract.address,
|
|
939
|
+
functionName: "getTotalMessagesForAppUserCount",
|
|
940
|
+
args: [STORAGE_CONTRACT.address, operatorAddress],
|
|
941
|
+
chainId
|
|
942
|
+
});
|
|
943
|
+
const totalCountNumber = totalCount ? Number(totalCount) : 0;
|
|
944
|
+
const { data: messages, isLoading: isLoadingMessages } = wagmi.useReadContract({
|
|
945
|
+
abi: netContract.abi,
|
|
946
|
+
address: netContract.address,
|
|
947
|
+
functionName: "getMessagesInRangeForAppUser",
|
|
948
|
+
args: [0, totalCountNumber, STORAGE_CONTRACT.address, operatorAddress],
|
|
949
|
+
chainId
|
|
950
|
+
});
|
|
951
|
+
return {
|
|
952
|
+
data: messages?.map((msg) => [
|
|
953
|
+
msg.topic,
|
|
954
|
+
msg.text,
|
|
955
|
+
Number(msg.timestamp),
|
|
956
|
+
msg.data
|
|
957
|
+
]) || [],
|
|
958
|
+
isLoading: isLoadingCount || isLoadingMessages,
|
|
959
|
+
error: void 0
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function useStorageForOperatorAndKey({
|
|
963
|
+
chainId,
|
|
964
|
+
key,
|
|
965
|
+
operatorAddress,
|
|
966
|
+
keyFormat
|
|
967
|
+
}) {
|
|
968
|
+
const storageKeyBytes = key ? getStorageKeyBytes(key, keyFormat) : void 0;
|
|
969
|
+
const readContractArgs = {
|
|
970
|
+
abi: STORAGE_CONTRACT.abi,
|
|
971
|
+
address: STORAGE_CONTRACT.address,
|
|
972
|
+
functionName: "getForOperatorAndKey",
|
|
973
|
+
args: storageKeyBytes ? [operatorAddress, storageKeyBytes] : void 0,
|
|
974
|
+
chainId,
|
|
975
|
+
query: {
|
|
976
|
+
enabled: !!key && !!operatorAddress
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
const { data, isLoading, error } = wagmi.useReadContract(readContractArgs);
|
|
980
|
+
return {
|
|
981
|
+
data,
|
|
982
|
+
isLoading,
|
|
983
|
+
error
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function useBulkStorage({
|
|
987
|
+
chainId,
|
|
988
|
+
keys,
|
|
989
|
+
safe = false,
|
|
990
|
+
keyFormat
|
|
991
|
+
}) {
|
|
992
|
+
const contract = safe ? SAFE_STORAGE_READER_CONTRACT : STORAGE_CONTRACT;
|
|
993
|
+
const bulkKeys = keys.map((k) => ({
|
|
994
|
+
key: getStorageKeyBytes(k.key, keyFormat),
|
|
995
|
+
operator: k.operator
|
|
996
|
+
}));
|
|
997
|
+
const readContractArgs = {
|
|
998
|
+
abi: contract.abi,
|
|
999
|
+
address: contract.address,
|
|
1000
|
+
functionName: "bulkGet",
|
|
1001
|
+
args: [bulkKeys],
|
|
1002
|
+
chainId
|
|
1003
|
+
};
|
|
1004
|
+
const { data, isLoading, error } = wagmi.useReadContract(readContractArgs);
|
|
1005
|
+
return {
|
|
1006
|
+
data,
|
|
1007
|
+
isLoading,
|
|
1008
|
+
error
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
function useStorageTotalWrites({
|
|
1012
|
+
chainId,
|
|
1013
|
+
key,
|
|
1014
|
+
operatorAddress,
|
|
1015
|
+
enabled = true,
|
|
1016
|
+
keyFormat
|
|
1017
|
+
}) {
|
|
1018
|
+
const storageKeyBytes = key ? getStorageKeyBytes(key, keyFormat) : void 0;
|
|
1019
|
+
const {
|
|
1020
|
+
data: chunkedTotal,
|
|
1021
|
+
isLoading: chunkedLoading,
|
|
1022
|
+
error: chunkedError
|
|
1023
|
+
} = wagmi.useReadContract({
|
|
1024
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
1025
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
1026
|
+
functionName: "getTotalWrites",
|
|
1027
|
+
args: storageKeyBytes && operatorAddress ? [storageKeyBytes, operatorAddress] : void 0,
|
|
1028
|
+
chainId,
|
|
1029
|
+
query: {
|
|
1030
|
+
enabled: enabled && !!key && !!operatorAddress
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
const {
|
|
1034
|
+
data: regularTotal,
|
|
1035
|
+
isLoading: regularLoading,
|
|
1036
|
+
error: regularError
|
|
1037
|
+
} = wagmi.useReadContract({
|
|
1038
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1039
|
+
address: STORAGE_CONTRACT.address,
|
|
1040
|
+
functionName: "getTotalWrites",
|
|
1041
|
+
args: storageKeyBytes && operatorAddress ? [storageKeyBytes, operatorAddress] : void 0,
|
|
1042
|
+
chainId,
|
|
1043
|
+
query: {
|
|
1044
|
+
enabled: enabled && !!key && !!operatorAddress && (chunkedTotal === void 0 || Number(chunkedTotal) === 0)
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1047
|
+
const chunkedTotalNumber = chunkedTotal ? Number(chunkedTotal) : 0;
|
|
1048
|
+
const regularTotalNumber = regularTotal ? Number(regularTotal) : 0;
|
|
1049
|
+
const totalWrites = chunkedTotalNumber > 0 ? chunkedTotalNumber : regularTotalNumber;
|
|
1050
|
+
return {
|
|
1051
|
+
data: totalWrites > 0 ? totalWrites : void 0,
|
|
1052
|
+
isLoading: chunkedLoading || regularLoading,
|
|
1053
|
+
error: chunkedTotalNumber === 0 && regularTotalNumber === 0 ? chunkedError || regularError : void 0
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
var MAX_XML_DEPTH = 3;
|
|
1057
|
+
var CONCURRENT_XML_FETCHES = 3;
|
|
1058
|
+
function assembleXmlData(metadata, chunks, references) {
|
|
1059
|
+
let result = metadata;
|
|
1060
|
+
references.forEach((ref, index) => {
|
|
1061
|
+
const chunkData2 = chunks[index];
|
|
1062
|
+
if (chunkData2) {
|
|
1063
|
+
const indexAttr = ref.index !== void 0 ? ` i="${ref.index}"` : "";
|
|
1064
|
+
const operatorAttr = ref.operator ? ` o="${ref.operator}"` : "";
|
|
1065
|
+
const sourceAttr = ref.source ? ` s="${ref.source}"` : "";
|
|
1066
|
+
const xmlTag = `<net k="${ref.hash}" v="${ref.version}"${indexAttr}${operatorAttr}${sourceAttr} />`;
|
|
1067
|
+
result = result.replace(xmlTag, chunkData2);
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
return result;
|
|
1071
|
+
}
|
|
1072
|
+
async function fetchFromDirectStorage(reference, operator, client) {
|
|
1073
|
+
const functionName = reference.index !== void 0 ? "getValueAtIndex" : "get";
|
|
1074
|
+
const args = reference.index !== void 0 ? [reference.hash, operator, reference.index] : [reference.hash, operator];
|
|
1075
|
+
const result = await actions.readContract(client, {
|
|
1076
|
+
address: STORAGE_CONTRACT.address,
|
|
1077
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1078
|
+
functionName,
|
|
1079
|
+
args
|
|
1080
|
+
});
|
|
1081
|
+
const content = viem.hexToString(result[1] || "");
|
|
1082
|
+
return content;
|
|
1083
|
+
}
|
|
1084
|
+
async function fetchFromChunkedStorage(reference, operator, client) {
|
|
1085
|
+
const contract = CHUNKED_STORAGE_READER_CONTRACT;
|
|
1086
|
+
const functionName = reference.index !== void 0 ? "getMetadataAtIndex" : "getMetadata";
|
|
1087
|
+
const chunksFunctionName = reference.index !== void 0 ? "getChunksAtIndex" : "getChunks";
|
|
1088
|
+
const metadataArgs = reference.index !== void 0 ? [reference.hash, operator, reference.index] : [reference.hash, operator];
|
|
1089
|
+
const metadata = await actions.readContract(client, {
|
|
1090
|
+
abi: contract.abi,
|
|
1091
|
+
address: contract.address,
|
|
1092
|
+
functionName,
|
|
1093
|
+
args: metadataArgs
|
|
1094
|
+
});
|
|
1095
|
+
const chunkCount = metadata[0];
|
|
1096
|
+
if (chunkCount === 0) return "";
|
|
1097
|
+
const chunksArgs = reference.index !== void 0 ? [reference.hash, operator, 0, chunkCount, reference.index] : [reference.hash, operator, 0, chunkCount];
|
|
1098
|
+
const chunks = await actions.readContract(client, {
|
|
1099
|
+
abi: contract.abi,
|
|
1100
|
+
address: contract.address,
|
|
1101
|
+
functionName: chunksFunctionName,
|
|
1102
|
+
args: chunksArgs
|
|
1103
|
+
});
|
|
1104
|
+
const assembledResult = assembleChunks(chunks);
|
|
1105
|
+
const content = assembledResult || "";
|
|
1106
|
+
return content;
|
|
1107
|
+
}
|
|
1108
|
+
async function fetchSingleChunk(reference, defaultOperator, inheritedOperator, client) {
|
|
1109
|
+
const effectiveOperator = reference.operator || inheritedOperator || defaultOperator;
|
|
1110
|
+
if (reference.source === "d") {
|
|
1111
|
+
return await fetchFromDirectStorage(reference, effectiveOperator, client);
|
|
1112
|
+
} else {
|
|
1113
|
+
return await fetchFromChunkedStorage(reference, effectiveOperator, client);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
async function resolveXmlRecursive(content, defaultOperator, client, maxDepth, visited = /* @__PURE__ */ new Set(), inheritedOperator) {
|
|
1117
|
+
if (maxDepth <= 0) {
|
|
1118
|
+
return content;
|
|
1119
|
+
}
|
|
1120
|
+
if (!containsXmlReferences(content)) {
|
|
1121
|
+
return content;
|
|
1122
|
+
}
|
|
1123
|
+
const references = parseNetReferences(content);
|
|
1124
|
+
if (references.length === 0) {
|
|
1125
|
+
return content;
|
|
1126
|
+
}
|
|
1127
|
+
const resolvedChunks = [];
|
|
1128
|
+
for (let batchStart = 0; batchStart < references.length; batchStart += CONCURRENT_XML_FETCHES) {
|
|
1129
|
+
const batchEnd = Math.min(
|
|
1130
|
+
batchStart + CONCURRENT_XML_FETCHES,
|
|
1131
|
+
references.length
|
|
1132
|
+
);
|
|
1133
|
+
const batch = references.slice(batchStart, batchEnd);
|
|
1134
|
+
const batchResults = await Promise.all(
|
|
1135
|
+
batch.map(async (ref, batchIndex) => {
|
|
1136
|
+
const index = batchStart + batchIndex;
|
|
1137
|
+
const effectiveOperator = ref.operator || inheritedOperator || defaultOperator;
|
|
1138
|
+
const refKey = getReferenceKey(
|
|
1139
|
+
{ ...ref, operator: effectiveOperator },
|
|
1140
|
+
defaultOperator
|
|
1141
|
+
);
|
|
1142
|
+
if (visited.has(refKey)) {
|
|
1143
|
+
console.warn(
|
|
1144
|
+
`[resolveXmlRecursive] Circular reference detected: ${refKey}`
|
|
1145
|
+
);
|
|
1146
|
+
return `[Circular: ${refKey}]`;
|
|
1147
|
+
}
|
|
1148
|
+
const newVisited = new Set(visited);
|
|
1149
|
+
newVisited.add(refKey);
|
|
1150
|
+
try {
|
|
1151
|
+
const chunkContent = await fetchSingleChunk(
|
|
1152
|
+
ref,
|
|
1153
|
+
defaultOperator,
|
|
1154
|
+
inheritedOperator,
|
|
1155
|
+
client
|
|
1156
|
+
);
|
|
1157
|
+
const resolvedContent = await resolveXmlRecursive(
|
|
1158
|
+
chunkContent,
|
|
1159
|
+
defaultOperator,
|
|
1160
|
+
client,
|
|
1161
|
+
maxDepth - 1,
|
|
1162
|
+
newVisited,
|
|
1163
|
+
effectiveOperator
|
|
1164
|
+
// Pass the effective operator to children
|
|
1165
|
+
);
|
|
1166
|
+
return resolvedContent;
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
console.error(
|
|
1169
|
+
`[resolveXmlRecursive] Failed to fetch/resolve chunk ${index}:`,
|
|
1170
|
+
error
|
|
1171
|
+
);
|
|
1172
|
+
return "";
|
|
1173
|
+
}
|
|
1174
|
+
})
|
|
1175
|
+
);
|
|
1176
|
+
resolvedChunks.push(...batchResults);
|
|
1177
|
+
}
|
|
1178
|
+
const assembled = assembleXmlData(content, resolvedChunks, references);
|
|
1179
|
+
return assembled;
|
|
1180
|
+
}
|
|
1181
|
+
function useXmlStorage({
|
|
1182
|
+
chainId,
|
|
1183
|
+
key,
|
|
1184
|
+
operatorAddress,
|
|
1185
|
+
skipXmlParsing = false,
|
|
1186
|
+
enabled = true,
|
|
1187
|
+
content,
|
|
1188
|
+
index,
|
|
1189
|
+
keyFormat,
|
|
1190
|
+
useRouter,
|
|
1191
|
+
returnFormat = "object",
|
|
1192
|
+
outputFormat = "hex"
|
|
1193
|
+
}) {
|
|
1194
|
+
const isPreviewMode = !!content;
|
|
1195
|
+
const returnAsTuple = returnFormat === "tuple";
|
|
1196
|
+
const outputAsString = outputFormat === "string";
|
|
1197
|
+
const {
|
|
1198
|
+
data: metadata,
|
|
1199
|
+
isLoading: metadataLoading,
|
|
1200
|
+
error: metadataError
|
|
1201
|
+
} = useStorage({
|
|
1202
|
+
chainId,
|
|
1203
|
+
key: key || "",
|
|
1204
|
+
operatorAddress,
|
|
1205
|
+
enabled: enabled && !isPreviewMode,
|
|
1206
|
+
index,
|
|
1207
|
+
// Pass index to useStorage for historical versions
|
|
1208
|
+
keyFormat,
|
|
1209
|
+
// Pass keyFormat through
|
|
1210
|
+
useRouter,
|
|
1211
|
+
// Pass useRouter through to enable router path
|
|
1212
|
+
outputFormat: "string"
|
|
1213
|
+
// Always get plain string from useStorage, then convert based on our outputFormat
|
|
1214
|
+
});
|
|
1215
|
+
const metadataString = react.useMemo(() => {
|
|
1216
|
+
if (skipXmlParsing) return "";
|
|
1217
|
+
if (isPreviewMode) return content || "";
|
|
1218
|
+
if (!metadata?.[1]) return "";
|
|
1219
|
+
return metadata[1];
|
|
1220
|
+
}, [skipXmlParsing, isPreviewMode, content, metadata]);
|
|
1221
|
+
react.useMemo(() => {
|
|
1222
|
+
if (!metadataString) return [];
|
|
1223
|
+
return parseNetReferences(metadataString);
|
|
1224
|
+
}, [metadataString]);
|
|
1225
|
+
const [chunks, setChunks] = react.useState([]);
|
|
1226
|
+
const [chunksLoading, setChunksLoading] = react.useState(false);
|
|
1227
|
+
const [chunksError, setChunksError] = react.useState();
|
|
1228
|
+
useAsyncEffect__default.default(async () => {
|
|
1229
|
+
if (skipXmlParsing || !metadataString) {
|
|
1230
|
+
setChunks([]);
|
|
1231
|
+
setChunksLoading(false);
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (!containsXmlReferences(metadataString)) {
|
|
1235
|
+
setChunks([]);
|
|
1236
|
+
setChunksLoading(false);
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
setChunksLoading(true);
|
|
1240
|
+
setChunksError(void 0);
|
|
1241
|
+
try {
|
|
1242
|
+
const client = core.getPublicClient({ chainId });
|
|
1243
|
+
if (!client) {
|
|
1244
|
+
throw new Error(`Chain not found for chainId: ${chainId}`);
|
|
1245
|
+
}
|
|
1246
|
+
const resolved = await resolveXmlRecursive(
|
|
1247
|
+
metadataString,
|
|
1248
|
+
operatorAddress,
|
|
1249
|
+
client,
|
|
1250
|
+
MAX_XML_DEPTH,
|
|
1251
|
+
/* @__PURE__ */ new Set()
|
|
1252
|
+
);
|
|
1253
|
+
setChunks([resolved]);
|
|
1254
|
+
} catch (error) {
|
|
1255
|
+
console.error("[useXmlStorage] Error in recursive resolution:", error);
|
|
1256
|
+
setChunksError(error);
|
|
1257
|
+
setChunks([]);
|
|
1258
|
+
} finally {
|
|
1259
|
+
setChunksLoading(false);
|
|
1260
|
+
}
|
|
1261
|
+
}, [metadataString, operatorAddress, chainId, skipXmlParsing]);
|
|
1262
|
+
const assembledData = react.useMemo(() => {
|
|
1263
|
+
if (skipXmlParsing || !metadataString || !chunks.length) return void 0;
|
|
1264
|
+
return chunks[0];
|
|
1265
|
+
}, [metadataString, chunks, skipXmlParsing]);
|
|
1266
|
+
const isXml = react.useMemo(() => {
|
|
1267
|
+
if (skipXmlParsing || !metadataString) return false;
|
|
1268
|
+
return containsXmlReferences(metadataString);
|
|
1269
|
+
}, [metadataString, skipXmlParsing]);
|
|
1270
|
+
if (returnAsTuple) {
|
|
1271
|
+
if (skipXmlParsing) {
|
|
1272
|
+
if (isPreviewMode) {
|
|
1273
|
+
const contentValue = content || "";
|
|
1274
|
+
return {
|
|
1275
|
+
data: contentValue ? outputAsString ? [metadata?.[0] || "", contentValue] : [
|
|
1276
|
+
metadata?.[0] || "",
|
|
1277
|
+
viem.stringToHex(contentValue)
|
|
1278
|
+
] : void 0,
|
|
1279
|
+
isLoading: metadataLoading,
|
|
1280
|
+
error: metadataError
|
|
1281
|
+
};
|
|
1282
|
+
} else {
|
|
1283
|
+
const dataValue = metadata?.[1];
|
|
1284
|
+
return {
|
|
1285
|
+
data: dataValue ? outputAsString ? [metadata?.[0] || "", dataValue] : [
|
|
1286
|
+
metadata?.[0] || "",
|
|
1287
|
+
viem.stringToHex(dataValue)
|
|
1288
|
+
] : void 0,
|
|
1289
|
+
isLoading: metadataLoading,
|
|
1290
|
+
error: metadataError
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (isXml) {
|
|
1295
|
+
if (!assembledData) {
|
|
1296
|
+
return {
|
|
1297
|
+
data: void 0,
|
|
1298
|
+
isLoading: metadataLoading || chunksLoading,
|
|
1299
|
+
error: metadataError || chunksError
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
const hexData = viem.stringToHex(assembledData);
|
|
1303
|
+
return {
|
|
1304
|
+
data: outputAsString ? [metadata?.[0] || "", assembledData] : [metadata?.[0] || "", hexData],
|
|
1305
|
+
isLoading: metadataLoading || chunksLoading,
|
|
1306
|
+
error: metadataError || chunksError
|
|
1307
|
+
};
|
|
1308
|
+
} else {
|
|
1309
|
+
if (!metadata) {
|
|
1310
|
+
return {
|
|
1311
|
+
data: void 0,
|
|
1312
|
+
isLoading: metadataLoading,
|
|
1313
|
+
error: metadataError
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
const dataValue = metadata[1];
|
|
1317
|
+
const returnValue = dataValue ? outputAsString ? [metadata[0], dataValue] : [
|
|
1318
|
+
metadata[0],
|
|
1319
|
+
viem.stringToHex(dataValue)
|
|
1320
|
+
] : void 0;
|
|
1321
|
+
return {
|
|
1322
|
+
data: returnValue,
|
|
1323
|
+
isLoading: metadataLoading,
|
|
1324
|
+
error: metadataError
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
if (skipXmlParsing) {
|
|
1329
|
+
return {
|
|
1330
|
+
data: isPreviewMode ? content || "" : metadata?.[1] || "",
|
|
1331
|
+
// metadata[1] is already a plain string
|
|
1332
|
+
filename: metadata?.[0] || "",
|
|
1333
|
+
isLoading: metadataLoading,
|
|
1334
|
+
error: metadataError,
|
|
1335
|
+
isXml: false
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
return {
|
|
1339
|
+
data: isXml ? assembledData : isPreviewMode ? content || "" : metadata?.[1] || "",
|
|
1340
|
+
// metadata[1] is already a plain string
|
|
1341
|
+
filename: metadata?.[0] || "",
|
|
1342
|
+
isLoading: metadataLoading || isXml && chunksLoading,
|
|
1343
|
+
error: metadataError || chunksError,
|
|
1344
|
+
isXml
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
var BATCH_SIZE2 = 2;
|
|
1348
|
+
function useStorageFromRouter({
|
|
1349
|
+
chainId,
|
|
1350
|
+
storageKey,
|
|
1351
|
+
operatorAddress,
|
|
1352
|
+
enabled = true
|
|
1353
|
+
}) {
|
|
1354
|
+
const [assembledData, setAssembledData] = react.useState();
|
|
1355
|
+
const [isChunkLoading, setIsChunkLoading] = react.useState(false);
|
|
1356
|
+
const [chunkError, setChunkError] = react.useState();
|
|
1357
|
+
const {
|
|
1358
|
+
data: routerResult,
|
|
1359
|
+
isLoading: routerLoading,
|
|
1360
|
+
error: routerError
|
|
1361
|
+
} = wagmi.useReadContract({
|
|
1362
|
+
abi: STORAGE_ROUTER_CONTRACT.abi,
|
|
1363
|
+
address: STORAGE_ROUTER_CONTRACT.address,
|
|
1364
|
+
functionName: "get",
|
|
1365
|
+
args: [storageKey, operatorAddress],
|
|
1366
|
+
chainId,
|
|
1367
|
+
query: {
|
|
1368
|
+
enabled: enabled && !!operatorAddress
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
react.useEffect(() => {
|
|
1372
|
+
async function processResult() {
|
|
1373
|
+
if (!routerResult || routerLoading || routerError) {
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
const [isChunkedStorage, text, data] = routerResult;
|
|
1377
|
+
if (!isChunkedStorage) {
|
|
1378
|
+
setAssembledData([text, data]);
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
setIsChunkLoading(true);
|
|
1382
|
+
setChunkError(void 0);
|
|
1383
|
+
try {
|
|
1384
|
+
const [chunkCount] = viem.decodeAbiParameters(
|
|
1385
|
+
[{ type: "uint8" }],
|
|
1386
|
+
data
|
|
1387
|
+
);
|
|
1388
|
+
if (chunkCount === 0) {
|
|
1389
|
+
setAssembledData(void 0);
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
const allChunks = await fetchChunksInBatches(
|
|
1393
|
+
Number(chunkCount),
|
|
1394
|
+
operatorAddress,
|
|
1395
|
+
chainId,
|
|
1396
|
+
storageKey
|
|
1397
|
+
);
|
|
1398
|
+
const assembledString = assembleChunks(allChunks);
|
|
1399
|
+
if (assembledString === void 0) {
|
|
1400
|
+
setAssembledData(void 0);
|
|
1401
|
+
} else {
|
|
1402
|
+
const hexData = viem.stringToHex(assembledString);
|
|
1403
|
+
setAssembledData([text, hexData]);
|
|
1404
|
+
}
|
|
1405
|
+
} catch (error) {
|
|
1406
|
+
setChunkError(error);
|
|
1407
|
+
} finally {
|
|
1408
|
+
setIsChunkLoading(false);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
processResult();
|
|
1412
|
+
}, [
|
|
1413
|
+
routerResult,
|
|
1414
|
+
routerLoading,
|
|
1415
|
+
routerError,
|
|
1416
|
+
operatorAddress,
|
|
1417
|
+
chainId,
|
|
1418
|
+
storageKey
|
|
1419
|
+
]);
|
|
1420
|
+
return {
|
|
1421
|
+
data: assembledData,
|
|
1422
|
+
isLoading: routerLoading || isChunkLoading,
|
|
1423
|
+
error: routerError || chunkError
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
async function fetchChunksInBatches(chunkCount, operatorAddress, chainId, storageKey) {
|
|
1427
|
+
const client = core.getPublicClient({ chainId });
|
|
1428
|
+
if (!client) {
|
|
1429
|
+
throw new Error(`Chain not found for chainId: ${chainId}`);
|
|
1430
|
+
}
|
|
1431
|
+
const allChunks = [];
|
|
1432
|
+
for (let start = 0; start < chunkCount; start += BATCH_SIZE2) {
|
|
1433
|
+
const end = Math.min(start + BATCH_SIZE2, chunkCount);
|
|
1434
|
+
const batch = await actions.readContract(client, {
|
|
1435
|
+
abi: CHUNKED_STORAGE_CONTRACT.abi,
|
|
1436
|
+
address: CHUNKED_STORAGE_CONTRACT.address,
|
|
1437
|
+
functionName: "getChunks",
|
|
1438
|
+
args: [storageKey, operatorAddress, start, end]
|
|
1439
|
+
});
|
|
1440
|
+
allChunks.push(...batch);
|
|
1441
|
+
}
|
|
1442
|
+
return allChunks;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// src/client/storage.ts
|
|
1446
|
+
function getStorageReadConfig(params) {
|
|
1447
|
+
const { chainId, key, operator, keyFormat } = params;
|
|
1448
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1449
|
+
return {
|
|
1450
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1451
|
+
address: STORAGE_CONTRACT.address,
|
|
1452
|
+
functionName: "get",
|
|
1453
|
+
args: [storageKeyBytes, operator],
|
|
1454
|
+
chainId
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
function getStorageValueAtIndexReadConfig(params) {
|
|
1458
|
+
const { chainId, key, operator, index, keyFormat } = params;
|
|
1459
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1460
|
+
return {
|
|
1461
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1462
|
+
address: STORAGE_CONTRACT.address,
|
|
1463
|
+
functionName: "getValueAtIndex",
|
|
1464
|
+
args: [storageKeyBytes, operator, index],
|
|
1465
|
+
chainId
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
function getStorageTotalWritesReadConfig(params) {
|
|
1469
|
+
const { chainId, key, operator, keyFormat } = params;
|
|
1470
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1471
|
+
return {
|
|
1472
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1473
|
+
address: STORAGE_CONTRACT.address,
|
|
1474
|
+
functionName: "getTotalWrites",
|
|
1475
|
+
args: [storageKeyBytes, operator],
|
|
1476
|
+
chainId
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
function getStorageBulkGetReadConfig(params) {
|
|
1480
|
+
const { chainId, keys, safe = false, keyFormat } = params;
|
|
1481
|
+
const contract = safe ? SAFE_STORAGE_READER_CONTRACT : STORAGE_CONTRACT;
|
|
1482
|
+
const bulkKeys = keys.map((k) => ({
|
|
1483
|
+
key: getStorageKeyBytes(k.key, k.keyFormat ?? keyFormat),
|
|
1484
|
+
operator: k.operator
|
|
1485
|
+
}));
|
|
1486
|
+
return {
|
|
1487
|
+
abi: contract.abi,
|
|
1488
|
+
address: contract.address,
|
|
1489
|
+
functionName: "bulkGet",
|
|
1490
|
+
args: [bulkKeys],
|
|
1491
|
+
chainId
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
function getStorageRouterReadConfig(params) {
|
|
1495
|
+
const { chainId, key, operator, keyFormat } = params;
|
|
1496
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1497
|
+
return {
|
|
1498
|
+
abi: STORAGE_ROUTER_CONTRACT.abi,
|
|
1499
|
+
address: STORAGE_ROUTER_CONTRACT.address,
|
|
1500
|
+
functionName: "get",
|
|
1501
|
+
args: [storageKeyBytes, operator],
|
|
1502
|
+
chainId
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// src/client/chunkedStorage.ts
|
|
1507
|
+
function getChunkedStorageMetadataReadConfig(params) {
|
|
1508
|
+
const { chainId, key, operator, index, keyFormat } = params;
|
|
1509
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1510
|
+
const functionName = index !== void 0 ? "getMetadataAtIndex" : "getMetadata";
|
|
1511
|
+
const args = index !== void 0 ? [storageKeyBytes, operator, index] : [storageKeyBytes, operator];
|
|
1512
|
+
return {
|
|
1513
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
1514
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
1515
|
+
functionName,
|
|
1516
|
+
args,
|
|
1517
|
+
chainId
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
function getChunkedStorageChunksReadConfig(params) {
|
|
1521
|
+
const { chainId, key, operator, start, end, index, keyFormat } = params;
|
|
1522
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1523
|
+
const functionName = index !== void 0 ? "getChunksAtIndex" : "getChunks";
|
|
1524
|
+
const args = index !== void 0 ? [storageKeyBytes, operator, start, end, index] : [storageKeyBytes, operator, start, end];
|
|
1525
|
+
return {
|
|
1526
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
1527
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
1528
|
+
functionName,
|
|
1529
|
+
args,
|
|
1530
|
+
chainId
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
function getChunkedStorageTotalWritesReadConfig(params) {
|
|
1534
|
+
const { chainId, key, operator, keyFormat } = params;
|
|
1535
|
+
const storageKeyBytes = getStorageKeyBytes(key, keyFormat);
|
|
1536
|
+
return {
|
|
1537
|
+
abi: CHUNKED_STORAGE_READER_CONTRACT.abi,
|
|
1538
|
+
address: CHUNKED_STORAGE_READER_CONTRACT.address,
|
|
1539
|
+
functionName: "getTotalWrites",
|
|
1540
|
+
args: [storageKeyBytes, operator],
|
|
1541
|
+
chainId
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
var MAX_CHUNKS = 255;
|
|
1545
|
+
var OPTIMAL_CHUNK_SIZE = 80 * 1e3;
|
|
1546
|
+
function chunkData(data, chunkSize = OPTIMAL_CHUNK_SIZE) {
|
|
1547
|
+
const chunks = [];
|
|
1548
|
+
for (let i = 0; i < data.length; i += chunkSize) {
|
|
1549
|
+
chunks.push(data.slice(i, i + chunkSize));
|
|
1550
|
+
}
|
|
1551
|
+
return chunks;
|
|
1552
|
+
}
|
|
1553
|
+
function generateXmlMetadata(chunkHashes, historicalIndex, operatorAddress) {
|
|
1554
|
+
return chunkHashes.map((hash) => {
|
|
1555
|
+
const operator = operatorAddress.toLowerCase();
|
|
1556
|
+
return `<net k="${hash}" v="0.0.1" i="${historicalIndex}" o="${operator}" />`;
|
|
1557
|
+
}).join("");
|
|
1558
|
+
}
|
|
1559
|
+
function generateXmlMetadataWithSource(chunkHashes, historicalIndex, operatorAddress, source) {
|
|
1560
|
+
return chunkHashes.map((hash) => {
|
|
1561
|
+
const operator = operatorAddress.toLowerCase();
|
|
1562
|
+
const sourceAttr = source ? ` s="${source}"` : "";
|
|
1563
|
+
return `<net k="${hash}" v="0.0.1" i="${historicalIndex}" o="${operator}"${sourceAttr} />`;
|
|
1564
|
+
}).join("");
|
|
1565
|
+
}
|
|
1566
|
+
function validateDataSize(chunks) {
|
|
1567
|
+
if (chunks.length === 0) {
|
|
1568
|
+
return { valid: false, error: "No chunks generated" };
|
|
1569
|
+
}
|
|
1570
|
+
if (chunks.length > MAX_CHUNKS) {
|
|
1571
|
+
return {
|
|
1572
|
+
valid: false,
|
|
1573
|
+
error: `Too many chunks: ${chunks.length} exceeds maximum of ${MAX_CHUNKS}`
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
return { valid: true };
|
|
1577
|
+
}
|
|
1578
|
+
function computeTopLevelHash(chunkHashes) {
|
|
1579
|
+
return core.keccak256HashString(chunkHashes.join(""));
|
|
1580
|
+
}
|
|
1581
|
+
function processDataForStorage(data, operatorAddress, storageKey) {
|
|
1582
|
+
const chunks = chunkData(data);
|
|
1583
|
+
const validation = validateDataSize(chunks);
|
|
1584
|
+
if (!validation.valid) {
|
|
1585
|
+
return {
|
|
1586
|
+
chunks: [],
|
|
1587
|
+
chunkHashes: [],
|
|
1588
|
+
xmlMetadata: "",
|
|
1589
|
+
topLevelHash: "",
|
|
1590
|
+
valid: false,
|
|
1591
|
+
error: validation.error
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
const chunkHashes = chunks.map((chunk) => core.keccak256HashString(chunk));
|
|
1595
|
+
const xmlMetadata = generateXmlMetadata(chunkHashes, 0, operatorAddress);
|
|
1596
|
+
const topLevelHash = storageKey || computeTopLevelHash(chunkHashes);
|
|
1597
|
+
return {
|
|
1598
|
+
chunks,
|
|
1599
|
+
chunkHashes,
|
|
1600
|
+
xmlMetadata,
|
|
1601
|
+
topLevelHash,
|
|
1602
|
+
valid: true
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
// src/client/StorageClient.ts
|
|
1607
|
+
var StorageClient = class {
|
|
1608
|
+
constructor(params) {
|
|
1609
|
+
this.client = core.getPublicClient({
|
|
1610
|
+
chainId: params.chainId,
|
|
1611
|
+
rpcUrl: params.overrides?.rpcUrls
|
|
1612
|
+
});
|
|
1613
|
+
this.chainId = params.chainId;
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Get storage value for a key and operator (latest version)
|
|
1617
|
+
*/
|
|
1618
|
+
async get(params) {
|
|
1619
|
+
const config = getStorageReadConfig({
|
|
1620
|
+
chainId: this.chainId,
|
|
1621
|
+
key: params.key,
|
|
1622
|
+
operator: params.operator,
|
|
1623
|
+
keyFormat: params.keyFormat
|
|
1624
|
+
});
|
|
1625
|
+
try {
|
|
1626
|
+
const result = await actions.readContract(this.client, config);
|
|
1627
|
+
return result;
|
|
1628
|
+
} catch {
|
|
1629
|
+
return null;
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Get storage value at a specific historical index
|
|
1634
|
+
*/
|
|
1635
|
+
async getValueAtIndex(params) {
|
|
1636
|
+
const config = getStorageValueAtIndexReadConfig({
|
|
1637
|
+
chainId: this.chainId,
|
|
1638
|
+
key: params.key,
|
|
1639
|
+
operator: params.operator,
|
|
1640
|
+
index: params.index,
|
|
1641
|
+
keyFormat: params.keyFormat
|
|
1642
|
+
});
|
|
1643
|
+
try {
|
|
1644
|
+
const result = await actions.readContract(this.client, config);
|
|
1645
|
+
return result;
|
|
1646
|
+
} catch {
|
|
1647
|
+
return null;
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Get total number of writes (versions) for a key-operator pair
|
|
1652
|
+
* Tries ChunkedStorageReader first, then Storage
|
|
1653
|
+
*/
|
|
1654
|
+
async getTotalWrites(params) {
|
|
1655
|
+
try {
|
|
1656
|
+
const config = getChunkedStorageTotalWritesReadConfig({
|
|
1657
|
+
chainId: this.chainId,
|
|
1658
|
+
key: params.key,
|
|
1659
|
+
operator: params.operator,
|
|
1660
|
+
keyFormat: params.keyFormat
|
|
1661
|
+
});
|
|
1662
|
+
const count = await actions.readContract(this.client, config);
|
|
1663
|
+
return Number(count);
|
|
1664
|
+
} catch {
|
|
1665
|
+
try {
|
|
1666
|
+
const config = getStorageTotalWritesReadConfig({
|
|
1667
|
+
chainId: this.chainId,
|
|
1668
|
+
key: params.key,
|
|
1669
|
+
operator: params.operator,
|
|
1670
|
+
keyFormat: params.keyFormat
|
|
1671
|
+
});
|
|
1672
|
+
const count = await actions.readContract(this.client, config);
|
|
1673
|
+
return Number(count);
|
|
1674
|
+
} catch {
|
|
1675
|
+
return 0;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Bulk get storage values
|
|
1681
|
+
*/
|
|
1682
|
+
async bulkGet(params) {
|
|
1683
|
+
const config = getStorageBulkGetReadConfig({
|
|
1684
|
+
chainId: this.chainId,
|
|
1685
|
+
keys: params.keys,
|
|
1686
|
+
safe: params.safe,
|
|
1687
|
+
keyFormat: params.keyFormat
|
|
1688
|
+
});
|
|
1689
|
+
try {
|
|
1690
|
+
const results = await actions.readContract(this.client, config);
|
|
1691
|
+
return results.map((r) => ({
|
|
1692
|
+
text: r[0],
|
|
1693
|
+
value: r[1]
|
|
1694
|
+
}));
|
|
1695
|
+
} catch {
|
|
1696
|
+
return [];
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Get storage value via StorageRouter (latest version)
|
|
1701
|
+
* Returns data with storage type indication
|
|
1702
|
+
*/
|
|
1703
|
+
async getViaRouter(params) {
|
|
1704
|
+
const config = getStorageRouterReadConfig({
|
|
1705
|
+
chainId: this.chainId,
|
|
1706
|
+
key: params.key,
|
|
1707
|
+
operator: params.operator,
|
|
1708
|
+
keyFormat: params.keyFormat
|
|
1709
|
+
});
|
|
1710
|
+
try {
|
|
1711
|
+
const result = await actions.readContract(this.client, config);
|
|
1712
|
+
const [isChunkedStorage, text, data] = result;
|
|
1713
|
+
if (isChunkedStorage) {
|
|
1714
|
+
const [chunkCount] = viem.decodeAbiParameters([{ type: "uint8" }], data);
|
|
1715
|
+
if (chunkCount === 0) {
|
|
1716
|
+
return { isChunkedStorage: true, text, data: "" };
|
|
1717
|
+
}
|
|
1718
|
+
const chunks = await this.getChunked({
|
|
1719
|
+
key: params.key,
|
|
1720
|
+
operator: params.operator,
|
|
1721
|
+
start: 0,
|
|
1722
|
+
end: Number(chunkCount),
|
|
1723
|
+
keyFormat: params.keyFormat
|
|
1724
|
+
});
|
|
1725
|
+
const assembled = assembleChunks(chunks);
|
|
1726
|
+
return {
|
|
1727
|
+
isChunkedStorage: true,
|
|
1728
|
+
text,
|
|
1729
|
+
data: assembled || ""
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
return {
|
|
1733
|
+
isChunkedStorage: false,
|
|
1734
|
+
text,
|
|
1735
|
+
data: viem.hexToString(data)
|
|
1736
|
+
};
|
|
1737
|
+
} catch {
|
|
1738
|
+
return null;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
/**
|
|
1742
|
+
* Get chunked storage metadata
|
|
1743
|
+
*/
|
|
1744
|
+
async getChunkedMetadata(params) {
|
|
1745
|
+
const config = getChunkedStorageMetadataReadConfig({
|
|
1746
|
+
chainId: this.chainId,
|
|
1747
|
+
key: params.key,
|
|
1748
|
+
operator: params.operator,
|
|
1749
|
+
index: params.index,
|
|
1750
|
+
keyFormat: params.keyFormat
|
|
1751
|
+
});
|
|
1752
|
+
try {
|
|
1753
|
+
const result = await actions.readContract(this.client, config);
|
|
1754
|
+
const [chunkCount, originalText] = result;
|
|
1755
|
+
return { chunkCount, originalText };
|
|
1756
|
+
} catch {
|
|
1757
|
+
return null;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* Get chunked storage chunks
|
|
1762
|
+
*/
|
|
1763
|
+
async getChunked(params) {
|
|
1764
|
+
const config = getChunkedStorageChunksReadConfig({
|
|
1765
|
+
chainId: this.chainId,
|
|
1766
|
+
key: params.key,
|
|
1767
|
+
operator: params.operator,
|
|
1768
|
+
start: params.start,
|
|
1769
|
+
end: params.end,
|
|
1770
|
+
index: params.index,
|
|
1771
|
+
keyFormat: params.keyFormat
|
|
1772
|
+
});
|
|
1773
|
+
try {
|
|
1774
|
+
const chunks = await actions.readContract(this.client, config);
|
|
1775
|
+
return chunks;
|
|
1776
|
+
} catch {
|
|
1777
|
+
return [];
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Get chunked storage at a specific historical index
|
|
1782
|
+
*/
|
|
1783
|
+
async getChunkedAtIndex(params) {
|
|
1784
|
+
return this.getChunked({
|
|
1785
|
+
...params,
|
|
1786
|
+
index: params.index
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Get all storage keys for an operator using Net contract
|
|
1791
|
+
*/
|
|
1792
|
+
async getForOperator(params) {
|
|
1793
|
+
const netContract = core.getNetContract(this.chainId);
|
|
1794
|
+
const totalCount = await actions.readContract(this.client, {
|
|
1795
|
+
abi: netContract.abi,
|
|
1796
|
+
address: netContract.address,
|
|
1797
|
+
functionName: "getTotalMessagesForAppUserCount",
|
|
1798
|
+
args: [STORAGE_CONTRACT.address, params.operator]
|
|
1799
|
+
});
|
|
1800
|
+
const totalCountNumber = Number(totalCount);
|
|
1801
|
+
if (totalCountNumber === 0) {
|
|
1802
|
+
return [];
|
|
1803
|
+
}
|
|
1804
|
+
const messages = await actions.readContract(this.client, {
|
|
1805
|
+
abi: netContract.abi,
|
|
1806
|
+
address: netContract.address,
|
|
1807
|
+
functionName: "getMessagesInRangeForAppUser",
|
|
1808
|
+
args: [0, totalCountNumber, STORAGE_CONTRACT.address, params.operator]
|
|
1809
|
+
});
|
|
1810
|
+
return messages.map((msg) => [
|
|
1811
|
+
msg.topic,
|
|
1812
|
+
msg.text,
|
|
1813
|
+
Number(msg.timestamp),
|
|
1814
|
+
msg.data
|
|
1815
|
+
]);
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Get storage value for operator and key
|
|
1819
|
+
*/
|
|
1820
|
+
async getForOperatorAndKey(params) {
|
|
1821
|
+
const storageKeyBytes = getStorageKeyBytes(
|
|
1822
|
+
params.key,
|
|
1823
|
+
params.keyFormat
|
|
1824
|
+
);
|
|
1825
|
+
try {
|
|
1826
|
+
const result = await actions.readContract(this.client, {
|
|
1827
|
+
abi: STORAGE_CONTRACT.abi,
|
|
1828
|
+
address: STORAGE_CONTRACT.address,
|
|
1829
|
+
functionName: "getForOperatorAndKey",
|
|
1830
|
+
args: [params.operator, storageKeyBytes]
|
|
1831
|
+
});
|
|
1832
|
+
return result;
|
|
1833
|
+
} catch {
|
|
1834
|
+
return null;
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Read storage data with XML resolution
|
|
1839
|
+
*/
|
|
1840
|
+
async readStorageData(params) {
|
|
1841
|
+
let text;
|
|
1842
|
+
let data;
|
|
1843
|
+
if (params.index !== void 0) {
|
|
1844
|
+
const chunkedMeta = await this.getChunkedMetadata({
|
|
1845
|
+
key: params.key,
|
|
1846
|
+
operator: params.operator,
|
|
1847
|
+
index: params.index,
|
|
1848
|
+
keyFormat: params.keyFormat
|
|
1849
|
+
});
|
|
1850
|
+
if (chunkedMeta && chunkedMeta.chunkCount > 0) {
|
|
1851
|
+
text = chunkedMeta.originalText;
|
|
1852
|
+
const chunks = await this.getChunked({
|
|
1853
|
+
key: params.key,
|
|
1854
|
+
operator: params.operator,
|
|
1855
|
+
start: 0,
|
|
1856
|
+
end: chunkedMeta.chunkCount,
|
|
1857
|
+
index: params.index,
|
|
1858
|
+
keyFormat: params.keyFormat
|
|
1859
|
+
});
|
|
1860
|
+
const assembled = assembleChunks(chunks);
|
|
1861
|
+
data = assembled || "";
|
|
1862
|
+
} else {
|
|
1863
|
+
const result = await this.getValueAtIndex({
|
|
1864
|
+
key: params.key,
|
|
1865
|
+
operator: params.operator,
|
|
1866
|
+
index: params.index,
|
|
1867
|
+
keyFormat: params.keyFormat
|
|
1868
|
+
});
|
|
1869
|
+
if (!result) {
|
|
1870
|
+
throw new Error("StoredDataNotFound");
|
|
1871
|
+
}
|
|
1872
|
+
[text, data] = result;
|
|
1873
|
+
data = viem.hexToString(data);
|
|
1874
|
+
}
|
|
1875
|
+
} else {
|
|
1876
|
+
const result = await this.getViaRouter({
|
|
1877
|
+
key: params.key,
|
|
1878
|
+
operator: params.operator,
|
|
1879
|
+
keyFormat: params.keyFormat
|
|
1880
|
+
});
|
|
1881
|
+
if (!result) {
|
|
1882
|
+
throw new Error("StoredDataNotFound");
|
|
1883
|
+
}
|
|
1884
|
+
result.isChunkedStorage;
|
|
1885
|
+
text = result.text;
|
|
1886
|
+
data = result.data;
|
|
1887
|
+
}
|
|
1888
|
+
const isXml = containsXmlReferences(data);
|
|
1889
|
+
if (isXml) {
|
|
1890
|
+
const resolvedData = await resolveXmlRecursive(
|
|
1891
|
+
data,
|
|
1892
|
+
params.operator,
|
|
1893
|
+
this.client,
|
|
1894
|
+
3,
|
|
1895
|
+
// MAX_XML_DEPTH
|
|
1896
|
+
/* @__PURE__ */ new Set()
|
|
1897
|
+
);
|
|
1898
|
+
return { text, data: resolvedData, isXml: true };
|
|
1899
|
+
}
|
|
1900
|
+
return { text, data, isXml: false };
|
|
1901
|
+
}
|
|
1902
|
+
/**
|
|
1903
|
+
* Read chunked storage data with decompression
|
|
1904
|
+
*/
|
|
1905
|
+
async readChunkedStorage(params) {
|
|
1906
|
+
const metadata = await this.getChunkedMetadata({
|
|
1907
|
+
key: params.key,
|
|
1908
|
+
operator: params.operator,
|
|
1909
|
+
index: params.index,
|
|
1910
|
+
keyFormat: params.keyFormat
|
|
1911
|
+
});
|
|
1912
|
+
if (!metadata) {
|
|
1913
|
+
throw new Error("ChunkedStorage metadata not found");
|
|
1914
|
+
}
|
|
1915
|
+
if (metadata.chunkCount === 0) {
|
|
1916
|
+
return { text: metadata.originalText, data: "" };
|
|
1917
|
+
}
|
|
1918
|
+
const chunks = await this.getChunked({
|
|
1919
|
+
key: params.key,
|
|
1920
|
+
operator: params.operator,
|
|
1921
|
+
start: 0,
|
|
1922
|
+
end: metadata.chunkCount,
|
|
1923
|
+
index: params.index,
|
|
1924
|
+
keyFormat: params.keyFormat
|
|
1925
|
+
});
|
|
1926
|
+
const assembled = assembleChunks(chunks);
|
|
1927
|
+
return {
|
|
1928
|
+
text: metadata.originalText,
|
|
1929
|
+
data: assembled || ""
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Validate storage parameters
|
|
1934
|
+
*/
|
|
1935
|
+
validateStorageParams(params) {
|
|
1936
|
+
if (!params.key || typeof params.key === "string" && params.key.length === 0) {
|
|
1937
|
+
throw new Error("Storage key cannot be empty");
|
|
1938
|
+
}
|
|
1939
|
+
if (params.chunks && params.chunks.length === 0) {
|
|
1940
|
+
throw new Error("Chunks array cannot be empty");
|
|
1941
|
+
}
|
|
1942
|
+
if (params.chunks && params.chunks.length > 255) {
|
|
1943
|
+
throw new Error(`Too many chunks: ${params.chunks.length} exceeds maximum of 255`);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Prepare transaction configs for storing XML chunks in ChunkedStorage backend.
|
|
1948
|
+
* Each XML chunk is compressed and chunked into 20KB ChunkedStorage chunks.
|
|
1949
|
+
*/
|
|
1950
|
+
prepareXmlChunksForChunkedStorage(params) {
|
|
1951
|
+
const chunkedStorageHashes = [];
|
|
1952
|
+
const transactionConfigs = [];
|
|
1953
|
+
for (const xmlChunk of params.xmlChunks) {
|
|
1954
|
+
const chunks = chunkDataForStorage(xmlChunk);
|
|
1955
|
+
const chunkedHash = core.keccak256HashString(xmlChunk + params.operatorAddress);
|
|
1956
|
+
chunkedStorageHashes.push(chunkedHash);
|
|
1957
|
+
const config = this.prepareChunkedPut({
|
|
1958
|
+
key: chunkedHash,
|
|
1959
|
+
text: "",
|
|
1960
|
+
chunks
|
|
1961
|
+
});
|
|
1962
|
+
transactionConfigs.push(config);
|
|
1963
|
+
}
|
|
1964
|
+
const xmlMetadata = generateXmlMetadata(
|
|
1965
|
+
chunkedStorageHashes,
|
|
1966
|
+
0,
|
|
1967
|
+
params.operatorAddress
|
|
1968
|
+
);
|
|
1969
|
+
return {
|
|
1970
|
+
transactionConfigs,
|
|
1971
|
+
chunkedStorageHashes,
|
|
1972
|
+
xmlMetadata
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Prepare transaction config for storing a single value in Storage contract.
|
|
1977
|
+
*/
|
|
1978
|
+
preparePut(params) {
|
|
1979
|
+
this.validateStorageParams({ key: params.key });
|
|
1980
|
+
const keyBytes32 = getStorageKeyBytes(params.key, params.keyFormat);
|
|
1981
|
+
const valueHex = core.normalizeDataOrEmpty(params.value);
|
|
1982
|
+
return {
|
|
1983
|
+
to: STORAGE_CONTRACT.address,
|
|
1984
|
+
functionName: "put",
|
|
1985
|
+
args: [keyBytes32, params.text, valueHex],
|
|
1986
|
+
abi: STORAGE_CONTRACT.abi
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
/**
|
|
1990
|
+
* Prepare transaction config for storing data in ChunkedStorage contract.
|
|
1991
|
+
*/
|
|
1992
|
+
prepareChunkedPut(params) {
|
|
1993
|
+
this.validateStorageParams({ key: params.key, chunks: params.chunks });
|
|
1994
|
+
const keyBytes32 = getStorageKeyBytes(params.key, params.keyFormat);
|
|
1995
|
+
for (const chunk of params.chunks) {
|
|
1996
|
+
if (!chunk.startsWith("0x")) {
|
|
1997
|
+
throw new Error(`Invalid chunk format: ${chunk} must be a hex string`);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
return {
|
|
2001
|
+
to: CHUNKED_STORAGE_CONTRACT.address,
|
|
2002
|
+
functionName: "put",
|
|
2003
|
+
args: [keyBytes32, params.text, params.chunks],
|
|
2004
|
+
abi: CHUNKED_STORAGE_CONTRACT.abi
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Prepare transaction config for bulk storage operations using Storage.bulkPut.
|
|
2009
|
+
*/
|
|
2010
|
+
prepareBulkPut(params) {
|
|
2011
|
+
if (params.entries.length === 0) {
|
|
2012
|
+
throw new Error("Entries array cannot be empty");
|
|
2013
|
+
}
|
|
2014
|
+
const bulkEntries = params.entries.map((entry) => {
|
|
2015
|
+
this.validateStorageParams({ key: entry.key });
|
|
2016
|
+
const keyBytes32 = getStorageKeyBytes(entry.key, params.keyFormat);
|
|
2017
|
+
const valueHex = core.normalizeDataOrEmpty(entry.value);
|
|
2018
|
+
return {
|
|
2019
|
+
key: keyBytes32,
|
|
2020
|
+
text: entry.text,
|
|
2021
|
+
value: valueHex
|
|
2022
|
+
};
|
|
2023
|
+
});
|
|
2024
|
+
return {
|
|
2025
|
+
to: STORAGE_CONTRACT.address,
|
|
2026
|
+
functionName: "bulkPut",
|
|
2027
|
+
args: [bulkEntries],
|
|
2028
|
+
abi: STORAGE_CONTRACT.abi
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* Prepare transaction configs for XML storage (multiple transactions - metadata + chunks).
|
|
2033
|
+
*/
|
|
2034
|
+
prepareXmlStorage(params) {
|
|
2035
|
+
const result = processDataForStorage(
|
|
2036
|
+
params.data,
|
|
2037
|
+
params.operatorAddress,
|
|
2038
|
+
params.storageKey
|
|
2039
|
+
);
|
|
2040
|
+
if (!result.valid) {
|
|
2041
|
+
throw new Error(result.error || "Failed to process data for storage");
|
|
2042
|
+
}
|
|
2043
|
+
const useChunkedStorageBackend = params.useChunkedStorageBackend !== false;
|
|
2044
|
+
if (useChunkedStorageBackend) {
|
|
2045
|
+
const chunkedResult = this.prepareXmlChunksForChunkedStorage({
|
|
2046
|
+
xmlChunks: result.chunks,
|
|
2047
|
+
operatorAddress: params.operatorAddress
|
|
2048
|
+
});
|
|
2049
|
+
const metadataConfig = this.preparePut({
|
|
2050
|
+
key: result.topLevelHash,
|
|
2051
|
+
text: params.filename || "",
|
|
2052
|
+
value: chunkedResult.xmlMetadata,
|
|
2053
|
+
keyFormat: params.keyFormat
|
|
2054
|
+
});
|
|
2055
|
+
return {
|
|
2056
|
+
transactionConfigs: [metadataConfig, ...chunkedResult.transactionConfigs],
|
|
2057
|
+
topLevelHash: result.topLevelHash,
|
|
2058
|
+
metadata: chunkedResult.xmlMetadata
|
|
2059
|
+
};
|
|
2060
|
+
} else {
|
|
2061
|
+
const chunkConfigs = result.chunkHashes.map(
|
|
2062
|
+
(hash, index) => this.preparePut({
|
|
2063
|
+
key: hash,
|
|
2064
|
+
text: "",
|
|
2065
|
+
value: result.chunks[index],
|
|
2066
|
+
keyFormat: params.keyFormat
|
|
2067
|
+
})
|
|
2068
|
+
);
|
|
2069
|
+
const metadataConfig = this.preparePut({
|
|
2070
|
+
key: result.topLevelHash,
|
|
2071
|
+
text: params.filename || "",
|
|
2072
|
+
value: result.xmlMetadata,
|
|
2073
|
+
keyFormat: params.keyFormat
|
|
2074
|
+
});
|
|
2075
|
+
return {
|
|
2076
|
+
transactionConfigs: [metadataConfig, ...chunkConfigs],
|
|
2077
|
+
topLevelHash: result.topLevelHash,
|
|
2078
|
+
metadata: result.xmlMetadata
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
};
|
|
2083
|
+
|
|
2084
|
+
exports.CHUNKED_STORAGE_CONTRACT = CHUNKED_STORAGE_CONTRACT;
|
|
2085
|
+
exports.CHUNKED_STORAGE_READER_CONTRACT = CHUNKED_STORAGE_READER_CONTRACT;
|
|
2086
|
+
exports.CONCURRENT_XML_FETCHES = CONCURRENT_XML_FETCHES;
|
|
2087
|
+
exports.MAX_XML_DEPTH = MAX_XML_DEPTH;
|
|
2088
|
+
exports.SAFE_STORAGE_READER_CONTRACT = SAFE_STORAGE_READER_CONTRACT;
|
|
2089
|
+
exports.STORAGE_CONTRACT = STORAGE_CONTRACT;
|
|
2090
|
+
exports.STORAGE_ROUTER_CONTRACT = STORAGE_ROUTER_CONTRACT;
|
|
2091
|
+
exports.StorageClient = StorageClient;
|
|
2092
|
+
exports.assembleChunks = assembleChunks;
|
|
2093
|
+
exports.chunkData = chunkData;
|
|
2094
|
+
exports.chunkDataForStorage = chunkDataForStorage;
|
|
2095
|
+
exports.computeTopLevelHash = computeTopLevelHash;
|
|
2096
|
+
exports.containsXmlReferences = containsXmlReferences;
|
|
2097
|
+
exports.detectStorageType = detectStorageType;
|
|
2098
|
+
exports.encodeStorageKeyForUrl = encodeStorageKeyForUrl;
|
|
2099
|
+
exports.formatStorageKeyForDisplay = formatStorageKeyForDisplay;
|
|
2100
|
+
exports.generateStorageEmbedTag = generateStorageEmbedTag;
|
|
2101
|
+
exports.generateXmlMetadata = generateXmlMetadata;
|
|
2102
|
+
exports.generateXmlMetadataWithSource = generateXmlMetadataWithSource;
|
|
2103
|
+
exports.getChunkCount = getChunkCount;
|
|
2104
|
+
exports.getReferenceKey = getReferenceKey;
|
|
2105
|
+
exports.getStorageKeyBytes = getStorageKeyBytes;
|
|
2106
|
+
exports.parseNetReferences = parseNetReferences;
|
|
2107
|
+
exports.processDataForStorage = processDataForStorage;
|
|
2108
|
+
exports.resolveOperator = resolveOperator;
|
|
2109
|
+
exports.resolveXmlRecursive = resolveXmlRecursive;
|
|
2110
|
+
exports.shouldSuggestXmlStorage = shouldSuggestXmlStorage;
|
|
2111
|
+
exports.useBulkStorage = useBulkStorage;
|
|
2112
|
+
exports.useStorage = useStorage;
|
|
2113
|
+
exports.useStorageForOperator = useStorageForOperator;
|
|
2114
|
+
exports.useStorageForOperatorAndKey = useStorageForOperatorAndKey;
|
|
2115
|
+
exports.useStorageFromRouter = useStorageFromRouter;
|
|
2116
|
+
exports.useStorageTotalWrites = useStorageTotalWrites;
|
|
2117
|
+
exports.useXmlStorage = useXmlStorage;
|
|
2118
|
+
exports.validateDataSize = validateDataSize;
|
|
2119
|
+
//# sourceMappingURL=index.js.map
|
|
2120
|
+
//# sourceMappingURL=index.js.map
|