@osmura/merkletreejs 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,570 @@
1
+ /// <reference types="node" />
2
+ import Base from './Base';
3
+ declare type TValue = Buffer | BigInt | string | number | null | undefined;
4
+ declare type THashFnResult = Buffer | string;
5
+ declare type THashFn = (value: TValue) => Buffer;
6
+ declare type TLeaf = Buffer;
7
+ declare type TFillDefaultHash = (idx?: number, hashFn?: THashFn) => THashFnResult;
8
+ export interface Options {
9
+ /** If set to `true`, an odd node will be duplicated and combined to make a pair to generate the layer hash. */
10
+ duplicateOdd?: boolean;
11
+ /** If set to `true`, the leaves will hashed using the set hashing algorithms. */
12
+ hashLeaves?: boolean;
13
+ /** If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin-constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. */
14
+ isBitcoinTree?: boolean;
15
+ /** If set to `true`, the leaves will be sorted. Recommended for use of multiProofs. */
16
+ sortLeaves?: boolean;
17
+ /** If set to `true`, the hashing pairs will be sorted. */
18
+ sortPairs?: boolean;
19
+ /** If set to `true`, the leaves and hashing pairs will be sorted. */
20
+ sort?: boolean;
21
+ /** If defined, the resulting hash of this function will be used to fill in odd-numbered layers. */
22
+ fillDefaultHash?: TFillDefaultHash | Buffer | string;
23
+ /** If set to `true`, the resulting tree will be a complete tree. Recommended for use of multiProofs. */
24
+ complete?: boolean;
25
+ concatenator?: (inputs: Buffer[]) => Buffer | Buffer[] | BigInt[];
26
+ }
27
+ /**
28
+ * Class reprensenting a Merkle Tree
29
+ * @namespace MerkleTree
30
+ */
31
+ export declare class MerkleTree extends Base {
32
+ private duplicateOdd;
33
+ private hashFn;
34
+ private concatenator;
35
+ private hashLeaves;
36
+ private isBitcoinTree;
37
+ private leaves;
38
+ private layers;
39
+ private sortLeaves;
40
+ private sortPairs;
41
+ private sort;
42
+ private fillDefaultHash;
43
+ private complete;
44
+ /**
45
+ * @desc Constructs a Merkle Tree.
46
+ * All nodes and leaves are stored as Buffers.
47
+ * Lonely leaf nodes are promoted to the next level up without being hashed again.
48
+ * @param {Buffer[]} leaves - Array of hashed leaves. Each leaf must be a Buffer.
49
+ * @param {Function} hashFunction - Hash function to use for hashing leaves and nodes
50
+ * @param {Object} options - Additional options
51
+ * @example
52
+ *```js
53
+ *const MerkleTree = require('merkletreejs')
54
+ *const crypto = require('crypto')
55
+ *
56
+ *function sha256(data) {
57
+ * // returns Buffer
58
+ * return crypto.createHash('sha256').update(data).digest()
59
+ *}
60
+ *
61
+ *const leaves = ['a', 'b', 'c'].map(value => keccak(value))
62
+ *
63
+ *const tree = new MerkleTree(leaves, sha256)
64
+ *```
65
+ */
66
+ constructor(leaves: any[], hashFn?: any, options?: Options);
67
+ getOptions(): {
68
+ complete: boolean;
69
+ isBitcoinTree: boolean;
70
+ hashLeaves: boolean;
71
+ sortLeaves: boolean;
72
+ sortPairs: boolean;
73
+ sort: boolean;
74
+ fillDefaultHash: string;
75
+ duplicateOdd: boolean;
76
+ };
77
+ private processLeaves;
78
+ private createHashes;
79
+ /**
80
+ * addLeaf
81
+ * @desc Adds a leaf to the tree and re-calculates layers.
82
+ * @param {String|Buffer} - Leaf
83
+ * @param {Boolean} - Set to true if the leaf should be hashed before being added to tree.
84
+ * @example
85
+ *```js
86
+ *tree.addLeaf(newLeaf)
87
+ *```
88
+ */
89
+ addLeaf(leaf: TLeaf, shouldHash?: boolean): void;
90
+ /**
91
+ * addLeaves
92
+ * @desc Adds multiple leaves to the tree and re-calculates layers.
93
+ * @param {String[]|Buffer[]} - Array of leaves
94
+ * @param {Boolean} - Set to true if the leaves should be hashed before being added to tree.
95
+ * @example
96
+ *```js
97
+ *tree.addLeaves(newLeaves)
98
+ *```
99
+ */
100
+ addLeaves(leaves: TLeaf[], shouldHash?: boolean): void;
101
+ /**
102
+ * getLeaves
103
+ * @desc Returns array of leaves of Merkle Tree.
104
+ * @return {Buffer[]}
105
+ * @example
106
+ *```js
107
+ *const leaves = tree.getLeaves()
108
+ *```
109
+ */
110
+ getLeaves(values?: any[]): Buffer[];
111
+ removeLeaf(index: number): Buffer;
112
+ updateLeaf(index: number, value: Buffer, shouldHash?: boolean): void;
113
+ /**
114
+ * getLeaf
115
+ * @desc Returns the leaf at the given index.
116
+ * @param {Number} - Index number
117
+ * @return {Buffer}
118
+ * @example
119
+ *```js
120
+ *const leaf = tree.getLeaf(1)
121
+ *```
122
+ */
123
+ getLeaf(index: number): Buffer;
124
+ /**
125
+ * getHexLeaf
126
+ * @desc Returns the leaf at the given index as a hex string.
127
+ * @param {Number} - Index number
128
+ * @return {String}
129
+ * @example
130
+ *```js
131
+ *const leaf = tree.getHexLeaf(1)
132
+ *```
133
+ */
134
+ getHexLeaf(index: number): string;
135
+ /**
136
+ * getLeafIndex
137
+ * @desc Returns the index of the given leaf, or -1 if the leaf is not found.
138
+ * @param {String|Buffer} - Target leaf
139
+ * @return {number}
140
+ * @example
141
+ *```js
142
+ *const leaf = Buffer.from('abc')
143
+ *const index = tree.getLeafIndex(leaf)
144
+ *```
145
+ */
146
+ getLeafIndex(target: TLeaf): number;
147
+ /**
148
+ * getLeafCount
149
+ * @desc Returns the total number of leaves.
150
+ * @return {number}
151
+ * @example
152
+ *```js
153
+ *const count = tree.getLeafCount()
154
+ *```
155
+ */
156
+ getLeafCount(): number;
157
+ /**
158
+ * getHexLeaves
159
+ * @desc Returns array of leaves of Merkle Tree as hex strings.
160
+ * @return {String[]}
161
+ * @example
162
+ *```js
163
+ *const leaves = tree.getHexLeaves()
164
+ *```
165
+ */
166
+ getHexLeaves(): string[];
167
+ /**
168
+ * marshalLeaves
169
+ * @desc Returns array of leaves of Merkle Tree as a JSON string.
170
+ * @param {String[]|Buffer[]} - Merkle tree leaves
171
+ * @return {String} - List of leaves as JSON string
172
+ * @example
173
+ *```js
174
+ *const jsonStr = MerkleTree.marshalLeaves(leaves)
175
+ *```
176
+ */
177
+ static marshalLeaves(leaves: any[]): string;
178
+ /**
179
+ * unmarshalLeaves
180
+ * @desc Returns array of leaves of Merkle Tree as a Buffers.
181
+ * @param {String|Object} - JSON stringified leaves
182
+ * @return {Buffer[]} - Unmarshalled list of leaves
183
+ * @example
184
+ *```js
185
+ *const leaves = MerkleTree.unmarshalLeaves(jsonStr)
186
+ *```
187
+ */
188
+ static unmarshalLeaves(jsonStr: string | object): Buffer[];
189
+ /**
190
+ * getLayers
191
+ * @desc Returns multi-dimensional array of all layers of Merkle Tree, including leaves and root.
192
+ * @return {Buffer[][]}
193
+ * @example
194
+ *```js
195
+ *const layers = tree.getLayers()
196
+ *```
197
+ */
198
+ getLayers(): Buffer[][];
199
+ /**
200
+ * getHexLayers
201
+ * @desc Returns multi-dimensional array of all layers of Merkle Tree, including leaves and root as hex strings.
202
+ * @return {String[][]}
203
+ * @example
204
+ *```js
205
+ *const layers = tree.getHexLayers()
206
+ *```
207
+ */
208
+ getHexLayers(): string[][];
209
+ /**
210
+ * getLayersFlat
211
+ * @desc Returns single flat array of all layers of Merkle Tree, including leaves and root.
212
+ * @return {Buffer[]}
213
+ * @example
214
+ *```js
215
+ *const layers = tree.getLayersFlat()
216
+ *```
217
+ */
218
+ getLayersFlat(): Buffer[];
219
+ /**
220
+ * getHexLayersFlat
221
+ * @desc Returns single flat array of all layers of Merkle Tree, including leaves and root as hex string.
222
+ * @return {String[]}
223
+ * @example
224
+ *```js
225
+ *const layers = tree.getHexLayersFlat()
226
+ *```
227
+ */
228
+ getHexLayersFlat(): string[];
229
+ /**
230
+ * getLayerCount
231
+ * @desc Returns the total number of layers.
232
+ * @return {number}
233
+ * @example
234
+ *```js
235
+ *const count = tree.getLayerCount()
236
+ *```
237
+ */
238
+ getLayerCount(): number;
239
+ /**
240
+ * getRoot
241
+ * @desc Returns the Merkle root hash as a Buffer.
242
+ * @return {Buffer}
243
+ * @example
244
+ *```js
245
+ *const root = tree.getRoot()
246
+ *```
247
+ */
248
+ getRoot(): Buffer;
249
+ /**
250
+ * getHexRoot
251
+ * @desc Returns the Merkle root hash as a hex string.
252
+ * @return {String}
253
+ * @example
254
+ *```js
255
+ *const root = tree.getHexRoot()
256
+ *```
257
+ */
258
+ getHexRoot(): string;
259
+ /**
260
+ * getProof
261
+ * @desc Returns the proof for a target leaf.
262
+ * @param {Buffer} leaf - Target leaf
263
+ * @param {Number} [index] - Target leaf index in leaves array.
264
+ * Use if there are leaves containing duplicate data in order to distinguish it.
265
+ * @return {Object[]} - Array of objects containing a position property of type string
266
+ * with values of 'left' or 'right' and a data property of type Buffer.
267
+ * @example
268
+ * ```js
269
+ *const proof = tree.getProof(leaves[2])
270
+ *```
271
+ *
272
+ * @example
273
+ *```js
274
+ *const leaves = ['a', 'b', 'a'].map(value => keccak(value))
275
+ *const tree = new MerkleTree(leaves, keccak)
276
+ *const proof = tree.getProof(leaves[2], 2)
277
+ *```
278
+ */
279
+ getProof(leaf: Buffer | string, index?: number): {
280
+ position: 'left' | 'right';
281
+ data: Buffer;
282
+ }[];
283
+ /**
284
+ * getHexProof
285
+ * @desc Returns the proof for a target leaf as hex strings.
286
+ * @param {Buffer} leaf - Target leaf
287
+ * @param {Number} [index] - Target leaf index in leaves array.
288
+ * Use if there are leaves containing duplicate data in order to distinguish it.
289
+ * @return {String[]} - Proof array as hex strings.
290
+ * @example
291
+ * ```js
292
+ *const proof = tree.getHexProof(leaves[2])
293
+ *```
294
+ */
295
+ getHexProof(leaf: Buffer | string, index?: number): string[];
296
+ /**
297
+ * getProofs
298
+ * @desc Returns the proofs for all leaves.
299
+ * @return {Object[]} - Array of objects containing a position property of type string
300
+ * with values of 'left' or 'right' and a data property of type Buffer for all leaves.
301
+ * @example
302
+ * ```js
303
+ *const proofs = tree.getProofs()
304
+ *```
305
+ *
306
+ * @example
307
+ *```js
308
+ *const leaves = ['a', 'b', 'a'].map(value => keccak(value))
309
+ *const tree = new MerkleTree(leaves, keccak)
310
+ *const proofs = tree.getProofs()
311
+ *```
312
+ */
313
+ getProofs(): any[];
314
+ /**
315
+ * getProofsDFS
316
+ * @desc Get all proofs through single traverse
317
+ * @param {Number} currentLayer - Current layer index in traverse.
318
+ * @param {Number} index - Current tarvese node index in traverse.
319
+ * @param {Object[]} proof - Proof chain for single leaf.
320
+ * @param {Object[]} proofs - Proofs for all leaves
321
+ * @example
322
+ * ```js
323
+ *const layers = tree.getLayers()
324
+ *const index = 0;
325
+ *let proof = [];
326
+ *let proofs = [];
327
+ *const proof = tree.getProofsDFS(layers, index, proof, proofs)
328
+ *```
329
+ */
330
+ getProofsDFS(currentLayer: any, index: any, proof: any, proofs: any): any[];
331
+ /**
332
+ * getHexProofs
333
+ * @desc Returns the proofs for all leaves as hex strings.
334
+ * @return {String[]} - Proofs array as hex strings.
335
+ * @example
336
+ * ```js
337
+ *const proofs = tree.getHexProofs()
338
+ *```
339
+ */
340
+ getHexProofs(): string[];
341
+ /**
342
+ * getPositionalHexProof
343
+ * @desc Returns the proof for a target leaf as hex strings and the position in binary (left == 0).
344
+ * @param {Buffer} leaf - Target leaf
345
+ * @param {Number} [index] - Target leaf index in leaves array.
346
+ * Use if there are leaves containing duplicate data in order to distinguish it.
347
+ * @return {(string | number)[][]} - Proof array as hex strings. position at index 0
348
+ * @example
349
+ * ```js
350
+ *const proof = tree.getPositionalHexProof(leaves[2])
351
+ *```
352
+ */
353
+ getPositionalHexProof(leaf: Buffer | string, index?: number): (string | number)[][];
354
+ /**
355
+ * marshalProof
356
+ * @desc Returns proof array as JSON string.
357
+ * @param {String[]|Object[]} proof - Merkle tree proof array
358
+ * @return {String} - Proof array as JSON string.
359
+ * @example
360
+ * ```js
361
+ *const jsonStr = MerkleTree.marshalProof(proof)
362
+ *```
363
+ */
364
+ static marshalProof(proof: any[]): string;
365
+ /**
366
+ * unmarshalProof
367
+ * @desc Returns the proof for a target leaf as a list of Buffers.
368
+ * @param {String|Object} - Merkle tree leaves
369
+ * @return {String|Object} - Marshalled proof
370
+ * @example
371
+ * ```js
372
+ *const proof = MerkleTree.unmarshalProof(jsonStr)
373
+ *```
374
+ */
375
+ static unmarshalProof(jsonStr: string | object): any[];
376
+ static marshalTree(tree: MerkleTree): string;
377
+ static unmarshalTree(jsonStr: string | object, hashFn?: any, options?: Options): MerkleTree;
378
+ /**
379
+ * getProofIndices
380
+ * @desc Returns the proof indices for given tree indices.
381
+ * @param {Number[]} treeIndices - Tree indices
382
+ * @param {Number} depth - Tree depth; number of layers.
383
+ * @return {Number[]} - Proof indices
384
+ * @example
385
+ * ```js
386
+ *const proofIndices = tree.getProofIndices([2,5,6], 4)
387
+ *console.log(proofIndices) // [ 23, 20, 19, 8, 3 ]
388
+ *```
389
+ */
390
+ getProofIndices(treeIndices: number[], depth: number): number[];
391
+ private getProofIndicesForUnevenTree;
392
+ /**
393
+ * getMultiProof
394
+ * @desc Returns the multiproof for given tree indices.
395
+ * @param {Number[]} indices - Tree indices.
396
+ * @return {Buffer[]} - Multiproofs
397
+ * @example
398
+ * ```js
399
+ *const indices = [2, 5, 6]
400
+ *const proof = tree.getMultiProof(indices)
401
+ *```
402
+ */
403
+ getMultiProof(tree?: any[], indices?: any[]): Buffer[];
404
+ private getMultiProofForUnevenTree;
405
+ /**
406
+ * getHexMultiProof
407
+ * @desc Returns the multiproof for given tree indices as hex strings.
408
+ * @param {Number[]} indices - Tree indices.
409
+ * @return {String[]} - Multiproofs as hex strings.
410
+ * @example
411
+ * ```js
412
+ *const indices = [2, 5, 6]
413
+ *const proof = tree.getHexMultiProof(indices)
414
+ *```
415
+ */
416
+ getHexMultiProof(tree: Buffer[] | string[], indices: number[]): string[];
417
+ /**
418
+ * getProofFlags
419
+ * @desc Returns list of booleans where proofs should be used instead of hashing.
420
+ * Proof flags are used in the Solidity multiproof verifiers.
421
+ * @param {Number[]|Buffer[]} leaves
422
+ * @param {Buffer[]} proofs
423
+ * @return {Boolean[]} - Boolean flags
424
+ * @example
425
+ * ```js
426
+ *const indices = [2, 5, 6]
427
+ *const proof = tree.getMultiProof(indices)
428
+ *const proofFlags = tree.getProofFlags(leaves, proof)
429
+ *```
430
+ */
431
+ getProofFlags(leaves: any[], proofs: Buffer[] | string[]): boolean[];
432
+ /**
433
+ * verify
434
+ * @desc Returns true if the proof path (array of hashes) can connect the target node
435
+ * to the Merkle root.
436
+ * @param {Object[]} proof - Array of proof objects that should connect
437
+ * target node to Merkle root.
438
+ * @param {Buffer} targetNode - Target node Buffer
439
+ * @param {Buffer} root - Merkle root Buffer
440
+ * @return {Boolean}
441
+ * @example
442
+ *```js
443
+ *const root = tree.getRoot()
444
+ *const proof = tree.getProof(leaves[2])
445
+ *const verified = tree.verify(proof, leaves[2], root)
446
+ *```
447
+ */
448
+ verify(proof: any[], targetNode: Buffer | string, root: Buffer | string): boolean;
449
+ /**
450
+ * verifyMultiProof
451
+ * @desc Returns true if the multiproofs can connect the leaves to the Merkle root.
452
+ * @param {Buffer} root - Merkle tree root
453
+ * @param {Number[]} proofIndices - Leave indices for proof
454
+ * @param {Buffer[]} proofLeaves - Leaf values at indices for proof
455
+ * @param {Number} leavesCount - Count of original leaves
456
+ * @param {Buffer[]} proof - Multiproofs given indices
457
+ * @return {Boolean}
458
+ * @example
459
+ *```js
460
+ *const leaves = tree.getLeaves()
461
+ *const root = tree.getRoot()
462
+ *const treeFlat = tree.getLayersFlat()
463
+ *const leavesCount = leaves.length
464
+ *const proofIndices = [2, 5, 6]
465
+ *const proofLeaves = proofIndices.map(i => leaves[i])
466
+ *const proof = tree.getMultiProof(treeFlat, indices)
467
+ *const verified = tree.verifyMultiProof(root, proofIndices, proofLeaves, leavesCount, proof)
468
+ *```
469
+ */
470
+ verifyMultiProof(root: Buffer | string, proofIndices: number[], proofLeaves: Buffer[] | string[], leavesCount: number, proof: Buffer[] | string[]): boolean;
471
+ verifyMultiProofWithFlags(root: Buffer | string, leaves: TLeaf[], proofs: Buffer[] | string[], proofFlag: boolean[]): boolean;
472
+ private verifyMultiProofForUnevenTree;
473
+ /**
474
+ * getDepth
475
+ * @desc Returns the tree depth (number of layers)
476
+ * @return {Number}
477
+ * @example
478
+ *```js
479
+ *const depth = tree.getDepth()
480
+ *```
481
+ */
482
+ getDepth(): number;
483
+ /**
484
+ * getLayersAsObject
485
+ * @desc Returns the layers as nested objects instead of an array.
486
+ * @example
487
+ *```js
488
+ *const layersObj = tree.getLayersAsObject()
489
+ *```
490
+ */
491
+ getLayersAsObject(): any;
492
+ /**
493
+ * verify
494
+ * @desc Returns true if the proof path (array of hashes) can connect the target node
495
+ * to the Merkle root.
496
+ * @param {Object[]} proof - Array of proof objects that should connect
497
+ * target node to Merkle root.
498
+ * @param {Buffer} targetNode - Target node Buffer
499
+ * @param {Buffer} root - Merkle root Buffer
500
+ * @param {Function} hashFunction - Hash function for hashing leaves and nodes
501
+ * @param {Object} options - Additional options
502
+ * @return {Boolean}
503
+ * @example
504
+ *```js
505
+ *const verified = MerkleTree.verify(proof, leaf, root, sha256, options)
506
+ *```
507
+ */
508
+ static verify(proof: any[], targetNode: Buffer | string, root: Buffer | string, hashFn?: any, options?: Options): boolean;
509
+ /**
510
+ * getMultiProof
511
+ * @desc Returns the multiproof for given tree indices.
512
+ * @param {Buffer[]} tree - Tree as a flat array.
513
+ * @param {Number[]} indices - Tree indices.
514
+ * @return {Buffer[]} - Multiproofs
515
+ *
516
+ *@example
517
+ * ```js
518
+ *const flatTree = tree.getLayersFlat()
519
+ *const indices = [2, 5, 6]
520
+ *const proof = MerkleTree.getMultiProof(flatTree, indices)
521
+ *```
522
+ */
523
+ static getMultiProof(tree: Buffer[] | string[], indices: number[]): Buffer[];
524
+ /**
525
+ * resetTree
526
+ * @desc Resets the tree by clearing the leaves and layers.
527
+ * @example
528
+ *```js
529
+ *tree.resetTree()
530
+ *```
531
+ */
532
+ resetTree(): void;
533
+ /**
534
+ * getPairNode
535
+ * @desc Returns the node at the index for given layer.
536
+ * @param {Buffer[]} layer - Tree layer
537
+ * @param {Number} index - Index at layer.
538
+ * @return {Buffer} - Node
539
+ *
540
+ *@example
541
+ * ```js
542
+ *const node = tree.getPairNode(layer, index)
543
+ *```
544
+ */
545
+ private getPairNode;
546
+ /**
547
+ * toTreeString
548
+ * @desc Returns a visual representation of the merkle tree as a string.
549
+ * @return {String}
550
+ * @example
551
+ *```js
552
+ *console.log(tree.toTreeString())
553
+ *```
554
+ */
555
+ protected toTreeString(): string;
556
+ /**
557
+ * toString
558
+ * @desc Returns a visual representation of the merkle tree as a string.
559
+ * @example
560
+ *```js
561
+ *console.log(tree.toString())
562
+ *```
563
+ */
564
+ toString(): string;
565
+ isUnevenTree(treeLayers?: any[]): boolean;
566
+ private isPowOf2;
567
+ isValidLeafIndex(idx: number): boolean;
568
+ private calculateRootForUnevenTree;
569
+ }
570
+ export default MerkleTree;