@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.
@@ -0,0 +1,523 @@
1
+ import * as viem from 'viem';
2
+ import { Abi, PublicClient } from 'viem';
3
+ import { WriteTransactionConfig } from '@net-protocol/core';
4
+
5
+ /**
6
+ * Storage data tuple: [text, data]
7
+ */
8
+ type StorageData = [string, string];
9
+ /**
10
+ * Bulk storage key for batch operations
11
+ */
12
+ type BulkStorageKey = {
13
+ key: string;
14
+ operator: string;
15
+ keyFormat?: "raw" | "bytes32";
16
+ };
17
+ /**
18
+ * Bulk storage result
19
+ */
20
+ type BulkStorageResult = {
21
+ text: string;
22
+ value: string;
23
+ };
24
+ /**
25
+ * Options for useStorage hook
26
+ */
27
+ type UseStorageOptions = {
28
+ chainId: number;
29
+ key?: string;
30
+ operatorAddress?: string;
31
+ enabled?: boolean;
32
+ index?: number;
33
+ keyFormat?: "raw" | "bytes32";
34
+ useRouter?: boolean;
35
+ outputFormat?: "hex" | "string";
36
+ };
37
+ /**
38
+ * Options for StorageClient
39
+ */
40
+ type StorageClientOptions = {
41
+ chainId: number;
42
+ overrides?: {
43
+ rpcUrls: string[];
44
+ };
45
+ };
46
+ /**
47
+ * XML reference structure
48
+ */
49
+ interface XmlReference$1 {
50
+ hash: string;
51
+ version: string;
52
+ index?: number;
53
+ operator?: string;
54
+ source?: string;
55
+ }
56
+ /**
57
+ * Chunked storage metadata
58
+ */
59
+ type ChunkedMetadata = {
60
+ chunkCount: number;
61
+ originalText: string;
62
+ };
63
+ /**
64
+ * Options for useXmlStorage hook
65
+ */
66
+ type UseXmlStorageOptions = {
67
+ chainId: number;
68
+ key?: string;
69
+ operatorAddress: string;
70
+ skipXmlParsing?: boolean;
71
+ enabled?: boolean;
72
+ content?: string;
73
+ index?: number;
74
+ keyFormat?: "raw" | "bytes32";
75
+ useRouter?: boolean;
76
+ returnFormat?: "object" | "tuple";
77
+ outputFormat?: "hex" | "string";
78
+ };
79
+ /**
80
+ * Options for useStorageFromRouter hook
81
+ */
82
+ type UseStorageFromRouterOptions = {
83
+ chainId: number;
84
+ storageKey: `0x${string}`;
85
+ operatorAddress: string;
86
+ enabled?: boolean;
87
+ };
88
+
89
+ declare function useStorage({ chainId, key, operatorAddress, enabled, index, keyFormat, useRouter, outputFormat, }: UseStorageOptions): {
90
+ data: StorageData | undefined;
91
+ isLoading: boolean;
92
+ error: Error | undefined;
93
+ };
94
+ declare function useStorageForOperator({ chainId, operatorAddress, }: UseStorageOptions): {
95
+ data: any[][];
96
+ isLoading: boolean;
97
+ error: undefined;
98
+ };
99
+ declare function useStorageForOperatorAndKey({ chainId, key, operatorAddress, keyFormat, }: UseStorageOptions): {
100
+ data: StorageData | undefined;
101
+ isLoading: boolean;
102
+ error: Error | undefined;
103
+ };
104
+ declare function useBulkStorage({ chainId, keys, safe, keyFormat, }: {
105
+ chainId: number;
106
+ keys: BulkStorageKey[];
107
+ safe?: boolean;
108
+ keyFormat?: "raw" | "bytes32";
109
+ }): {
110
+ data: {
111
+ text: string;
112
+ value: string;
113
+ }[] | undefined;
114
+ isLoading: boolean;
115
+ error: Error | undefined;
116
+ };
117
+ /**
118
+ * Get total number of versions (writes) for a storage key
119
+ * Tries both chunked storage and regular storage
120
+ */
121
+ declare function useStorageTotalWrites({ chainId, key, operatorAddress, enabled, keyFormat, }: {
122
+ chainId: number;
123
+ key?: string;
124
+ operatorAddress?: string;
125
+ enabled?: boolean;
126
+ keyFormat?: "raw" | "bytes32";
127
+ }): {
128
+ data: number | undefined;
129
+ isLoading: boolean;
130
+ error: viem.ReadContractErrorType | null | undefined;
131
+ };
132
+
133
+ declare function useXmlStorage({ chainId, key, operatorAddress, skipXmlParsing, enabled, content, index, keyFormat, useRouter, returnFormat, outputFormat, }: UseXmlStorageOptions): {
134
+ data: StorageData | undefined;
135
+ isLoading: boolean;
136
+ error: Error | undefined;
137
+ filename?: undefined;
138
+ isXml?: undefined;
139
+ } | {
140
+ data: string | undefined;
141
+ filename: string;
142
+ isLoading: boolean;
143
+ error: Error | undefined;
144
+ isXml: boolean;
145
+ };
146
+
147
+ /**
148
+ * Generic hook to fetch storage content from StorageRouter
149
+ * Handles both regular storage and chunked storage seamlessly
150
+ * Works for any storage key (not just canvases)
151
+ */
152
+ declare function useStorageFromRouter({ chainId, storageKey, operatorAddress, enabled, }: UseStorageFromRouterOptions): {
153
+ data: StorageData | undefined;
154
+ isLoading: boolean;
155
+ error: Error | undefined;
156
+ };
157
+
158
+ /**
159
+ * StorageClient - Client for interacting with Net protocol storage
160
+ *
161
+ * **Pattern for client methods:**
162
+ * - Client methods never require `chainId` in their parameters
163
+ * - All methods use `this.chainId` internally (set during construction)
164
+ * - Config builders receive `chainId` as a separate required parameter
165
+ * - This ensures consistency: the client's `chainId` is the single source of truth
166
+ */
167
+ declare class StorageClient {
168
+ private client;
169
+ private chainId;
170
+ constructor(params: StorageClientOptions);
171
+ /**
172
+ * Get storage value for a key and operator (latest version)
173
+ */
174
+ get(params: {
175
+ key: string;
176
+ operator: string;
177
+ keyFormat?: "raw" | "bytes32";
178
+ }): Promise<StorageData | null>;
179
+ /**
180
+ * Get storage value at a specific historical index
181
+ */
182
+ getValueAtIndex(params: {
183
+ key: string;
184
+ operator: string;
185
+ index: number;
186
+ keyFormat?: "raw" | "bytes32";
187
+ }): Promise<StorageData | null>;
188
+ /**
189
+ * Get total number of writes (versions) for a key-operator pair
190
+ * Tries ChunkedStorageReader first, then Storage
191
+ */
192
+ getTotalWrites(params: {
193
+ key: string;
194
+ operator: string;
195
+ keyFormat?: "raw" | "bytes32";
196
+ }): Promise<number>;
197
+ /**
198
+ * Bulk get storage values
199
+ */
200
+ bulkGet(params: {
201
+ keys: BulkStorageKey[];
202
+ safe?: boolean;
203
+ keyFormat?: "raw" | "bytes32";
204
+ }): Promise<BulkStorageResult[]>;
205
+ /**
206
+ * Get storage value via StorageRouter (latest version)
207
+ * Returns data with storage type indication
208
+ */
209
+ getViaRouter(params: {
210
+ key: string;
211
+ operator: string;
212
+ keyFormat?: "raw" | "bytes32";
213
+ }): Promise<{
214
+ isChunkedStorage: boolean;
215
+ text: string;
216
+ data: string;
217
+ } | null>;
218
+ /**
219
+ * Get chunked storage metadata
220
+ */
221
+ getChunkedMetadata(params: {
222
+ key: string;
223
+ operator: string;
224
+ index?: number;
225
+ keyFormat?: "raw" | "bytes32";
226
+ }): Promise<{
227
+ chunkCount: number;
228
+ originalText: string;
229
+ } | null>;
230
+ /**
231
+ * Get chunked storage chunks
232
+ */
233
+ getChunked(params: {
234
+ key: string;
235
+ operator: string;
236
+ start: number;
237
+ end: number;
238
+ index?: number;
239
+ keyFormat?: "raw" | "bytes32";
240
+ }): Promise<string[]>;
241
+ /**
242
+ * Get chunked storage at a specific historical index
243
+ */
244
+ getChunkedAtIndex(params: {
245
+ key: string;
246
+ operator: string;
247
+ start: number;
248
+ end: number;
249
+ index: number;
250
+ }): Promise<string[]>;
251
+ /**
252
+ * Get all storage keys for an operator using Net contract
253
+ */
254
+ getForOperator(params: {
255
+ operator: string;
256
+ }): Promise<Array<[string, string, number, string]>>;
257
+ /**
258
+ * Get storage value for operator and key
259
+ */
260
+ getForOperatorAndKey(params: {
261
+ operator: string;
262
+ key: string;
263
+ keyFormat?: "raw" | "bytes32";
264
+ }): Promise<StorageData | null>;
265
+ /**
266
+ * Read storage data with XML resolution
267
+ */
268
+ readStorageData(params: {
269
+ key: string;
270
+ operator: string;
271
+ index?: number;
272
+ keyFormat?: "raw" | "bytes32";
273
+ }): Promise<{
274
+ text: string;
275
+ data: string;
276
+ isXml: boolean;
277
+ }>;
278
+ /**
279
+ * Read chunked storage data with decompression
280
+ */
281
+ readChunkedStorage(params: {
282
+ key: string;
283
+ operator: string;
284
+ index?: number;
285
+ keyFormat?: "raw" | "bytes32";
286
+ }): Promise<{
287
+ text: string;
288
+ data: string;
289
+ }>;
290
+ /**
291
+ * Validate storage parameters
292
+ */
293
+ private validateStorageParams;
294
+ /**
295
+ * Prepare transaction configs for storing XML chunks in ChunkedStorage backend.
296
+ * Each XML chunk is compressed and chunked into 20KB ChunkedStorage chunks.
297
+ */
298
+ private prepareXmlChunksForChunkedStorage;
299
+ /**
300
+ * Prepare transaction config for storing a single value in Storage contract.
301
+ */
302
+ preparePut(params: {
303
+ key: string | `0x${string}`;
304
+ text: string;
305
+ value: string | `0x${string}`;
306
+ keyFormat?: "raw" | "bytes32";
307
+ }): WriteTransactionConfig;
308
+ /**
309
+ * Prepare transaction config for storing data in ChunkedStorage contract.
310
+ */
311
+ prepareChunkedPut(params: {
312
+ key: string | `0x${string}`;
313
+ text: string;
314
+ chunks: string[];
315
+ keyFormat?: "raw" | "bytes32";
316
+ }): WriteTransactionConfig;
317
+ /**
318
+ * Prepare transaction config for bulk storage operations using Storage.bulkPut.
319
+ */
320
+ prepareBulkPut(params: {
321
+ entries: Array<{
322
+ key: string | `0x${string}`;
323
+ text: string;
324
+ value: string | `0x${string}`;
325
+ }>;
326
+ keyFormat?: "raw" | "bytes32";
327
+ }): WriteTransactionConfig;
328
+ /**
329
+ * Prepare transaction configs for XML storage (multiple transactions - metadata + chunks).
330
+ */
331
+ prepareXmlStorage(params: {
332
+ data: string;
333
+ operatorAddress: `0x${string}`;
334
+ storageKey?: string | `0x${string}`;
335
+ filename?: string;
336
+ useChunkedStorageBackend?: boolean;
337
+ keyFormat?: "raw" | "bytes32";
338
+ }): {
339
+ transactionConfigs: WriteTransactionConfig[];
340
+ topLevelHash: string;
341
+ metadata: string;
342
+ };
343
+ }
344
+
345
+ /**
346
+ * Format storage key for display, decoding hex to readable text when possible
347
+ * Returns both the display text and whether it was successfully decoded
348
+ */
349
+ declare function formatStorageKeyForDisplay(storageKey: string): {
350
+ displayText: string;
351
+ isDecoded: boolean;
352
+ };
353
+ /**
354
+ * Get storage key as bytes32 format
355
+ * Supports direct hex bytes32 input or converts string to bytes32
356
+ * For strings longer than 32 bytes, hashes them
357
+ *
358
+ * @param input - The storage key (raw string or bytes32 hex)
359
+ * @param keyFormat - Optional format override: "raw" to always convert, "bytes32" to use as-is, undefined for auto-detect
360
+ */
361
+ declare function getStorageKeyBytes(input: string, keyFormat?: "raw" | "bytes32"): string;
362
+ /**
363
+ * Encodes a storage key for use in URL paths.
364
+ *
365
+ * This ensures special characters (including trailing spaces) are preserved
366
+ * when storage keys are used in URLs.
367
+ *
368
+ * @param key - The storage key string (already decoded, from data or URL params)
369
+ * @returns URL-encoded storage key safe for use in path segments
370
+ *
371
+ * @example
372
+ * encodeStorageKeyForUrl('declaration of independence ')
373
+ * // Returns: 'declaration%20of%20independence%20'
374
+ */
375
+ declare function encodeStorageKeyForUrl(key: string): string;
376
+ /**
377
+ * Generate a <net ... /> embed tag for storage
378
+ * @param params - Object containing storage embed parameters
379
+ * @param params.storageKeyBytes - The storage key as bytes32 (hex string)
380
+ * @param params.operatorAddress - The operator address
381
+ * @param params.isRegularStorage - If true, includes s="d" for direct Storage.sol reads. If false/undefined, omits s attribute (defaults to ChunkedStorage)
382
+ * @param params.versionIndex - Optional version index. If provided, includes i="versionIndex" attribute to reference specific historical version
383
+ * @returns The embed tag string
384
+ */
385
+ declare function generateStorageEmbedTag(params: {
386
+ storageKeyBytes: string;
387
+ operatorAddress: string;
388
+ isRegularStorage?: boolean;
389
+ versionIndex?: number;
390
+ }): string;
391
+
392
+ /**
393
+ * Chunks data for storage in ChunkedStorage contract
394
+ * First compresses the data using gzip, then chunks the compressed data
395
+ * @param data - The string data to chunk
396
+ * @returns Array of hex-encoded byte chunks of compressed data
397
+ */
398
+ declare function chunkDataForStorage(data: string): string[];
399
+ /**
400
+ * Determines if XML storage should be suggested for the given data
401
+ * @param data - The string data to check
402
+ * @returns True if XML storage should be suggested
403
+ */
404
+ declare function shouldSuggestXmlStorage(data: string): boolean;
405
+ /**
406
+ * Gets the estimated number of chunks for given data
407
+ * @param data - The string data
408
+ * @returns Number of chunks that would be created
409
+ */
410
+ declare function getChunkCount(data: string): number;
411
+ /**
412
+ * Assemble chunks into a single string and decompress
413
+ * Pure function - can be used in both client and server code
414
+ * @param chunks - Array of hex-encoded chunk strings
415
+ * @returns Decompressed string or undefined if decompression fails
416
+ */
417
+ declare function assembleChunks(chunks: string[]): string | undefined;
418
+
419
+ /**
420
+ * XML reference type for chunk metadata
421
+ */
422
+ interface XmlReference {
423
+ hash: string;
424
+ version: string;
425
+ index?: number;
426
+ operator?: string;
427
+ source?: string;
428
+ }
429
+ /**
430
+ * Parse XML metadata to extract chunk references
431
+ * Format: <net k="hashValue" v="0.0.1" o="0xoperator" s="d" />
432
+ */
433
+ declare function parseNetReferences(metadata: string): XmlReference[];
434
+ /**
435
+ * Check if a string contains XML references
436
+ */
437
+ declare function containsXmlReferences(data: string): boolean;
438
+ /**
439
+ * Detect storage type based on content
440
+ */
441
+ declare function detectStorageType(metadata: string): "xml" | "regular";
442
+ /**
443
+ * Resolve operator address for a reference with fallback to default
444
+ */
445
+ declare function resolveOperator(reference: XmlReference, defaultOperator: string): string;
446
+ /**
447
+ * Generate unique key for a reference to detect circular dependencies
448
+ */
449
+ declare function getReferenceKey(reference: XmlReference, defaultOperator: string): string;
450
+
451
+ /**
452
+ * Split data into chunks of specified size
453
+ */
454
+ declare function chunkData(data: string, chunkSize?: number): string[];
455
+ /**
456
+ * Generate XML metadata string from chunk hashes
457
+ * Format: <net k="hash1" v="0.0.1" i="0" o="0xoperator" /><net k="hash2" v="0.0.1" i="0" o="0xoperator" />
458
+ */
459
+ declare function generateXmlMetadata(chunkHashes: string[], historicalIndex: number, operatorAddress: string): string;
460
+ /**
461
+ * Generate XML metadata string from chunk hashes with source support
462
+ * Format: <net k="hash1" v="0.0.1" i="0" o="0xoperator" s="d" /><net k="hash2" v="0.0.1" i="0" o="0xoperator" />
463
+ */
464
+ declare function generateXmlMetadataWithSource(chunkHashes: string[], historicalIndex: number, operatorAddress: string, source?: string): string;
465
+ /**
466
+ * Validate data size against constraints
467
+ */
468
+ declare function validateDataSize(chunks: string[]): {
469
+ valid: boolean;
470
+ error?: string;
471
+ };
472
+ /**
473
+ * Compute top-level hash from chunk hashes
474
+ */
475
+ declare function computeTopLevelHash(chunkHashes: string[]): string;
476
+ /**
477
+ * Complete chunking and hash generation process
478
+ */
479
+ declare function processDataForStorage(data: string, operatorAddress: string, storageKey?: string): {
480
+ chunks: string[];
481
+ chunkHashes: string[];
482
+ xmlMetadata: string;
483
+ topLevelHash: string;
484
+ valid: boolean;
485
+ error?: string;
486
+ };
487
+
488
+ declare const STORAGE_CONTRACT: {
489
+ abi: Abi;
490
+ address: `0x${string}`;
491
+ };
492
+ declare const CHUNKED_STORAGE_CONTRACT: {
493
+ abi: Abi;
494
+ address: `0x${string}`;
495
+ };
496
+ declare const CHUNKED_STORAGE_READER_CONTRACT: {
497
+ abi: Abi;
498
+ address: `0x${string}`;
499
+ };
500
+ declare const STORAGE_ROUTER_CONTRACT: {
501
+ abi: Abi;
502
+ address: `0x${string}`;
503
+ };
504
+ declare const SAFE_STORAGE_READER_CONTRACT: {
505
+ abi: Abi;
506
+ address: `0x${string}`;
507
+ };
508
+
509
+ /**
510
+ * Maximum depth for recursive XML resolution
511
+ */
512
+ declare const MAX_XML_DEPTH = 3;
513
+ /**
514
+ * Number of XML references to fetch concurrently per batch
515
+ */
516
+ declare const CONCURRENT_XML_FETCHES = 3;
517
+ /**
518
+ * Recursively resolve XML references up to specified depth
519
+ * Handles circular reference detection and parallel fetching per layer
520
+ */
521
+ declare function resolveXmlRecursive(content: string, defaultOperator: string, client: PublicClient, maxDepth: number, visited?: Set<string>, inheritedOperator?: string): Promise<string>;
522
+
523
+ export { type BulkStorageKey, CHUNKED_STORAGE_CONTRACT, CHUNKED_STORAGE_READER_CONTRACT, CONCURRENT_XML_FETCHES, type ChunkedMetadata, MAX_XML_DEPTH, SAFE_STORAGE_READER_CONTRACT, STORAGE_CONTRACT, STORAGE_ROUTER_CONTRACT, StorageClient, type StorageClientOptions, type StorageData, type UseStorageOptions, type UseXmlStorageOptions, type XmlReference$1 as XmlReference, assembleChunks, chunkData, chunkDataForStorage, computeTopLevelHash, containsXmlReferences, detectStorageType, encodeStorageKeyForUrl, formatStorageKeyForDisplay, generateStorageEmbedTag, generateXmlMetadata, generateXmlMetadataWithSource, getChunkCount, getReferenceKey, getStorageKeyBytes, parseNetReferences, processDataForStorage, resolveOperator, resolveXmlRecursive, shouldSuggestXmlStorage, useBulkStorage, useStorage, useStorageForOperator, useStorageForOperatorAndKey, useStorageFromRouter, useStorageTotalWrites, useXmlStorage, validateDataSize };