@bsv/sdk 1.8.1 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/kvstore/index.js +3 -1
- package/dist/cjs/src/kvstore/index.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js +78 -19
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/kvstore/index.js +1 -0
- package/dist/esm/src/kvstore/index.js.map +1 -1
- package/dist/esm/src/primitives/Random.js +78 -19
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/kvstore/index.d.ts +1 -0
- package/dist/types/src/kvstore/index.d.ts.map +1 -1
- package/dist/types/src/primitives/Random.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/kvstore.md +485 -0
- package/package.json +1 -1
- package/src/kvstore/index.ts +1 -0
- package/src/primitives/Random.ts +86 -17
- package/src/primitives/__tests/Random.test.ts +21 -0
|
@@ -4,8 +4,434 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
4
4
|
|
|
5
5
|
## Interfaces
|
|
6
6
|
|
|
7
|
+
| |
|
|
8
|
+
| --- |
|
|
9
|
+
| [KVContext](#interface-kvcontext) |
|
|
10
|
+
| [KVStoreConfig](#interface-kvstoreconfig) |
|
|
11
|
+
| [KVStoreEntry](#interface-kvstoreentry) |
|
|
12
|
+
| [KVStoreGetOptions](#interface-kvstoregetoptions) |
|
|
13
|
+
| [KVStoreLookupResult](#interface-kvstorelookupresult) |
|
|
14
|
+
| [KVStoreQuery](#interface-kvstorequery) |
|
|
15
|
+
| [KVStoreRemoveOptions](#interface-kvstoreremoveoptions) |
|
|
16
|
+
| [KVStoreSetOptions](#interface-kvstoresetoptions) |
|
|
17
|
+
| [KVStoreToken](#interface-kvstoretoken) |
|
|
18
|
+
|
|
19
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### Interface: KVContext
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
export interface KVContext {
|
|
27
|
+
key: string;
|
|
28
|
+
protocolID: WalletProtocol;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
See also: [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
33
|
+
|
|
34
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
### Interface: KVStoreConfig
|
|
38
|
+
|
|
39
|
+
Configuration interface for GlobalKVStore operations.
|
|
40
|
+
Defines all options for connecting to overlay services and managing KVStore behavior.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
export interface KVStoreConfig {
|
|
44
|
+
overlayHost?: string;
|
|
45
|
+
protocolID?: WalletProtocol;
|
|
46
|
+
serviceName?: string;
|
|
47
|
+
tokenAmount?: number;
|
|
48
|
+
topics?: string[];
|
|
49
|
+
originator?: string;
|
|
50
|
+
wallet?: WalletInterface;
|
|
51
|
+
networkPreset?: "mainnet" | "testnet" | "local";
|
|
52
|
+
acceptDelayedBroadcast?: boolean;
|
|
53
|
+
tokenSetDescription?: string;
|
|
54
|
+
tokenUpdateDescription?: string;
|
|
55
|
+
tokenRemovalDescription?: string;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
See also: [WalletInterface](./wallet.md#interface-walletinterface), [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
60
|
+
|
|
61
|
+
#### Property acceptDelayedBroadcast
|
|
62
|
+
|
|
63
|
+
Whether to accept delayed broadcast
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
acceptDelayedBroadcast?: boolean
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Property networkPreset
|
|
70
|
+
|
|
71
|
+
Network preset for overlay services
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
networkPreset?: "mainnet" | "testnet" | "local"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### Property originator
|
|
78
|
+
|
|
79
|
+
Originator
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
originator?: string
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Property overlayHost
|
|
86
|
+
|
|
87
|
+
The overlay service host URL
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
overlayHost?: string
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Property protocolID
|
|
94
|
+
|
|
95
|
+
Protocol ID for the KVStore protocol
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
protocolID?: WalletProtocol
|
|
99
|
+
```
|
|
100
|
+
See also: [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
101
|
+
|
|
102
|
+
#### Property serviceName
|
|
103
|
+
|
|
104
|
+
Service name for overlay submission
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
serviceName?: string
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Property tokenAmount
|
|
111
|
+
|
|
112
|
+
Amount of satoshis for each token
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
tokenAmount?: number
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Property tokenRemovalDescription
|
|
119
|
+
|
|
120
|
+
Description for token removal
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
tokenRemovalDescription?: string
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Property tokenSetDescription
|
|
127
|
+
|
|
128
|
+
Description for token set
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
tokenSetDescription?: string
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Property tokenUpdateDescription
|
|
135
|
+
|
|
136
|
+
Description for token update
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
tokenUpdateDescription?: string
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Property topics
|
|
143
|
+
|
|
144
|
+
Topics for overlay submission
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
topics?: string[]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Property wallet
|
|
151
|
+
|
|
152
|
+
Wallet interface for operations
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
wallet?: WalletInterface
|
|
156
|
+
```
|
|
157
|
+
See also: [WalletInterface](./wallet.md#interface-walletinterface)
|
|
158
|
+
|
|
159
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
### Interface: KVStoreEntry
|
|
163
|
+
|
|
164
|
+
KVStore entry returned from queries
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
export interface KVStoreEntry {
|
|
168
|
+
key: string;
|
|
169
|
+
value: string;
|
|
170
|
+
controller: PubKeyHex;
|
|
171
|
+
protocolID: WalletProtocol;
|
|
172
|
+
token?: KVStoreToken;
|
|
173
|
+
history?: string[];
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
See also: [KVStoreToken](./kvstore.md#interface-kvstoretoken), [PubKeyHex](./wallet.md#type-pubkeyhex), [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
178
|
+
|
|
179
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
### Interface: KVStoreGetOptions
|
|
183
|
+
|
|
184
|
+
Options for configuring KVStore get operations (local processing)
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
export interface KVStoreGetOptions {
|
|
188
|
+
history?: boolean;
|
|
189
|
+
includeToken?: boolean;
|
|
190
|
+
serviceName?: string;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
#### Property history
|
|
195
|
+
|
|
196
|
+
Whether to build and include history for each entry
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
history?: boolean
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Property includeToken
|
|
203
|
+
|
|
204
|
+
Whether to include token transaction data in results
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
includeToken?: boolean
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Property serviceName
|
|
211
|
+
|
|
212
|
+
Service name for overlay retrieval
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
serviceName?: string
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
### Interface: KVStoreLookupResult
|
|
222
|
+
|
|
223
|
+
Result structure for KVStore lookups from overlay services.
|
|
224
|
+
Contains the transaction output information for a found key-value pair.
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
export interface KVStoreLookupResult {
|
|
228
|
+
txid: string;
|
|
229
|
+
outputIndex: number;
|
|
230
|
+
outputScript: string;
|
|
231
|
+
satoshis: number;
|
|
232
|
+
history?: (output: any, currentDepth: number) => Promise<boolean>;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
### Interface: KVStoreQuery
|
|
240
|
+
|
|
241
|
+
Query parameters for KVStore lookups from overlay services.
|
|
242
|
+
Used when searching for existing key-value pairs in the network.
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
export interface KVStoreQuery {
|
|
246
|
+
key?: string;
|
|
247
|
+
controller?: PubKeyHex;
|
|
248
|
+
protocolID?: WalletProtocol;
|
|
249
|
+
limit?: number;
|
|
250
|
+
skip?: number;
|
|
251
|
+
sortOrder?: "asc" | "desc";
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
See also: [PubKeyHex](./wallet.md#type-pubkeyhex), [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
256
|
+
|
|
257
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
### Interface: KVStoreRemoveOptions
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
export interface KVStoreRemoveOptions {
|
|
264
|
+
protocolID?: WalletProtocol;
|
|
265
|
+
tokenRemovalDescription?: string;
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
See also: [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
270
|
+
|
|
271
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
### Interface: KVStoreSetOptions
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
export interface KVStoreSetOptions {
|
|
278
|
+
protocolID?: WalletProtocol;
|
|
279
|
+
tokenSetDescription?: string;
|
|
280
|
+
tokenUpdateDescription?: string;
|
|
281
|
+
tokenAmount?: number;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
See also: [WalletProtocol](./wallet.md#type-walletprotocol)
|
|
286
|
+
|
|
287
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
### Interface: KVStoreToken
|
|
291
|
+
|
|
292
|
+
Token structure containing a KVStore token from overlay services.
|
|
293
|
+
Wraps the transaction data and metadata for a key-value pair.
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
export interface KVStoreToken {
|
|
297
|
+
txid: string;
|
|
298
|
+
outputIndex: number;
|
|
299
|
+
satoshis: number;
|
|
300
|
+
beef: Beef;
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
See also: [Beef](./transaction.md#class-beef)
|
|
305
|
+
|
|
306
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
307
|
+
|
|
308
|
+
---
|
|
7
309
|
## Classes
|
|
8
310
|
|
|
311
|
+
| |
|
|
312
|
+
| --- |
|
|
313
|
+
| [GlobalKVStore](#class-globalkvstore) |
|
|
314
|
+
| [LocalKVStore](#class-localkvstore) |
|
|
315
|
+
|
|
316
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
### Class: GlobalKVStore
|
|
321
|
+
|
|
322
|
+
Implements a global key-value storage system which uses an overlay service to track key-value pairs.
|
|
323
|
+
Each key-value pair is represented by a PushDrop token output.
|
|
324
|
+
Allows getting, setting, and removing key-value pairs with optional fetching by protocolID and history tracking.
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
export class GlobalKVStore {
|
|
328
|
+
constructor(config: KVStoreConfig = {})
|
|
329
|
+
async get(query: KVStoreQuery, options: KVStoreGetOptions = {}): Promise<KVStoreEntry | KVStoreEntry[] | undefined>
|
|
330
|
+
async set(key: string, value: string, options: KVStoreSetOptions = {}): Promise<OutpointString>
|
|
331
|
+
async remove(key: string, outputs?: CreateActionOutput[], options: KVStoreRemoveOptions = {}): Promise<HexString>
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
See also: [CreateActionOutput](./wallet.md#interface-createactionoutput), [HexString](./wallet.md#type-hexstring), [KVStoreConfig](./kvstore.md#interface-kvstoreconfig), [KVStoreEntry](./kvstore.md#interface-kvstoreentry), [KVStoreGetOptions](./kvstore.md#interface-kvstoregetoptions), [KVStoreQuery](./kvstore.md#interface-kvstorequery), [KVStoreRemoveOptions](./kvstore.md#interface-kvstoreremoveoptions), [KVStoreSetOptions](./kvstore.md#interface-kvstoresetoptions), [OutpointString](./wallet.md#type-outpointstring)
|
|
336
|
+
|
|
337
|
+
#### Constructor
|
|
338
|
+
|
|
339
|
+
Creates an instance of the GlobalKVStore.
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
constructor(config: KVStoreConfig = {})
|
|
343
|
+
```
|
|
344
|
+
See also: [KVStoreConfig](./kvstore.md#interface-kvstoreconfig)
|
|
345
|
+
|
|
346
|
+
Argument Details
|
|
347
|
+
|
|
348
|
+
+ **config**
|
|
349
|
+
+ Configuration options for the KVStore. Defaults to empty object.
|
|
350
|
+
+ **config.wallet**
|
|
351
|
+
+ Wallet to use for operations. Defaults to WalletClient.
|
|
352
|
+
|
|
353
|
+
Throws
|
|
354
|
+
|
|
355
|
+
If the configuration contains invalid parameters.
|
|
356
|
+
|
|
357
|
+
#### Method get
|
|
358
|
+
|
|
359
|
+
Retrieves data from the KVStore.
|
|
360
|
+
Can query by key+controller (single result), protocolID, controller, or key (multiple results).
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
async get(query: KVStoreQuery, options: KVStoreGetOptions = {}): Promise<KVStoreEntry | KVStoreEntry[] | undefined>
|
|
364
|
+
```
|
|
365
|
+
See also: [KVStoreEntry](./kvstore.md#interface-kvstoreentry), [KVStoreGetOptions](./kvstore.md#interface-kvstoregetoptions), [KVStoreQuery](./kvstore.md#interface-kvstorequery)
|
|
366
|
+
|
|
367
|
+
Returns
|
|
368
|
+
|
|
369
|
+
Single entry for key+controller queries, array for all other queries
|
|
370
|
+
|
|
371
|
+
Argument Details
|
|
372
|
+
|
|
373
|
+
+ **query**
|
|
374
|
+
+ Query parameters sent to overlay
|
|
375
|
+
+ **options**
|
|
376
|
+
+ Configuration options for the get operation
|
|
377
|
+
|
|
378
|
+
#### Method remove
|
|
379
|
+
|
|
380
|
+
Removes the key-value pair associated with the given key from the overlay service.
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
async remove(key: string, outputs?: CreateActionOutput[], options: KVStoreRemoveOptions = {}): Promise<HexString>
|
|
384
|
+
```
|
|
385
|
+
See also: [CreateActionOutput](./wallet.md#interface-createactionoutput), [HexString](./wallet.md#type-hexstring), [KVStoreRemoveOptions](./kvstore.md#interface-kvstoreremoveoptions)
|
|
386
|
+
|
|
387
|
+
Returns
|
|
388
|
+
|
|
389
|
+
A promise that resolves to the txid of the removal transaction if successful.
|
|
390
|
+
|
|
391
|
+
Argument Details
|
|
392
|
+
|
|
393
|
+
+ **key**
|
|
394
|
+
+ The key to remove.
|
|
395
|
+
+ **outputs**
|
|
396
|
+
+ Additional outputs to include in the removal transaction.
|
|
397
|
+
+ **options**
|
|
398
|
+
+ Optional parameters for the removal operation.
|
|
399
|
+
|
|
400
|
+
Throws
|
|
401
|
+
|
|
402
|
+
If the key is invalid.
|
|
403
|
+
|
|
404
|
+
If the key does not exist in the store.
|
|
405
|
+
|
|
406
|
+
If the overlay service is unreachable or the transaction fails.
|
|
407
|
+
|
|
408
|
+
If there are existing tokens that cannot be unlocked.
|
|
409
|
+
|
|
410
|
+
#### Method set
|
|
411
|
+
|
|
412
|
+
Sets a key-value pair. The current user (wallet identity) becomes the controller.
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
async set(key: string, value: string, options: KVStoreSetOptions = {}): Promise<OutpointString>
|
|
416
|
+
```
|
|
417
|
+
See also: [KVStoreSetOptions](./kvstore.md#interface-kvstoresetoptions), [OutpointString](./wallet.md#type-outpointstring)
|
|
418
|
+
|
|
419
|
+
Returns
|
|
420
|
+
|
|
421
|
+
The outpoint of the created token
|
|
422
|
+
|
|
423
|
+
Argument Details
|
|
424
|
+
|
|
425
|
+
+ **key**
|
|
426
|
+
+ The key to set (user computes this however they want)
|
|
427
|
+
+ **value**
|
|
428
|
+
+ The value to store
|
|
429
|
+
+ **options**
|
|
430
|
+
+ Configuration options for the set operation
|
|
431
|
+
|
|
432
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
433
|
+
|
|
434
|
+
---
|
|
9
435
|
### Class: LocalKVStore
|
|
10
436
|
|
|
11
437
|
Implements a key-value storage system backed by transaction outputs managed by a wallet.
|
|
@@ -134,3 +560,62 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
134
560
|
|
|
135
561
|
## Variables
|
|
136
562
|
|
|
563
|
+
| |
|
|
564
|
+
| --- |
|
|
565
|
+
| [kvProtocol](#variable-kvprotocol) |
|
|
566
|
+
| [kvStoreInterpreter](#variable-kvstoreinterpreter) |
|
|
567
|
+
|
|
568
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
### Variable: kvProtocol
|
|
573
|
+
|
|
574
|
+
```ts
|
|
575
|
+
kvProtocol = {
|
|
576
|
+
protocolID: 0,
|
|
577
|
+
key: 1,
|
|
578
|
+
value: 2,
|
|
579
|
+
controller: 3,
|
|
580
|
+
signature: 4
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
### Variable: kvStoreInterpreter
|
|
588
|
+
|
|
589
|
+
```ts
|
|
590
|
+
kvStoreInterpreter: InterpreterFunction<string, KVContext> = async (transaction: Transaction, outputIndex: number, ctx?: KVContext): Promise<string | undefined> => {
|
|
591
|
+
try {
|
|
592
|
+
const output = transaction.outputs[outputIndex];
|
|
593
|
+
if (output == null || output.lockingScript == null)
|
|
594
|
+
return undefined;
|
|
595
|
+
if (ctx == null || ctx.key == null)
|
|
596
|
+
return undefined;
|
|
597
|
+
const decoded = PushDrop.decode(output.lockingScript);
|
|
598
|
+
if (decoded.fields.length !== Object.keys(kvProtocol).length)
|
|
599
|
+
return undefined;
|
|
600
|
+
const key = Utils.toUTF8(decoded.fields[kvProtocol.key]);
|
|
601
|
+
const protocolID = Utils.toUTF8(decoded.fields[kvProtocol.protocolID]);
|
|
602
|
+
if (key !== ctx.key || protocolID !== JSON.stringify(ctx.protocolID))
|
|
603
|
+
return undefined;
|
|
604
|
+
try {
|
|
605
|
+
return Utils.toUTF8(decoded.fields[kvProtocol.value]);
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
return undefined;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
catch {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
See also: [KVContext](./kvstore.md#interface-kvcontext), [PushDrop](./script.md#class-pushdrop), [Transaction](./transaction.md#class-transaction), [kvProtocol](./kvstore.md#variable-kvprotocol), [toUTF8](./primitives.md#variable-toutf8)
|
|
618
|
+
|
|
619
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
620
|
+
|
|
621
|
+
---
|
package/package.json
CHANGED
package/src/kvstore/index.ts
CHANGED
package/src/primitives/Random.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Random number generator that works across modern JavaScript environments.
|
|
3
|
+
*
|
|
4
|
+
* This implementation uses the Web Crypto API which is available in:
|
|
5
|
+
* - Node.js 6+ via require('crypto').randomBytes()
|
|
6
|
+
* - Node.js 18+ via globalThis.crypto
|
|
7
|
+
* - Modern browsers via globalThis.crypto, self.crypto, or window.crypto
|
|
8
|
+
* - Web Workers and Service Workers via self.crypto
|
|
9
|
+
* - Deno and Bun via globalThis.crypto
|
|
10
|
+
* - React Native (requires react-native-get-random-values polyfill)
|
|
11
|
+
*
|
|
12
|
+
* @throws {Error} If no secure random number generator is available
|
|
13
|
+
*/
|
|
1
14
|
class Rand {
|
|
2
15
|
_rand: (n: number) => number[] // ✅ Explicit function type
|
|
3
16
|
|
|
17
|
+
getRandomValues (obj: any, n: number): number[] {
|
|
18
|
+
const arr = new Uint8Array(n)
|
|
19
|
+
obj.crypto.getRandomValues(arr)
|
|
20
|
+
return Array.from(arr)
|
|
21
|
+
}
|
|
22
|
+
|
|
4
23
|
constructor () {
|
|
5
24
|
const noRand = (): never => {
|
|
6
25
|
throw new Error(
|
|
@@ -10,29 +29,79 @@ class Rand {
|
|
|
10
29
|
|
|
11
30
|
this._rand = noRand // Assign the function
|
|
12
31
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/* eslint-disable-next-line */
|
|
19
|
-
self.crypto.getRandomValues(arr);
|
|
20
|
-
return [...arr]
|
|
21
|
-
}
|
|
22
|
-
} /* if (typeof window === 'object') */ else {
|
|
23
|
-
this._rand = noRand
|
|
32
|
+
// Try globalThis.crypto (works in Node.js 18+, modern browsers, and Deno)
|
|
33
|
+
if (typeof globalThis !== 'undefined' && typeof (globalThis as any).crypto?.getRandomValues === 'function') {
|
|
34
|
+
this._rand = (n) => {
|
|
35
|
+
/* eslint-disable-next-line */
|
|
36
|
+
return this.getRandomValues(globalThis as any, n)
|
|
24
37
|
}
|
|
25
|
-
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Node.js fallback for versions < 18
|
|
42
|
+
if (typeof process !== 'undefined' && process.release?.name === 'node') {
|
|
26
43
|
try {
|
|
27
|
-
|
|
28
|
-
const crypto = require(
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
45
|
+
const crypto = require('crypto')
|
|
29
46
|
if (typeof crypto.randomBytes === 'function') {
|
|
30
|
-
this._rand = (n
|
|
47
|
+
this._rand = (n) => {
|
|
48
|
+
return Array.from(crypto.randomBytes(n))
|
|
49
|
+
}
|
|
50
|
+
return
|
|
31
51
|
}
|
|
32
|
-
} catch {
|
|
33
|
-
|
|
52
|
+
} catch (e) {
|
|
53
|
+
// crypto module not available, continue to other checks
|
|
34
54
|
}
|
|
35
55
|
}
|
|
56
|
+
|
|
57
|
+
// Try self.crypto (Web Workers and Service Workers)
|
|
58
|
+
if (typeof self !== 'undefined' && typeof self.crypto?.getRandomValues === 'function') {
|
|
59
|
+
this._rand = (n) => {
|
|
60
|
+
/* eslint-disable-next-line */
|
|
61
|
+
return this.getRandomValues(self as any, n)
|
|
62
|
+
}
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Try window.crypto (browsers)
|
|
67
|
+
if (typeof window !== 'undefined' && typeof (window as any).crypto?.getRandomValues === 'function') {
|
|
68
|
+
this._rand = (n) => {
|
|
69
|
+
/* eslint-disable-next-line */
|
|
70
|
+
return this.getRandomValues(window as any, n)
|
|
71
|
+
}
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// React Native support - try to load polyfill
|
|
76
|
+
if (typeof navigator !== 'undefined' && (navigator as any).product === 'ReactNative') {
|
|
77
|
+
try {
|
|
78
|
+
// Try to require the polyfill - this will populate globalThis.crypto
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
80
|
+
require('react-native-get-random-values')
|
|
81
|
+
|
|
82
|
+
if (typeof (globalThis as any).crypto?.getRandomValues === 'function') {
|
|
83
|
+
this._rand = (n) => {
|
|
84
|
+
/* eslint-disable-next-line */
|
|
85
|
+
return this.getRandomValues(globalThis as any, n)
|
|
86
|
+
}
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// Polyfill not available - provide helpful error
|
|
91
|
+
this._rand = (): never => {
|
|
92
|
+
throw new Error(
|
|
93
|
+
'React Native detected but crypto is not available. ' +
|
|
94
|
+
'Please install and import "react-native-get-random-values" at the top of your entry file:\n' +
|
|
95
|
+
'npm install react-native-get-random-values\n' +
|
|
96
|
+
'Then add: import "react-native-get-random-values" to your index.js/App.js'
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// No crypto available
|
|
104
|
+
this._rand = noRand
|
|
36
105
|
}
|
|
37
106
|
|
|
38
107
|
generate (len: number): number[] {
|
|
@@ -11,4 +11,25 @@ describe('Random', () => {
|
|
|
11
11
|
// I haven't seen it fail yet. If you see it fail, please let me know.
|
|
12
12
|
expect(Random(32)).not.toEqual(Random(32))
|
|
13
13
|
})
|
|
14
|
+
it('Produces values in valid byte range (0-255)', () => {
|
|
15
|
+
const bytes = Random(100)
|
|
16
|
+
bytes.forEach(byte => {
|
|
17
|
+
expect(byte).toBeGreaterThanOrEqual(0)
|
|
18
|
+
expect(byte).toBeLessThanOrEqual(255)
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
it('Works with various lengths including edge cases', () => {
|
|
22
|
+
expect(Random(1).length).toBe(1)
|
|
23
|
+
expect(Random(16).length).toBe(16)
|
|
24
|
+
expect(Random(32).length).toBe(32)
|
|
25
|
+
expect(Random(64).length).toBe(64)
|
|
26
|
+
expect(Random(256).length).toBe(256)
|
|
27
|
+
})
|
|
28
|
+
it('Returns an array of numbers', () => {
|
|
29
|
+
const bytes = Random(10)
|
|
30
|
+
expect(Array.isArray(bytes)).toBe(true)
|
|
31
|
+
bytes.forEach(byte => {
|
|
32
|
+
expect(typeof byte).toBe('number')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
14
35
|
})
|