@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/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