@kynesyslabs/demosdk 2.8.10 → 2.8.11
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/build/storage/StorageProgram.d.ts +244 -54
- package/build/storage/StorageProgram.js +347 -69
- package/build/storage/StorageProgram.js.map +1 -1
- package/build/storage/index.d.ts +2 -1
- package/build/storage/index.js +6 -1
- package/build/storage/index.js.map +1 -1
- package/build/types/blockchain/TransactionSubtypes/StorageProgramTransaction.d.ts +124 -25
- package/build/types/blockchain/TransactionSubtypes/StorageProgramTransaction.js +47 -0
- package/build/types/blockchain/TransactionSubtypes/StorageProgramTransaction.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import type { StorageProgramPayload, StorageProgramAccessControl } from "../types/blockchain/TransactionSubtypes/StorageProgramTransaction";
|
|
1
|
+
import type { StorageProgramPayload, StorageProgramACL, StorageACLMode, StorageEncoding, StorageLocation, StorageGroupPermissions, StorageProgramAccessControl } from "../types/blockchain/TransactionSubtypes/StorageProgramTransaction";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* StorageProgram - Unified storage solution for Demos Network
|
|
4
|
+
*
|
|
5
|
+
* Supports both JSON (structured) and Binary (raw) data storage
|
|
6
|
+
* with robust access control and size-based pricing.
|
|
4
7
|
*
|
|
5
8
|
* Features:
|
|
6
9
|
* - Deterministic address derivation (stor-{sha256})
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
+
* - Dual encoding: JSON key-value or raw binary
|
|
11
|
+
* - Robust ACL: owner, allowed, blacklisted, public, groups
|
|
12
|
+
* - Size limit: 1MB for both encodings
|
|
13
|
+
* - Pricing: 1 DEM per 10KB
|
|
14
|
+
* - Permanent storage, owner/ACL-deletable only
|
|
15
|
+
* - IPFS-ready (stubs for future hybrid storage)
|
|
10
16
|
*
|
|
11
17
|
* @example
|
|
12
18
|
* ```typescript
|
|
13
19
|
* import { StorageProgram } from '@kynesyslabs/demosdk'
|
|
14
20
|
*
|
|
15
|
-
* //
|
|
16
|
-
* const
|
|
17
|
-
* '
|
|
18
|
-
* '
|
|
19
|
-
* '
|
|
21
|
+
* // Create JSON storage program
|
|
22
|
+
* const jsonPayload = StorageProgram.createStorageProgram(
|
|
23
|
+
* 'demos1abc...',
|
|
24
|
+
* 'myConfig',
|
|
25
|
+
* { apiKey: 'secret', settings: { theme: 'dark' } },
|
|
26
|
+
* 'json',
|
|
27
|
+
* { mode: 'public' }
|
|
20
28
|
* )
|
|
21
29
|
*
|
|
22
|
-
* // Create storage program
|
|
23
|
-
* const
|
|
24
|
-
* '
|
|
25
|
-
* '
|
|
26
|
-
*
|
|
27
|
-
* '
|
|
28
|
-
* '
|
|
30
|
+
* // Create Binary storage program
|
|
31
|
+
* const binaryPayload = StorageProgram.createStorageProgram(
|
|
32
|
+
* 'demos1abc...',
|
|
33
|
+
* 'myImage',
|
|
34
|
+
* Buffer.from(imageData).toString('base64'),
|
|
35
|
+
* 'binary',
|
|
36
|
+
* { mode: 'restricted', allowed: ['demos1user1...'] },
|
|
37
|
+
* { metadata: { filename: 'avatar.png', mimeType: 'image/png' } }
|
|
29
38
|
* )
|
|
30
39
|
* ```
|
|
31
40
|
*/
|
|
@@ -33,7 +42,7 @@ export declare class StorageProgram {
|
|
|
33
42
|
/**
|
|
34
43
|
* Derive a deterministic storage program address
|
|
35
44
|
*
|
|
36
|
-
* @param deployerAddress - Address of the program deployer
|
|
45
|
+
* @param deployerAddress - Address of the program deployer (will be owner)
|
|
37
46
|
* @param programName - Name of the storage program
|
|
38
47
|
* @param salt - Optional random salt for uniqueness (default: empty string)
|
|
39
48
|
* @returns Storage address in format: stor-{first 40 chars of sha256}
|
|
@@ -52,43 +61,75 @@ export declare class StorageProgram {
|
|
|
52
61
|
/**
|
|
53
62
|
* Create a new Storage Program
|
|
54
63
|
*
|
|
55
|
-
* @param deployerAddress - Address creating the storage program (
|
|
56
|
-
* @param programName -
|
|
57
|
-
* @param
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
* @param
|
|
64
|
+
* @param deployerAddress - Address creating the storage program (becomes owner)
|
|
65
|
+
* @param programName - Unique name for the program
|
|
66
|
+
* @param data - Initial data (JSON object or base64 binary string)
|
|
67
|
+
* @param encoding - "json" or "binary" (default: "json")
|
|
68
|
+
* @param acl - Access control configuration (default: owner-only)
|
|
69
|
+
* @param options - Additional options (salt, metadata, storageLocation)
|
|
61
70
|
* @returns StorageProgramPayload for transaction creation
|
|
62
71
|
*
|
|
63
72
|
* @example
|
|
64
73
|
* ```typescript
|
|
74
|
+
* // JSON storage with public read access
|
|
75
|
+
* const payload = StorageProgram.createStorageProgram(
|
|
76
|
+
* 'demos1abc...',
|
|
77
|
+
* 'appConfig',
|
|
78
|
+
* { version: '1.0', features: ['auth', 'storage'] },
|
|
79
|
+
* 'json',
|
|
80
|
+
* { mode: 'public' }
|
|
81
|
+
* )
|
|
82
|
+
*
|
|
83
|
+
* // Binary storage with group access
|
|
65
84
|
* const payload = StorageProgram.createStorageProgram(
|
|
66
85
|
* 'demos1abc...',
|
|
67
|
-
* '
|
|
68
|
-
*
|
|
69
|
-
* '
|
|
86
|
+
* 'teamDocument',
|
|
87
|
+
* base64EncodedPdf,
|
|
88
|
+
* 'binary',
|
|
89
|
+
* {
|
|
90
|
+
* mode: 'restricted',
|
|
91
|
+
* groups: {
|
|
92
|
+
* editors: { members: ['demos1a...', 'demos1b...'], permissions: ['read', 'write'] },
|
|
93
|
+
* viewers: { members: ['demos1c...'], permissions: ['read'] }
|
|
94
|
+
* }
|
|
95
|
+
* },
|
|
96
|
+
* { metadata: { filename: 'report.pdf', mimeType: 'application/pdf' } }
|
|
70
97
|
* )
|
|
71
98
|
* ```
|
|
72
99
|
*/
|
|
73
|
-
static createStorageProgram(deployerAddress: string, programName: string,
|
|
100
|
+
static createStorageProgram(deployerAddress: string, programName: string, data: Record<string, any> | string, encoding?: StorageEncoding, acl?: Partial<StorageProgramACL>, options?: {
|
|
101
|
+
salt?: string;
|
|
102
|
+
metadata?: Record<string, unknown>;
|
|
103
|
+
storageLocation?: StorageLocation;
|
|
104
|
+
}): StorageProgramPayload;
|
|
74
105
|
/**
|
|
75
|
-
* Write
|
|
106
|
+
* Write/update data in a Storage Program
|
|
76
107
|
*
|
|
77
108
|
* @param storageAddress - The storage program address (stor-{hash})
|
|
78
|
-
* @param data -
|
|
109
|
+
* @param data - Data to write (JSON object or base64 binary string)
|
|
110
|
+
* @param encoding - "json" or "binary" (default: "json")
|
|
79
111
|
* @returns StorageProgramPayload for transaction creation
|
|
80
112
|
*
|
|
81
113
|
* @example
|
|
82
114
|
* ```typescript
|
|
115
|
+
* // Update JSON data
|
|
116
|
+
* const payload = StorageProgram.writeStorage(
|
|
117
|
+
* 'stor-7a8b9c...',
|
|
118
|
+
* { newKey: 'value', existingKey: 'updatedValue' },
|
|
119
|
+
* 'json'
|
|
120
|
+
* )
|
|
121
|
+
*
|
|
122
|
+
* // Update binary data
|
|
83
123
|
* const payload = StorageProgram.writeStorage(
|
|
84
124
|
* 'stor-7a8b9c...',
|
|
85
|
-
*
|
|
125
|
+
* newBase64Content,
|
|
126
|
+
* 'binary'
|
|
86
127
|
* )
|
|
87
128
|
* ```
|
|
88
129
|
*/
|
|
89
|
-
static writeStorage(storageAddress: string, data: Record<string, any>): StorageProgramPayload;
|
|
130
|
+
static writeStorage(storageAddress: string, data: Record<string, any> | string, encoding?: StorageEncoding): StorageProgramPayload;
|
|
90
131
|
/**
|
|
91
|
-
* Read data from a Storage Program (
|
|
132
|
+
* Read data from a Storage Program (creates payload for RPC)
|
|
92
133
|
*
|
|
93
134
|
* Note: This creates a payload for validation purposes.
|
|
94
135
|
* Actual reads should use RPC endpoints like GET /storage-program/:address
|
|
@@ -107,32 +148,45 @@ export declare class StorageProgram {
|
|
|
107
148
|
*/
|
|
108
149
|
static readStorage(storageAddress: string): StorageProgramPayload;
|
|
109
150
|
/**
|
|
110
|
-
* Update access control settings for a Storage Program (
|
|
151
|
+
* Update access control settings for a Storage Program (owner only)
|
|
111
152
|
*
|
|
112
153
|
* @param storageAddress - The storage program address
|
|
113
|
-
* @param
|
|
114
|
-
* @param allowedAddresses - Updated list of allowed addresses (for 'restricted' mode)
|
|
154
|
+
* @param acl - New access control configuration
|
|
115
155
|
* @returns StorageProgramPayload for transaction creation
|
|
116
156
|
*
|
|
117
157
|
* @example
|
|
118
158
|
* ```typescript
|
|
119
|
-
* // Change
|
|
159
|
+
* // Change to public access
|
|
120
160
|
* const payload = StorageProgram.updateAccessControl(
|
|
121
161
|
* 'stor-7a8b9c...',
|
|
122
|
-
* 'public'
|
|
162
|
+
* { mode: 'public' }
|
|
123
163
|
* )
|
|
124
164
|
*
|
|
125
|
-
* //
|
|
165
|
+
* // Add users to blacklist
|
|
126
166
|
* const payload = StorageProgram.updateAccessControl(
|
|
127
167
|
* 'stor-7a8b9c...',
|
|
128
|
-
*
|
|
129
|
-
*
|
|
168
|
+
* {
|
|
169
|
+
* mode: 'public',
|
|
170
|
+
* blacklisted: ['demos1bad...', 'demos1spam...']
|
|
171
|
+
* }
|
|
172
|
+
* )
|
|
173
|
+
*
|
|
174
|
+
* // Set up group-based access
|
|
175
|
+
* const payload = StorageProgram.updateAccessControl(
|
|
176
|
+
* 'stor-7a8b9c...',
|
|
177
|
+
* {
|
|
178
|
+
* mode: 'restricted',
|
|
179
|
+
* groups: {
|
|
180
|
+
* admins: { members: ['demos1admin...'], permissions: ['read', 'write', 'delete'] },
|
|
181
|
+
* users: { members: ['demos1user1...', 'demos1user2...'], permissions: ['read'] }
|
|
182
|
+
* }
|
|
183
|
+
* }
|
|
130
184
|
* )
|
|
131
185
|
* ```
|
|
132
186
|
*/
|
|
133
|
-
static updateAccessControl(storageAddress: string,
|
|
187
|
+
static updateAccessControl(storageAddress: string, acl: Partial<StorageProgramACL>): StorageProgramPayload;
|
|
134
188
|
/**
|
|
135
|
-
* Delete
|
|
189
|
+
* Delete a Storage Program (owner/ACL-permissioned only)
|
|
136
190
|
*
|
|
137
191
|
* WARNING: This operation is irreversible and will delete all stored data.
|
|
138
192
|
*
|
|
@@ -146,35 +200,66 @@ export declare class StorageProgram {
|
|
|
146
200
|
*/
|
|
147
201
|
static deleteStorageProgram(storageAddress: string): StorageProgramPayload;
|
|
148
202
|
/**
|
|
149
|
-
* Validate
|
|
203
|
+
* Validate data size against 1MB limit
|
|
150
204
|
*
|
|
151
|
-
* @param data -
|
|
152
|
-
* @
|
|
205
|
+
* @param data - Data to validate (JSON object or base64 string)
|
|
206
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
207
|
+
* @returns true if size is within 1MB limit, false otherwise
|
|
153
208
|
*
|
|
154
209
|
* @example
|
|
155
210
|
* ```typescript
|
|
156
|
-
*
|
|
157
|
-
* if (StorageProgram.validateSize(
|
|
211
|
+
* // Validate JSON data
|
|
212
|
+
* if (StorageProgram.validateSize({ key: 'value' }, 'json')) {
|
|
213
|
+
* // Safe to store
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
* // Validate binary data
|
|
217
|
+
* if (StorageProgram.validateSize(base64String, 'binary')) {
|
|
158
218
|
* // Safe to store
|
|
159
219
|
* }
|
|
160
220
|
* ```
|
|
161
221
|
*/
|
|
162
|
-
static validateSize(data: Record<string, any>): boolean;
|
|
222
|
+
static validateSize(data: Record<string, any> | string, encoding?: StorageEncoding): boolean;
|
|
163
223
|
/**
|
|
164
|
-
* Get
|
|
224
|
+
* Get data size in bytes
|
|
165
225
|
*
|
|
166
|
-
* @param data -
|
|
226
|
+
* @param data - Data to measure (JSON object or base64 string)
|
|
227
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
167
228
|
* @returns Size in bytes
|
|
168
229
|
*
|
|
169
230
|
* @example
|
|
170
231
|
* ```typescript
|
|
171
|
-
* const size = StorageProgram.getDataSize({ key: 'value' })
|
|
232
|
+
* const size = StorageProgram.getDataSize({ key: 'value' }, 'json')
|
|
172
233
|
* console.log(`Data size: ${size} bytes`)
|
|
173
234
|
* ```
|
|
174
235
|
*/
|
|
175
|
-
static getDataSize(data: Record<string, any>): number;
|
|
236
|
+
static getDataSize(data: Record<string, any> | string, encoding?: StorageEncoding): number;
|
|
176
237
|
/**
|
|
177
|
-
*
|
|
238
|
+
* Calculate storage fee based on data size
|
|
239
|
+
*
|
|
240
|
+
* Pricing: 1 DEM per 10KB (minimum 1 DEM)
|
|
241
|
+
*
|
|
242
|
+
* @param data - Data to calculate fee for (JSON object or base64 string)
|
|
243
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
244
|
+
* @returns Fee in DEM (bigint)
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const fee = StorageProgram.calculateStorageFee({ key: 'value' }, 'json')
|
|
249
|
+
* console.log(`Storage fee: ${fee} DEM`)
|
|
250
|
+
*
|
|
251
|
+
* // Examples:
|
|
252
|
+
* // 5KB -> 1 DEM
|
|
253
|
+
* // 15KB -> 2 DEM
|
|
254
|
+
* // 100KB -> 10 DEM
|
|
255
|
+
* // 1MB -> 103 DEM
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
static calculateStorageFee(data: Record<string, any> | string, encoding?: StorageEncoding): bigint;
|
|
259
|
+
/**
|
|
260
|
+
* Validate JSON nesting depth (max 64 levels)
|
|
261
|
+
*
|
|
262
|
+
* Only applicable for JSON encoding.
|
|
178
263
|
*
|
|
179
264
|
* @param data - The data object to validate
|
|
180
265
|
* @param maxDepth - Maximum allowed nesting depth (default: 64)
|
|
@@ -189,4 +274,109 @@ export declare class StorageProgram {
|
|
|
189
274
|
* ```
|
|
190
275
|
*/
|
|
191
276
|
static validateNestingDepth(data: any, maxDepth?: number): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Check if an address has permission for an operation
|
|
279
|
+
*
|
|
280
|
+
* ACL Resolution Priority:
|
|
281
|
+
* 1. Owner -> FULL ACCESS (always)
|
|
282
|
+
* 2. Blacklisted -> DENIED (even if in allowed/groups)
|
|
283
|
+
* 3. Allowed -> permissions granted
|
|
284
|
+
* 4. Groups -> check group permissions
|
|
285
|
+
* 5. Mode fallback: owner/restricted -> DENIED, public -> READ only
|
|
286
|
+
*
|
|
287
|
+
* @param acl - Access control configuration
|
|
288
|
+
* @param ownerAddress - Owner address of the storage program
|
|
289
|
+
* @param requestingAddress - Address requesting permission
|
|
290
|
+
* @param permission - Permission type to check
|
|
291
|
+
* @returns true if permission is granted
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```typescript
|
|
295
|
+
* const acl = { mode: 'public', blacklisted: ['demos1spam...'] }
|
|
296
|
+
* const canRead = StorageProgram.checkPermission(acl, owner, user, 'read')
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
static checkPermission(acl: StorageProgramACL, ownerAddress: string, requestingAddress: string, permission: "read" | "write" | "delete"): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Create a public ACL (anyone can read, owner writes)
|
|
302
|
+
*
|
|
303
|
+
* @returns StorageProgramACL configured for public read access
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* const acl = StorageProgram.publicACL()
|
|
308
|
+
* // { mode: 'public' }
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
static publicACL(): StorageProgramACL;
|
|
312
|
+
/**
|
|
313
|
+
* Create a private/owner-only ACL
|
|
314
|
+
*
|
|
315
|
+
* @returns StorageProgramACL configured for owner-only access
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* const acl = StorageProgram.privateACL()
|
|
320
|
+
* // { mode: 'owner' }
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
static privateACL(): StorageProgramACL;
|
|
324
|
+
/**
|
|
325
|
+
* Create a restricted ACL with allowed addresses
|
|
326
|
+
*
|
|
327
|
+
* @param allowed - List of addresses allowed to access
|
|
328
|
+
* @returns StorageProgramACL configured for restricted access
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* const acl = StorageProgram.restrictedACL(['demos1a...', 'demos1b...'])
|
|
333
|
+
* // { mode: 'restricted', allowed: ['demos1a...', 'demos1b...'] }
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
static restrictedACL(allowed: string[]): StorageProgramACL;
|
|
337
|
+
/**
|
|
338
|
+
* Create a group-based ACL
|
|
339
|
+
*
|
|
340
|
+
* @param groups - Named groups with members and permissions
|
|
341
|
+
* @returns StorageProgramACL configured for group-based access
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```typescript
|
|
345
|
+
* const acl = StorageProgram.groupACL({
|
|
346
|
+
* admins: { members: ['demos1admin...'], permissions: ['read', 'write', 'delete'] },
|
|
347
|
+
* editors: { members: ['demos1ed1...', 'demos1ed2...'], permissions: ['read', 'write'] },
|
|
348
|
+
* viewers: { members: ['demos1view...'], permissions: ['read'] }
|
|
349
|
+
* })
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
static groupACL(groups: Record<string, StorageGroupPermissions>): StorageProgramACL;
|
|
353
|
+
/**
|
|
354
|
+
* Create an ACL with a blacklist
|
|
355
|
+
*
|
|
356
|
+
* @param mode - Base mode ('public' or 'restricted')
|
|
357
|
+
* @param blacklisted - Addresses to block
|
|
358
|
+
* @param allowed - Optional allowed addresses (for restricted mode)
|
|
359
|
+
* @returns StorageProgramACL with blacklist configured
|
|
360
|
+
*
|
|
361
|
+
* @example
|
|
362
|
+
* ```typescript
|
|
363
|
+
* // Public but block spam addresses
|
|
364
|
+
* const acl = StorageProgram.blacklistACL('public', ['demos1spam...'])
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
static blacklistACL(mode: StorageACLMode, blacklisted: string[], allowed?: string[]): StorageProgramACL;
|
|
368
|
+
/**
|
|
369
|
+
* @deprecated Use createStorageProgram with acl parameter instead.
|
|
370
|
+
* Kept for backward compatibility.
|
|
371
|
+
*
|
|
372
|
+
* Create a new Storage Program with legacy access control
|
|
373
|
+
*/
|
|
374
|
+
static createStorageProgramLegacy(deployerAddress: string, programName: string, initialData: Record<string, any>, accessControl?: StorageProgramAccessControl, salt?: string, allowedAddresses?: string[]): StorageProgramPayload;
|
|
375
|
+
/**
|
|
376
|
+
* @deprecated Use updateAccessControl with acl parameter instead.
|
|
377
|
+
* Kept for backward compatibility.
|
|
378
|
+
*
|
|
379
|
+
* Update access control with legacy mode
|
|
380
|
+
*/
|
|
381
|
+
static updateAccessControlLegacy(storageAddress: string, accessControl: StorageProgramAccessControl, allowedAddresses?: string[]): StorageProgramPayload;
|
|
192
382
|
}
|
|
@@ -2,42 +2,55 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StorageProgram = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
|
-
|
|
5
|
+
const StorageProgramTransaction_1 = require("../types/blockchain/TransactionSubtypes/StorageProgramTransaction");
|
|
6
|
+
// REVIEW: Unified Storage Program class for both JSON and Binary storage with robust ACL
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* StorageProgram - Unified storage solution for Demos Network
|
|
9
|
+
*
|
|
10
|
+
* Supports both JSON (structured) and Binary (raw) data storage
|
|
11
|
+
* with robust access control and size-based pricing.
|
|
8
12
|
*
|
|
9
13
|
* Features:
|
|
10
14
|
* - Deterministic address derivation (stor-{sha256})
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
15
|
+
* - Dual encoding: JSON key-value or raw binary
|
|
16
|
+
* - Robust ACL: owner, allowed, blacklisted, public, groups
|
|
17
|
+
* - Size limit: 1MB for both encodings
|
|
18
|
+
* - Pricing: 1 DEM per 10KB
|
|
19
|
+
* - Permanent storage, owner/ACL-deletable only
|
|
20
|
+
* - IPFS-ready (stubs for future hybrid storage)
|
|
14
21
|
*
|
|
15
22
|
* @example
|
|
16
23
|
* ```typescript
|
|
17
24
|
* import { StorageProgram } from '@kynesyslabs/demosdk'
|
|
18
25
|
*
|
|
19
|
-
* //
|
|
20
|
-
* const
|
|
21
|
-
* '
|
|
22
|
-
* '
|
|
23
|
-
* '
|
|
26
|
+
* // Create JSON storage program
|
|
27
|
+
* const jsonPayload = StorageProgram.createStorageProgram(
|
|
28
|
+
* 'demos1abc...',
|
|
29
|
+
* 'myConfig',
|
|
30
|
+
* { apiKey: 'secret', settings: { theme: 'dark' } },
|
|
31
|
+
* 'json',
|
|
32
|
+
* { mode: 'public' }
|
|
24
33
|
* )
|
|
25
34
|
*
|
|
26
|
-
* // Create storage program
|
|
27
|
-
* const
|
|
28
|
-
* '
|
|
29
|
-
* '
|
|
30
|
-
*
|
|
31
|
-
* '
|
|
32
|
-
* '
|
|
35
|
+
* // Create Binary storage program
|
|
36
|
+
* const binaryPayload = StorageProgram.createStorageProgram(
|
|
37
|
+
* 'demos1abc...',
|
|
38
|
+
* 'myImage',
|
|
39
|
+
* Buffer.from(imageData).toString('base64'),
|
|
40
|
+
* 'binary',
|
|
41
|
+
* { mode: 'restricted', allowed: ['demos1user1...'] },
|
|
42
|
+
* { metadata: { filename: 'avatar.png', mimeType: 'image/png' } }
|
|
33
43
|
* )
|
|
34
44
|
* ```
|
|
35
45
|
*/
|
|
36
46
|
class StorageProgram {
|
|
47
|
+
// ========================================================================
|
|
48
|
+
// Address Derivation
|
|
49
|
+
// ========================================================================
|
|
37
50
|
/**
|
|
38
51
|
* Derive a deterministic storage program address
|
|
39
52
|
*
|
|
40
|
-
* @param deployerAddress - Address of the program deployer
|
|
53
|
+
* @param deployerAddress - Address of the program deployer (will be owner)
|
|
41
54
|
* @param programName - Name of the storage program
|
|
42
55
|
* @param salt - Optional random salt for uniqueness (default: empty string)
|
|
43
56
|
* @returns Storage address in format: stor-{first 40 chars of sha256}
|
|
@@ -60,64 +73,103 @@ class StorageProgram {
|
|
|
60
73
|
const addressHash = hash.substring(0, 40);
|
|
61
74
|
return `stor-${addressHash}`;
|
|
62
75
|
}
|
|
76
|
+
// ========================================================================
|
|
77
|
+
// Program Operations
|
|
78
|
+
// ========================================================================
|
|
63
79
|
/**
|
|
64
80
|
* Create a new Storage Program
|
|
65
81
|
*
|
|
66
|
-
* @param deployerAddress - Address creating the storage program (
|
|
67
|
-
* @param programName -
|
|
68
|
-
* @param
|
|
69
|
-
* @param
|
|
70
|
-
* @param
|
|
71
|
-
* @param
|
|
82
|
+
* @param deployerAddress - Address creating the storage program (becomes owner)
|
|
83
|
+
* @param programName - Unique name for the program
|
|
84
|
+
* @param data - Initial data (JSON object or base64 binary string)
|
|
85
|
+
* @param encoding - "json" or "binary" (default: "json")
|
|
86
|
+
* @param acl - Access control configuration (default: owner-only)
|
|
87
|
+
* @param options - Additional options (salt, metadata, storageLocation)
|
|
72
88
|
* @returns StorageProgramPayload for transaction creation
|
|
73
89
|
*
|
|
74
90
|
* @example
|
|
75
91
|
* ```typescript
|
|
92
|
+
* // JSON storage with public read access
|
|
76
93
|
* const payload = StorageProgram.createStorageProgram(
|
|
77
94
|
* 'demos1abc...',
|
|
78
|
-
* '
|
|
79
|
-
* {
|
|
80
|
-
* '
|
|
95
|
+
* 'appConfig',
|
|
96
|
+
* { version: '1.0', features: ['auth', 'storage'] },
|
|
97
|
+
* 'json',
|
|
98
|
+
* { mode: 'public' }
|
|
99
|
+
* )
|
|
100
|
+
*
|
|
101
|
+
* // Binary storage with group access
|
|
102
|
+
* const payload = StorageProgram.createStorageProgram(
|
|
103
|
+
* 'demos1abc...',
|
|
104
|
+
* 'teamDocument',
|
|
105
|
+
* base64EncodedPdf,
|
|
106
|
+
* 'binary',
|
|
107
|
+
* {
|
|
108
|
+
* mode: 'restricted',
|
|
109
|
+
* groups: {
|
|
110
|
+
* editors: { members: ['demos1a...', 'demos1b...'], permissions: ['read', 'write'] },
|
|
111
|
+
* viewers: { members: ['demos1c...'], permissions: ['read'] }
|
|
112
|
+
* }
|
|
113
|
+
* },
|
|
114
|
+
* { metadata: { filename: 'report.pdf', mimeType: 'application/pdf' } }
|
|
81
115
|
* )
|
|
82
116
|
* ```
|
|
83
117
|
*/
|
|
84
|
-
static createStorageProgram(deployerAddress, programName,
|
|
85
|
-
|
|
86
|
-
const
|
|
118
|
+
static createStorageProgram(deployerAddress, programName, data, encoding = "json", acl, options) {
|
|
119
|
+
const storageAddress = this.deriveStorageAddress(deployerAddress, programName, options?.salt || "");
|
|
120
|
+
const fullACL = {
|
|
121
|
+
mode: acl?.mode || "owner",
|
|
122
|
+
allowed: acl?.allowed,
|
|
123
|
+
blacklisted: acl?.blacklisted,
|
|
124
|
+
groups: acl?.groups,
|
|
125
|
+
};
|
|
87
126
|
return {
|
|
88
127
|
operation: "CREATE_STORAGE_PROGRAM",
|
|
89
128
|
storageAddress,
|
|
90
129
|
programName,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
salt,
|
|
130
|
+
encoding,
|
|
131
|
+
data,
|
|
132
|
+
acl: fullACL,
|
|
133
|
+
salt: options?.salt,
|
|
134
|
+
metadata: options?.metadata,
|
|
135
|
+
storageLocation: options?.storageLocation || "onchain",
|
|
95
136
|
};
|
|
96
137
|
}
|
|
97
138
|
/**
|
|
98
|
-
* Write
|
|
139
|
+
* Write/update data in a Storage Program
|
|
99
140
|
*
|
|
100
141
|
* @param storageAddress - The storage program address (stor-{hash})
|
|
101
|
-
* @param data -
|
|
142
|
+
* @param data - Data to write (JSON object or base64 binary string)
|
|
143
|
+
* @param encoding - "json" or "binary" (default: "json")
|
|
102
144
|
* @returns StorageProgramPayload for transaction creation
|
|
103
145
|
*
|
|
104
146
|
* @example
|
|
105
147
|
* ```typescript
|
|
148
|
+
* // Update JSON data
|
|
149
|
+
* const payload = StorageProgram.writeStorage(
|
|
150
|
+
* 'stor-7a8b9c...',
|
|
151
|
+
* { newKey: 'value', existingKey: 'updatedValue' },
|
|
152
|
+
* 'json'
|
|
153
|
+
* )
|
|
154
|
+
*
|
|
155
|
+
* // Update binary data
|
|
106
156
|
* const payload = StorageProgram.writeStorage(
|
|
107
157
|
* 'stor-7a8b9c...',
|
|
108
|
-
*
|
|
158
|
+
* newBase64Content,
|
|
159
|
+
* 'binary'
|
|
109
160
|
* )
|
|
110
161
|
* ```
|
|
111
162
|
*/
|
|
112
|
-
static writeStorage(storageAddress, data) {
|
|
163
|
+
static writeStorage(storageAddress, data, encoding = "json") {
|
|
113
164
|
return {
|
|
114
165
|
operation: "WRITE_STORAGE",
|
|
115
166
|
storageAddress,
|
|
116
167
|
data,
|
|
168
|
+
encoding,
|
|
117
169
|
};
|
|
118
170
|
}
|
|
119
171
|
/**
|
|
120
|
-
* Read data from a Storage Program (
|
|
172
|
+
* Read data from a Storage Program (creates payload for RPC)
|
|
121
173
|
*
|
|
122
174
|
* Note: This creates a payload for validation purposes.
|
|
123
175
|
* Actual reads should use RPC endpoints like GET /storage-program/:address
|
|
@@ -141,39 +193,51 @@ class StorageProgram {
|
|
|
141
193
|
};
|
|
142
194
|
}
|
|
143
195
|
/**
|
|
144
|
-
* Update access control settings for a Storage Program (
|
|
196
|
+
* Update access control settings for a Storage Program (owner only)
|
|
145
197
|
*
|
|
146
198
|
* @param storageAddress - The storage program address
|
|
147
|
-
* @param
|
|
148
|
-
* @param allowedAddresses - Updated list of allowed addresses (for 'restricted' mode)
|
|
199
|
+
* @param acl - New access control configuration
|
|
149
200
|
* @returns StorageProgramPayload for transaction creation
|
|
150
201
|
*
|
|
151
202
|
* @example
|
|
152
203
|
* ```typescript
|
|
153
|
-
* // Change
|
|
204
|
+
* // Change to public access
|
|
205
|
+
* const payload = StorageProgram.updateAccessControl(
|
|
206
|
+
* 'stor-7a8b9c...',
|
|
207
|
+
* { mode: 'public' }
|
|
208
|
+
* )
|
|
209
|
+
*
|
|
210
|
+
* // Add users to blacklist
|
|
154
211
|
* const payload = StorageProgram.updateAccessControl(
|
|
155
212
|
* 'stor-7a8b9c...',
|
|
156
|
-
*
|
|
213
|
+
* {
|
|
214
|
+
* mode: 'public',
|
|
215
|
+
* blacklisted: ['demos1bad...', 'demos1spam...']
|
|
216
|
+
* }
|
|
157
217
|
* )
|
|
158
218
|
*
|
|
159
|
-
* // Set
|
|
219
|
+
* // Set up group-based access
|
|
160
220
|
* const payload = StorageProgram.updateAccessControl(
|
|
161
221
|
* 'stor-7a8b9c...',
|
|
162
|
-
*
|
|
163
|
-
*
|
|
222
|
+
* {
|
|
223
|
+
* mode: 'restricted',
|
|
224
|
+
* groups: {
|
|
225
|
+
* admins: { members: ['demos1admin...'], permissions: ['read', 'write', 'delete'] },
|
|
226
|
+
* users: { members: ['demos1user1...', 'demos1user2...'], permissions: ['read'] }
|
|
227
|
+
* }
|
|
228
|
+
* }
|
|
164
229
|
* )
|
|
165
230
|
* ```
|
|
166
231
|
*/
|
|
167
|
-
static updateAccessControl(storageAddress,
|
|
232
|
+
static updateAccessControl(storageAddress, acl) {
|
|
168
233
|
return {
|
|
169
234
|
operation: "UPDATE_ACCESS_CONTROL",
|
|
170
235
|
storageAddress,
|
|
171
|
-
|
|
172
|
-
allowedAddresses,
|
|
236
|
+
acl: acl,
|
|
173
237
|
};
|
|
174
238
|
}
|
|
175
239
|
/**
|
|
176
|
-
* Delete
|
|
240
|
+
* Delete a Storage Program (owner/ACL-permissioned only)
|
|
177
241
|
*
|
|
178
242
|
* WARNING: This operation is irreversible and will delete all stored data.
|
|
179
243
|
*
|
|
@@ -191,44 +255,91 @@ class StorageProgram {
|
|
|
191
255
|
storageAddress,
|
|
192
256
|
};
|
|
193
257
|
}
|
|
258
|
+
// ========================================================================
|
|
259
|
+
// Validation Helpers
|
|
260
|
+
// ========================================================================
|
|
194
261
|
/**
|
|
195
|
-
* Validate
|
|
262
|
+
* Validate data size against 1MB limit
|
|
196
263
|
*
|
|
197
|
-
* @param data -
|
|
198
|
-
* @
|
|
264
|
+
* @param data - Data to validate (JSON object or base64 string)
|
|
265
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
266
|
+
* @returns true if size is within 1MB limit, false otherwise
|
|
199
267
|
*
|
|
200
268
|
* @example
|
|
201
269
|
* ```typescript
|
|
202
|
-
*
|
|
203
|
-
* if (StorageProgram.validateSize(
|
|
270
|
+
* // Validate JSON data
|
|
271
|
+
* if (StorageProgram.validateSize({ key: 'value' }, 'json')) {
|
|
272
|
+
* // Safe to store
|
|
273
|
+
* }
|
|
274
|
+
*
|
|
275
|
+
* // Validate binary data
|
|
276
|
+
* if (StorageProgram.validateSize(base64String, 'binary')) {
|
|
204
277
|
* // Safe to store
|
|
205
278
|
* }
|
|
206
279
|
* ```
|
|
207
280
|
*/
|
|
208
|
-
static validateSize(data) {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
const maxSizeInBytes = 128 * 1024; // 128KB
|
|
212
|
-
return sizeInBytes <= maxSizeInBytes;
|
|
281
|
+
static validateSize(data, encoding = "json") {
|
|
282
|
+
const sizeBytes = this.getDataSize(data, encoding);
|
|
283
|
+
return sizeBytes <= StorageProgramTransaction_1.STORAGE_PROGRAM_CONSTANTS.MAX_SIZE_BYTES;
|
|
213
284
|
}
|
|
214
285
|
/**
|
|
215
|
-
* Get
|
|
286
|
+
* Get data size in bytes
|
|
216
287
|
*
|
|
217
|
-
* @param data -
|
|
288
|
+
* @param data - Data to measure (JSON object or base64 string)
|
|
289
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
218
290
|
* @returns Size in bytes
|
|
219
291
|
*
|
|
220
292
|
* @example
|
|
221
293
|
* ```typescript
|
|
222
|
-
* const size = StorageProgram.getDataSize({ key: 'value' })
|
|
294
|
+
* const size = StorageProgram.getDataSize({ key: 'value' }, 'json')
|
|
223
295
|
* console.log(`Data size: ${size} bytes`)
|
|
224
296
|
* ```
|
|
225
297
|
*/
|
|
226
|
-
static getDataSize(data) {
|
|
227
|
-
|
|
228
|
-
|
|
298
|
+
static getDataSize(data, encoding = "json") {
|
|
299
|
+
if (encoding === "binary") {
|
|
300
|
+
// Binary data is base64 encoded, decode to get actual size
|
|
301
|
+
// Base64 encoding: every 4 chars = 3 bytes
|
|
302
|
+
const base64String = data;
|
|
303
|
+
// Remove padding and calculate
|
|
304
|
+
const padding = (base64String.match(/=/g) || []).length;
|
|
305
|
+
return Math.floor((base64String.length * 3) / 4) - padding;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
// JSON data - measure serialized size
|
|
309
|
+
const jsonString = JSON.stringify(data);
|
|
310
|
+
return new TextEncoder().encode(jsonString).length;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Calculate storage fee based on data size
|
|
315
|
+
*
|
|
316
|
+
* Pricing: 1 DEM per 10KB (minimum 1 DEM)
|
|
317
|
+
*
|
|
318
|
+
* @param data - Data to calculate fee for (JSON object or base64 string)
|
|
319
|
+
* @param encoding - Encoding type ("json" or "binary")
|
|
320
|
+
* @returns Fee in DEM (bigint)
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```typescript
|
|
324
|
+
* const fee = StorageProgram.calculateStorageFee({ key: 'value' }, 'json')
|
|
325
|
+
* console.log(`Storage fee: ${fee} DEM`)
|
|
326
|
+
*
|
|
327
|
+
* // Examples:
|
|
328
|
+
* // 5KB -> 1 DEM
|
|
329
|
+
* // 15KB -> 2 DEM
|
|
330
|
+
* // 100KB -> 10 DEM
|
|
331
|
+
* // 1MB -> 103 DEM
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
static calculateStorageFee(data, encoding = "json") {
|
|
335
|
+
const sizeBytes = this.getDataSize(data, encoding);
|
|
336
|
+
const chunks = Math.ceil(sizeBytes / StorageProgramTransaction_1.STORAGE_PROGRAM_CONSTANTS.PRICING_CHUNK_BYTES);
|
|
337
|
+
return BigInt(Math.max(1, chunks)) * StorageProgramTransaction_1.STORAGE_PROGRAM_CONSTANTS.FEE_PER_CHUNK;
|
|
229
338
|
}
|
|
230
339
|
/**
|
|
231
|
-
* Validate nesting depth (max 64 levels)
|
|
340
|
+
* Validate JSON nesting depth (max 64 levels)
|
|
341
|
+
*
|
|
342
|
+
* Only applicable for JSON encoding.
|
|
232
343
|
*
|
|
233
344
|
* @param data - The data object to validate
|
|
234
345
|
* @param maxDepth - Maximum allowed nesting depth (default: 64)
|
|
@@ -242,7 +353,7 @@ class StorageProgram {
|
|
|
242
353
|
* }
|
|
243
354
|
* ```
|
|
244
355
|
*/
|
|
245
|
-
static validateNestingDepth(data, maxDepth =
|
|
356
|
+
static validateNestingDepth(data, maxDepth = StorageProgramTransaction_1.STORAGE_PROGRAM_CONSTANTS.MAX_JSON_NESTING_DEPTH) {
|
|
246
357
|
const getDepth = (obj, currentDepth = 1) => {
|
|
247
358
|
if (typeof obj !== "object" || obj === null) {
|
|
248
359
|
return currentDepth;
|
|
@@ -252,6 +363,173 @@ class StorageProgram {
|
|
|
252
363
|
};
|
|
253
364
|
return getDepth(data) <= maxDepth;
|
|
254
365
|
}
|
|
366
|
+
// ========================================================================
|
|
367
|
+
// ACL Helpers
|
|
368
|
+
// ========================================================================
|
|
369
|
+
/**
|
|
370
|
+
* Check if an address has permission for an operation
|
|
371
|
+
*
|
|
372
|
+
* ACL Resolution Priority:
|
|
373
|
+
* 1. Owner -> FULL ACCESS (always)
|
|
374
|
+
* 2. Blacklisted -> DENIED (even if in allowed/groups)
|
|
375
|
+
* 3. Allowed -> permissions granted
|
|
376
|
+
* 4. Groups -> check group permissions
|
|
377
|
+
* 5. Mode fallback: owner/restricted -> DENIED, public -> READ only
|
|
378
|
+
*
|
|
379
|
+
* @param acl - Access control configuration
|
|
380
|
+
* @param ownerAddress - Owner address of the storage program
|
|
381
|
+
* @param requestingAddress - Address requesting permission
|
|
382
|
+
* @param permission - Permission type to check
|
|
383
|
+
* @returns true if permission is granted
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* const acl = { mode: 'public', blacklisted: ['demos1spam...'] }
|
|
388
|
+
* const canRead = StorageProgram.checkPermission(acl, owner, user, 'read')
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
static checkPermission(acl, ownerAddress, requestingAddress, permission) {
|
|
392
|
+
// 1. Owner always has full access
|
|
393
|
+
if (requestingAddress === ownerAddress)
|
|
394
|
+
return true;
|
|
395
|
+
// 2. Blacklisted addresses are always denied
|
|
396
|
+
if (acl.blacklisted?.includes(requestingAddress))
|
|
397
|
+
return false;
|
|
398
|
+
// 3. Check allowed list (grants all permissions)
|
|
399
|
+
if (acl.allowed?.includes(requestingAddress))
|
|
400
|
+
return true;
|
|
401
|
+
// 4. Check groups
|
|
402
|
+
if (acl.groups) {
|
|
403
|
+
for (const group of Object.values(acl.groups)) {
|
|
404
|
+
if (group.members.includes(requestingAddress) && group.permissions.includes(permission)) {
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
// 5. Fall back to mode
|
|
410
|
+
switch (acl.mode) {
|
|
411
|
+
case "public":
|
|
412
|
+
return permission === "read"; // Public allows read only
|
|
413
|
+
case "owner":
|
|
414
|
+
case "restricted":
|
|
415
|
+
default:
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Create a public ACL (anyone can read, owner writes)
|
|
421
|
+
*
|
|
422
|
+
* @returns StorageProgramACL configured for public read access
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* const acl = StorageProgram.publicACL()
|
|
427
|
+
* // { mode: 'public' }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
static publicACL() {
|
|
431
|
+
return { mode: "public" };
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Create a private/owner-only ACL
|
|
435
|
+
*
|
|
436
|
+
* @returns StorageProgramACL configured for owner-only access
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```typescript
|
|
440
|
+
* const acl = StorageProgram.privateACL()
|
|
441
|
+
* // { mode: 'owner' }
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
static privateACL() {
|
|
445
|
+
return { mode: "owner" };
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Create a restricted ACL with allowed addresses
|
|
449
|
+
*
|
|
450
|
+
* @param allowed - List of addresses allowed to access
|
|
451
|
+
* @returns StorageProgramACL configured for restricted access
|
|
452
|
+
*
|
|
453
|
+
* @example
|
|
454
|
+
* ```typescript
|
|
455
|
+
* const acl = StorageProgram.restrictedACL(['demos1a...', 'demos1b...'])
|
|
456
|
+
* // { mode: 'restricted', allowed: ['demos1a...', 'demos1b...'] }
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
static restrictedACL(allowed) {
|
|
460
|
+
return { mode: "restricted", allowed };
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Create a group-based ACL
|
|
464
|
+
*
|
|
465
|
+
* @param groups - Named groups with members and permissions
|
|
466
|
+
* @returns StorageProgramACL configured for group-based access
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* ```typescript
|
|
470
|
+
* const acl = StorageProgram.groupACL({
|
|
471
|
+
* admins: { members: ['demos1admin...'], permissions: ['read', 'write', 'delete'] },
|
|
472
|
+
* editors: { members: ['demos1ed1...', 'demos1ed2...'], permissions: ['read', 'write'] },
|
|
473
|
+
* viewers: { members: ['demos1view...'], permissions: ['read'] }
|
|
474
|
+
* })
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
static groupACL(groups) {
|
|
478
|
+
return { mode: "restricted", groups };
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Create an ACL with a blacklist
|
|
482
|
+
*
|
|
483
|
+
* @param mode - Base mode ('public' or 'restricted')
|
|
484
|
+
* @param blacklisted - Addresses to block
|
|
485
|
+
* @param allowed - Optional allowed addresses (for restricted mode)
|
|
486
|
+
* @returns StorageProgramACL with blacklist configured
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript
|
|
490
|
+
* // Public but block spam addresses
|
|
491
|
+
* const acl = StorageProgram.blacklistACL('public', ['demos1spam...'])
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
static blacklistACL(mode, blacklisted, allowed) {
|
|
495
|
+
return { mode, blacklisted, allowed };
|
|
496
|
+
}
|
|
497
|
+
// ========================================================================
|
|
498
|
+
// Legacy Compatibility Methods
|
|
499
|
+
// ========================================================================
|
|
500
|
+
/**
|
|
501
|
+
* @deprecated Use createStorageProgram with acl parameter instead.
|
|
502
|
+
* Kept for backward compatibility.
|
|
503
|
+
*
|
|
504
|
+
* Create a new Storage Program with legacy access control
|
|
505
|
+
*/
|
|
506
|
+
static createStorageProgramLegacy(deployerAddress, programName, initialData, accessControl = "private", salt, allowedAddresses) {
|
|
507
|
+
const storageAddress = this.deriveStorageAddress(deployerAddress, programName, salt || "");
|
|
508
|
+
return {
|
|
509
|
+
operation: "CREATE_STORAGE_PROGRAM",
|
|
510
|
+
storageAddress,
|
|
511
|
+
programName,
|
|
512
|
+
data: initialData,
|
|
513
|
+
encoding: "json",
|
|
514
|
+
accessControl,
|
|
515
|
+
allowedAddresses,
|
|
516
|
+
salt,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* @deprecated Use updateAccessControl with acl parameter instead.
|
|
521
|
+
* Kept for backward compatibility.
|
|
522
|
+
*
|
|
523
|
+
* Update access control with legacy mode
|
|
524
|
+
*/
|
|
525
|
+
static updateAccessControlLegacy(storageAddress, accessControl, allowedAddresses) {
|
|
526
|
+
return {
|
|
527
|
+
operation: "UPDATE_ACCESS_CONTROL",
|
|
528
|
+
storageAddress,
|
|
529
|
+
accessControl,
|
|
530
|
+
allowedAddresses,
|
|
531
|
+
};
|
|
532
|
+
}
|
|
255
533
|
}
|
|
256
534
|
exports.StorageProgram = StorageProgram;
|
|
257
535
|
//# sourceMappingURL=StorageProgram.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageProgram.js","sourceRoot":"","sources":["../../../src/storage/StorageProgram.ts"],"names":[],"mappings":";;;AAAA,mCAAmC;
|
|
1
|
+
{"version":3,"file":"StorageProgram.js","sourceRoot":"","sources":["../../../src/storage/StorageProgram.ts"],"names":[],"mappings":";;;AAAA,mCAAmC;AAUnC,iHAA6G;AAE7G,yFAAyF;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAa,cAAc;IACvB,2EAA2E;IAC3E,qBAAqB;IACrB,2EAA2E;IAE3E;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,oBAAoB,CACvB,eAAuB,EACvB,WAAmB,EACnB,OAAe,EAAE;QAEjB,sDAAsD;QACtD,MAAM,SAAS,GAAG,GAAG,eAAe,IAAI,WAAW,IAAI,IAAI,EAAE,CAAA;QAE7D,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAEzC,OAAO,QAAQ,WAAW,EAAE,CAAA;IAChC,CAAC;IAED,2EAA2E;IAC3E,qBAAqB;IACrB,2EAA2E;IAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH,MAAM,CAAC,oBAAoB,CACvB,eAAuB,EACvB,WAAmB,EACnB,IAAkC,EAClC,WAA4B,MAAM,EAClC,GAAgC,EAChC,OAIC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAC5C,eAAe,EACf,WAAW,EACX,OAAO,EAAE,IAAI,IAAI,EAAE,CACtB,CAAA;QAED,MAAM,OAAO,GAAsB;YAC/B,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,OAAO;YAC1B,OAAO,EAAE,GAAG,EAAE,OAAO;YACrB,WAAW,EAAE,GAAG,EAAE,WAAW;YAC7B,MAAM,EAAE,GAAG,EAAE,MAAM;SACtB,CAAA;QAED,OAAO;YACH,SAAS,EAAE,wBAAwB;YACnC,cAAc;YACd,WAAW;YACX,QAAQ;YACR,IAAI;YACJ,GAAG,EAAE,OAAO;YACZ,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,SAAS;SACzD,CAAA;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,YAAY,CACf,cAAsB,EACtB,IAAkC,EAClC,WAA4B,MAAM;QAElC,OAAO;YACH,SAAS,EAAE,eAAe;YAC1B,cAAc;YACd,IAAI;YACJ,QAAQ;SACX,CAAA;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,WAAW,CAAC,cAAsB;QACrC,OAAO;YACH,SAAS,EAAE,cAAc;YACzB,cAAc;SACjB,CAAA;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,MAAM,CAAC,mBAAmB,CACtB,cAAsB,EACtB,GAA+B;QAE/B,OAAO;YACH,SAAS,EAAE,uBAAuB;YAClC,cAAc;YACd,GAAG,EAAE,GAAwB;SAChC,CAAA;IACL,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,oBAAoB,CAAC,cAAsB;QAC9C,OAAO;YACH,SAAS,EAAE,wBAAwB;YACnC,cAAc;SACjB,CAAA;IACL,CAAC;IAED,2EAA2E;IAC3E,qBAAqB;IACrB,2EAA2E;IAE3E;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,YAAY,CAAC,IAAkC,EAAE,WAA4B,MAAM;QACtF,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAClD,OAAO,SAAS,IAAI,qDAAyB,CAAC,cAAc,CAAA;IAChE,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,WAAW,CAAC,IAAkC,EAAE,WAA4B,MAAM;QACrF,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxB,2DAA2D;YAC3D,2CAA2C;YAC3C,MAAM,YAAY,GAAG,IAAc,CAAA;YACnC,+BAA+B;YAC/B,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;YACvD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAA;QAC9D,CAAC;aAAM,CAAC;YACJ,sCAAsC;YACtC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACvC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAA;QACtD,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAkC,EAAE,WAA4B,MAAM;QAC7F,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,qDAAyB,CAAC,mBAAmB,CAAC,CAAA;QACnF,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,qDAAyB,CAAC,aAAa,CAAA;IAChF,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,oBAAoB,CAAC,IAAS,EAAE,WAAmB,qDAAyB,CAAC,sBAAsB;QACtG,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAE,eAAuB,CAAC,EAAU,EAAE;YAC5D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBAC1C,OAAO,YAAY,CAAA;YACvB,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC1C,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,CAAC,CACpC,CAAA;YAED,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,YAAY,CAAC,CAAA;QAC5C,CAAC,CAAA;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAA;IACrC,CAAC;IAED,2EAA2E;IAC3E,cAAc;IACd,2EAA2E;IAE3E;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,eAAe,CAClB,GAAsB,EACtB,YAAoB,EACpB,iBAAyB,EACzB,UAAuC;QAEvC,kCAAkC;QAClC,IAAI,iBAAiB,KAAK,YAAY;YAAE,OAAO,IAAI,CAAA;QAEnD,6CAA6C;QAC7C,IAAI,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC;YAAE,OAAO,KAAK,CAAA;QAE9D,iDAAiD;QACjD,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC;YAAE,OAAO,IAAI,CAAA;QAEzD,kBAAkB;QAClB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACb,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACtF,OAAO,IAAI,CAAA;gBACf,CAAC;YACL,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,QAAQ;gBACT,OAAO,UAAU,KAAK,MAAM,CAAA,CAAC,0BAA0B;YAC3D,KAAK,OAAO,CAAC;YACb,KAAK,YAAY,CAAC;YAClB;gBACI,OAAO,KAAK,CAAA;QACpB,CAAC;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,SAAS;QACZ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IAC7B,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,UAAU;QACb,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC5B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,aAAa,CAAC,OAAiB;QAClC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAA;IAC1C,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,QAAQ,CAAC,MAA+C;QAC3D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAA;IACzC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,YAAY,CACf,IAAoB,EACpB,WAAqB,EACrB,OAAkB;QAElB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA;IACzC,CAAC;IAED,2EAA2E;IAC3E,+BAA+B;IAC/B,2EAA2E;IAE3E;;;;;OAKG;IACH,MAAM,CAAC,0BAA0B,CAC7B,eAAuB,EACvB,WAAmB,EACnB,WAAgC,EAChC,gBAA6C,SAAS,EACtD,IAAa,EACb,gBAA2B;QAE3B,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAC5C,eAAe,EACf,WAAW,EACX,IAAI,IAAI,EAAE,CACb,CAAA;QAED,OAAO;YACH,SAAS,EAAE,wBAAwB;YACnC,cAAc;YACd,WAAW;YACX,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,MAAM;YAChB,aAAa;YACb,gBAAgB;YAChB,IAAI;SACP,CAAA;IACL,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,yBAAyB,CAC5B,cAAsB,EACtB,aAA0C,EAC1C,gBAA2B;QAE3B,OAAO;YACH,SAAS,EAAE,uBAAuB;YAClC,cAAc;YACd,aAAa;YACb,gBAAgB;SACnB,CAAA;IACL,CAAC;CACJ;AAzjBD,wCAyjBC"}
|
package/build/storage/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { StorageProgram } from "./StorageProgram";
|
|
2
|
-
export type {
|
|
2
|
+
export type { StorageProgramOperation, StorageEncoding, StorageLocation, StorageACLMode, StorageGroupPermissions, StorageProgramACL, StorageProgramPayload, StorageProgramTransactionContent, StorageProgramTransaction, StorageProgramAccessControl, } from "../types/blockchain/TransactionSubtypes/StorageProgramTransaction";
|
|
3
|
+
export { STORAGE_PROGRAM_CONSTANTS, isStorageProgramPayload, isValidEncoding, isValidStorageLocation, } from "../types/blockchain/TransactionSubtypes/StorageProgramTransaction";
|
package/build/storage/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StorageProgram = void 0;
|
|
3
|
+
exports.isValidStorageLocation = exports.isValidEncoding = exports.isStorageProgramPayload = exports.STORAGE_PROGRAM_CONSTANTS = exports.StorageProgram = void 0;
|
|
4
4
|
var StorageProgram_1 = require("./StorageProgram");
|
|
5
5
|
Object.defineProperty(exports, "StorageProgram", { enumerable: true, get: function () { return StorageProgram_1.StorageProgram; } });
|
|
6
|
+
var StorageProgramTransaction_1 = require("../types/blockchain/TransactionSubtypes/StorageProgramTransaction");
|
|
7
|
+
Object.defineProperty(exports, "STORAGE_PROGRAM_CONSTANTS", { enumerable: true, get: function () { return StorageProgramTransaction_1.STORAGE_PROGRAM_CONSTANTS; } });
|
|
8
|
+
Object.defineProperty(exports, "isStorageProgramPayload", { enumerable: true, get: function () { return StorageProgramTransaction_1.isStorageProgramPayload; } });
|
|
9
|
+
Object.defineProperty(exports, "isValidEncoding", { enumerable: true, get: function () { return StorageProgramTransaction_1.isValidEncoding; } });
|
|
10
|
+
Object.defineProperty(exports, "isValidStorageLocation", { enumerable: true, get: function () { return StorageProgramTransaction_1.isValidStorageLocation; } });
|
|
6
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAAxC,gHAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAAxC,gHAAA,cAAc,OAAA;AAiBvB,+GAK0E;AAJtE,sIAAA,yBAAyB,OAAA;AACzB,oIAAA,uBAAuB,OAAA;AACvB,4HAAA,eAAe,OAAA;AACf,mIAAA,sBAAsB,OAAA"}
|
|
@@ -1,33 +1,87 @@
|
|
|
1
1
|
import { Transaction, TransactionContent } from "../Transaction";
|
|
2
|
+
/**
|
|
3
|
+
* Storage Program constants for validation and pricing
|
|
4
|
+
*/
|
|
5
|
+
export declare const STORAGE_PROGRAM_CONSTANTS: {
|
|
6
|
+
/** Maximum storage size in bytes (1MB) */
|
|
7
|
+
readonly MAX_SIZE_BYTES: 1048576;
|
|
8
|
+
/** Size chunk for pricing in bytes (10KB) */
|
|
9
|
+
readonly PRICING_CHUNK_BYTES: 10240;
|
|
10
|
+
/** Fee per chunk in DEM */
|
|
11
|
+
readonly FEE_PER_CHUNK: 1n;
|
|
12
|
+
/** Maximum nesting depth for JSON encoding */
|
|
13
|
+
readonly MAX_JSON_NESTING_DEPTH: 64;
|
|
14
|
+
};
|
|
2
15
|
/**
|
|
3
16
|
* Storage Program operations
|
|
4
17
|
*
|
|
5
18
|
* - CREATE_STORAGE_PROGRAM: Initialize a new storage program with access control
|
|
6
|
-
* - WRITE_STORAGE: Write/update
|
|
19
|
+
* - WRITE_STORAGE: Write/update data in the storage
|
|
7
20
|
* - READ_STORAGE: Query operation (not a transaction, used for validation)
|
|
8
|
-
* - UPDATE_ACCESS_CONTROL: Modify access control settings (
|
|
9
|
-
* - DELETE_STORAGE_PROGRAM: Remove the entire storage program (
|
|
21
|
+
* - UPDATE_ACCESS_CONTROL: Modify access control settings (owner only)
|
|
22
|
+
* - DELETE_STORAGE_PROGRAM: Remove the entire storage program (owner/ACL permissioned)
|
|
10
23
|
*/
|
|
11
24
|
export type StorageProgramOperation = "CREATE_STORAGE_PROGRAM" | "WRITE_STORAGE" | "READ_STORAGE" | "UPDATE_ACCESS_CONTROL" | "DELETE_STORAGE_PROGRAM";
|
|
12
25
|
/**
|
|
13
|
-
*
|
|
26
|
+
* Storage encoding format
|
|
27
|
+
* - json: Structured key-value data (Record<string, any>)
|
|
28
|
+
* - binary: Raw binary data (base64 encoded string)
|
|
29
|
+
*/
|
|
30
|
+
export type StorageEncoding = "json" | "binary";
|
|
31
|
+
/**
|
|
32
|
+
* Storage location type
|
|
33
|
+
* - onchain: Stored directly in PostgreSQL (current implementation)
|
|
34
|
+
* - ipfs: Stored on IPFS with CID reference (future - not yet implemented)
|
|
35
|
+
*/
|
|
36
|
+
export type StorageLocation = "onchain" | "ipfs";
|
|
37
|
+
/**
|
|
38
|
+
* Access control mode determining default behavior
|
|
39
|
+
* - owner: Only owner can read and write (most restrictive)
|
|
40
|
+
* - public: Anyone can read, only owner can write
|
|
41
|
+
* - restricted: Only addresses in allowed/groups can access
|
|
42
|
+
*/
|
|
43
|
+
export type StorageACLMode = "owner" | "public" | "restricted";
|
|
44
|
+
/**
|
|
45
|
+
* Group permissions for access control
|
|
46
|
+
*/
|
|
47
|
+
export interface StorageGroupPermissions {
|
|
48
|
+
/** Member addresses in this group */
|
|
49
|
+
members: string[];
|
|
50
|
+
/** Permissions granted to group members */
|
|
51
|
+
permissions: ("read" | "write" | "delete")[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Robust Access Control for Storage Programs
|
|
55
|
+
* Applies to both JSON and Binary encodings
|
|
14
56
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
57
|
+
* ACL Resolution Priority:
|
|
58
|
+
* 1. Owner -> FULL ACCESS (always)
|
|
59
|
+
* 2. Blacklisted -> DENIED (even if in allowed/groups)
|
|
60
|
+
* 3. Allowed -> permissions granted
|
|
61
|
+
* 4. Groups -> check group permissions
|
|
62
|
+
* 5. Mode fallback:
|
|
63
|
+
* - "owner" -> DENIED
|
|
64
|
+
* - "public" -> READ only
|
|
65
|
+
* - "restricted" -> DENIED
|
|
66
|
+
*/
|
|
67
|
+
export interface StorageProgramACL {
|
|
68
|
+
/** Access mode determining default behavior */
|
|
69
|
+
mode: StorageACLMode;
|
|
70
|
+
/** Addresses explicitly allowed to read/write */
|
|
71
|
+
allowed?: string[];
|
|
72
|
+
/** Addresses explicitly blocked (takes precedence over allowed/groups) */
|
|
73
|
+
blacklisted?: string[];
|
|
74
|
+
/** Named groups with member addresses and permissions */
|
|
75
|
+
groups?: Record<string, StorageGroupPermissions>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @deprecated Use StorageProgramACL instead. Kept for backward compatibility.
|
|
19
79
|
*/
|
|
20
80
|
export type StorageProgramAccessControl = "private" | "public" | "restricted" | "deployer-only";
|
|
21
81
|
/**
|
|
22
82
|
* Storage Program payload for transaction data
|
|
23
83
|
*
|
|
24
|
-
*
|
|
25
|
-
* @property storageAddress - The storage program address (stor-{hash})
|
|
26
|
-
* @property programName - Name of the storage program (required for CREATE)
|
|
27
|
-
* @property data - Key-value data to write (required for CREATE and WRITE)
|
|
28
|
-
* @property accessControl - Access control mode (optional for CREATE, required for UPDATE_ACCESS_CONTROL)
|
|
29
|
-
* @property allowedAddresses - List of allowed addresses for 'restricted' mode
|
|
30
|
-
* @property salt - Random salt for address derivation (optional for CREATE)
|
|
84
|
+
* Unified payload supporting both JSON and Binary encodings with robust ACL.
|
|
31
85
|
*/
|
|
32
86
|
export interface StorageProgramPayload {
|
|
33
87
|
/** The storage operation to perform */
|
|
@@ -36,14 +90,45 @@ export interface StorageProgramPayload {
|
|
|
36
90
|
storageAddress: string;
|
|
37
91
|
/** Name of the storage program (required for CREATE_STORAGE_PROGRAM) */
|
|
38
92
|
programName?: string;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Encoding format for the data
|
|
95
|
+
* - json: data field contains Record<string, any>
|
|
96
|
+
* - binary: data field contains base64 string
|
|
97
|
+
* @default "json"
|
|
98
|
+
*/
|
|
99
|
+
encoding?: StorageEncoding;
|
|
100
|
+
/**
|
|
101
|
+
* Data to store
|
|
102
|
+
* - For json encoding: Record<string, any> (max 64 nesting levels)
|
|
103
|
+
* - For binary encoding: base64 encoded string
|
|
104
|
+
* Max size: 1MB for both
|
|
105
|
+
*/
|
|
106
|
+
data?: Record<string, any> | string;
|
|
107
|
+
/**
|
|
108
|
+
* Robust access control configuration (new)
|
|
109
|
+
* Supports owner, allowed, blacklisted, public, and groups
|
|
110
|
+
*/
|
|
111
|
+
acl?: StorageProgramACL;
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated Use acl instead. Kept for backward compatibility.
|
|
114
|
+
* Simple access control mode
|
|
115
|
+
*/
|
|
42
116
|
accessControl?: StorageProgramAccessControl;
|
|
43
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* @deprecated Use acl.allowed instead. Kept for backward compatibility.
|
|
119
|
+
* Allowed addresses for 'restricted' access control
|
|
120
|
+
*/
|
|
44
121
|
allowedAddresses?: string[];
|
|
45
122
|
/** Random salt for deterministic address derivation (optional) */
|
|
46
123
|
salt?: string;
|
|
124
|
+
/** Optional metadata (filename, mimeType, description, etc.) */
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
/**
|
|
127
|
+
* Storage location preference
|
|
128
|
+
* @default "onchain"
|
|
129
|
+
* Note: "ipfs" is not yet implemented, will fall back to "onchain"
|
|
130
|
+
*/
|
|
131
|
+
storageLocation?: StorageLocation;
|
|
47
132
|
}
|
|
48
133
|
/**
|
|
49
134
|
* Transaction content type for Storage Program operations.
|
|
@@ -55,16 +140,30 @@ export type StorageProgramTransactionContent = Omit<TransactionContent, "type" |
|
|
|
55
140
|
};
|
|
56
141
|
/**
|
|
57
142
|
* Complete Storage Program transaction interface.
|
|
58
|
-
* Used for
|
|
143
|
+
* Used for unified storage on the blockchain with access control.
|
|
59
144
|
*
|
|
60
145
|
* Storage Programs support:
|
|
61
|
-
* -
|
|
62
|
-
* -
|
|
63
|
-
* -
|
|
64
|
-
* -
|
|
146
|
+
* - Dual encoding: JSON (structured) or Binary (raw)
|
|
147
|
+
* - Max size: 1MB for both encodings
|
|
148
|
+
* - Pricing: 1 DEM per 10KB
|
|
149
|
+
* - Robust ACL: owner, allowed, blacklisted, public, groups
|
|
150
|
+
* - Permanent storage, owner/ACL-deletable only
|
|
151
|
+
* - IPFS-ready (stubs for future hybrid storage)
|
|
65
152
|
*
|
|
66
|
-
* @see
|
|
153
|
+
* @see feature_storage_programs_plan.md for complete specification
|
|
67
154
|
*/
|
|
68
155
|
export interface StorageProgramTransaction extends Omit<Transaction, "content"> {
|
|
69
156
|
content: StorageProgramTransactionContent;
|
|
70
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Check if a payload is a StorageProgram payload
|
|
160
|
+
*/
|
|
161
|
+
export declare function isStorageProgramPayload(payload: unknown): payload is StorageProgramPayload;
|
|
162
|
+
/**
|
|
163
|
+
* Check if encoding is valid
|
|
164
|
+
*/
|
|
165
|
+
export declare function isValidEncoding(encoding: unknown): encoding is StorageEncoding;
|
|
166
|
+
/**
|
|
167
|
+
* Check if storage location is valid
|
|
168
|
+
*/
|
|
169
|
+
export declare function isValidStorageLocation(location: unknown): location is StorageLocation;
|
|
@@ -1,3 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STORAGE_PROGRAM_CONSTANTS = void 0;
|
|
4
|
+
exports.isStorageProgramPayload = isStorageProgramPayload;
|
|
5
|
+
exports.isValidEncoding = isValidEncoding;
|
|
6
|
+
exports.isValidStorageLocation = isValidStorageLocation;
|
|
7
|
+
// REVIEW: Unified Storage Program transaction types for both JSON and Binary storage
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Storage Program constants for validation and pricing
|
|
13
|
+
*/
|
|
14
|
+
exports.STORAGE_PROGRAM_CONSTANTS = {
|
|
15
|
+
/** Maximum storage size in bytes (1MB) */
|
|
16
|
+
MAX_SIZE_BYTES: 1048576,
|
|
17
|
+
/** Size chunk for pricing in bytes (10KB) */
|
|
18
|
+
PRICING_CHUNK_BYTES: 10240,
|
|
19
|
+
/** Fee per chunk in DEM */
|
|
20
|
+
FEE_PER_CHUNK: 1n,
|
|
21
|
+
/** Maximum nesting depth for JSON encoding */
|
|
22
|
+
MAX_JSON_NESTING_DEPTH: 64,
|
|
23
|
+
};
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Type Guards
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Check if a payload is a StorageProgram payload
|
|
29
|
+
*/
|
|
30
|
+
function isStorageProgramPayload(payload) {
|
|
31
|
+
if (!payload || typeof payload !== "object")
|
|
32
|
+
return false;
|
|
33
|
+
const p = payload;
|
|
34
|
+
return (typeof p.operation === "string" &&
|
|
35
|
+
typeof p.storageAddress === "string" &&
|
|
36
|
+
["CREATE_STORAGE_PROGRAM", "WRITE_STORAGE", "READ_STORAGE", "UPDATE_ACCESS_CONTROL", "DELETE_STORAGE_PROGRAM"].includes(p.operation));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if encoding is valid
|
|
40
|
+
*/
|
|
41
|
+
function isValidEncoding(encoding) {
|
|
42
|
+
return encoding === "json" || encoding === "binary";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if storage location is valid
|
|
46
|
+
*/
|
|
47
|
+
function isValidStorageLocation(location) {
|
|
48
|
+
return location === "onchain" || location === "ipfs";
|
|
49
|
+
}
|
|
3
50
|
//# sourceMappingURL=StorageProgramTransaction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageProgramTransaction.js","sourceRoot":"","sources":["../../../../../src/types/blockchain/TransactionSubtypes/StorageProgramTransaction.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"StorageProgramTransaction.js","sourceRoot":"","sources":["../../../../../src/types/blockchain/TransactionSubtypes/StorageProgramTransaction.ts"],"names":[],"mappings":";;;AAoOA,0DAQC;AAKD,0CAEC;AAKD,wDAEC;AAxPD,qFAAqF;AAErF,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;GAEG;AACU,QAAA,yBAAyB,GAAG;IACrC,0CAA0C;IAC1C,cAAc,EAAE,OAAO;IAEvB,6CAA6C;IAC7C,mBAAmB,EAAE,KAAK;IAE1B,2BAA2B;IAC3B,aAAa,EAAE,EAAE;IAEjB,8CAA8C;IAC9C,sBAAsB,EAAE,EAAE;CACpB,CAAA;AAsMV,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E;;GAEG;AACH,SAAgB,uBAAuB,CAAC,OAAgB;IACpD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACzD,MAAM,CAAC,GAAG,OAAkC,CAAA;IAC5C,OAAO,CACH,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAC/B,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ;QACpC,CAAC,wBAAwB,EAAE,eAAe,EAAE,cAAc,EAAE,uBAAuB,EAAE,wBAAwB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAmB,CAAC,CACjJ,CAAA;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,QAAiB;IAC7C,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,QAAQ,CAAA;AACvD,CAAC;AAED;;GAEG;AACH,SAAgB,sBAAsB,CAAC,QAAiB;IACpD,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,MAAM,CAAA;AACxD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kynesyslabs/demosdk",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.11",
|
|
4
4
|
"description": "Demosdk is a JavaScript/TypeScript SDK that provides a unified interface for interacting with Demos network",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|