@taquito/sapling 24.2.0-beta.1 → 24.3.0-beta.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.
- package/dist/lib/errors.js +10 -10
- package/dist/lib/sapling-forger/sapling-forger.js +3 -3
- package/dist/lib/sapling-keys/helpers.js +3 -3
- package/dist/lib/sapling-keys/in-memory-proving-key.js +16 -30
- package/dist/lib/sapling-keys/in-memory-spending-key.js +48 -68
- package/dist/lib/sapling-keys/in-memory-viewing-key.js +20 -37
- package/dist/lib/sapling-module-wrapper.js +33 -57
- package/dist/lib/sapling-state/sapling-state.js +83 -106
- package/dist/lib/sapling-state/utils.js +7 -18
- package/dist/lib/sapling-tx-builder/sapling-transactions-builder.js +194 -216
- package/dist/lib/sapling-tx-viewer/sapling-transaction-viewer.js +98 -135
- package/dist/lib/taquito-sapling.js +84 -119
- package/dist/lib/version.js +2 -2
- package/dist/taquito-sapling.es6.js +605 -727
- package/dist/taquito-sapling.es6.js.map +1 -1
- package/dist/taquito-sapling.umd.js +604 -726
- package/dist/taquito-sapling.umd.js.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/types/errors.d.ts +11 -8
- package/dist/types/sapling-forger/sapling-forger.d.ts +5 -5
- package/dist/types/sapling-keys/helpers.d.ts +1 -1
- package/dist/types/sapling-keys/in-memory-proving-key.d.ts +3 -4
- package/dist/types/sapling-keys/in-memory-spending-key.d.ts +4 -5
- package/dist/types/sapling-keys/in-memory-viewing-key.d.ts +9 -9
- package/dist/types/sapling-module-wrapper.d.ts +11 -11
- package/dist/types/sapling-state/sapling-state.d.ts +1 -1
- package/dist/types/sapling-state/utils.d.ts +1 -1
- package/dist/types/sapling-tx-builder/sapling-transactions-builder.d.ts +3 -3
- package/dist/types/sapling-tx-viewer/helpers.d.ts +1 -1
- package/dist/types/sapling-tx-viewer/sapling-transaction-viewer.d.ts +4 -4
- package/dist/types/taquito-sapling.d.ts +5 -5
- package/package.json +26 -13
- package/LICENSE +0 -202
|
@@ -4,15 +4,6 @@
|
|
|
4
4
|
* https://github.com/airgap-it/airgap-coin-lib/blob/master/LICENSE.md
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
7
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
8
|
exports.SaplingState = void 0;
|
|
18
9
|
const errors_1 = require("../errors");
|
|
@@ -21,7 +12,7 @@ const utils_1 = require("./utils");
|
|
|
21
12
|
const utils_2 = require("@taquito/utils");
|
|
22
13
|
const bignumber_js_1 = require("bignumber.js");
|
|
23
14
|
/**
|
|
24
|
-
*
|
|
15
|
+
* The SaplingState class's main purpose is to provide a Merkle path for the forger and the transaction builder, so that it may verify that the Sapling transaction is valid
|
|
25
16
|
*
|
|
26
17
|
*/
|
|
27
18
|
class SaplingState {
|
|
@@ -30,25 +21,23 @@ class SaplingState {
|
|
|
30
21
|
this.uncommittedMerkleHash = '0100000000000000000000000000000000000000000000000000000000000000';
|
|
31
22
|
this.uncommittedMerkleHashes = new utils_1.Lazy(() => this.createUncommittedMerkleHashes());
|
|
32
23
|
}
|
|
33
|
-
getStateTree(
|
|
34
|
-
|
|
35
|
-
if (this.stateTree !== undefined && this.stateTree.root === stateDiff.root) {
|
|
36
|
-
return this.stateTree;
|
|
37
|
-
}
|
|
38
|
-
const commitments = stateDiff.commitments_and_ciphertexts.map(([commitment, _]) => commitment);
|
|
39
|
-
let merkleTree;
|
|
40
|
-
if (constructTree) {
|
|
41
|
-
merkleTree = yield this.constructMerkleTree(commitments, 0);
|
|
42
|
-
yield this.validateMerkleTree(merkleTree, stateDiff.root);
|
|
43
|
-
}
|
|
44
|
-
this.stateTree = {
|
|
45
|
-
height: this.height,
|
|
46
|
-
size: commitments.length,
|
|
47
|
-
root: stateDiff.root,
|
|
48
|
-
tree: merkleTree,
|
|
49
|
-
};
|
|
24
|
+
async getStateTree(stateDiff, constructTree = true) {
|
|
25
|
+
if (this.stateTree !== undefined && this.stateTree.root === stateDiff.root) {
|
|
50
26
|
return this.stateTree;
|
|
51
|
-
}
|
|
27
|
+
}
|
|
28
|
+
const commitments = stateDiff.commitments_and_ciphertexts.map(([commitment, _]) => commitment);
|
|
29
|
+
let merkleTree;
|
|
30
|
+
if (constructTree) {
|
|
31
|
+
merkleTree = await this.constructMerkleTree(commitments, 0);
|
|
32
|
+
await this.validateMerkleTree(merkleTree, stateDiff.root);
|
|
33
|
+
}
|
|
34
|
+
this.stateTree = {
|
|
35
|
+
height: this.height,
|
|
36
|
+
size: commitments.length,
|
|
37
|
+
root: stateDiff.root,
|
|
38
|
+
tree: merkleTree,
|
|
39
|
+
};
|
|
40
|
+
return this.stateTree;
|
|
52
41
|
}
|
|
53
42
|
/**
|
|
54
43
|
*
|
|
@@ -56,17 +45,15 @@ class SaplingState {
|
|
|
56
45
|
* @param position position of the hash in the Merkle tree
|
|
57
46
|
* @returns a promise of a string that serves as the Merkle path that can be passed on to the Sapling forger or the transaction builder
|
|
58
47
|
*/
|
|
59
|
-
getWitness(stateTree, position) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return Buffer.concat([heightBuffer, witness, posBuffer]).toString('hex');
|
|
69
|
-
});
|
|
48
|
+
async getWitness(stateTree, position) {
|
|
49
|
+
const heightBuffer = (0, utils_2.hex2Bytes)((0, utils_1.changeEndianness)((0, utils_2.num2PaddedHex)(stateTree.height)));
|
|
50
|
+
const posBuffer = (0, utils_2.hex2Bytes)((0, utils_1.changeEndianness)((0, utils_2.num2PaddedHex)(position, 64)));
|
|
51
|
+
const neighbouringHashes = await this.getNeighbouringHashes([], stateTree.height, position, stateTree.tree);
|
|
52
|
+
const witness = neighbouringHashes
|
|
53
|
+
.map((hash) => Buffer.concat([(0, utils_2.hex2Bytes)((0, utils_1.changeEndianness)((0, utils_2.num2PaddedHex)(hash.length))), hash]))
|
|
54
|
+
.reverse()
|
|
55
|
+
.reduce((acc, next) => Buffer.concat([acc, next]));
|
|
56
|
+
return Buffer.concat([heightBuffer, witness, posBuffer]).toString('hex');
|
|
70
57
|
}
|
|
71
58
|
/**
|
|
72
59
|
*
|
|
@@ -74,51 +61,45 @@ class SaplingState {
|
|
|
74
61
|
* @param height height of the desired Merkle tree
|
|
75
62
|
* @returns a promise of MerkleTree type object
|
|
76
63
|
*/
|
|
77
|
-
constructMerkleTree(leaves, height) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return this.constructMerkleTree(updatedLeaves, height + 1);
|
|
93
|
-
});
|
|
64
|
+
async constructMerkleTree(leaves, height) {
|
|
65
|
+
if (height === this.height && leaves.length === 1) {
|
|
66
|
+
return leaves[0];
|
|
67
|
+
}
|
|
68
|
+
if (height === this.height || leaves.length > Math.pow(2, this.height - 1 - height)) {
|
|
69
|
+
throw new errors_1.TreeConstructionFailure('Children length exceeds maximum number of nodes in a merkle tree');
|
|
70
|
+
}
|
|
71
|
+
const pairedLeaves = (0, utils_1.pairNodes)(leaves);
|
|
72
|
+
const updatedLeaves = await Promise.all(pairedLeaves.map(async (chunk) => {
|
|
73
|
+
const left = await this.getMerkleHash(chunk[0], height);
|
|
74
|
+
const right = await this.getMerkleHash(chunk[1], height);
|
|
75
|
+
const parentHash = await (0, sapling_wasm_1.merkleHash)(height, left, right);
|
|
76
|
+
return [parentHash.toString('hex'), chunk[0], chunk[1]];
|
|
77
|
+
}));
|
|
78
|
+
return this.constructMerkleTree(updatedLeaves, height + 1);
|
|
94
79
|
}
|
|
95
|
-
getMerkleHash(tree, height) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
});
|
|
80
|
+
async getMerkleHash(tree, height) {
|
|
81
|
+
if (tree === undefined) {
|
|
82
|
+
return (await this.uncommittedMerkleHashes.get())[height];
|
|
83
|
+
}
|
|
84
|
+
else if (typeof tree === 'string') {
|
|
85
|
+
return Buffer.from(tree, 'hex');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return Buffer.from(tree[0], 'hex');
|
|
89
|
+
}
|
|
107
90
|
}
|
|
108
91
|
/**
|
|
109
92
|
*
|
|
110
93
|
* @returns hashes of empty or null values to fill in the Merkle tree
|
|
111
94
|
*/
|
|
112
|
-
createUncommittedMerkleHashes() {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return res;
|
|
121
|
-
});
|
|
95
|
+
async createUncommittedMerkleHashes() {
|
|
96
|
+
const res = new Array(this.height);
|
|
97
|
+
res[0] = Buffer.from(this.uncommittedMerkleHash, 'hex');
|
|
98
|
+
for (let i = 0; i < this.height; i++) {
|
|
99
|
+
const hash = res[i];
|
|
100
|
+
res[i + 1] = await (0, sapling_wasm_1.merkleHash)(i, hash, hash);
|
|
101
|
+
}
|
|
102
|
+
return res;
|
|
122
103
|
}
|
|
123
104
|
/**
|
|
124
105
|
*
|
|
@@ -126,13 +107,11 @@ class SaplingState {
|
|
|
126
107
|
* @param expectedRoot the expected merkle root to validate against
|
|
127
108
|
* @throws {@link InvalidMerkleTreeError}
|
|
128
109
|
*/
|
|
129
|
-
validateMerkleTree(tree, expectedRoot) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
});
|
|
110
|
+
async validateMerkleTree(tree, expectedRoot) {
|
|
111
|
+
const root = await this.getMerkleHash(tree, this.height - 1);
|
|
112
|
+
if (root.toString('hex') !== expectedRoot) {
|
|
113
|
+
throw new errors_1.InvalidMerkleTreeError(root.toString('hex'));
|
|
114
|
+
}
|
|
136
115
|
}
|
|
137
116
|
/**
|
|
138
117
|
*
|
|
@@ -142,30 +121,28 @@ class SaplingState {
|
|
|
142
121
|
* @param tree the Merkle tree that we want to traverse
|
|
143
122
|
* @returns the accumulated Buffer array of neighbouring hashes
|
|
144
123
|
*/
|
|
145
|
-
getNeighbouringHashes(acc, height, position, tree) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
124
|
+
async getNeighbouringHashes(acc, height, position, tree) {
|
|
125
|
+
if (typeof tree === 'undefined') {
|
|
126
|
+
throw new Error();
|
|
127
|
+
}
|
|
128
|
+
else if (typeof tree === 'string') {
|
|
129
|
+
return acc;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
let nextPos, nextTree, otherTree;
|
|
133
|
+
const fullTree = new bignumber_js_1.default(2).pow(height - 1);
|
|
134
|
+
if (position.lt(fullTree)) {
|
|
135
|
+
nextPos = position;
|
|
136
|
+
nextTree = tree[1];
|
|
137
|
+
otherTree = tree[2];
|
|
152
138
|
}
|
|
153
139
|
else {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
nextPos = position;
|
|
158
|
-
nextTree = tree[1];
|
|
159
|
-
otherTree = tree[2];
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
nextPos = position.minus(fullTree);
|
|
163
|
-
nextTree = tree[2];
|
|
164
|
-
otherTree = tree[1];
|
|
165
|
-
}
|
|
166
|
-
return this.getNeighbouringHashes([yield this.getMerkleHash(otherTree, height - 1), ...acc], height - 1, nextPos, nextTree);
|
|
140
|
+
nextPos = position.minus(fullTree);
|
|
141
|
+
nextTree = tree[2];
|
|
142
|
+
otherTree = tree[1];
|
|
167
143
|
}
|
|
168
|
-
|
|
144
|
+
return this.getNeighbouringHashes([await this.getMerkleHash(otherTree, height - 1), ...acc], height - 1, nextPos, nextTree);
|
|
145
|
+
}
|
|
169
146
|
}
|
|
170
147
|
}
|
|
171
148
|
exports.SaplingState = SaplingState;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.changeEndianness = exports.Lazy = void 0;
|
|
13
4
|
exports.pairNodes = pairNodes;
|
|
@@ -24,7 +15,7 @@ function pairNodes(leaves) {
|
|
|
24
15
|
return pairs;
|
|
25
16
|
}
|
|
26
17
|
/**
|
|
27
|
-
*
|
|
18
|
+
* helper function to assist in Lazy initializing an object
|
|
28
19
|
*/
|
|
29
20
|
class Lazy {
|
|
30
21
|
constructor(init) {
|
|
@@ -33,14 +24,12 @@ class Lazy {
|
|
|
33
24
|
this.value = undefined;
|
|
34
25
|
}
|
|
35
26
|
// initializes the lazily initiated object
|
|
36
|
-
get() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return this.value;
|
|
43
|
-
});
|
|
27
|
+
async get() {
|
|
28
|
+
if (!this.isInitialized) {
|
|
29
|
+
this.value = await this.init();
|
|
30
|
+
this.isInitialized = true;
|
|
31
|
+
}
|
|
32
|
+
return this.value;
|
|
44
33
|
}
|
|
45
34
|
}
|
|
46
35
|
exports.Lazy = Lazy;
|