@fizzyflow/endless-vector 0.0.8 → 0.0.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Endless Vector - JavaScript SDK
2
2
 
3
- JavaScript/TypeScript SDK for interacting with the Endless Vector smart contract on the Sui blockchain. Endless Vector provides a scalable, on-chain data structure storing `vector<vector<u8>>` that can grow beyond Sui object size limits.
3
+ JavaScript/TypeScript SDK for the Endless Vector smart contract on [Sui](https://sui.io). Endless Vector is a scalable, append-only on-chain `vector<vector<u8>>` that grows beyond Sui object size limits by automatically splitting data into history segments. Items larger than ~120 KB are transparently stored as [Walrus](https://walrus.xyz) blobs. Optional [Seal](https://github.com/nicola/seal) encryption protects all stored data with AES-256-GCM.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,276 +10,346 @@ npm install @fizzyflow/endless-vector
10
10
 
11
11
  ## Quick Start
12
12
 
13
- ### Creating a New Vector
14
-
15
13
  ```javascript
16
- import { SuiClient } from '@mysten/sui/client';
17
14
  import { EndlessVector } from '@fizzyflow/endless-vector';
18
15
 
19
- const client = new SuiClient({ url: 'https://fullnode.mainnet.sui.io:443' });
20
-
21
- // Create an empty vector
22
- const vector = await EndlessVector.create({
16
+ // Create
17
+ const ev = await EndlessVector.create({
23
18
  suiClient: client,
24
- packageId: 'testnet', // or 'mainnet' or '0xYOUR_PACKAGE_ID'
19
+ packageId: 'testnet', // or 'mainnet', or an explicit 0x... package ID
25
20
  signAndExecuteTransaction: async (tx) => {
26
21
  const result = await wallet.signAndExecuteTransaction({ transaction: tx });
27
22
  return result.digest;
28
- }
23
+ },
29
24
  });
30
25
 
31
- // Or create with initial data
32
- const vectorWithData = await EndlessVector.create({
33
- suiClient: client,
34
- packageId: 'testnet', // or 'mainnet' or '0xYOUR_PACKAGE_ID'
35
- array: new Uint8Array([1, 2, 3]), // [0] to append to EndlessVector
36
- //array: [new Uint8Array([1, 2, 3]), new Uint8Array([5, 6, 7])], // or [0] and [1] to append to EndlessVector
37
- signAndExecuteTransaction: async (tx) => {
38
- const result = await wallet.signAndExecuteTransaction({ transaction: tx });
39
- return result.digest;
40
- }
41
- });
26
+ // Write
27
+ await ev.push(new Uint8Array([1, 2, 3]));
28
+
29
+ // Read
30
+ const item = await ev.at(0); // Uint8Array
42
31
  ```
43
32
 
44
- ### Reading an Existing Vector
33
+ ## Constructor
45
34
 
46
35
  ```javascript
47
- const vector = new EndlessVector({
48
- suiClient: client,
49
- id: '0xYOUR_VECTOR_OBJECT_ID'
50
- });
36
+ const ev = new EndlessVector(params);
37
+ ```
51
38
 
52
- await vector.initialize();
39
+ | Parameter | Type | Required | Description |
40
+ |-----------|------|----------|-------------|
41
+ | `suiClient` | SuiGrpcClient | yes | Sui gRPC client instance |
42
+ | `id` | string | yes | On-chain object ID of the vector |
43
+ | `packageId` | string | no | Move package ID, or `'testnet'`/`'mainnet'`. Enables writes |
44
+ | `signAndExecuteTransaction` | function | no | Signs and submits a Transaction, returns its digest. Enables writes |
45
+ | `walrusClient` | WalrusClient | no | `@mysten/walrus` client for blob read/write |
46
+ | `publisherUrl` | string | no | Walrus publisher HTTP URL (fallback when no `walrusClient`) |
47
+ | `aggregatorUrl` | string | no | Walrus aggregator HTTP URL (fallback when no `walrusClient`) |
48
+ | `senderAddress` | string | no | Sender Sui address, required for Walrus blob writes |
49
+ | `sealClient` | SealClient | no | `@mysten/seal` client for encryption/decryption |
50
+ | `sessionKey` | SessionKey | no | Pre-built Seal SessionKey. Alternative to `signer` |
51
+ | `signer` | Signer | no | Keypair or wallet signer used to auto-create a SessionKey when needed |
52
+ | `sealTtlMin` | number | no | SessionKey TTL in minutes (default: 5) |
53
53
 
54
- console.log('Total items:', vector.length);
55
- console.log('Total size:', vector.binaryLength, 'bytes');
54
+ Providing only `suiClient` + `id` gives a **read-only** instance. Add `packageId` + `signAndExecuteTransaction` for **writes**. Add Walrus params for **large items** (>120 KB). Add Seal params for **encryption**.
56
55
 
57
- // Read items
58
- const firstItem = await vector.at(0); // Uint8Array
56
+ ## EndlessVector.create(params)
57
+
58
+ Creates a new on-chain vector.
59
+
60
+ Accepts all constructor params above, plus:
61
+
62
+ | Parameter | Type | Required | Description |
63
+ |-----------|------|----------|-------------|
64
+ | `array` | Uint8Array \| Uint8Array[] | no | Initial item(s) to push |
65
+ | `gasCoin` | `{objectId, digest, version}` | no | Explicit gas coin for parallel creation |
66
+ | `options.timeout` | number | no | Tx confirmation timeout, ms (default: 30000) |
67
+ | `options.pollIntervalMs` | number | no | Tx poll interval, ms (default: 200) |
68
+
69
+ When `sealClient` is provided, the vector is created with Seal encryption enabled. A random AES-256-GCM key is generated, Seal-wrapped scoped to the new vector's object ID, and stored on-chain. Any initial `array` items are encrypted before storage.
70
+
71
+ ```javascript
72
+ const ev = await EndlessVector.create({
73
+ suiClient: client,
74
+ packageId: 'testnet',
75
+ sealClient,
76
+ signer: keypair,
77
+ signAndExecuteTransaction: sign,
78
+ });
79
+ // All push() / at() calls now encrypt/decrypt transparently
59
80
  ```
60
81
 
61
- ## API Reference
82
+ ## Properties
83
+
84
+ | Property | Type | Description |
85
+ |----------|------|-------------|
86
+ | `id` | string | Object ID |
87
+ | `isWritable` | boolean | Whether writes are enabled |
88
+ | `length` | number | Total item count (append-only, never decreases) |
89
+ | `binaryLength` | number | Total size of all items in bytes |
90
+ | `sealEncryptedKey` | Uint8Array \| null | Seal-wrapped AES key, or null if unencrypted |
91
+ | `seal` | EndlessVectorSeal | Seal companion (always present; active only when `sealClient` was provided) |
92
+ | `walrus` | EndlessVectorWalrus | Walrus companion (always present; active only when Walrus params were provided) |
93
+ | `historyItemsCount` | number | History segments in the current object |
94
+ | `archiveItemsCount` | number | Total archive entries ever created |
95
+ | `archivedAtLength` | number | `length` at the time of the last archive |
96
+ | `archivedFromLength` | number | Items before this index have been burned |
97
+ | `burnedArchiveCount` | number | Burned archive count |
98
+ | `firstNotHistoryIndex` | number | First index stored in the current object |
62
99
 
63
- ### Static Methods
100
+ ## Methods
64
101
 
65
- #### EndlessVector.create(params)
102
+ ### initialize()
66
103
 
67
- Creates a new EndlessVector on the blockchain.
104
+ Loads metadata from chain. Most read methods call this internally.
105
+
106
+ ```javascript
107
+ await ev.initialize();
108
+ ```
68
109
 
69
- **Parameters:**
70
- - `suiClient` (SuiClient) - Sui client instance for blockchain interactions
71
- - `packageId` (string) - 'testnet', 'mainnet', or ID of the Move package containing the EndlessVector module
72
- - `signAndExecuteTransaction` (function) - Function to sign and execute transactions
73
- - `array` (Uint8Array or Uint8Array[], optional) - Optional first vector<u8>(s) to push back to the new vector
74
- - `gasCoin` (Object, optional) - Gas coin object reference `{objectId: string, digest: string, version: string}` for transaction payment
75
- - `options` (Object, optional) - Additional options:
76
- - `timeout` (number) - Transaction confirmation timeout in ms (default: 30000)
77
- - `pollIntervalMs` (number) - Poll interval in ms (default: 1000)
110
+ ### reInitialize()
78
111
 
79
- **Returns:** Promise<EndlessVector>
112
+ Marks the instance stale so the next operation re-fetches from chain.
80
113
 
81
- **Example:**
82
114
  ```javascript
83
- const vector = await EndlessVector.create({
84
- suiClient: client,
85
- packageId: 'testnet', // or 'mainnet' or '0xPACKAGE_ID'
86
- array: new Uint8Array([1, 2, 3]),
87
- gasCoin: {
88
- objectId: '0xGAS_COIN_ID',
89
- digest: 'DIGEST',
90
- version: 'VERSION'
91
- },
92
- signAndExecuteTransaction: async (tx) => {
93
- const result = await wallet.signAndExecuteTransaction({ transaction: tx });
94
- return result.digest;
95
- }
96
- });
115
+ ev.reInitialize();
97
116
  ```
98
117
 
99
- ### Constructor
118
+ ### isEncrypted()
119
+
120
+ Async. Returns `true` if the vector has a Seal encryption key on-chain. Calls `initialize()` internally.
100
121
 
101
122
  ```javascript
102
- const vector = new EndlessVector({
103
- suiClient, // SuiClient instance (required for reading)
104
- id, // Object ID of the EndlessVector (required)
105
- packageId, // 'testnet', 'mainnet', or Package ID for write operations (optional)
106
- signAndExecuteTransaction // Function to sign/execute transactions (optional)
107
- });
123
+ if (await ev.isEncrypted()) { /* ... */ }
108
124
  ```
109
125
 
110
- **Modes:**
111
- - **Read-only mode**: Provide only `suiClient` and `id`
112
- - **Writable mode**: Provide all parameters including `packageId` and `signAndExecuteTransaction`
126
+ ### push(arr, params?)
113
127
 
114
- ### Properties
128
+ Appends one or more `Uint8Array` items. Requires writable mode.
115
129
 
116
- - `id` (string) - Object ID of the EndlessVector
117
- - `isWritable` (boolean) - Whether the instance can perform write operations
118
- - `length` (number) - Total number of items in the vector
119
- - `binaryLength` (number) - Total binary size of all items in bytes
120
- - `historyItemsCount` (number) - Number of history segments
121
- - `archiveItemsCount` (number) - Number of archive segments
122
- - `archivedFromLength` (number) - Starting index after burned archives
123
- - `burnedArchiveCount` (number) - Number of archives that have been burned
124
- - `firstNotHistoryIndex` (number) - First index stored in current object (not in history)
130
+ - Items up to ~120 KB are stored on-chain as `vector<u8>`.
131
+ - Larger items are stored as Walrus blobs (requires Walrus params).
132
+ - On encrypted vectors, every item is AES-256-GCM encrypted before storage (28 bytes overhead per item).
125
133
 
126
- ### Methods
134
+ ```javascript
135
+ await ev.push(new Uint8Array([1, 2, 3]));
136
+ await ev.push([chunk1, chunk2, chunk3]); // multiple items
137
+ ```
127
138
 
128
- #### initialize()
139
+ ### getPushTransaction(arr, tx?)
129
140
 
130
- Loads the vector's metadata from the blockchain. Called automatically by most methods.
141
+ Returns a `Transaction` without executing it. Useful for batching multiple pushes.
131
142
 
132
143
  ```javascript
133
- await vector.initialize();
144
+ const tx = new Transaction();
145
+ ev.getPushTransaction(data1, tx);
146
+ ev.getPushTransaction(data2, tx);
147
+ await signAndExecuteTransaction(tx);
134
148
  ```
135
149
 
136
- #### reInitialize()
150
+ ### at(index)
137
151
 
138
- Forces a reload of the vector's metadata, clearing caches.
152
+ Reads the item at a zero-based index. On encrypted vectors, decrypts transparently.
139
153
 
140
154
  ```javascript
141
- await vector.reInitialize();
155
+ const data = await ev.at(0); // Uint8Array
142
156
  ```
143
157
 
144
- #### push(arr, params)
158
+ ### concat(other, params?)
145
159
 
146
- Pushes a Uint8Array or few Uint8Array(Uint8Array[]) to the vector. Requires writable mode. Maximum size per push: ~120KB.
160
+ Appends all items from another vector (or array of vectors) into this one. Sources are consumed (destroyed).
147
161
 
148
162
  ```javascript
149
- const data = new Uint8Array([1, 2, 3, 4, 5]);
150
- await vector.push(data);
163
+ await ev.concat(otherVector);
164
+ await ev.concat([v2, v3]);
165
+ await ev.concat('0xOTHER_VECTOR_ID');
151
166
  ```
152
167
 
153
- **Parameters:**
154
- - `arr` (Uint8Array or Uint8Array[]) - Data to push
155
- - `params` (Object, optional) - Additional parameters
168
+ **Restrictions:** cannot concat vectors that have archived items or that are Seal-encrypted.
156
169
 
157
- #### getPushTransaction(arr, tx)
170
+ ### getConcatTransaction(other, tx?)
158
171
 
159
- Creates a transaction for pushing data without executing it. Useful for batching multiple pushes.
172
+ Returns a concat `Transaction` without executing.
160
173
 
161
- ```javascript
162
- // Single push transaction
163
- const tx = vector.getPushTransaction(new Uint8Array([1, 2, 3]));
164
- await signAndExecuteTransaction(tx);
174
+ ### archive(params?)
165
175
 
166
- // Multiple pushes in one transaction
167
- const tx = new Transaction();
168
- vector.getPushTransaction(new Uint8Array([1, 2, 3]), tx);
169
- vector.getPushTransaction(new Uint8Array([4, 5, 6]), tx);
170
- await signAndExecuteTransaction(tx);
176
+ Sweeps current history segments into a new archive entry, freeing capacity for future pushes.
177
+
178
+ ```javascript
179
+ await ev.archive();
171
180
  ```
172
181
 
173
- **Parameters:**
174
- - `arr` (Uint8Array or Uint8Array[]) - Data to push
175
- - `tx` (Transaction, optional) - Existing transaction to append to
182
+ ### getArchiveTransaction(tx?)
176
183
 
177
- **Returns:** Transaction
184
+ Returns an archive `Transaction` without executing.
178
185
 
179
- #### at(index)
186
+ ### burnArchive(params?)
180
187
 
181
- Retrieves an item at a specific index. Alias: `get(index)`
188
+ Permanently deletes the oldest archive entry. Items in the burned range become unreadable.
182
189
 
183
190
  ```javascript
184
- const item = await vector.at(42); // Returns Uint8Array
191
+ await ev.burnArchive();
192
+ // ev.archivedFromLength now advanced; at() throws for burned indices
185
193
  ```
186
194
 
187
- **Parameters:**
188
- - `index` (number) - Zero-based index
195
+ ### getBurnArchiveTransaction(tx?)
189
196
 
190
- **Returns:** Promise<Uint8Array>
197
+ Returns a burn-archive `Transaction` without executing.
191
198
 
192
- #### concat(other)
199
+ ## Walrus Blob Storage
193
200
 
194
- Concatenates another EndlessVector (or array of vectors) into this one. The other vector(s) will be consumed.
201
+ When Walrus params are configured, items larger than ~120 KB are automatically stored as Walrus blobs instead of on-chain `vector<u8>`. The SDK handles upload, certification, and read-back. On encrypted vectors, blobs contain ciphertext only.
195
202
 
196
203
  ```javascript
197
- // Concat single vector
198
- await vector1.concat(vector2);
199
-
200
- // Concat multiple vectors at once
201
- await vector1.concat([vector2, vector3, vector4]);
204
+ const ev = new EndlessVector({
205
+ suiClient: client,
206
+ id: '0x...',
207
+ packageId: 'testnet',
208
+ walrusClient, // or aggregatorUrl + publisherUrl
209
+ senderAddress: wallet.address,
210
+ signAndExecuteTransaction: sign,
211
+ });
202
212
 
203
- // Also accepts object IDs
204
- await vector1.concat('0xVECTOR2_ID');
205
- await vector1.concat(['0xVECTOR2_ID', '0xVECTOR3_ID']);
213
+ await ev.push(largeFile); // >120 KB stored as Walrus blob
214
+ const data = await ev.at(0); // fetched from Walrus transparently
206
215
  ```
207
216
 
208
- **Parameters:**
209
- - `other` (string | EndlessVector | Array<string | EndlessVector>) - Vector(s) to concatenate
217
+ ### Blob lifetime: inspect & extend
210
218
 
211
- **Returns:** Promise<void>
219
+ Walrus blobs are backed by storage that expires at an `end_epoch`. The Walrus companion (`ev.walrus`) can report when a vector's blobs expire and renew them all in a single transaction — covering blobs in current items, history segments, and non-burned archive segments. These methods require `walrusClient` (to resolve the Walrus `System` object and current storage price).
212
220
 
213
- **Note:** Cannot concat vectors that have archived items.
221
+ #### minBlobEndEpoch()
214
222
 
215
- #### getConcatTransaction(other, tx)
223
+ Async. Reads the soonest-expiring blob's `end_epoch` across the whole vector, on-chain via simulation (no gas, works read-only). Returns `null` if the vector holds no blobs.
216
224
 
217
- Creates a transaction for concatenation without executing it.
225
+ ```javascript
226
+ const minEpoch = await ev.walrus.minBlobEndEpoch(); // number | null
227
+ ```
228
+
229
+ #### extendBlobsCostToEpoch(targetEndEpoch)
230
+
231
+ Async. Returns the exact WAL cost (in FROST, as a `bigint`) to bring every blob up to `targetEndEpoch`. Computed on-chain, so it accounts for every blob across all tiers — even ones not loaded in the SDK. `0n` when nothing needs extending.
218
232
 
219
233
  ```javascript
220
- const tx = vector1.getConcatTransaction(vector2);
221
- await signAndExecuteTransaction(tx);
234
+ const cost = await ev.walrus.extendBlobsCostToEpoch(minEpoch + 10); // bigint (FROST)
235
+ ```
222
236
 
223
- // Or append to existing transaction
224
- const tx = new Transaction();
225
- vector1.getConcatTransaction([vector2, vector3], tx);
226
- await signAndExecuteTransaction(tx);
237
+ #### extendBlobsToEpoch(targetEndEpoch, params?)
238
+
239
+ Async. Extends every blob whose storage ends before `targetEndEpoch` up to that epoch, in one transaction. Blobs already valid through the target (and expired blobs, which Walrus cannot extend) are skipped on-chain. Resolves to the new minimum blob end epoch. Requires writable mode and `senderAddress`.
240
+
241
+ The WAL payment is sourced automatically from the sender's balance for exactly the on-chain cost, and any leftover is returned to the sender. Pass `walCoin` to pay from a specific coin, or `cost` to skip the cost read.
242
+
243
+ ```javascript
244
+ const minEpoch = await ev.walrus.minBlobEndEpoch();
245
+ const newMin = await ev.walrus.extendBlobsToEpoch(minEpoch + 10);
246
+ // newMin === minEpoch + 10
227
247
  ```
228
248
 
229
- **Parameters:**
230
- - `other` (string | EndlessVector | Array<string | EndlessVector>) - Vector(s) to concatenate
231
- - `tx` (Transaction, optional) - Existing transaction to append to
249
+ | Parameter | Type | Required | Description |
250
+ |-----------|------|----------|-------------|
251
+ | `cost` | bigint | no | Precomputed cost in FROST; skips the on-chain cost read |
252
+ | `walCoin` | TransactionObjectArgument | no | WAL coin to pay from; if omitted, one is sourced from the sender's balance |
253
+ | `timeout` | number | no | Tx confirmation timeout, ms |
254
+ | `pollIntervalMs` | number | no | Tx poll interval, ms |
255
+
256
+ #### getExtendBlobsToEpochTransaction(targetEndEpoch, params?)
257
+
258
+ Async. Returns the extend `Transaction` without executing, for batching. Accepts `cost`, `walCoin`, and `txToAppendTo`.
232
259
 
233
- **Returns:** Transaction
260
+ ## Seal Encryption
234
261
 
235
- ## Usage Examples
262
+ Seal provides end-to-end encryption for vector items. The access policy (`seal_approve_endless_vector_owner`) ensures only the vector owner can decrypt.
263
+
264
+ ### Creating an encrypted vector
236
265
 
237
266
  ```javascript
238
- const vector = new EndlessVector({
267
+ const ev = await EndlessVector.create({
239
268
  suiClient: client,
240
- id: '0xVECTOR_ID'
269
+ packageId: 'testnet',
270
+ sealClient,
271
+ signer: keypair,
272
+ signAndExecuteTransaction: sign,
241
273
  });
274
+ // AES key generated → Seal-wrapped → stored on-chain
275
+ // All push()/at() calls encrypt/decrypt transparently
276
+ ```
242
277
 
243
- await vector.initialize();
278
+ ### Reading an encrypted vector
244
279
 
245
- // Read metadata
246
- console.log('Items:', vector.length);
247
- console.log('Size:', vector.binaryLength, 'bytes');
248
- console.log('History segments:', vector.historyItemsCount);
249
- console.log('Archive segments:', vector.archiveItemsCount);
280
+ You can provide a `signer` and the SDK auto-creates a SessionKey:
250
281
 
251
- // Read specific item
252
- const item = await vector.at(42); // Uint8Array
282
+ ```javascript
283
+ const ev = new EndlessVector({
284
+ suiClient: client,
285
+ id: '0x...',
286
+ sealClient,
287
+ signer: keypair, // SDK creates a 5-minute SessionKey automatically
288
+ });
289
+ const data = await ev.at(0); // decrypted
253
290
  ```
254
291
 
255
- ### Custom Gas Coin for Parallel Operations
256
-
257
- To execute transactions in parallel, speeding up data upload process, you would probably need separate gas coin for each tx:
292
+ Or provide a pre-built `sessionKey` (useful in browser wallets where signing is interactive):
258
293
 
259
294
  ```javascript
260
- // Get available gas coins
261
- const coins = await client.getCoins({
262
- owner: address,
263
- coinType: '0x2::sui::SUI'
295
+ const ev = new EndlessVector({
296
+ suiClient: client,
297
+ id: '0x...',
298
+ sealClient,
299
+ sessionKey: mySessionKey, // created externally, e.g. via wallet adapter
264
300
  });
265
- const gasCoinRefs = coins.data.map(c => ({
266
- objectId: c.coinObjectId,
267
- digest: c.digest,
268
- version: c.version
269
- }));
301
+ const data = await ev.at(0); // decrypted using the provided SessionKey
302
+ ```
303
+
304
+ You can also set the session key after construction:
305
+
306
+ ```javascript
307
+ ev.seal._sessionKey = mySessionKey;
308
+ ```
309
+
310
+ ### How it works
311
+
312
+ 1. `create()` generates a random AES-256-GCM key
313
+ 2. The key is Seal-wrapped scoped to the vector's object ID and stored on-chain as `seal_encrypted_key`
314
+ 3. `push()` encrypts each item before storage (adds 28 bytes: 12B nonce + 16B GCM tag)
315
+ 4. `at()` unwraps the AES key via Seal (requires a valid SessionKey), then decrypts the item
316
+ 5. The unwrapped AES key is cached in memory for subsequent reads
317
+
318
+ Passing `sealClient` to an unencrypted vector is safe — `push()` and `at()` check for the on-chain `sealEncryptedKey` before attempting any encryption/decryption.
319
+
320
+ ## Examples
321
+
322
+ ### Archive and burn lifecycle
270
323
 
271
- // Create vectors in parallel, each with its own gas coin
324
+ ```javascript
325
+ await ev.push(largeData);
326
+ await ev.archive();
327
+ await ev.initialize();
328
+
329
+ console.log(ev.archiveItemsCount); // 1
330
+ console.log(ev.archivedAtLength); // e.g. 5
331
+
332
+ const item = await ev.at(0); // still readable
333
+
334
+ await ev.burnArchive();
335
+ await ev.initialize();
336
+
337
+ console.log(ev.burnedArchiveCount); // 1
338
+ console.log(ev.archivedFromLength); // 5 — items 0..4 are gone
339
+ await ev.at(0); // throws
340
+ ```
341
+
342
+ ### Parallel vector creation with gas coins
343
+
344
+ ```javascript
272
345
  const vectors = await Promise.all(
273
- testData.map((items, i) =>
346
+ dataChunks.map((chunk, i) =>
274
347
  EndlessVector.create({
275
348
  suiClient: client,
276
- packageId: 'testnet', // or 'mainnet' or '0xPACKAGE_ID'
277
- array: items,
349
+ packageId: 'testnet',
350
+ array: chunk,
278
351
  gasCoin: gasCoinRefs[i],
279
- signAndExecuteTransaction: async (tx) => {
280
- const result = await wallet.signAndExecuteTransaction({ transaction: tx });
281
- return result.digest;
282
- }
352
+ signAndExecuteTransaction: sign,
283
353
  })
284
354
  )
285
355
  );
@@ -287,38 +357,23 @@ const vectors = await Promise.all(
287
357
 
288
358
  ## Testing
289
359
 
290
- Run the test suite:
291
-
292
360
  ```bash
293
- npm test
361
+ pnpm test:base # core tests
362
+ pnpm test:seal # seal encryption tests
363
+ pnpm test:walrus-blobs # walrus blob storage
364
+ pnpm test:walrus-blobs-sdk # walrus blob storage (SDK client)
365
+ pnpm test:walrus-blobs-history # blob storage across history segments
366
+ pnpm test:walrus-blobs-extend # blob lifetime: min end epoch, cost, extend
294
367
  ```
295
368
 
296
- Tests use the TAP framework and require a configured local sui validator installed.
297
-
298
- ### Performance Considerations
299
-
300
- - **Caching**: Loaded history and archive segments are cached
301
- - **Lazy Loading**: History/archive data is only loaded when accessed
302
- - **Batch Writes**: Use `getPushTransaction()` to combine multiple pushes in one transaction
303
- - **Re-initialization**: After `push()` or `concat()`, metadata is refreshed on next read
304
-
305
- ### Concatenation
306
-
307
- The `concat()` method efficiently merges vectors by transferring ownership of internal data structures rather than copying items one by one. This makes it very efficient for combining large datasets.
308
-
309
- **Restrictions:**
310
- - Cannot concatenate vectors that have archived items
311
- - The concatenated vector is consumed (destroyed) in the process
312
- - All items from concatenated vector(s) are appended in order
369
+ Tests use [vitest](https://vitest.dev/) and require a local Sui validator with Walrus and Seal localnet services.
313
370
 
314
371
  ## License
315
372
 
316
373
  Apache-2.0
317
374
 
318
- ## Repository
319
-
320
- https://github.com/fizzyFlow/endless_vector
321
-
322
- ## Author
375
+ ## Links
323
376
 
324
- [suidouble](https://github.com/suidouble)
377
+ - [Repository](https://github.com/fizzyFlow/endless_vector)
378
+ - [npm](https://www.npmjs.com/package/@fizzyflow/endless-vector)
379
+ - [Author](https://github.com/suidouble)
package/ids.js CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
2
  export default {
3
3
  'testnet': {
4
- packageId: '0x609cf37d16c135b784f32db4755ed0dafbaa2d5e24ab6edfa25a45a9b4ca7ffd', // should be the same as in Move.lock
5
- originalPackageId: '0x30bf8e91f40774ed08234f767360b4154562232903928b5f2f8fe5b2d51655bc',
4
+ packageId: '0xaa7b048bc68a31204955da199b18020d68bb9823ae021b4c5d3f7245330ce825', // should be the same as in Move.lock
5
+ originalPackageId: '0xaa7b048bc68a31204955da199b18020d68bb9823ae021b4c5d3f7245330ce825',
6
6
  },
7
7
  'mainnet': {
8
- packageId: '0xf29b3e238f806fab64f2d838822786ccab4c7af9d096dbcd544a8d68957c9e9a', // should be the same as in Move.lock
9
- originalPackageId: '0x94cf19d164f014cfe73dda1121f27b54b69f0dbfa89d8b6ed48ae8a9144f5d65',
8
+ packageId: '0xec49cff1adbf19e0fdfa7933047162a749005fdfb64a1cebfb1ea5a8727b16f3', // should be the same as in Move.lock
9
+ originalPackageId: '0xec49cff1adbf19e0fdfa7933047162a749005fdfb64a1cebfb1ea5a8727b16f3',
10
10
  },
11
11
  };