@taquito/sapling 17.3.2 → 17.4.0-beta-RC.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.
Files changed (53) hide show
  1. package/dist/lib/constants.js +0 -1
  2. package/dist/lib/errors.js +0 -1
  3. package/dist/lib/sapling-forger/sapling-forger.js +8 -9
  4. package/dist/lib/sapling-keys/helpers.js +6 -7
  5. package/dist/lib/sapling-keys/in-memory-proving-key.js +15 -18
  6. package/dist/lib/sapling-keys/in-memory-spending-key.js +22 -25
  7. package/dist/lib/sapling-keys/in-memory-viewing-key.js +18 -21
  8. package/dist/lib/sapling-module-wrapper.js +1 -2
  9. package/dist/lib/sapling-state/sapling-state.js +6 -7
  10. package/dist/lib/sapling-state/utils.js +0 -1
  11. package/dist/lib/sapling-tx-builder/sapling-transactions-builder.js +78 -80
  12. package/dist/lib/sapling-tx-viewer/helpers.js +2 -3
  13. package/dist/lib/sapling-tx-viewer/sapling-transaction-viewer.js +36 -39
  14. package/dist/lib/taquito-sapling.js +55 -58
  15. package/dist/lib/types.js +0 -1
  16. package/dist/lib/version.js +2 -3
  17. package/dist/taquito-sapling.es6.js +1383 -1380
  18. package/dist/taquito-sapling.es6.js.map +1 -1
  19. package/dist/taquito-sapling.umd.js +1387 -1393
  20. package/dist/taquito-sapling.umd.js.map +1 -1
  21. package/dist/types/constants.d.ts +5 -5
  22. package/dist/types/errors.d.ts +52 -52
  23. package/dist/types/sapling-forger/sapling-forger.d.ts +30 -30
  24. package/dist/types/sapling-keys/helpers.d.ts +2 -2
  25. package/dist/types/sapling-keys/in-memory-proving-key.d.ts +35 -35
  26. package/dist/types/sapling-keys/in-memory-spending-key.d.ts +53 -53
  27. package/dist/types/sapling-keys/in-memory-viewing-key.d.ts +48 -48
  28. package/dist/types/sapling-module-wrapper.d.ts +19 -19
  29. package/dist/types/sapling-state/sapling-state.d.ts +56 -56
  30. package/dist/types/sapling-state/utils.d.ts +22 -22
  31. package/dist/types/sapling-tx-builder/sapling-transactions-builder.d.ts +32 -32
  32. package/dist/types/sapling-tx-viewer/helpers.d.ts +11 -11
  33. package/dist/types/sapling-tx-viewer/sapling-transaction-viewer.d.ts +50 -50
  34. package/dist/types/taquito-sapling.d.ts +81 -81
  35. package/dist/types/types.d.ts +147 -147
  36. package/dist/types/version.d.ts +4 -4
  37. package/package.json +33 -35
  38. package/dist/lib/constants.js.map +0 -1
  39. package/dist/lib/errors.js.map +0 -1
  40. package/dist/lib/sapling-forger/sapling-forger.js.map +0 -1
  41. package/dist/lib/sapling-keys/helpers.js.map +0 -1
  42. package/dist/lib/sapling-keys/in-memory-proving-key.js.map +0 -1
  43. package/dist/lib/sapling-keys/in-memory-spending-key.js.map +0 -1
  44. package/dist/lib/sapling-keys/in-memory-viewing-key.js.map +0 -1
  45. package/dist/lib/sapling-module-wrapper.js.map +0 -1
  46. package/dist/lib/sapling-state/sapling-state.js.map +0 -1
  47. package/dist/lib/sapling-state/utils.js.map +0 -1
  48. package/dist/lib/sapling-tx-builder/sapling-transactions-builder.js.map +0 -1
  49. package/dist/lib/sapling-tx-viewer/helpers.js.map +0 -1
  50. package/dist/lib/sapling-tx-viewer/sapling-transaction-viewer.js.map +0 -1
  51. package/dist/lib/taquito-sapling.js.map +0 -1
  52. package/dist/lib/types.js.map +0 -1
  53. package/dist/lib/version.js.map +0 -1
@@ -4,10 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.taquitoSapling = {}, global.BigNumber, global.taquito, global.utils, global.core, global.sapling, global.blake, global.nacl, global.random, global.bip39, global.toBuffer, global.pbkdf2));
5
5
  })(this, (function (exports, BigNumber, taquito, utils, core, sapling, blake, nacl, random, bip39, toBuffer, pbkdf2) { 'use strict';
6
6
 
7
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
-
9
- function _interopNamespace(e) {
10
- if (e && e.__esModule) return e;
7
+ function _interopNamespaceDefault(e) {
11
8
  var n = Object.create(null);
12
9
  if (e) {
13
10
  Object.keys(e).forEach(function (k) {
@@ -20,16 +17,12 @@
20
17
  }
21
18
  });
22
19
  }
23
- n["default"] = e;
20
+ n.default = e;
24
21
  return Object.freeze(n);
25
22
  }
26
23
 
27
- var BigNumber__default = /*#__PURE__*/_interopDefaultLegacy(BigNumber);
28
- var sapling__namespace = /*#__PURE__*/_interopNamespace(sapling);
29
- var blake__default = /*#__PURE__*/_interopDefaultLegacy(blake);
30
- var bip39__namespace = /*#__PURE__*/_interopNamespace(bip39);
31
- var toBuffer__default = /*#__PURE__*/_interopDefaultLegacy(toBuffer);
32
- var pbkdf2__default = /*#__PURE__*/_interopDefaultLegacy(pbkdf2);
24
+ var sapling__namespace = /*#__PURE__*/_interopNamespaceDefault(sapling);
25
+ var bip39__namespace = /*#__PURE__*/_interopNamespaceDefault(bip39);
33
26
 
34
27
  /******************************************************************************
35
28
  Copyright (c) Microsoft Corporation.
@@ -45,6 +38,8 @@
45
38
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
46
39
  PERFORMANCE OF THIS SOFTWARE.
47
40
  ***************************************************************************** */
41
+ /* global Reflect, Promise, SuppressedError, Symbol */
42
+
48
43
 
49
44
  function __rest(s, e) {
50
45
  var t = {};
@@ -86,1407 +81,1408 @@
86
81
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
87
82
  };
88
83
 
89
- /**
90
- * @category Error
91
- * @description Error indicates the spending key is invalid
92
- */
93
- class InvalidSpendingKey extends core.ParameterValidationError {
94
- constructor(sk, errorDetail) {
95
- super();
96
- this.sk = sk;
97
- this.errorDetail = errorDetail;
98
- this.name = 'InvalidSpendingKey';
99
- this.message = `Invalid spending key "${sk}" ${errorDetail}.`;
100
- }
101
- }
102
- /**
103
- * @category Error
104
- * @description Error indicates an invalid Merkle tree being passed
105
- */
106
- class InvalidMerkleTreeError extends core.ParameterValidationError {
107
- constructor(root) {
108
- super();
109
- this.root = root;
110
- this.name = 'InvalidMerkleTreeError';
111
- this.message = `Invalid merkle tree has root "${JSON.stringify(root)}" different from expected root.`;
112
- }
113
- }
114
- /**
115
- * @category Error
116
- * @description Error indicates a failure when trying to construct the Merkle tree
117
- */
118
- class TreeConstructionFailure extends core.TaquitoError {
119
- constructor(message) {
120
- super();
121
- this.message = message;
122
- this.name = 'TreeConstructionFailure';
123
- }
124
- }
125
- /**
126
- * @category Error
127
- * @description Error indicates the memo is invalid
128
- */
129
- class InvalidMemo extends core.ParameterValidationError {
130
- constructor(memo, errorDetails) {
131
- super();
132
- this.memo = memo;
133
- this.errorDetails = errorDetails;
134
- this.name = 'InvalidMemo';
135
- this.message = `Invalid memo "${memo}" with length ${memo.length} ${errorDetails}`;
136
- }
137
- }
138
- /**
139
- * @category Error
140
- * @description Error indicates not enough balance to prepare the sapling transaction
141
- */
142
- class InsufficientBalance extends core.TaquitoError {
143
- constructor(realBalance, amountToSpend) {
144
- super();
145
- this.realBalance = realBalance;
146
- this.amountToSpend = amountToSpend;
147
- this.name = 'InsufficientBalance';
148
- this.message = `Unable to spend "${amountToSpend}" mutez while the balance is only ${realBalance} mutez.`;
149
- }
150
- }
151
- /**
152
- * @category Error
153
- * @description Error indicates SaplingTransactionViewer failure
154
- */
155
- class SaplingTransactionViewerError extends core.TaquitoError {
156
- constructor(message) {
157
- super();
158
- this.message = message;
159
- this.name = 'SaplingTransactionViewerError';
160
- }
84
+ /**
85
+ * @category Error
86
+ * @description Error indicates the spending key is invalid
87
+ */
88
+ class InvalidSpendingKey extends core.ParameterValidationError {
89
+ constructor(sk, errorDetail) {
90
+ super();
91
+ this.sk = sk;
92
+ this.errorDetail = errorDetail;
93
+ this.name = 'InvalidSpendingKey';
94
+ this.message = `Invalid spending key "${sk}" ${errorDetail}.`;
95
+ }
96
+ }
97
+ /**
98
+ * @category Error
99
+ * @description Error indicates an invalid Merkle tree being passed
100
+ */
101
+ class InvalidMerkleTreeError extends core.ParameterValidationError {
102
+ constructor(root) {
103
+ super();
104
+ this.root = root;
105
+ this.name = 'InvalidMerkleTreeError';
106
+ this.message = `Invalid merkle tree has root "${JSON.stringify(root)}" different from expected root.`;
107
+ }
108
+ }
109
+ /**
110
+ * @category Error
111
+ * @description Error indicates a failure when trying to construct the Merkle tree
112
+ */
113
+ class TreeConstructionFailure extends core.TaquitoError {
114
+ constructor(message) {
115
+ super();
116
+ this.message = message;
117
+ this.name = 'TreeConstructionFailure';
118
+ }
119
+ }
120
+ /**
121
+ * @category Error
122
+ * @description Error indicates the memo is invalid
123
+ */
124
+ class InvalidMemo extends core.ParameterValidationError {
125
+ constructor(memo, errorDetails) {
126
+ super();
127
+ this.memo = memo;
128
+ this.errorDetails = errorDetails;
129
+ this.name = 'InvalidMemo';
130
+ this.message = `Invalid memo "${memo}" with length ${memo.length} ${errorDetails}`;
131
+ }
132
+ }
133
+ /**
134
+ * @category Error
135
+ * @description Error indicates not enough balance to prepare the sapling transaction
136
+ */
137
+ class InsufficientBalance extends core.TaquitoError {
138
+ constructor(realBalance, amountToSpend) {
139
+ super();
140
+ this.realBalance = realBalance;
141
+ this.amountToSpend = amountToSpend;
142
+ this.name = 'InsufficientBalance';
143
+ this.message = `Unable to spend "${amountToSpend}" mutez while the balance is only ${realBalance} mutez.`;
144
+ }
145
+ }
146
+ /**
147
+ * @category Error
148
+ * @description Error indicates SaplingTransactionViewer failure
149
+ */
150
+ class SaplingTransactionViewerError extends core.TaquitoError {
151
+ constructor(message) {
152
+ super();
153
+ this.message = message;
154
+ this.name = 'SaplingTransactionViewerError';
155
+ }
161
156
  }
162
157
 
163
- function memoHexToUtf8(memo) {
164
- const memoNoPadding = removeZeroPaddedBytesRight(memo);
165
- return memoNoPadding === '' ? memoNoPadding : utils.bytes2Char(memoNoPadding);
166
- }
167
- function removeZeroPaddedBytesRight(memo) {
168
- const matchZeroRight = memo.match(/^(.*?)(00)+$/);
169
- return matchZeroRight ? matchZeroRight[1] : memo;
170
- }
171
- function readableFormat(saplingTransactionProperties) {
172
- return {
173
- value: convertValueToBigNumber(saplingTransactionProperties.value),
174
- memo: memoHexToUtf8(Buffer.from(saplingTransactionProperties.memo).toString('hex')),
175
- paymentAddress: utils.b58cencode(saplingTransactionProperties.paymentAddress, utils.prefix[utils.Prefix.ZET1]),
176
- };
177
- }
178
- function convertValueToBigNumber(value) {
179
- return new BigNumber__default["default"](Buffer.from(value).toString('hex'), 16);
180
- }
181
- function bufToUint8Array(buffer) {
182
- return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
158
+ function memoHexToUtf8(memo) {
159
+ const memoNoPadding = removeZeroPaddedBytesRight(memo);
160
+ return memoNoPadding === '' ? memoNoPadding : utils.bytes2Char(memoNoPadding);
161
+ }
162
+ function removeZeroPaddedBytesRight(memo) {
163
+ const matchZeroRight = memo.match(/^(.*?)(00)+$/);
164
+ return matchZeroRight ? matchZeroRight[1] : memo;
165
+ }
166
+ function readableFormat(saplingTransactionProperties) {
167
+ return {
168
+ value: convertValueToBigNumber(saplingTransactionProperties.value),
169
+ memo: memoHexToUtf8(Buffer.from(saplingTransactionProperties.memo).toString('hex')),
170
+ paymentAddress: utils.b58cencode(saplingTransactionProperties.paymentAddress, utils.prefix[utils.Prefix.ZET1]),
171
+ };
172
+ }
173
+ function convertValueToBigNumber(value) {
174
+ return new BigNumber(Buffer.from(value).toString('hex'), 16);
175
+ }
176
+ function bufToUint8Array(buffer) {
177
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
183
178
  }
184
179
 
185
- class SaplingForger {
186
- /**
187
- * @description Forge sapling transactions
188
- * @param spendDescriptions the list of spend descriptions
189
- * @param outputDescriptions the list of output descriptions
190
- * @param signature signature hash
191
- * @param balance balance of the Sapling contract (input/output difference)
192
- * @param root root of the merkle tree
193
- * @returns Forged sapling transaction of type Buffer
194
- */
195
- forgeSaplingTransaction(tx) {
196
- const spendBuf = this.forgeSpendDescriptions(tx.inputs);
197
- const spend = Buffer.concat([utils.toHexBuf(spendBuf.length, 32), spendBuf]);
198
- const outputBuf = this.forgeOutputDescriptions(tx.outputs);
199
- const output = Buffer.concat([utils.toHexBuf(outputBuf.length, 32), outputBuf]);
200
- const root = Buffer.from(tx.root, 'hex');
201
- return Buffer.concat([
202
- spend,
203
- output,
204
- tx.signature,
205
- utils.toHexBuf(tx.balance, 64),
206
- root,
207
- utils.toHexBuf(tx.boundData.length, 32),
208
- tx.boundData,
209
- ]);
210
- }
211
- /**
212
- * @description Forge list of spend descriptions
213
- * @param spendDescriptions list of spend descriptions
214
- * @returns concatenated forged bytes of type Buffer
215
- */
216
- forgeSpendDescriptions(spendDescriptions) {
217
- const descriptions = [];
218
- for (const i of spendDescriptions) {
219
- const buff = this.forgeSpendDescription(i);
220
- descriptions.push(buff);
221
- }
222
- return Buffer.concat(descriptions);
223
- }
224
- forgeSpendDescription(desc) {
225
- return Buffer.concat([
226
- desc.commitmentValue,
227
- desc.nullifier,
228
- desc.publicKeyReRandomization,
229
- desc.proof,
230
- desc.signature,
231
- ]);
232
- }
233
- /**
234
- * @description Forge list of output descriptions
235
- * @param outputDescriptions list of output descriptions
236
- * @returns concatenated forged bytes of type Buffer
237
- */
238
- forgeOutputDescriptions(outputDescriptions) {
239
- const descriptions = [];
240
- for (const i of outputDescriptions) {
241
- const buff = this.forgeOutputDescription(i);
242
- descriptions.push(buff);
243
- }
244
- return Buffer.concat(descriptions);
245
- }
246
- forgeOutputDescription(desc) {
247
- const ct = desc.ciphertext;
248
- return Buffer.concat([
249
- desc.commitment,
250
- desc.proof,
251
- ct.commitmentValue,
252
- ct.ephemeralPublicKey,
253
- utils.toHexBuf(ct.payloadEnc.length, 32),
254
- ct.payloadEnc,
255
- ct.nonceEnc,
256
- ct.payloadOut,
257
- ct.nonceOut,
258
- ]);
259
- }
260
- forgeUnsignedTxInput(unsignedSpendDescription) {
261
- return Buffer.concat([
262
- unsignedSpendDescription.commitmentValue,
263
- unsignedSpendDescription.nullifier,
264
- unsignedSpendDescription.publicKeyReRandomization,
265
- unsignedSpendDescription.proof,
266
- ]);
267
- }
268
- forgeTransactionPlaintext(txPlainText) {
269
- const encodedMemo = Buffer.from(utils.char2Bytes(txPlainText.memo).padEnd(txPlainText.memoSize, '0'), 'hex');
270
- return Buffer.concat([
271
- txPlainText.diversifier,
272
- utils.toHexBuf(new BigNumber__default["default"](txPlainText.amount), 64),
273
- txPlainText.randomCommitmentTrapdoor,
274
- utils.toHexBuf(txPlainText.memoSize, 32),
275
- encodedMemo,
276
- ]);
277
- }
180
+ class SaplingForger {
181
+ /**
182
+ * @description Forge sapling transactions
183
+ * @param spendDescriptions the list of spend descriptions
184
+ * @param outputDescriptions the list of output descriptions
185
+ * @param signature signature hash
186
+ * @param balance balance of the Sapling contract (input/output difference)
187
+ * @param root root of the merkle tree
188
+ * @returns Forged sapling transaction of type Buffer
189
+ */
190
+ forgeSaplingTransaction(tx) {
191
+ const spendBuf = this.forgeSpendDescriptions(tx.inputs);
192
+ const spend = Buffer.concat([utils.toHexBuf(spendBuf.length, 32), spendBuf]);
193
+ const outputBuf = this.forgeOutputDescriptions(tx.outputs);
194
+ const output = Buffer.concat([utils.toHexBuf(outputBuf.length, 32), outputBuf]);
195
+ const root = Buffer.from(tx.root, 'hex');
196
+ return Buffer.concat([
197
+ spend,
198
+ output,
199
+ tx.signature,
200
+ utils.toHexBuf(tx.balance, 64),
201
+ root,
202
+ utils.toHexBuf(tx.boundData.length, 32),
203
+ tx.boundData,
204
+ ]);
205
+ }
206
+ /**
207
+ * @description Forge list of spend descriptions
208
+ * @param spendDescriptions list of spend descriptions
209
+ * @returns concatenated forged bytes of type Buffer
210
+ */
211
+ forgeSpendDescriptions(spendDescriptions) {
212
+ const descriptions = [];
213
+ for (const i of spendDescriptions) {
214
+ const buff = this.forgeSpendDescription(i);
215
+ descriptions.push(buff);
216
+ }
217
+ return Buffer.concat(descriptions);
218
+ }
219
+ forgeSpendDescription(desc) {
220
+ return Buffer.concat([
221
+ desc.commitmentValue,
222
+ desc.nullifier,
223
+ desc.publicKeyReRandomization,
224
+ desc.proof,
225
+ desc.signature,
226
+ ]);
227
+ }
228
+ /**
229
+ * @description Forge list of output descriptions
230
+ * @param outputDescriptions list of output descriptions
231
+ * @returns concatenated forged bytes of type Buffer
232
+ */
233
+ forgeOutputDescriptions(outputDescriptions) {
234
+ const descriptions = [];
235
+ for (const i of outputDescriptions) {
236
+ const buff = this.forgeOutputDescription(i);
237
+ descriptions.push(buff);
238
+ }
239
+ return Buffer.concat(descriptions);
240
+ }
241
+ forgeOutputDescription(desc) {
242
+ const ct = desc.ciphertext;
243
+ return Buffer.concat([
244
+ desc.commitment,
245
+ desc.proof,
246
+ ct.commitmentValue,
247
+ ct.ephemeralPublicKey,
248
+ utils.toHexBuf(ct.payloadEnc.length, 32),
249
+ ct.payloadEnc,
250
+ ct.nonceEnc,
251
+ ct.payloadOut,
252
+ ct.nonceOut,
253
+ ]);
254
+ }
255
+ forgeUnsignedTxInput(unsignedSpendDescription) {
256
+ return Buffer.concat([
257
+ unsignedSpendDescription.commitmentValue,
258
+ unsignedSpendDescription.nullifier,
259
+ unsignedSpendDescription.publicKeyReRandomization,
260
+ unsignedSpendDescription.proof,
261
+ ]);
262
+ }
263
+ forgeTransactionPlaintext(txPlainText) {
264
+ const encodedMemo = Buffer.from(utils.char2Bytes(txPlainText.memo).padEnd(txPlainText.memoSize, '0'), 'hex');
265
+ return Buffer.concat([
266
+ txPlainText.diversifier,
267
+ utils.toHexBuf(new BigNumber(txPlainText.amount), 64),
268
+ txPlainText.randomCommitmentTrapdoor,
269
+ utils.toHexBuf(txPlainText.memoSize, 32),
270
+ encodedMemo,
271
+ ]);
272
+ }
278
273
  }
279
274
 
280
- const KDF_KEY = 'KDFSaplingForTezosV1';
281
- const OCK_KEY = 'OCK_keystringderivation_TEZOS';
282
- const DEFAULT_MEMO = '';
275
+ const KDF_KEY = 'KDFSaplingForTezosV1';
276
+ const OCK_KEY = 'OCK_keystringderivation_TEZOS';
277
+ const DEFAULT_MEMO = '';
283
278
  const DEFAULT_BOUND_DATA = Buffer.from('', 'hex');
284
279
 
285
- var _viewingKeyProvider, _readProvider$2, _saplingContractId;
286
- /**
287
- * @description Allows to retrieve and decrypt sapling transactions using on a viewing key
288
- *
289
- * @param inMemoryViewingKey Holds the sapling viewing key
290
- * @param saplingContractId Address of the sapling contract or sapling id if the smart contract contains multiple sapling states
291
- * @param readProvider Allows to read data from the blockchain
292
- */
293
- class SaplingTransactionViewer {
294
- constructor(inMemoryViewingKey, saplingContractId, readProvider) {
295
- _viewingKeyProvider.set(this, void 0);
296
- _readProvider$2.set(this, void 0);
297
- _saplingContractId.set(this, void 0);
298
- __classPrivateFieldSet(this, _viewingKeyProvider, inMemoryViewingKey);
299
- __classPrivateFieldSet(this, _saplingContractId, saplingContractId);
300
- __classPrivateFieldSet(this, _readProvider$2, readProvider);
301
- }
302
- /**
303
- * @description Retrieve the unspent balance associated with the configured viewing key and sapling state
304
- *
305
- * @returns the balance in mutez represented as a BigNumber
306
- *
307
- */
308
- getBalance() {
309
- return __awaiter(this, void 0, void 0, function* () {
310
- let balance = new BigNumber__default["default"](0);
311
- const { commitments_and_ciphertexts, nullifiers } = yield this.getSaplingDiff();
312
- for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
313
- const decrypted = yield this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
314
- if (decrypted) {
315
- const valueBigNumber = convertValueToBigNumber(decrypted.value);
316
- const isSpent = yield this.isSpent(decrypted.paymentAddress, valueBigNumber.toString(), decrypted.randomCommitmentTrapdoor, i, nullifiers);
317
- if (!isSpent) {
318
- balance = balance.plus(valueBigNumber);
319
- }
320
- }
321
- }
322
- return balance;
323
- });
324
- }
325
- /**
326
- * @description Retrieve all the incoming and outgoing transactions associated with the configured viewing key.
327
- * The response properties are in Uint8Array format; use the getIncomingAndOutgoingTransactions method for readable properties
328
- *
329
- */
330
- getIncomingAndOutgoingTransactionsRaw() {
331
- return __awaiter(this, void 0, void 0, function* () {
332
- const incoming = [];
333
- const outgoing = [];
334
- const { commitments_and_ciphertexts, nullifiers } = yield this.getSaplingDiff();
335
- for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
336
- const decryptedAsReceiver = yield this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
337
- const decryptedAsSender = yield this.decryptCiphertextAsSender(commitments_and_ciphertexts[i]);
338
- if (decryptedAsReceiver) {
339
- const balance = convertValueToBigNumber(decryptedAsReceiver.value);
340
- const isSpent = yield this.isSpent(decryptedAsReceiver.paymentAddress, balance.toString(), decryptedAsReceiver.randomCommitmentTrapdoor, i, nullifiers);
341
- incoming.push(Object.assign(Object.assign({}, decryptedAsReceiver), { isSpent, position: i }));
342
- }
343
- if (decryptedAsSender) {
344
- outgoing.push(decryptedAsSender);
345
- }
346
- }
347
- return {
348
- incoming,
349
- outgoing,
350
- };
351
- });
352
- }
353
- /**
354
- * @description Retrieve all the incoming and outgoing decoded transactions associated with the configured viewing key
355
- *
356
- */
357
- getIncomingAndOutgoingTransactions() {
358
- return __awaiter(this, void 0, void 0, function* () {
359
- const tx = yield this.getIncomingAndOutgoingTransactionsRaw();
360
- const incoming = tx.incoming.map((_a) => {
361
- var { isSpent } = _a, rest = __rest(_a, ["isSpent"]);
362
- return Object.assign(Object.assign({}, readableFormat(rest)), { isSpent });
363
- });
364
- const outgoing = tx.outgoing.map((outgoingTx) => {
365
- return readableFormat(outgoingTx);
366
- });
367
- return { incoming, outgoing };
368
- });
369
- }
370
- getSaplingDiff() {
371
- return __awaiter(this, void 0, void 0, function* () {
372
- let saplingDiffResponse;
373
- if (__classPrivateFieldGet(this, _saplingContractId).saplingId) {
374
- saplingDiffResponse = yield __classPrivateFieldGet(this, _readProvider$2).getSaplingDiffById({ id: __classPrivateFieldGet(this, _saplingContractId).saplingId }, 'head');
375
- }
376
- else if (__classPrivateFieldGet(this, _saplingContractId).contractAddress) {
377
- saplingDiffResponse = yield __classPrivateFieldGet(this, _readProvider$2).getSaplingDiffByContract(__classPrivateFieldGet(this, _saplingContractId).contractAddress, 'head');
378
- }
379
- else {
380
- throw new SaplingTransactionViewerError('A contract address or a sapling id was expected in the SaplingTransactionViewer constructor.');
381
- }
382
- return saplingDiffResponse;
383
- });
384
- }
385
- decryptCiphertextAsReceiver(commitmentsAndCiphertexts) {
386
- return __awaiter(this, void 0, void 0, function* () {
387
- const commitment = commitmentsAndCiphertexts[0];
388
- const { epk, payload_enc, nonce_enc } = commitmentsAndCiphertexts[1];
389
- const incomingViewingKey = yield __classPrivateFieldGet(this, _viewingKeyProvider).getIncomingViewingKey();
390
- const keyAgreement = yield sapling__namespace.keyAgreement(epk, incomingViewingKey);
391
- const keyAgreementHash = blake__default["default"].blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
392
- const decrypted = yield this.decryptCiphertext(keyAgreementHash, utils.hex2buf(nonce_enc), utils.hex2buf(payload_enc));
393
- if (decrypted) {
394
- const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decrypted);
395
- const paymentAddress = bufToUint8Array(yield sapling__namespace.getRawPaymentAddressFromIncomingViewingKey(incomingViewingKey, diversifier));
396
- try {
397
- const valid = yield sapling__namespace.verifyCommitment(commitment, paymentAddress, convertValueToBigNumber(value).toString(), rcm);
398
- if (valid) {
399
- return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
400
- }
401
- }
402
- catch (ex) {
403
- if (!/invalid value/.test(ex)) {
404
- throw ex;
405
- }
406
- }
407
- }
408
- });
409
- }
410
- decryptCiphertextAsSender(commitmentsAndCiphertexts) {
411
- return __awaiter(this, void 0, void 0, function* () {
412
- const commitment = commitmentsAndCiphertexts[0];
413
- const { epk, payload_enc, nonce_enc, payload_out, nonce_out, cv } = commitmentsAndCiphertexts[1];
414
- const outgoingViewingKey = yield __classPrivateFieldGet(this, _viewingKeyProvider).getOutgoingViewingKey();
415
- const concat = cv.concat(commitment, epk, outgoingViewingKey.toString('hex'));
416
- const outgoingCipherKey = blake__default["default"].blake2b(Buffer.from(concat, 'hex'), Buffer.from(OCK_KEY), 32);
417
- const decryptedOut = yield this.decryptCiphertext(outgoingCipherKey, utils.hex2buf(nonce_out), utils.hex2buf(payload_out));
418
- if (decryptedOut) {
419
- const { recipientDiversifiedTransmissionKey: pkd, ephemeralPrivateKey: esk } = this.extractPkdAndEsk(decryptedOut);
420
- const keyAgreement = yield sapling__namespace.keyAgreement(pkd, esk);
421
- const keyAgreementHash = blake__default["default"].blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
422
- const decryptedEnc = yield this.decryptCiphertext(keyAgreementHash, utils.hex2buf(nonce_enc), utils.hex2buf(payload_enc));
423
- if (decryptedEnc) {
424
- const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decryptedEnc);
425
- const paymentAddress = utils.mergebuf(diversifier, pkd);
426
- try {
427
- const isValid = yield sapling__namespace.verifyCommitment(commitment, paymentAddress, convertValueToBigNumber(value).toString(), rcm);
428
- if (isValid) {
429
- return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
430
- }
431
- }
432
- catch (ex) {
433
- if (!/invalid value/.test(ex)) {
434
- throw ex;
435
- }
436
- }
437
- }
438
- }
439
- });
440
- }
441
- decryptCiphertext(keyAgreementHash, nonce, payload) {
442
- return __awaiter(this, void 0, void 0, function* () {
443
- return nacl.openSecretBox(keyAgreementHash, nonce, payload);
444
- });
445
- }
446
- extractTransactionProperties(decrypted) {
447
- return {
448
- diversifier: decrypted.slice(0, 11),
449
- value: decrypted.slice(11, 19),
450
- randomCommitmentTrapdoor: decrypted.slice(19, 51),
451
- memoSize: decrypted.slice(51, 55),
452
- memo: decrypted.slice(55),
453
- };
454
- }
455
- extractPkdAndEsk(decrypted) {
456
- return {
457
- recipientDiversifiedTransmissionKey: decrypted.slice(0, 32),
458
- ephemeralPrivateKey: decrypted.slice(32),
459
- };
460
- }
461
- isSpent(address, value, randomCommitmentTrapdoor, position, nullifiers) {
462
- return __awaiter(this, void 0, void 0, function* () {
463
- const computedNullifier = yield sapling__namespace.computeNullifier(__classPrivateFieldGet(this, _viewingKeyProvider).getFullViewingKey(), address, value, randomCommitmentTrapdoor, position);
464
- return nullifiers.includes(computedNullifier.toString('hex'));
465
- });
466
- }
467
- }
468
- _viewingKeyProvider = new WeakMap(), _readProvider$2 = new WeakMap(), _saplingContractId = new WeakMap();
280
+ var _SaplingTransactionViewer_viewingKeyProvider, _SaplingTransactionViewer_readProvider, _SaplingTransactionViewer_saplingContractId;
281
+ /**
282
+ * @description Allows to retrieve and decrypt sapling transactions using on a viewing key
283
+ *
284
+ * @param inMemoryViewingKey Holds the sapling viewing key
285
+ * @param saplingContractId Address of the sapling contract or sapling id if the smart contract contains multiple sapling states
286
+ * @param readProvider Allows to read data from the blockchain
287
+ */
288
+ class SaplingTransactionViewer {
289
+ constructor(inMemoryViewingKey, saplingContractId, readProvider) {
290
+ _SaplingTransactionViewer_viewingKeyProvider.set(this, void 0);
291
+ _SaplingTransactionViewer_readProvider.set(this, void 0);
292
+ _SaplingTransactionViewer_saplingContractId.set(this, void 0);
293
+ __classPrivateFieldSet(this, _SaplingTransactionViewer_viewingKeyProvider, inMemoryViewingKey, "f");
294
+ __classPrivateFieldSet(this, _SaplingTransactionViewer_saplingContractId, saplingContractId, "f");
295
+ __classPrivateFieldSet(this, _SaplingTransactionViewer_readProvider, readProvider, "f");
296
+ }
297
+ /**
298
+ * @description Retrieve the unspent balance associated with the configured viewing key and sapling state
299
+ *
300
+ * @returns the balance in mutez represented as a BigNumber
301
+ *
302
+ */
303
+ getBalance() {
304
+ return __awaiter(this, void 0, void 0, function* () {
305
+ let balance = new BigNumber(0);
306
+ const { commitments_and_ciphertexts, nullifiers } = yield this.getSaplingDiff();
307
+ for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
308
+ const decrypted = yield this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
309
+ if (decrypted) {
310
+ const valueBigNumber = convertValueToBigNumber(decrypted.value);
311
+ const isSpent = yield this.isSpent(decrypted.paymentAddress, valueBigNumber.toString(), decrypted.randomCommitmentTrapdoor, i, nullifiers);
312
+ if (!isSpent) {
313
+ balance = balance.plus(valueBigNumber);
314
+ }
315
+ }
316
+ }
317
+ return balance;
318
+ });
319
+ }
320
+ /**
321
+ * @description Retrieve all the incoming and outgoing transactions associated with the configured viewing key.
322
+ * The response properties are in Uint8Array format; use the getIncomingAndOutgoingTransactions method for readable properties
323
+ *
324
+ */
325
+ getIncomingAndOutgoingTransactionsRaw() {
326
+ return __awaiter(this, void 0, void 0, function* () {
327
+ const incoming = [];
328
+ const outgoing = [];
329
+ const { commitments_and_ciphertexts, nullifiers } = yield this.getSaplingDiff();
330
+ for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
331
+ const decryptedAsReceiver = yield this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
332
+ const decryptedAsSender = yield this.decryptCiphertextAsSender(commitments_and_ciphertexts[i]);
333
+ if (decryptedAsReceiver) {
334
+ const balance = convertValueToBigNumber(decryptedAsReceiver.value);
335
+ const isSpent = yield this.isSpent(decryptedAsReceiver.paymentAddress, balance.toString(), decryptedAsReceiver.randomCommitmentTrapdoor, i, nullifiers);
336
+ incoming.push(Object.assign(Object.assign({}, decryptedAsReceiver), { isSpent, position: i }));
337
+ }
338
+ if (decryptedAsSender) {
339
+ outgoing.push(decryptedAsSender);
340
+ }
341
+ }
342
+ return {
343
+ incoming,
344
+ outgoing,
345
+ };
346
+ });
347
+ }
348
+ /**
349
+ * @description Retrieve all the incoming and outgoing decoded transactions associated with the configured viewing key
350
+ *
351
+ */
352
+ getIncomingAndOutgoingTransactions() {
353
+ return __awaiter(this, void 0, void 0, function* () {
354
+ const tx = yield this.getIncomingAndOutgoingTransactionsRaw();
355
+ const incoming = tx.incoming.map((_a) => {
356
+ var { isSpent } = _a, rest = __rest(_a, ["isSpent"]);
357
+ return Object.assign(Object.assign({}, readableFormat(rest)), { isSpent });
358
+ });
359
+ const outgoing = tx.outgoing.map((outgoingTx) => {
360
+ return readableFormat(outgoingTx);
361
+ });
362
+ return { incoming, outgoing };
363
+ });
364
+ }
365
+ getSaplingDiff() {
366
+ return __awaiter(this, void 0, void 0, function* () {
367
+ let saplingDiffResponse;
368
+ if (__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").saplingId) {
369
+ saplingDiffResponse = yield __classPrivateFieldGet(this, _SaplingTransactionViewer_readProvider, "f").getSaplingDiffById({ id: __classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").saplingId }, 'head');
370
+ }
371
+ else if (__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").contractAddress) {
372
+ saplingDiffResponse = yield __classPrivateFieldGet(this, _SaplingTransactionViewer_readProvider, "f").getSaplingDiffByContract(__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").contractAddress, 'head');
373
+ }
374
+ else {
375
+ throw new SaplingTransactionViewerError('A contract address or a sapling id was expected in the SaplingTransactionViewer constructor.');
376
+ }
377
+ return saplingDiffResponse;
378
+ });
379
+ }
380
+ decryptCiphertextAsReceiver(commitmentsAndCiphertexts) {
381
+ return __awaiter(this, void 0, void 0, function* () {
382
+ const commitment = commitmentsAndCiphertexts[0];
383
+ const { epk, payload_enc, nonce_enc } = commitmentsAndCiphertexts[1];
384
+ const incomingViewingKey = yield __classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getIncomingViewingKey();
385
+ const keyAgreement = yield sapling__namespace.keyAgreement(epk, incomingViewingKey);
386
+ const keyAgreementHash = blake.blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
387
+ const decrypted = yield this.decryptCiphertext(keyAgreementHash, utils.hex2buf(nonce_enc), utils.hex2buf(payload_enc));
388
+ if (decrypted) {
389
+ const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decrypted);
390
+ const paymentAddress = bufToUint8Array(yield sapling__namespace.getRawPaymentAddressFromIncomingViewingKey(incomingViewingKey, diversifier));
391
+ try {
392
+ const valid = yield sapling__namespace.verifyCommitment(commitment, paymentAddress, convertValueToBigNumber(value).toString(), rcm);
393
+ if (valid) {
394
+ return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
395
+ }
396
+ }
397
+ catch (ex) {
398
+ if (!/invalid value/.test(ex)) {
399
+ throw ex;
400
+ }
401
+ }
402
+ }
403
+ });
404
+ }
405
+ decryptCiphertextAsSender(commitmentsAndCiphertexts) {
406
+ return __awaiter(this, void 0, void 0, function* () {
407
+ const commitment = commitmentsAndCiphertexts[0];
408
+ const { epk, payload_enc, nonce_enc, payload_out, nonce_out, cv } = commitmentsAndCiphertexts[1];
409
+ const outgoingViewingKey = yield __classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getOutgoingViewingKey();
410
+ const concat = cv.concat(commitment, epk, outgoingViewingKey.toString('hex'));
411
+ const outgoingCipherKey = blake.blake2b(Buffer.from(concat, 'hex'), Buffer.from(OCK_KEY), 32);
412
+ const decryptedOut = yield this.decryptCiphertext(outgoingCipherKey, utils.hex2buf(nonce_out), utils.hex2buf(payload_out));
413
+ if (decryptedOut) {
414
+ const { recipientDiversifiedTransmissionKey: pkd, ephemeralPrivateKey: esk } = this.extractPkdAndEsk(decryptedOut);
415
+ const keyAgreement = yield sapling__namespace.keyAgreement(pkd, esk);
416
+ const keyAgreementHash = blake.blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
417
+ const decryptedEnc = yield this.decryptCiphertext(keyAgreementHash, utils.hex2buf(nonce_enc), utils.hex2buf(payload_enc));
418
+ if (decryptedEnc) {
419
+ const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decryptedEnc);
420
+ const paymentAddress = utils.mergebuf(diversifier, pkd);
421
+ try {
422
+ const isValid = yield sapling__namespace.verifyCommitment(commitment, paymentAddress, convertValueToBigNumber(value).toString(), rcm);
423
+ if (isValid) {
424
+ return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
425
+ }
426
+ }
427
+ catch (ex) {
428
+ if (!/invalid value/.test(ex)) {
429
+ throw ex;
430
+ }
431
+ }
432
+ }
433
+ }
434
+ });
435
+ }
436
+ decryptCiphertext(keyAgreementHash, nonce, payload) {
437
+ return __awaiter(this, void 0, void 0, function* () {
438
+ return nacl.openSecretBox(keyAgreementHash, nonce, payload);
439
+ });
440
+ }
441
+ extractTransactionProperties(decrypted) {
442
+ return {
443
+ diversifier: decrypted.slice(0, 11),
444
+ value: decrypted.slice(11, 19),
445
+ randomCommitmentTrapdoor: decrypted.slice(19, 51),
446
+ memoSize: decrypted.slice(51, 55),
447
+ memo: decrypted.slice(55),
448
+ };
449
+ }
450
+ extractPkdAndEsk(decrypted) {
451
+ return {
452
+ recipientDiversifiedTransmissionKey: decrypted.slice(0, 32),
453
+ ephemeralPrivateKey: decrypted.slice(32),
454
+ };
455
+ }
456
+ isSpent(address, value, randomCommitmentTrapdoor, position, nullifiers) {
457
+ return __awaiter(this, void 0, void 0, function* () {
458
+ const computedNullifier = yield sapling__namespace.computeNullifier(__classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getFullViewingKey(), address, value, randomCommitmentTrapdoor, position);
459
+ return nullifiers.includes(computedNullifier.toString('hex'));
460
+ });
461
+ }
462
+ }
463
+ _SaplingTransactionViewer_viewingKeyProvider = new WeakMap(), _SaplingTransactionViewer_readProvider = new WeakMap(), _SaplingTransactionViewer_saplingContractId = new WeakMap();
469
464
 
470
- /**
471
- *
472
- * @param leaves nodes in the tree that we would like to make pairs from
473
- * @returns a paired/chunked array: [a, b, c, d] => [[a, b], [c, d]]
474
- */
475
- function pairNodes(leaves) {
476
- const pairs = new Array(Math.ceil(leaves.length / 2));
477
- for (let i = 0; i < leaves.length / 2; i++) {
478
- pairs[i] = leaves.slice(i * 2, i * 2 + 2);
479
- }
480
- return pairs;
481
- }
482
- /**
483
- * @description helper function to assist in Lazy initializing an object
484
- */
485
- class Lazy {
486
- constructor(init) {
487
- this.init = init;
488
- this.isInitialized = false;
489
- this.value = undefined;
490
- }
491
- // initializes the lazily initiated object
492
- get() {
493
- return __awaiter(this, void 0, void 0, function* () {
494
- if (!this.isInitialized) {
495
- this.value = yield this.init();
496
- this.isInitialized = true;
497
- }
498
- return this.value;
499
- });
500
- }
501
- }
502
- /**
503
- *
504
- * @param hex hexadecimal string we would like to swap
505
- * @returns a hexadecimal string with swapped endians
506
- */
507
- const changeEndianness = (hex) => {
508
- if (hex.length % 2 != 0) {
509
- hex = '0' + hex;
510
- }
511
- const bytes = hex.match(/.{2}/g) || [];
512
- return bytes.reverse().join('');
465
+ /**
466
+ *
467
+ * @param leaves nodes in the tree that we would like to make pairs from
468
+ * @returns a paired/chunked array: [a, b, c, d] => [[a, b], [c, d]]
469
+ */
470
+ function pairNodes(leaves) {
471
+ const pairs = new Array(Math.ceil(leaves.length / 2));
472
+ for (let i = 0; i < leaves.length / 2; i++) {
473
+ pairs[i] = leaves.slice(i * 2, i * 2 + 2);
474
+ }
475
+ return pairs;
476
+ }
477
+ /**
478
+ * @description helper function to assist in Lazy initializing an object
479
+ */
480
+ class Lazy {
481
+ constructor(init) {
482
+ this.init = init;
483
+ this.isInitialized = false;
484
+ this.value = undefined;
485
+ }
486
+ // initializes the lazily initiated object
487
+ get() {
488
+ return __awaiter(this, void 0, void 0, function* () {
489
+ if (!this.isInitialized) {
490
+ this.value = yield this.init();
491
+ this.isInitialized = true;
492
+ }
493
+ return this.value;
494
+ });
495
+ }
496
+ }
497
+ /**
498
+ *
499
+ * @param hex hexadecimal string we would like to swap
500
+ * @returns a hexadecimal string with swapped endians
501
+ */
502
+ const changeEndianness = (hex) => {
503
+ if (hex.length % 2 != 0) {
504
+ hex = '0' + hex;
505
+ }
506
+ const bytes = hex.match(/.{2}/g) || [];
507
+ return bytes.reverse().join('');
513
508
  };
514
509
 
515
- /**
516
- * Some code in this file was originally written or inspired by Airgap-it
517
- * https://github.com/airgap-it/airgap-coin-lib/blob/master/LICENSE.md
518
- *
519
- */
520
- /**
521
- * @description 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
522
- *
523
- */
524
- class SaplingState {
525
- constructor(height) {
526
- this.height = height;
527
- this.uncommittedMerkleHash = '0100000000000000000000000000000000000000000000000000000000000000';
528
- this.uncommittedMerkleHashes = new Lazy(() => this.createUncommittedMerkleHashes());
529
- }
530
- getStateTree(stateDiff, constructTree = true) {
531
- return __awaiter(this, void 0, void 0, function* () {
532
- if (this.stateTree !== undefined && this.stateTree.root === stateDiff.root) {
533
- return this.stateTree;
534
- }
535
- const commitments = stateDiff.commitments_and_ciphertexts.map(([commitment, _]) => commitment);
536
- let merkleTree;
537
- if (constructTree) {
538
- merkleTree = yield this.constructMerkleTree(commitments, 0);
539
- yield this.validateMerkleTree(merkleTree, stateDiff.root);
540
- }
541
- this.stateTree = {
542
- height: this.height,
543
- size: commitments.length,
544
- root: stateDiff.root,
545
- tree: merkleTree,
546
- };
547
- return this.stateTree;
548
- });
549
- }
550
- /**
551
- *
552
- * @param stateTree stateTree parameter that holds information details on our Merkle tree
553
- * @param position position of the hash in the Merkle tree
554
- * @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
555
- */
556
- getWitness(stateTree, position) {
557
- return __awaiter(this, void 0, void 0, function* () {
558
- const heightBuffer = utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(stateTree.height)));
559
- const posBuffer = utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(position, 64)));
560
- const neighbouringHashes = yield this.getNeighbouringHashes([], stateTree.height, position, stateTree.tree);
561
- const witness = neighbouringHashes
562
- .map((hash) => Buffer.concat([utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(hash.length))), hash]))
563
- .reverse()
564
- .reduce((acc, next) => Buffer.concat([acc, next]));
565
- return Buffer.concat([heightBuffer, witness, posBuffer]).toString('hex');
566
- });
567
- }
568
- /**
569
- *
570
- * @param leaves array of leaves or nodes that we want to construct the Merkle tree from
571
- * @param height height of the desired Merkle tree
572
- * @returns a promise of MerkleTree type object
573
- */
574
- constructMerkleTree(leaves, height) {
575
- return __awaiter(this, void 0, void 0, function* () {
576
- if (height === this.height && leaves.length === 1) {
577
- return leaves[0];
578
- }
579
- if (height === this.height || leaves.length > Math.pow(2, this.height - 1 - height)) {
580
- throw new TreeConstructionFailure('Children length exceeds maximum number of nodes in a merkle tree');
581
- }
582
- const pairedLeaves = pairNodes(leaves);
583
- const updatedLeaves = yield Promise.all(pairedLeaves.map((chunk) => __awaiter(this, void 0, void 0, function* () {
584
- const left = yield this.getMerkleHash(chunk[0], height);
585
- const right = yield this.getMerkleHash(chunk[1], height);
586
- const parentHash = yield sapling.merkleHash(height, left, right);
587
- return [parentHash.toString('hex'), chunk[0], chunk[1]];
588
- })));
589
- return this.constructMerkleTree(updatedLeaves, height + 1);
590
- });
591
- }
592
- getMerkleHash(tree, height) {
593
- return __awaiter(this, void 0, void 0, function* () {
594
- if (tree === undefined) {
595
- return (yield this.uncommittedMerkleHashes.get())[height];
596
- }
597
- else if (typeof tree === 'string') {
598
- return Buffer.from(tree, 'hex');
599
- }
600
- else {
601
- return Buffer.from(tree[0], 'hex');
602
- }
603
- });
604
- }
605
- /**
606
- *
607
- * @returns hashes of empty or null values to fill in the Merkle tree
608
- */
609
- createUncommittedMerkleHashes() {
610
- return __awaiter(this, void 0, void 0, function* () {
611
- const res = new Array(this.height);
612
- res[0] = Buffer.from(this.uncommittedMerkleHash, 'hex');
613
- for (let i = 0; i < this.height; i++) {
614
- const hash = res[i];
615
- res[i + 1] = yield sapling.merkleHash(i, hash, hash);
616
- }
617
- return res;
618
- });
619
- }
620
- /**
621
- *
622
- * @param tree Merkle tree to validate
623
- * @param expectedRoot the expected merkle root to validate against
624
- * @throws {@link InvalidMerkleTreeError}
625
- */
626
- validateMerkleTree(tree, expectedRoot) {
627
- return __awaiter(this, void 0, void 0, function* () {
628
- const root = yield this.getMerkleHash(tree, this.height - 1);
629
- if (root.toString('hex') !== expectedRoot) {
630
- throw new InvalidMerkleTreeError(root.toString('hex'));
631
- }
632
- });
633
- }
634
- /**
635
- *
636
- * @param acc accumulator variable for the recursive function
637
- * @param height height of the tree
638
- * @param position position of the hash we would like find the neighbours of
639
- * @param tree the Merkle tree that we want to traverse
640
- * @returns the accumulated Buffer array of neighbouring hashes
641
- */
642
- getNeighbouringHashes(acc, height, position, tree) {
643
- return __awaiter(this, void 0, void 0, function* () {
644
- if (typeof tree === 'undefined') {
645
- throw new Error();
646
- }
647
- else if (typeof tree === 'string') {
648
- return acc;
649
- }
650
- else {
651
- let nextPos, nextTree, otherTree;
652
- const fullTree = new BigNumber__default["default"](2).pow(height - 1);
653
- if (position.lt(fullTree)) {
654
- nextPos = position;
655
- nextTree = tree[1];
656
- otherTree = tree[2];
657
- }
658
- else {
659
- nextPos = position.minus(fullTree);
660
- nextTree = tree[2];
661
- otherTree = tree[1];
662
- }
663
- return this.getNeighbouringHashes([yield this.getMerkleHash(otherTree, height - 1), ...acc], height - 1, nextPos, nextTree);
664
- }
665
- });
666
- }
510
+ /**
511
+ * Some code in this file was originally written or inspired by Airgap-it
512
+ * https://github.com/airgap-it/airgap-coin-lib/blob/master/LICENSE.md
513
+ *
514
+ */
515
+ /**
516
+ * @description 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
517
+ *
518
+ */
519
+ class SaplingState {
520
+ constructor(height) {
521
+ this.height = height;
522
+ this.uncommittedMerkleHash = '0100000000000000000000000000000000000000000000000000000000000000';
523
+ this.uncommittedMerkleHashes = new Lazy(() => this.createUncommittedMerkleHashes());
524
+ }
525
+ getStateTree(stateDiff, constructTree = true) {
526
+ return __awaiter(this, void 0, void 0, function* () {
527
+ if (this.stateTree !== undefined && this.stateTree.root === stateDiff.root) {
528
+ return this.stateTree;
529
+ }
530
+ const commitments = stateDiff.commitments_and_ciphertexts.map(([commitment, _]) => commitment);
531
+ let merkleTree;
532
+ if (constructTree) {
533
+ merkleTree = yield this.constructMerkleTree(commitments, 0);
534
+ yield this.validateMerkleTree(merkleTree, stateDiff.root);
535
+ }
536
+ this.stateTree = {
537
+ height: this.height,
538
+ size: commitments.length,
539
+ root: stateDiff.root,
540
+ tree: merkleTree,
541
+ };
542
+ return this.stateTree;
543
+ });
544
+ }
545
+ /**
546
+ *
547
+ * @param stateTree stateTree parameter that holds information details on our Merkle tree
548
+ * @param position position of the hash in the Merkle tree
549
+ * @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
550
+ */
551
+ getWitness(stateTree, position) {
552
+ return __awaiter(this, void 0, void 0, function* () {
553
+ const heightBuffer = utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(stateTree.height)));
554
+ const posBuffer = utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(position, 64)));
555
+ const neighbouringHashes = yield this.getNeighbouringHashes([], stateTree.height, position, stateTree.tree);
556
+ const witness = neighbouringHashes
557
+ .map((hash) => Buffer.concat([utils.hex2Bytes(changeEndianness(utils.num2PaddedHex(hash.length))), hash]))
558
+ .reverse()
559
+ .reduce((acc, next) => Buffer.concat([acc, next]));
560
+ return Buffer.concat([heightBuffer, witness, posBuffer]).toString('hex');
561
+ });
562
+ }
563
+ /**
564
+ *
565
+ * @param leaves array of leaves or nodes that we want to construct the Merkle tree from
566
+ * @param height height of the desired Merkle tree
567
+ * @returns a promise of MerkleTree type object
568
+ */
569
+ constructMerkleTree(leaves, height) {
570
+ return __awaiter(this, void 0, void 0, function* () {
571
+ if (height === this.height && leaves.length === 1) {
572
+ return leaves[0];
573
+ }
574
+ if (height === this.height || leaves.length > Math.pow(2, this.height - 1 - height)) {
575
+ throw new TreeConstructionFailure('Children length exceeds maximum number of nodes in a merkle tree');
576
+ }
577
+ const pairedLeaves = pairNodes(leaves);
578
+ const updatedLeaves = yield Promise.all(pairedLeaves.map((chunk) => __awaiter(this, void 0, void 0, function* () {
579
+ const left = yield this.getMerkleHash(chunk[0], height);
580
+ const right = yield this.getMerkleHash(chunk[1], height);
581
+ const parentHash = yield sapling.merkleHash(height, left, right);
582
+ return [parentHash.toString('hex'), chunk[0], chunk[1]];
583
+ })));
584
+ return this.constructMerkleTree(updatedLeaves, height + 1);
585
+ });
586
+ }
587
+ getMerkleHash(tree, height) {
588
+ return __awaiter(this, void 0, void 0, function* () {
589
+ if (tree === undefined) {
590
+ return (yield this.uncommittedMerkleHashes.get())[height];
591
+ }
592
+ else if (typeof tree === 'string') {
593
+ return Buffer.from(tree, 'hex');
594
+ }
595
+ else {
596
+ return Buffer.from(tree[0], 'hex');
597
+ }
598
+ });
599
+ }
600
+ /**
601
+ *
602
+ * @returns hashes of empty or null values to fill in the Merkle tree
603
+ */
604
+ createUncommittedMerkleHashes() {
605
+ return __awaiter(this, void 0, void 0, function* () {
606
+ const res = new Array(this.height);
607
+ res[0] = Buffer.from(this.uncommittedMerkleHash, 'hex');
608
+ for (let i = 0; i < this.height; i++) {
609
+ const hash = res[i];
610
+ res[i + 1] = yield sapling.merkleHash(i, hash, hash);
611
+ }
612
+ return res;
613
+ });
614
+ }
615
+ /**
616
+ *
617
+ * @param tree Merkle tree to validate
618
+ * @param expectedRoot the expected merkle root to validate against
619
+ * @throws {@link InvalidMerkleTreeError}
620
+ */
621
+ validateMerkleTree(tree, expectedRoot) {
622
+ return __awaiter(this, void 0, void 0, function* () {
623
+ const root = yield this.getMerkleHash(tree, this.height - 1);
624
+ if (root.toString('hex') !== expectedRoot) {
625
+ throw new InvalidMerkleTreeError(root.toString('hex'));
626
+ }
627
+ });
628
+ }
629
+ /**
630
+ *
631
+ * @param acc accumulator variable for the recursive function
632
+ * @param height height of the tree
633
+ * @param position position of the hash we would like find the neighbours of
634
+ * @param tree the Merkle tree that we want to traverse
635
+ * @returns the accumulated Buffer array of neighbouring hashes
636
+ */
637
+ getNeighbouringHashes(acc, height, position, tree) {
638
+ return __awaiter(this, void 0, void 0, function* () {
639
+ if (typeof tree === 'undefined') {
640
+ throw new Error();
641
+ }
642
+ else if (typeof tree === 'string') {
643
+ return acc;
644
+ }
645
+ else {
646
+ let nextPos, nextTree, otherTree;
647
+ const fullTree = new BigNumber(2).pow(height - 1);
648
+ if (position.lt(fullTree)) {
649
+ nextPos = position;
650
+ nextTree = tree[1];
651
+ otherTree = tree[2];
652
+ }
653
+ else {
654
+ nextPos = position.minus(fullTree);
655
+ nextTree = tree[2];
656
+ otherTree = tree[1];
657
+ }
658
+ return this.getNeighbouringHashes([yield this.getMerkleHash(otherTree, height - 1), ...acc], height - 1, nextPos, nextTree);
659
+ }
660
+ });
661
+ }
667
662
  }
668
663
 
669
- // eslint-disable-next-line @typescript-eslint/no-var-requires
670
- const saplingOutputParams = require('../saplingOutputParams');
671
- // eslint-disable-next-line @typescript-eslint/no-var-requires
672
- const saplingSpendParams = require('../saplingSpendParams');
673
- class SaplingWrapper {
674
- withProvingContext(action) {
675
- return __awaiter(this, void 0, void 0, function* () {
676
- yield this.initSaplingParameters();
677
- return sapling__namespace.withProvingContext(action);
678
- });
679
- }
680
- getRandomBytes(length) {
681
- return random.randomBytes(length);
682
- }
683
- randR() {
684
- return __awaiter(this, void 0, void 0, function* () {
685
- return sapling__namespace.randR();
686
- });
687
- }
688
- getOutgoingViewingKey(vk) {
689
- return __awaiter(this, void 0, void 0, function* () {
690
- return sapling__namespace.getOutgoingViewingKey(vk);
691
- });
692
- }
693
- preparePartialOutputDescription(parametersOutputProof) {
694
- return __awaiter(this, void 0, void 0, function* () {
695
- const partialOutputDesc = yield sapling__namespace.preparePartialOutputDescription(parametersOutputProof.saplingContext, parametersOutputProof.address, parametersOutputProof.randomCommitmentTrapdoor, parametersOutputProof.ephemeralPrivateKey, parametersOutputProof.amount);
696
- return {
697
- commitmentValue: partialOutputDesc.cv,
698
- commitment: partialOutputDesc.cm,
699
- proof: partialOutputDesc.proof,
700
- };
701
- });
702
- }
703
- getDiversifiedFromRawPaymentAddress(decodedDestination) {
704
- return __awaiter(this, void 0, void 0, function* () {
705
- return sapling__namespace.getDiversifiedFromRawPaymentAddress(decodedDestination);
706
- });
707
- }
708
- deriveEphemeralPublicKey(diversifier, esk) {
709
- return __awaiter(this, void 0, void 0, function* () {
710
- return sapling__namespace.deriveEphemeralPublicKey(diversifier, esk);
711
- });
712
- }
713
- getPkdFromRawPaymentAddress(destination) {
714
- return __awaiter(this, void 0, void 0, function* () {
715
- return sapling__namespace.getPkdFromRawPaymentAddress(destination);
716
- });
717
- }
718
- keyAgreement(p, sk) {
719
- return __awaiter(this, void 0, void 0, function* () {
720
- return sapling__namespace.keyAgreement(p, sk);
721
- });
722
- }
723
- createBindingSignature(saplingContext, balance, transactionSigHash) {
724
- return __awaiter(this, void 0, void 0, function* () {
725
- return sapling__namespace.createBindingSignature(saplingContext, balance, transactionSigHash);
726
- });
727
- }
728
- initSaplingParameters() {
729
- return __awaiter(this, void 0, void 0, function* () {
730
- const spendParams = Buffer.from(saplingSpendParams.saplingSpendParams, 'base64');
731
- const outputParams = Buffer.from(saplingOutputParams.saplingOutputParams, 'base64');
732
- return sapling__namespace.initParameters(spendParams, outputParams);
733
- });
734
- }
664
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
665
+ const saplingOutputParams = require('../saplingOutputParams');
666
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
667
+ const saplingSpendParams = require('../saplingSpendParams');
668
+ class SaplingWrapper {
669
+ withProvingContext(action) {
670
+ return __awaiter(this, void 0, void 0, function* () {
671
+ yield this.initSaplingParameters();
672
+ return sapling__namespace.withProvingContext(action);
673
+ });
674
+ }
675
+ getRandomBytes(length) {
676
+ return random.randomBytes(length);
677
+ }
678
+ randR() {
679
+ return __awaiter(this, void 0, void 0, function* () {
680
+ return sapling__namespace.randR();
681
+ });
682
+ }
683
+ getOutgoingViewingKey(vk) {
684
+ return __awaiter(this, void 0, void 0, function* () {
685
+ return sapling__namespace.getOutgoingViewingKey(vk);
686
+ });
687
+ }
688
+ preparePartialOutputDescription(parametersOutputProof) {
689
+ return __awaiter(this, void 0, void 0, function* () {
690
+ const partialOutputDesc = yield sapling__namespace.preparePartialOutputDescription(parametersOutputProof.saplingContext, parametersOutputProof.address, parametersOutputProof.randomCommitmentTrapdoor, parametersOutputProof.ephemeralPrivateKey, parametersOutputProof.amount);
691
+ return {
692
+ commitmentValue: partialOutputDesc.cv,
693
+ commitment: partialOutputDesc.cm,
694
+ proof: partialOutputDesc.proof,
695
+ };
696
+ });
697
+ }
698
+ getDiversifiedFromRawPaymentAddress(decodedDestination) {
699
+ return __awaiter(this, void 0, void 0, function* () {
700
+ return sapling__namespace.getDiversifiedFromRawPaymentAddress(decodedDestination);
701
+ });
702
+ }
703
+ deriveEphemeralPublicKey(diversifier, esk) {
704
+ return __awaiter(this, void 0, void 0, function* () {
705
+ return sapling__namespace.deriveEphemeralPublicKey(diversifier, esk);
706
+ });
707
+ }
708
+ getPkdFromRawPaymentAddress(destination) {
709
+ return __awaiter(this, void 0, void 0, function* () {
710
+ return sapling__namespace.getPkdFromRawPaymentAddress(destination);
711
+ });
712
+ }
713
+ keyAgreement(p, sk) {
714
+ return __awaiter(this, void 0, void 0, function* () {
715
+ return sapling__namespace.keyAgreement(p, sk);
716
+ });
717
+ }
718
+ createBindingSignature(saplingContext, balance, transactionSigHash) {
719
+ return __awaiter(this, void 0, void 0, function* () {
720
+ return sapling__namespace.createBindingSignature(saplingContext, balance, transactionSigHash);
721
+ });
722
+ }
723
+ initSaplingParameters() {
724
+ return __awaiter(this, void 0, void 0, function* () {
725
+ const spendParams = Buffer.from(saplingSpendParams.saplingSpendParams, 'base64');
726
+ const outputParams = Buffer.from(saplingOutputParams.saplingOutputParams, 'base64');
727
+ return sapling__namespace.initParameters(spendParams, outputParams);
728
+ });
729
+ }
735
730
  }
736
731
 
737
- var _inMemorySpendingKey$1, _inMemoryProvingKey, _saplingForger$1, _contractAddress$1, _saplingId$1, _memoSize$1, _readProvider$1, _saplingWrapper, _chainId, _saplingState;
738
- class SaplingTransactionBuilder {
739
- constructor(keys, saplingForger, saplingContractDetails, readProvider, saplingWrapper = new SaplingWrapper()) {
740
- _inMemorySpendingKey$1.set(this, void 0);
741
- _inMemoryProvingKey.set(this, void 0);
742
- _saplingForger$1.set(this, void 0);
743
- _contractAddress$1.set(this, void 0);
744
- _saplingId$1.set(this, void 0);
745
- _memoSize$1.set(this, void 0);
746
- _readProvider$1.set(this, void 0);
747
- _saplingWrapper.set(this, void 0);
748
- _chainId.set(this, void 0);
749
- _saplingState.set(this, void 0);
750
- __classPrivateFieldSet(this, _saplingForger$1, saplingForger);
751
- __classPrivateFieldSet(this, _contractAddress$1, saplingContractDetails.contractAddress);
752
- __classPrivateFieldSet(this, _memoSize$1, saplingContractDetails.memoSize);
753
- __classPrivateFieldSet(this, _inMemorySpendingKey$1, keys.saplingSigner);
754
- __classPrivateFieldSet(this, _inMemoryProvingKey, keys.saplingProver);
755
- __classPrivateFieldSet(this, _saplingState, new SaplingState(32));
756
- __classPrivateFieldSet(this, _saplingId$1, saplingContractDetails.saplingId);
757
- __classPrivateFieldSet(this, _saplingWrapper, saplingWrapper);
758
- __classPrivateFieldSet(this, _readProvider$1, readProvider);
759
- }
760
- createShieldedTx(saplingTransactionParams, txTotalAmount, boundData) {
761
- return __awaiter(this, void 0, void 0, function* () {
762
- const rcm = yield __classPrivateFieldGet(this, _saplingWrapper).randR();
763
- const balance = this.calculateTransactionBalance('0', txTotalAmount.toString());
764
- const { signature, inputs, outputs } = yield __classPrivateFieldGet(this, _saplingWrapper).withProvingContext((saplingContext) => __awaiter(this, void 0, void 0, function* () {
765
- const outputs = [];
766
- const inputs = [];
767
- for (const i in saplingTransactionParams) {
768
- outputs.push(yield this.prepareSaplingOutputDescription({
769
- saplingContext,
770
- address: utils.b58cdecode(saplingTransactionParams[i].to, utils.prefix[utils.Prefix.ZET1]),
771
- amount: saplingTransactionParams[i].amount,
772
- memo: saplingTransactionParams[i].memo,
773
- randomCommitmentTrapdoor: rcm,
774
- }));
775
- }
776
- const signature = yield this.createBindingSignature({
777
- saplingContext,
778
- inputs,
779
- outputs,
780
- balance,
781
- boundData,
782
- });
783
- return { signature, inputs, outputs };
784
- }));
785
- return {
786
- inputs,
787
- outputs,
788
- signature,
789
- balance,
790
- };
791
- });
792
- }
793
- createSaplingTx(saplingTransactionParams, txTotalAmount, boundData, chosenInputs) {
794
- return __awaiter(this, void 0, void 0, function* () {
795
- const randomCommitmentTrapdoor = yield __classPrivateFieldGet(this, _saplingWrapper).randR();
796
- const saplingViewer = yield __classPrivateFieldGet(this, _inMemorySpendingKey$1).getSaplingViewingKeyProvider();
797
- const outgoingViewingKey = yield saplingViewer.getOutgoingViewingKey();
798
- const { signature, balance, inputs, outputs } = yield __classPrivateFieldGet(this, _saplingWrapper).withProvingContext((saplingContext) => __awaiter(this, void 0, void 0, function* () {
799
- const outputs = [];
800
- const inputs = [];
801
- inputs.push(...(yield this.prepareSaplingSpendDescription(saplingContext, chosenInputs.inputsToSpend)));
802
- let sumAmountOutput = new BigNumber__default["default"](0);
803
- for (const i in saplingTransactionParams) {
804
- sumAmountOutput = sumAmountOutput.plus(new BigNumber__default["default"](saplingTransactionParams[i].amount));
805
- outputs.push(yield this.prepareSaplingOutputDescription({
806
- saplingContext,
807
- address: utils.b58cdecode(saplingTransactionParams[i].to, utils.prefix[utils.Prefix.ZET1]),
808
- amount: saplingTransactionParams[i].amount,
809
- memo: saplingTransactionParams[i].memo,
810
- randomCommitmentTrapdoor,
811
- outgoingViewingKey,
812
- }));
813
- }
814
- if (chosenInputs.sumSelectedInputs.isGreaterThan(sumAmountOutput)) {
815
- const payBackAddress = (yield saplingViewer.getAddress()).address;
816
- const { payBackOutput, payBackAmount } = yield this.createPaybackOutput({
817
- saplingContext,
818
- address: utils.b58cdecode(payBackAddress, utils.prefix[utils.Prefix.ZET1]),
819
- amount: txTotalAmount.toString(),
820
- memo: DEFAULT_MEMO,
821
- randomCommitmentTrapdoor: randomCommitmentTrapdoor,
822
- outgoingViewingKey: outgoingViewingKey,
823
- }, chosenInputs.sumSelectedInputs);
824
- sumAmountOutput = sumAmountOutput.plus(new BigNumber__default["default"](payBackAmount));
825
- outputs.push(payBackOutput);
826
- }
827
- const balance = this.calculateTransactionBalance(chosenInputs.sumSelectedInputs.toString(), sumAmountOutput.toString());
828
- const signature = yield this.createBindingSignature({
829
- saplingContext,
830
- inputs,
831
- outputs,
832
- balance,
833
- boundData,
834
- });
835
- return { signature, balance, inputs, outputs };
836
- }));
837
- return {
838
- inputs,
839
- outputs,
840
- signature,
841
- balance,
842
- };
843
- });
844
- }
845
- // sum of values of inputs minus sums of values of output equals balance
846
- calculateTransactionBalance(inputTotal, outputTotal) {
847
- return new BigNumber__default["default"](inputTotal).minus(new BigNumber__default["default"](outputTotal));
848
- }
849
- prepareSaplingOutputDescription(parametersOutputDescription) {
850
- return __awaiter(this, void 0, void 0, function* () {
851
- const ephemeralPrivateKey = yield __classPrivateFieldGet(this, _saplingWrapper).randR();
852
- const { commitmentValue, commitment, proof } = yield __classPrivateFieldGet(this, _saplingWrapper).preparePartialOutputDescription({
853
- saplingContext: parametersOutputDescription.saplingContext,
854
- address: parametersOutputDescription.address,
855
- randomCommitmentTrapdoor: parametersOutputDescription.randomCommitmentTrapdoor,
856
- ephemeralPrivateKey,
857
- amount: parametersOutputDescription.amount,
858
- });
859
- const diversifier = yield __classPrivateFieldGet(this, _saplingWrapper).getDiversifiedFromRawPaymentAddress(parametersOutputDescription.address);
860
- const ephemeralPublicKey = yield __classPrivateFieldGet(this, _saplingWrapper).deriveEphemeralPublicKey(diversifier, ephemeralPrivateKey);
861
- const outgoingCipherKey = parametersOutputDescription.outgoingViewingKey
862
- ? blake__default["default"].blake2b(Buffer.concat([
863
- commitmentValue,
864
- commitment,
865
- ephemeralPublicKey,
866
- parametersOutputDescription.outgoingViewingKey,
867
- ]), Buffer.from(OCK_KEY), 32)
868
- : __classPrivateFieldGet(this, _saplingWrapper).getRandomBytes(32);
869
- const ciphertext = yield this.encryptCiphertext({
870
- address: parametersOutputDescription.address,
871
- ephemeralPrivateKey,
872
- diversifier,
873
- outgoingCipherKey,
874
- amount: parametersOutputDescription.amount,
875
- randomCommitmentTrapdoor: parametersOutputDescription.randomCommitmentTrapdoor,
876
- memo: parametersOutputDescription.memo,
877
- });
878
- return {
879
- commitment,
880
- proof,
881
- ciphertext: Object.assign(Object.assign({}, ciphertext), { commitmentValue,
882
- ephemeralPublicKey }),
883
- };
884
- });
885
- }
886
- prepareSaplingSpendDescription(saplingContext, inputsToSpend) {
887
- return __awaiter(this, void 0, void 0, function* () {
888
- const publicKeyReRandomization = yield __classPrivateFieldGet(this, _saplingWrapper).randR();
889
- let stateDiff;
890
- if (__classPrivateFieldGet(this, _saplingId$1)) {
891
- stateDiff = yield __classPrivateFieldGet(this, _readProvider$1).getSaplingDiffById({ id: __classPrivateFieldGet(this, _saplingId$1) }, 'head');
892
- }
893
- else {
894
- stateDiff = yield __classPrivateFieldGet(this, _readProvider$1).getSaplingDiffByContract(__classPrivateFieldGet(this, _contractAddress$1), 'head');
895
- }
896
- const stateTree = yield __classPrivateFieldGet(this, _saplingState).getStateTree(stateDiff, true);
897
- const saplingSpendDescriptions = [];
898
- for (let i = 0; i < inputsToSpend.length; i++) {
899
- const amount = convertValueToBigNumber(inputsToSpend[i].value).toString();
900
- const witness = yield __classPrivateFieldGet(this, _saplingState).getWitness(stateTree, new BigNumber__default["default"](inputsToSpend[i].position));
901
- const unsignedSpendDescription = __classPrivateFieldGet(this, _inMemoryProvingKey) ? yield __classPrivateFieldGet(this, _inMemoryProvingKey).prepareSpendDescription({
902
- saplingContext,
903
- address: inputsToSpend[i].paymentAddress,
904
- randomCommitmentTrapdoor: inputsToSpend[i].randomCommitmentTrapdoor,
905
- publicKeyReRandomization,
906
- amount,
907
- root: stateDiff.root,
908
- witness,
909
- })
910
- : yield __classPrivateFieldGet(this, _inMemorySpendingKey$1).prepareSpendDescription({
911
- saplingContext,
912
- address: inputsToSpend[i].paymentAddress,
913
- randomCommitmentTrapdoor: inputsToSpend[i].randomCommitmentTrapdoor,
914
- publicKeyReRandomization,
915
- amount,
916
- root: stateDiff.root,
917
- witness,
918
- });
919
- const unsignedSpendDescriptionBytes = __classPrivateFieldGet(this, _saplingForger$1).forgeUnsignedTxInput(unsignedSpendDescription);
920
- const hash = blake__default["default"].blake2b(unsignedSpendDescriptionBytes, yield this.getAntiReplay(), 32);
921
- const spendDescription = yield __classPrivateFieldGet(this, _inMemorySpendingKey$1).signSpendDescription({
922
- publicKeyReRandomization,
923
- unsignedSpendDescription,
924
- hash,
925
- });
926
- if (spendDescription.signature === undefined) {
927
- throw new Error('Spend signing failed');
928
- }
929
- saplingSpendDescriptions.push(spendDescription);
930
- }
931
- return saplingSpendDescriptions;
932
- });
933
- }
934
- encryptCiphertext(parametersCiphertext) {
935
- return __awaiter(this, void 0, void 0, function* () {
936
- const recipientDiversifiedTransmissionKey = yield __classPrivateFieldGet(this, _saplingWrapper).getPkdFromRawPaymentAddress(parametersCiphertext.address);
937
- const keyAgreement = yield __classPrivateFieldGet(this, _saplingWrapper).keyAgreement(recipientDiversifiedTransmissionKey, parametersCiphertext.ephemeralPrivateKey);
938
- const keyAgreementHash = blake__default["default"].blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
939
- const nonceEnc = Buffer.from(__classPrivateFieldGet(this, _saplingWrapper).getRandomBytes(24));
940
- const transactionPlaintext = __classPrivateFieldGet(this, _saplingForger$1).forgeTransactionPlaintext({
941
- diversifier: parametersCiphertext.diversifier,
942
- amount: parametersCiphertext.amount,
943
- randomCommitmentTrapdoor: parametersCiphertext.randomCommitmentTrapdoor,
944
- memoSize: __classPrivateFieldGet(this, _memoSize$1) * 2,
945
- memo: parametersCiphertext.memo,
946
- });
947
- const nonceOut = Buffer.from(__classPrivateFieldGet(this, _saplingWrapper).getRandomBytes(24));
948
- const payloadEnc = Buffer.from(nacl.secretBox(keyAgreementHash, nonceEnc, transactionPlaintext));
949
- const payloadOut = Buffer.from(nacl.secretBox(parametersCiphertext.outgoingCipherKey, nonceOut, Buffer.concat([
950
- recipientDiversifiedTransmissionKey,
951
- parametersCiphertext.ephemeralPrivateKey,
952
- ])));
953
- return { payloadEnc, nonceEnc, payloadOut, nonceOut };
954
- });
955
- }
956
- createPaybackOutput(params, sumSelectedInputs) {
957
- return __awaiter(this, void 0, void 0, function* () {
958
- const payBackAmount = sumSelectedInputs.minus(params.amount).toString();
959
- const payBackOutput = yield this.prepareSaplingOutputDescription({
960
- saplingContext: params.saplingContext,
961
- address: params.address,
962
- amount: payBackAmount,
963
- memo: params.memo,
964
- randomCommitmentTrapdoor: params.randomCommitmentTrapdoor,
965
- outgoingViewingKey: params.outgoingViewingKey,
966
- });
967
- return { payBackOutput, payBackAmount };
968
- });
969
- }
970
- createBindingSignature(parametersBindingSig) {
971
- return __awaiter(this, void 0, void 0, function* () {
972
- const outputs = __classPrivateFieldGet(this, _saplingForger$1).forgeOutputDescriptions(parametersBindingSig.outputs);
973
- const inputs = __classPrivateFieldGet(this, _saplingForger$1).forgeSpendDescriptions(parametersBindingSig.inputs);
974
- const transactionSigHash = blake__default["default"].blake2b(Buffer.concat([inputs, outputs, parametersBindingSig.boundData]), yield this.getAntiReplay(), 32);
975
- return __classPrivateFieldGet(this, _saplingWrapper).createBindingSignature(parametersBindingSig.saplingContext, parametersBindingSig.balance.toFixed(), transactionSigHash);
976
- });
977
- }
978
- getAntiReplay() {
979
- return __awaiter(this, void 0, void 0, function* () {
980
- let chainId = __classPrivateFieldGet(this, _chainId);
981
- if (!chainId) {
982
- chainId = yield __classPrivateFieldGet(this, _readProvider$1).getChainId();
983
- __classPrivateFieldSet(this, _chainId, chainId);
984
- }
985
- return Buffer.from(`${__classPrivateFieldGet(this, _contractAddress$1)}${chainId}`);
986
- });
987
- }
988
- }
989
- _inMemorySpendingKey$1 = new WeakMap(), _inMemoryProvingKey = new WeakMap(), _saplingForger$1 = new WeakMap(), _contractAddress$1 = new WeakMap(), _saplingId$1 = new WeakMap(), _memoSize$1 = new WeakMap(), _readProvider$1 = new WeakMap(), _saplingWrapper = new WeakMap(), _chainId = new WeakMap(), _saplingState = new WeakMap();
732
+ var _SaplingTransactionBuilder_inMemorySpendingKey, _SaplingTransactionBuilder_inMemoryProvingKey, _SaplingTransactionBuilder_saplingForger, _SaplingTransactionBuilder_contractAddress, _SaplingTransactionBuilder_saplingId, _SaplingTransactionBuilder_memoSize, _SaplingTransactionBuilder_readProvider, _SaplingTransactionBuilder_saplingWrapper, _SaplingTransactionBuilder_chainId, _SaplingTransactionBuilder_saplingState;
733
+ class SaplingTransactionBuilder {
734
+ constructor(keys, saplingForger, saplingContractDetails, readProvider, saplingWrapper = new SaplingWrapper()) {
735
+ _SaplingTransactionBuilder_inMemorySpendingKey.set(this, void 0);
736
+ _SaplingTransactionBuilder_inMemoryProvingKey.set(this, void 0);
737
+ _SaplingTransactionBuilder_saplingForger.set(this, void 0);
738
+ _SaplingTransactionBuilder_contractAddress.set(this, void 0);
739
+ _SaplingTransactionBuilder_saplingId.set(this, void 0);
740
+ _SaplingTransactionBuilder_memoSize.set(this, void 0);
741
+ _SaplingTransactionBuilder_readProvider.set(this, void 0);
742
+ _SaplingTransactionBuilder_saplingWrapper.set(this, void 0);
743
+ _SaplingTransactionBuilder_chainId.set(this, void 0);
744
+ _SaplingTransactionBuilder_saplingState.set(this, void 0);
745
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_saplingForger, saplingForger, "f");
746
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_contractAddress, saplingContractDetails.contractAddress, "f");
747
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_memoSize, saplingContractDetails.memoSize, "f");
748
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_inMemorySpendingKey, keys.saplingSigner, "f");
749
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_inMemoryProvingKey, keys.saplingProver, "f");
750
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_saplingState, new SaplingState(32), "f");
751
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_saplingId, saplingContractDetails.saplingId, "f");
752
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_saplingWrapper, saplingWrapper, "f");
753
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_readProvider, readProvider, "f");
754
+ }
755
+ createShieldedTx(saplingTransactionParams, txTotalAmount, boundData) {
756
+ return __awaiter(this, void 0, void 0, function* () {
757
+ const rcm = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
758
+ const balance = this.calculateTransactionBalance('0', txTotalAmount.toString());
759
+ const { signature, inputs, outputs } = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").withProvingContext((saplingContext) => __awaiter(this, void 0, void 0, function* () {
760
+ const outputs = [];
761
+ const inputs = [];
762
+ for (const i in saplingTransactionParams) {
763
+ outputs.push(yield this.prepareSaplingOutputDescription({
764
+ saplingContext,
765
+ address: utils.b58cdecode(saplingTransactionParams[i].to, utils.prefix[utils.Prefix.ZET1]),
766
+ amount: saplingTransactionParams[i].amount,
767
+ memo: saplingTransactionParams[i].memo,
768
+ randomCommitmentTrapdoor: rcm,
769
+ }));
770
+ }
771
+ const signature = yield this.createBindingSignature({
772
+ saplingContext,
773
+ inputs,
774
+ outputs,
775
+ balance,
776
+ boundData,
777
+ });
778
+ return { signature, inputs, outputs };
779
+ }));
780
+ return {
781
+ inputs,
782
+ outputs,
783
+ signature,
784
+ balance,
785
+ };
786
+ });
787
+ }
788
+ createSaplingTx(saplingTransactionParams, txTotalAmount, boundData, chosenInputs) {
789
+ return __awaiter(this, void 0, void 0, function* () {
790
+ const randomCommitmentTrapdoor = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
791
+ const saplingViewer = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemorySpendingKey, "f").getSaplingViewingKeyProvider();
792
+ const outgoingViewingKey = yield saplingViewer.getOutgoingViewingKey();
793
+ const { signature, balance, inputs, outputs } = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").withProvingContext((saplingContext) => __awaiter(this, void 0, void 0, function* () {
794
+ const outputs = [];
795
+ const inputs = [];
796
+ inputs.push(...(yield this.prepareSaplingSpendDescription(saplingContext, chosenInputs.inputsToSpend)));
797
+ let sumAmountOutput = new BigNumber(0);
798
+ for (const i in saplingTransactionParams) {
799
+ sumAmountOutput = sumAmountOutput.plus(new BigNumber(saplingTransactionParams[i].amount));
800
+ outputs.push(yield this.prepareSaplingOutputDescription({
801
+ saplingContext,
802
+ address: utils.b58cdecode(saplingTransactionParams[i].to, utils.prefix[utils.Prefix.ZET1]),
803
+ amount: saplingTransactionParams[i].amount,
804
+ memo: saplingTransactionParams[i].memo,
805
+ randomCommitmentTrapdoor,
806
+ outgoingViewingKey,
807
+ }));
808
+ }
809
+ if (chosenInputs.sumSelectedInputs.isGreaterThan(sumAmountOutput)) {
810
+ const payBackAddress = (yield saplingViewer.getAddress()).address;
811
+ const { payBackOutput, payBackAmount } = yield this.createPaybackOutput({
812
+ saplingContext,
813
+ address: utils.b58cdecode(payBackAddress, utils.prefix[utils.Prefix.ZET1]),
814
+ amount: txTotalAmount.toString(),
815
+ memo: DEFAULT_MEMO,
816
+ randomCommitmentTrapdoor: randomCommitmentTrapdoor,
817
+ outgoingViewingKey: outgoingViewingKey,
818
+ }, chosenInputs.sumSelectedInputs);
819
+ sumAmountOutput = sumAmountOutput.plus(new BigNumber(payBackAmount));
820
+ outputs.push(payBackOutput);
821
+ }
822
+ const balance = this.calculateTransactionBalance(chosenInputs.sumSelectedInputs.toString(), sumAmountOutput.toString());
823
+ const signature = yield this.createBindingSignature({
824
+ saplingContext,
825
+ inputs,
826
+ outputs,
827
+ balance,
828
+ boundData,
829
+ });
830
+ return { signature, balance, inputs, outputs };
831
+ }));
832
+ return {
833
+ inputs,
834
+ outputs,
835
+ signature,
836
+ balance,
837
+ };
838
+ });
839
+ }
840
+ // sum of values of inputs minus sums of values of output equals balance
841
+ calculateTransactionBalance(inputTotal, outputTotal) {
842
+ return new BigNumber(inputTotal).minus(new BigNumber(outputTotal));
843
+ }
844
+ prepareSaplingOutputDescription(parametersOutputDescription) {
845
+ return __awaiter(this, void 0, void 0, function* () {
846
+ const ephemeralPrivateKey = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
847
+ const { commitmentValue, commitment, proof } = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").preparePartialOutputDescription({
848
+ saplingContext: parametersOutputDescription.saplingContext,
849
+ address: parametersOutputDescription.address,
850
+ randomCommitmentTrapdoor: parametersOutputDescription.randomCommitmentTrapdoor,
851
+ ephemeralPrivateKey,
852
+ amount: parametersOutputDescription.amount,
853
+ });
854
+ const diversifier = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").getDiversifiedFromRawPaymentAddress(parametersOutputDescription.address);
855
+ const ephemeralPublicKey = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").deriveEphemeralPublicKey(diversifier, ephemeralPrivateKey);
856
+ const outgoingCipherKey = parametersOutputDescription.outgoingViewingKey
857
+ ? blake.blake2b(Buffer.concat([
858
+ commitmentValue,
859
+ commitment,
860
+ ephemeralPublicKey,
861
+ parametersOutputDescription.outgoingViewingKey,
862
+ ]), Buffer.from(OCK_KEY), 32)
863
+ : __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").getRandomBytes(32);
864
+ const ciphertext = yield this.encryptCiphertext({
865
+ address: parametersOutputDescription.address,
866
+ ephemeralPrivateKey,
867
+ diversifier,
868
+ outgoingCipherKey,
869
+ amount: parametersOutputDescription.amount,
870
+ randomCommitmentTrapdoor: parametersOutputDescription.randomCommitmentTrapdoor,
871
+ memo: parametersOutputDescription.memo,
872
+ });
873
+ return {
874
+ commitment,
875
+ proof,
876
+ ciphertext: Object.assign(Object.assign({}, ciphertext), { commitmentValue,
877
+ ephemeralPublicKey }),
878
+ };
879
+ });
880
+ }
881
+ prepareSaplingSpendDescription(saplingContext, inputsToSpend) {
882
+ return __awaiter(this, void 0, void 0, function* () {
883
+ const publicKeyReRandomization = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
884
+ let stateDiff;
885
+ if (__classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingId, "f")) {
886
+ stateDiff = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_readProvider, "f").getSaplingDiffById({ id: __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingId, "f") }, 'head');
887
+ }
888
+ else {
889
+ stateDiff = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_readProvider, "f").getSaplingDiffByContract(__classPrivateFieldGet(this, _SaplingTransactionBuilder_contractAddress, "f"), 'head');
890
+ }
891
+ const stateTree = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getStateTree(stateDiff, true);
892
+ const saplingSpendDescriptions = [];
893
+ for (let i = 0; i < inputsToSpend.length; i++) {
894
+ const amount = convertValueToBigNumber(inputsToSpend[i].value).toString();
895
+ const witness = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getWitness(stateTree, new BigNumber(inputsToSpend[i].position));
896
+ const unsignedSpendDescription = __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f")
897
+ ? yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f").prepareSpendDescription({
898
+ saplingContext,
899
+ address: inputsToSpend[i].paymentAddress,
900
+ randomCommitmentTrapdoor: inputsToSpend[i].randomCommitmentTrapdoor,
901
+ publicKeyReRandomization,
902
+ amount,
903
+ root: stateDiff.root,
904
+ witness,
905
+ })
906
+ : yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemorySpendingKey, "f").prepareSpendDescription({
907
+ saplingContext,
908
+ address: inputsToSpend[i].paymentAddress,
909
+ randomCommitmentTrapdoor: inputsToSpend[i].randomCommitmentTrapdoor,
910
+ publicKeyReRandomization,
911
+ amount,
912
+ root: stateDiff.root,
913
+ witness,
914
+ });
915
+ const unsignedSpendDescriptionBytes = __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingForger, "f").forgeUnsignedTxInput(unsignedSpendDescription);
916
+ const hash = blake.blake2b(unsignedSpendDescriptionBytes, yield this.getAntiReplay(), 32);
917
+ const spendDescription = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemorySpendingKey, "f").signSpendDescription({
918
+ publicKeyReRandomization,
919
+ unsignedSpendDescription,
920
+ hash,
921
+ });
922
+ if (spendDescription.signature === undefined) {
923
+ throw new Error('Spend signing failed');
924
+ }
925
+ saplingSpendDescriptions.push(spendDescription);
926
+ }
927
+ return saplingSpendDescriptions;
928
+ });
929
+ }
930
+ encryptCiphertext(parametersCiphertext) {
931
+ return __awaiter(this, void 0, void 0, function* () {
932
+ const recipientDiversifiedTransmissionKey = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").getPkdFromRawPaymentAddress(parametersCiphertext.address);
933
+ const keyAgreement = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").keyAgreement(recipientDiversifiedTransmissionKey, parametersCiphertext.ephemeralPrivateKey);
934
+ const keyAgreementHash = blake.blake2b(keyAgreement, Buffer.from(KDF_KEY), 32);
935
+ const nonceEnc = Buffer.from(__classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").getRandomBytes(24));
936
+ const transactionPlaintext = __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingForger, "f").forgeTransactionPlaintext({
937
+ diversifier: parametersCiphertext.diversifier,
938
+ amount: parametersCiphertext.amount,
939
+ randomCommitmentTrapdoor: parametersCiphertext.randomCommitmentTrapdoor,
940
+ memoSize: __classPrivateFieldGet(this, _SaplingTransactionBuilder_memoSize, "f") * 2,
941
+ memo: parametersCiphertext.memo,
942
+ });
943
+ const nonceOut = Buffer.from(__classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").getRandomBytes(24));
944
+ const payloadEnc = Buffer.from(nacl.secretBox(keyAgreementHash, nonceEnc, transactionPlaintext));
945
+ const payloadOut = Buffer.from(nacl.secretBox(parametersCiphertext.outgoingCipherKey, nonceOut, Buffer.concat([
946
+ recipientDiversifiedTransmissionKey,
947
+ parametersCiphertext.ephemeralPrivateKey,
948
+ ])));
949
+ return { payloadEnc, nonceEnc, payloadOut, nonceOut };
950
+ });
951
+ }
952
+ createPaybackOutput(params, sumSelectedInputs) {
953
+ return __awaiter(this, void 0, void 0, function* () {
954
+ const payBackAmount = sumSelectedInputs.minus(params.amount).toString();
955
+ const payBackOutput = yield this.prepareSaplingOutputDescription({
956
+ saplingContext: params.saplingContext,
957
+ address: params.address,
958
+ amount: payBackAmount,
959
+ memo: params.memo,
960
+ randomCommitmentTrapdoor: params.randomCommitmentTrapdoor,
961
+ outgoingViewingKey: params.outgoingViewingKey,
962
+ });
963
+ return { payBackOutput, payBackAmount };
964
+ });
965
+ }
966
+ createBindingSignature(parametersBindingSig) {
967
+ return __awaiter(this, void 0, void 0, function* () {
968
+ const outputs = __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingForger, "f").forgeOutputDescriptions(parametersBindingSig.outputs);
969
+ const inputs = __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingForger, "f").forgeSpendDescriptions(parametersBindingSig.inputs);
970
+ const transactionSigHash = blake.blake2b(Buffer.concat([inputs, outputs, parametersBindingSig.boundData]), yield this.getAntiReplay(), 32);
971
+ return __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").createBindingSignature(parametersBindingSig.saplingContext, parametersBindingSig.balance.toFixed(), transactionSigHash);
972
+ });
973
+ }
974
+ getAntiReplay() {
975
+ return __awaiter(this, void 0, void 0, function* () {
976
+ let chainId = __classPrivateFieldGet(this, _SaplingTransactionBuilder_chainId, "f");
977
+ if (!chainId) {
978
+ chainId = yield __classPrivateFieldGet(this, _SaplingTransactionBuilder_readProvider, "f").getChainId();
979
+ __classPrivateFieldSet(this, _SaplingTransactionBuilder_chainId, chainId, "f");
980
+ }
981
+ return Buffer.from(`${__classPrivateFieldGet(this, _SaplingTransactionBuilder_contractAddress, "f")}${chainId}`);
982
+ });
983
+ }
984
+ }
985
+ _SaplingTransactionBuilder_inMemorySpendingKey = new WeakMap(), _SaplingTransactionBuilder_inMemoryProvingKey = new WeakMap(), _SaplingTransactionBuilder_saplingForger = new WeakMap(), _SaplingTransactionBuilder_contractAddress = new WeakMap(), _SaplingTransactionBuilder_saplingId = new WeakMap(), _SaplingTransactionBuilder_memoSize = new WeakMap(), _SaplingTransactionBuilder_readProvider = new WeakMap(), _SaplingTransactionBuilder_saplingWrapper = new WeakMap(), _SaplingTransactionBuilder_chainId = new WeakMap(), _SaplingTransactionBuilder_saplingState = new WeakMap();
990
986
 
991
- function decryptKey(spendingKey, password) {
992
- const keyArr = utils.b58cdecode(spendingKey, utils.prefix[utils.Prefix.SASK]);
993
- // exit first if no password and key is encrypted
994
- if (!password && spendingKey.slice(0, 4) !== 'sask') {
995
- throw new InvalidSpendingKey(spendingKey, 'no password provided to decrypt');
996
- }
997
- if (password && spendingKey.slice(0, 4) !== 'sask') {
998
- const salt = toBuffer__default["default"](keyArr.slice(0, 8));
999
- const encryptedSk = toBuffer__default["default"](keyArr.slice(8));
1000
- const encryptionKey = pbkdf2__default["default"].pbkdf2Sync(password, salt, 32768, 32, 'sha512');
1001
- const decrypted = nacl.openSecretBox(new Uint8Array(encryptionKey), new Uint8Array(24), new Uint8Array(encryptedSk));
1002
- if (!decrypted) {
1003
- throw new InvalidSpendingKey(spendingKey, 'incorrect password or unable to decrypt');
1004
- }
1005
- return toBuffer__default["default"](decrypted);
1006
- }
1007
- else {
1008
- return toBuffer__default["default"](keyArr);
1009
- }
987
+ function decryptKey(spendingKey, password) {
988
+ const keyArr = utils.b58cdecode(spendingKey, utils.prefix[utils.Prefix.SASK]);
989
+ // exit first if no password and key is encrypted
990
+ if (!password && spendingKey.slice(0, 4) !== 'sask') {
991
+ throw new InvalidSpendingKey(spendingKey, 'no password provided to decrypt');
992
+ }
993
+ if (password && spendingKey.slice(0, 4) !== 'sask') {
994
+ const salt = toBuffer(keyArr.slice(0, 8));
995
+ const encryptedSk = toBuffer(keyArr.slice(8));
996
+ const encryptionKey = pbkdf2.pbkdf2Sync(password, salt, 32768, 32, 'sha512');
997
+ const decrypted = nacl.openSecretBox(new Uint8Array(encryptionKey), new Uint8Array(24), new Uint8Array(encryptedSk));
998
+ if (!decrypted) {
999
+ throw new InvalidSpendingKey(spendingKey, 'incorrect password or unable to decrypt');
1000
+ }
1001
+ return toBuffer(decrypted);
1002
+ }
1003
+ else {
1004
+ return toBuffer(keyArr);
1005
+ }
1010
1006
  }
1011
1007
 
1012
- var _spendingKeyBuf, _saplingViewingKey;
1013
- /**
1014
- * @description holds the spending key, create proof and signature for spend descriptions
1015
- * can instantiate from mnemonic word list or decrypt a encrypted spending key
1016
- * with access to instantiate a InMemoryViewingKey
1017
- */
1018
- class InMemorySpendingKey {
1019
- /**
1020
- *
1021
- * @param spendingKey unencrypted sask... or encrypted MMXj...
1022
- * @param password required for MMXj encrypted keys
1023
- */
1024
- constructor(spendingKey, password) {
1025
- _spendingKeyBuf.set(this, void 0);
1026
- _saplingViewingKey.set(this, void 0);
1027
- __classPrivateFieldSet(this, _spendingKeyBuf, decryptKey(spendingKey, password));
1028
- }
1029
- /**
1030
- *
1031
- * @param mnemonic string of words
1032
- * @param derivationPath tezos current standard 'm/'
1033
- * @returns InMemorySpendingKey class instantiated
1034
- */
1035
- static fromMnemonic(mnemonic, derivationPath = 'm/') {
1036
- return __awaiter(this, void 0, void 0, function* () {
1037
- // no password passed here. password provided only changes from sask -> MMXj
1038
- const fullSeed = yield bip39__namespace.mnemonicToSeed(mnemonic);
1039
- const first32 = fullSeed.slice(0, 32);
1040
- const second32 = fullSeed.slice(32);
1041
- // reduce seed bytes must be 32 bytes reflecting both halves
1042
- const seed = Buffer.from(first32.map((byte, index) => byte ^ second32[index]));
1043
- const spendingKeyArr = new Uint8Array(yield sapling__namespace.getExtendedSpendingKey(seed, derivationPath));
1044
- const spendingKey = utils.b58cencode(spendingKeyArr, utils.prefix[utils.Prefix.SASK]);
1045
- return new InMemorySpendingKey(spendingKey);
1046
- });
1047
- }
1048
- /**
1049
- *
1050
- * @returns InMemoryViewingKey instantiated class
1051
- */
1052
- getSaplingViewingKeyProvider() {
1053
- return __awaiter(this, void 0, void 0, function* () {
1054
- let viewingKey;
1055
- if (!__classPrivateFieldGet(this, _saplingViewingKey)) {
1056
- viewingKey = yield sapling__namespace.getExtendedFullViewingKeyFromSpendingKey(__classPrivateFieldGet(this, _spendingKeyBuf));
1057
- __classPrivateFieldSet(this, _saplingViewingKey, new InMemoryViewingKey(viewingKey.toString('hex')));
1058
- }
1059
- return __classPrivateFieldGet(this, _saplingViewingKey);
1060
- });
1061
- }
1062
- /**
1063
- * @description Prepare an unsigned sapling spend description using the spending key
1064
- * @param parametersSpendProof.saplingContext The sapling proving context
1065
- * @param parametersSpendProof.address The address of the input
1066
- * @param parametersSpendProof.randomCommitmentTrapdoor The randomness of the commitment
1067
- * @param parametersSpendProof.publicKeyReRandomization The re-randomization of the public key
1068
- * @param parametersSpendProof.amount The value of the input
1069
- * @param parametersSpendProof.root The root of the merkle tree
1070
- * @param parametersSpendProof.witness The path of the commitment in the tree
1071
- * @param derivationPath tezos current standard 'm/'
1072
- * @returns The unsigned spend description
1073
- */
1074
- prepareSpendDescription(parametersSpendProof) {
1075
- return __awaiter(this, void 0, void 0, function* () {
1076
- const spendDescription = yield sapling__namespace.prepareSpendDescriptionWithSpendingKey(parametersSpendProof.saplingContext, __classPrivateFieldGet(this, _spendingKeyBuf), parametersSpendProof.address, parametersSpendProof.randomCommitmentTrapdoor, parametersSpendProof.publicKeyReRandomization, parametersSpendProof.amount, parametersSpendProof.root, parametersSpendProof.witness);
1077
- return {
1078
- commitmentValue: spendDescription.cv,
1079
- nullifier: spendDescription.nf,
1080
- publicKeyReRandomization: spendDescription.rk,
1081
- rtAnchor: spendDescription.rt,
1082
- proof: spendDescription.proof,
1083
- };
1084
- });
1085
- }
1086
- /**
1087
- * @description Sign a sapling spend description
1088
- * @param parametersSpendSig.publicKeyReRandomization The re-randomization of the public key
1089
- * @param parametersSpendSig.unsignedSpendDescription The unsigned Spend description
1090
- * @param parametersSpendSig.hash The data to be signed
1091
- * @returns The signed spend description
1092
- */
1093
- signSpendDescription(parametersSpendSig) {
1094
- return __awaiter(this, void 0, void 0, function* () {
1095
- const signedSpendDescription = yield sapling__namespace.signSpendDescription({
1096
- cv: parametersSpendSig.unsignedSpendDescription.commitmentValue,
1097
- rt: parametersSpendSig.unsignedSpendDescription.rtAnchor,
1098
- nf: parametersSpendSig.unsignedSpendDescription.nullifier,
1099
- rk: parametersSpendSig.unsignedSpendDescription.publicKeyReRandomization,
1100
- proof: parametersSpendSig.unsignedSpendDescription.proof,
1101
- }, __classPrivateFieldGet(this, _spendingKeyBuf), parametersSpendSig.publicKeyReRandomization, parametersSpendSig.hash);
1102
- return {
1103
- commitmentValue: signedSpendDescription.cv,
1104
- nullifier: signedSpendDescription.nf,
1105
- publicKeyReRandomization: signedSpendDescription.rk,
1106
- proof: signedSpendDescription.proof,
1107
- signature: signedSpendDescription.spendAuthSig,
1108
- };
1109
- });
1110
- }
1111
- /**
1112
- * @description Return a proof authorizing key from the configured spending key
1113
- */
1114
- getProvingKey() {
1115
- return __awaiter(this, void 0, void 0, function* () {
1116
- const provingKey = yield sapling__namespace.getProofAuthorizingKey(__classPrivateFieldGet(this, _spendingKeyBuf));
1117
- return provingKey.toString('hex');
1118
- });
1119
- }
1120
- }
1121
- _spendingKeyBuf = new WeakMap(), _saplingViewingKey = new WeakMap();
1008
+ var _InMemorySpendingKey_spendingKeyBuf, _InMemorySpendingKey_saplingViewingKey;
1009
+ /**
1010
+ * @description holds the spending key, create proof and signature for spend descriptions
1011
+ * can instantiate from mnemonic word list or decrypt a encrypted spending key
1012
+ * with access to instantiate a InMemoryViewingKey
1013
+ */
1014
+ class InMemorySpendingKey {
1015
+ /**
1016
+ *
1017
+ * @param spendingKey unencrypted sask... or encrypted MMXj...
1018
+ * @param password required for MMXj encrypted keys
1019
+ */
1020
+ constructor(spendingKey, password) {
1021
+ _InMemorySpendingKey_spendingKeyBuf.set(this, void 0);
1022
+ _InMemorySpendingKey_saplingViewingKey.set(this, void 0);
1023
+ __classPrivateFieldSet(this, _InMemorySpendingKey_spendingKeyBuf, decryptKey(spendingKey, password), "f");
1024
+ }
1025
+ /**
1026
+ *
1027
+ * @param mnemonic string of words
1028
+ * @param derivationPath tezos current standard 'm/'
1029
+ * @returns InMemorySpendingKey class instantiated
1030
+ */
1031
+ static fromMnemonic(mnemonic, derivationPath = 'm/') {
1032
+ return __awaiter(this, void 0, void 0, function* () {
1033
+ // no password passed here. password provided only changes from sask -> MMXj
1034
+ const fullSeed = yield bip39__namespace.mnemonicToSeed(mnemonic);
1035
+ const first32 = fullSeed.slice(0, 32);
1036
+ const second32 = fullSeed.slice(32);
1037
+ // reduce seed bytes must be 32 bytes reflecting both halves
1038
+ const seed = Buffer.from(first32.map((byte, index) => byte ^ second32[index]));
1039
+ const spendingKeyArr = new Uint8Array(yield sapling__namespace.getExtendedSpendingKey(seed, derivationPath));
1040
+ const spendingKey = utils.b58cencode(spendingKeyArr, utils.prefix[utils.Prefix.SASK]);
1041
+ return new InMemorySpendingKey(spendingKey);
1042
+ });
1043
+ }
1044
+ /**
1045
+ *
1046
+ * @returns InMemoryViewingKey instantiated class
1047
+ */
1048
+ getSaplingViewingKeyProvider() {
1049
+ return __awaiter(this, void 0, void 0, function* () {
1050
+ let viewingKey;
1051
+ if (!__classPrivateFieldGet(this, _InMemorySpendingKey_saplingViewingKey, "f")) {
1052
+ viewingKey = yield sapling__namespace.getExtendedFullViewingKeyFromSpendingKey(__classPrivateFieldGet(this, _InMemorySpendingKey_spendingKeyBuf, "f"));
1053
+ __classPrivateFieldSet(this, _InMemorySpendingKey_saplingViewingKey, new InMemoryViewingKey(viewingKey.toString('hex')), "f");
1054
+ }
1055
+ return __classPrivateFieldGet(this, _InMemorySpendingKey_saplingViewingKey, "f");
1056
+ });
1057
+ }
1058
+ /**
1059
+ * @description Prepare an unsigned sapling spend description using the spending key
1060
+ * @param parametersSpendProof.saplingContext The sapling proving context
1061
+ * @param parametersSpendProof.address The address of the input
1062
+ * @param parametersSpendProof.randomCommitmentTrapdoor The randomness of the commitment
1063
+ * @param parametersSpendProof.publicKeyReRandomization The re-randomization of the public key
1064
+ * @param parametersSpendProof.amount The value of the input
1065
+ * @param parametersSpendProof.root The root of the merkle tree
1066
+ * @param parametersSpendProof.witness The path of the commitment in the tree
1067
+ * @param derivationPath tezos current standard 'm/'
1068
+ * @returns The unsigned spend description
1069
+ */
1070
+ prepareSpendDescription(parametersSpendProof) {
1071
+ return __awaiter(this, void 0, void 0, function* () {
1072
+ const spendDescription = yield sapling__namespace.prepareSpendDescriptionWithSpendingKey(parametersSpendProof.saplingContext, __classPrivateFieldGet(this, _InMemorySpendingKey_spendingKeyBuf, "f"), parametersSpendProof.address, parametersSpendProof.randomCommitmentTrapdoor, parametersSpendProof.publicKeyReRandomization, parametersSpendProof.amount, parametersSpendProof.root, parametersSpendProof.witness);
1073
+ return {
1074
+ commitmentValue: spendDescription.cv,
1075
+ nullifier: spendDescription.nf,
1076
+ publicKeyReRandomization: spendDescription.rk,
1077
+ rtAnchor: spendDescription.rt,
1078
+ proof: spendDescription.proof,
1079
+ };
1080
+ });
1081
+ }
1082
+ /**
1083
+ * @description Sign a sapling spend description
1084
+ * @param parametersSpendSig.publicKeyReRandomization The re-randomization of the public key
1085
+ * @param parametersSpendSig.unsignedSpendDescription The unsigned Spend description
1086
+ * @param parametersSpendSig.hash The data to be signed
1087
+ * @returns The signed spend description
1088
+ */
1089
+ signSpendDescription(parametersSpendSig) {
1090
+ return __awaiter(this, void 0, void 0, function* () {
1091
+ const signedSpendDescription = yield sapling__namespace.signSpendDescription({
1092
+ cv: parametersSpendSig.unsignedSpendDescription.commitmentValue,
1093
+ rt: parametersSpendSig.unsignedSpendDescription.rtAnchor,
1094
+ nf: parametersSpendSig.unsignedSpendDescription.nullifier,
1095
+ rk: parametersSpendSig.unsignedSpendDescription.publicKeyReRandomization,
1096
+ proof: parametersSpendSig.unsignedSpendDescription.proof,
1097
+ }, __classPrivateFieldGet(this, _InMemorySpendingKey_spendingKeyBuf, "f"), parametersSpendSig.publicKeyReRandomization, parametersSpendSig.hash);
1098
+ return {
1099
+ commitmentValue: signedSpendDescription.cv,
1100
+ nullifier: signedSpendDescription.nf,
1101
+ publicKeyReRandomization: signedSpendDescription.rk,
1102
+ proof: signedSpendDescription.proof,
1103
+ signature: signedSpendDescription.spendAuthSig,
1104
+ };
1105
+ });
1106
+ }
1107
+ /**
1108
+ * @description Return a proof authorizing key from the configured spending key
1109
+ */
1110
+ getProvingKey() {
1111
+ return __awaiter(this, void 0, void 0, function* () {
1112
+ const provingKey = yield sapling__namespace.getProofAuthorizingKey(__classPrivateFieldGet(this, _InMemorySpendingKey_spendingKeyBuf, "f"));
1113
+ return provingKey.toString('hex');
1114
+ });
1115
+ }
1116
+ }
1117
+ _InMemorySpendingKey_spendingKeyBuf = new WeakMap(), _InMemorySpendingKey_saplingViewingKey = new WeakMap();
1122
1118
 
1123
- var _fullViewingKey;
1124
- /**
1125
- * @description Holds the viewing key
1126
- */
1127
- class InMemoryViewingKey {
1128
- constructor(fullViewingKey) {
1129
- _fullViewingKey.set(this, void 0);
1130
- __classPrivateFieldSet(this, _fullViewingKey, Buffer.from(fullViewingKey, 'hex'));
1131
- }
1132
- /**
1133
- * @description Allows to instantiate the InMemoryViewingKey from an encrypted/unencrypted spending key
1134
- *
1135
- * @param spendingKey Base58Check-encoded spending key
1136
- * @param password Optional password to decrypt the spending key
1137
- * @example
1138
- * ```
1139
- * await InMemoryViewingKey.fromSpendingKey('sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L')
1140
- * ```
1141
- *
1142
- */
1143
- static fromSpendingKey(spendingKey, password) {
1144
- return __awaiter(this, void 0, void 0, function* () {
1145
- const inMemorySpendingkey = new InMemorySpendingKey(spendingKey, password);
1146
- return inMemorySpendingkey.getSaplingViewingKeyProvider();
1147
- });
1148
- }
1149
- /**
1150
- * @description Retrieve the full viewing key
1151
- * @returns Buffer representing the full viewing key
1152
- *
1153
- */
1154
- getFullViewingKey() {
1155
- return __classPrivateFieldGet(this, _fullViewingKey);
1156
- }
1157
- /**
1158
- * @description Retrieve the outgoing viewing key
1159
- * @returns Buffer representing the outgoing viewing key
1160
- *
1161
- */
1162
- getOutgoingViewingKey() {
1163
- return __awaiter(this, void 0, void 0, function* () {
1164
- return sapling__namespace.getOutgoingViewingKey(__classPrivateFieldGet(this, _fullViewingKey));
1165
- });
1166
- }
1167
- /**
1168
- * @description Retrieve the incoming viewing key
1169
- * @returns Buffer representing the incoming viewing key
1170
- *
1171
- */
1172
- getIncomingViewingKey() {
1173
- return __awaiter(this, void 0, void 0, function* () {
1174
- return sapling__namespace.getIncomingViewingKey(__classPrivateFieldGet(this, _fullViewingKey));
1175
- });
1176
- }
1177
- /**
1178
- * @description Retrieve a payment address
1179
- * @param addressIndex used to determine which diversifier should be used to derive the address, default is 0
1180
- * @returns Base58Check-encoded address and its index
1181
- *
1182
- */
1183
- getAddress(addressIndex) {
1184
- return __awaiter(this, void 0, void 0, function* () {
1185
- const { index, raw } = yield sapling__namespace.getPaymentAddressFromViewingKey(__classPrivateFieldGet(this, _fullViewingKey), addressIndex);
1186
- return {
1187
- address: utils.b58cencode(raw, utils.prefix[utils.Prefix.ZET1]),
1188
- addressIndex: index.readInt32LE(),
1189
- };
1190
- });
1191
- }
1192
- }
1193
- _fullViewingKey = new WeakMap();
1119
+ var _InMemoryViewingKey_fullViewingKey;
1120
+ /**
1121
+ * @description Holds the viewing key
1122
+ */
1123
+ class InMemoryViewingKey {
1124
+ constructor(fullViewingKey) {
1125
+ _InMemoryViewingKey_fullViewingKey.set(this, void 0);
1126
+ __classPrivateFieldSet(this, _InMemoryViewingKey_fullViewingKey, Buffer.from(fullViewingKey, 'hex'), "f");
1127
+ }
1128
+ /**
1129
+ * @description Allows to instantiate the InMemoryViewingKey from an encrypted/unencrypted spending key
1130
+ *
1131
+ * @param spendingKey Base58Check-encoded spending key
1132
+ * @param password Optional password to decrypt the spending key
1133
+ * @example
1134
+ * ```
1135
+ * await InMemoryViewingKey.fromSpendingKey('sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L')
1136
+ * ```
1137
+ *
1138
+ */
1139
+ static fromSpendingKey(spendingKey, password) {
1140
+ return __awaiter(this, void 0, void 0, function* () {
1141
+ const inMemorySpendingkey = new InMemorySpendingKey(spendingKey, password);
1142
+ return inMemorySpendingkey.getSaplingViewingKeyProvider();
1143
+ });
1144
+ }
1145
+ /**
1146
+ * @description Retrieve the full viewing key
1147
+ * @returns Buffer representing the full viewing key
1148
+ *
1149
+ */
1150
+ getFullViewingKey() {
1151
+ return __classPrivateFieldGet(this, _InMemoryViewingKey_fullViewingKey, "f");
1152
+ }
1153
+ /**
1154
+ * @description Retrieve the outgoing viewing key
1155
+ * @returns Buffer representing the outgoing viewing key
1156
+ *
1157
+ */
1158
+ getOutgoingViewingKey() {
1159
+ return __awaiter(this, void 0, void 0, function* () {
1160
+ return sapling__namespace.getOutgoingViewingKey(__classPrivateFieldGet(this, _InMemoryViewingKey_fullViewingKey, "f"));
1161
+ });
1162
+ }
1163
+ /**
1164
+ * @description Retrieve the incoming viewing key
1165
+ * @returns Buffer representing the incoming viewing key
1166
+ *
1167
+ */
1168
+ getIncomingViewingKey() {
1169
+ return __awaiter(this, void 0, void 0, function* () {
1170
+ return sapling__namespace.getIncomingViewingKey(__classPrivateFieldGet(this, _InMemoryViewingKey_fullViewingKey, "f"));
1171
+ });
1172
+ }
1173
+ /**
1174
+ * @description Retrieve a payment address
1175
+ * @param addressIndex used to determine which diversifier should be used to derive the address, default is 0
1176
+ * @returns Base58Check-encoded address and its index
1177
+ *
1178
+ */
1179
+ getAddress(addressIndex) {
1180
+ return __awaiter(this, void 0, void 0, function* () {
1181
+ const { index, raw } = yield sapling__namespace.getPaymentAddressFromViewingKey(__classPrivateFieldGet(this, _InMemoryViewingKey_fullViewingKey, "f"), addressIndex);
1182
+ return {
1183
+ address: utils.b58cencode(raw, utils.prefix[utils.Prefix.ZET1]),
1184
+ addressIndex: index.readInt32LE(),
1185
+ };
1186
+ });
1187
+ }
1188
+ }
1189
+ _InMemoryViewingKey_fullViewingKey = new WeakMap();
1194
1190
 
1195
- var _provingKey;
1196
- /**
1197
- * @description holds the proving key, create proof for spend descriptions
1198
- * The class can be instantiated from a proving key or a spending key
1199
- */
1200
- class InMemoryProvingKey {
1201
- constructor(provingKey) {
1202
- _provingKey.set(this, void 0);
1203
- __classPrivateFieldSet(this, _provingKey, Buffer.from(provingKey, 'hex'));
1204
- }
1205
- /**
1206
- * @description Allows to instantiate the InMemoryProvingKey from an encrypted/unencrypted spending key
1207
- *
1208
- * @param spendingKey Base58Check-encoded spending key
1209
- * @param password Optional password to decrypt the spending key
1210
- * @example
1211
- * ```
1212
- * await InMemoryProvingKey.fromSpendingKey('sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L')
1213
- * ```
1214
- *
1215
- */
1216
- static fromSpendingKey(spendingKey, password) {
1217
- return __awaiter(this, void 0, void 0, function* () {
1218
- const decodedSpendingKey = decryptKey(spendingKey, password);
1219
- const provingKey = yield sapling__namespace.getProofAuthorizingKey(decodedSpendingKey);
1220
- return new InMemoryProvingKey(provingKey.toString('hex'));
1221
- });
1222
- }
1223
- /**
1224
- * @description Prepare an unsigned sapling spend description using the proving key
1225
- *
1226
- * @param parametersSpendProof.saplingContext The sapling proving context
1227
- * @param parametersSpendProof.address The address of the input
1228
- * @param parametersSpendProof.randomCommitmentTrapdoor The randomness of the commitment
1229
- * @param parametersSpendProof.publicKeyReRandomization The re-randomization of the public key
1230
- * @param parametersSpendProof.amount The value of the input
1231
- * @param parametersSpendProof.root The root of the merkle tree
1232
- * @param parametersSpendProof.witness The path of the commitment in the tree
1233
- * @param derivationPath tezos current standard 'm/'
1234
- * @returns The unsinged spend description
1235
- */
1236
- prepareSpendDescription(parametersSpendProof) {
1237
- return __awaiter(this, void 0, void 0, function* () {
1238
- const spendDescription = yield sapling__namespace.prepareSpendDescriptionWithAuthorizingKey(parametersSpendProof.saplingContext, __classPrivateFieldGet(this, _provingKey), parametersSpendProof.address, parametersSpendProof.randomCommitmentTrapdoor, parametersSpendProof.publicKeyReRandomization, parametersSpendProof.amount, parametersSpendProof.root, parametersSpendProof.witness);
1239
- return {
1240
- commitmentValue: spendDescription.cv,
1241
- nullifier: spendDescription.nf,
1242
- publicKeyReRandomization: spendDescription.rk,
1243
- rtAnchor: spendDescription.rt,
1244
- proof: spendDescription.proof,
1245
- };
1246
- });
1247
- }
1248
- }
1249
- _provingKey = new WeakMap();
1191
+ var _InMemoryProvingKey_provingKey;
1192
+ /**
1193
+ * @description holds the proving key, create proof for spend descriptions
1194
+ * The class can be instantiated from a proving key or a spending key
1195
+ */
1196
+ class InMemoryProvingKey {
1197
+ constructor(provingKey) {
1198
+ _InMemoryProvingKey_provingKey.set(this, void 0);
1199
+ __classPrivateFieldSet(this, _InMemoryProvingKey_provingKey, Buffer.from(provingKey, 'hex'), "f");
1200
+ }
1201
+ /**
1202
+ * @description Allows to instantiate the InMemoryProvingKey from an encrypted/unencrypted spending key
1203
+ *
1204
+ * @param spendingKey Base58Check-encoded spending key
1205
+ * @param password Optional password to decrypt the spending key
1206
+ * @example
1207
+ * ```
1208
+ * await InMemoryProvingKey.fromSpendingKey('sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L')
1209
+ * ```
1210
+ *
1211
+ */
1212
+ static fromSpendingKey(spendingKey, password) {
1213
+ return __awaiter(this, void 0, void 0, function* () {
1214
+ const decodedSpendingKey = decryptKey(spendingKey, password);
1215
+ const provingKey = yield sapling__namespace.getProofAuthorizingKey(decodedSpendingKey);
1216
+ return new InMemoryProvingKey(provingKey.toString('hex'));
1217
+ });
1218
+ }
1219
+ /**
1220
+ * @description Prepare an unsigned sapling spend description using the proving key
1221
+ *
1222
+ * @param parametersSpendProof.saplingContext The sapling proving context
1223
+ * @param parametersSpendProof.address The address of the input
1224
+ * @param parametersSpendProof.randomCommitmentTrapdoor The randomness of the commitment
1225
+ * @param parametersSpendProof.publicKeyReRandomization The re-randomization of the public key
1226
+ * @param parametersSpendProof.amount The value of the input
1227
+ * @param parametersSpendProof.root The root of the merkle tree
1228
+ * @param parametersSpendProof.witness The path of the commitment in the tree
1229
+ * @param derivationPath tezos current standard 'm/'
1230
+ * @returns The unsinged spend description
1231
+ */
1232
+ prepareSpendDescription(parametersSpendProof) {
1233
+ return __awaiter(this, void 0, void 0, function* () {
1234
+ const spendDescription = yield sapling__namespace.prepareSpendDescriptionWithAuthorizingKey(parametersSpendProof.saplingContext, __classPrivateFieldGet(this, _InMemoryProvingKey_provingKey, "f"), parametersSpendProof.address, parametersSpendProof.randomCommitmentTrapdoor, parametersSpendProof.publicKeyReRandomization, parametersSpendProof.amount, parametersSpendProof.root, parametersSpendProof.witness);
1235
+ return {
1236
+ commitmentValue: spendDescription.cv,
1237
+ nullifier: spendDescription.nf,
1238
+ publicKeyReRandomization: spendDescription.rk,
1239
+ rtAnchor: spendDescription.rt,
1240
+ proof: spendDescription.proof,
1241
+ };
1242
+ });
1243
+ }
1244
+ }
1245
+ _InMemoryProvingKey_provingKey = new WeakMap();
1250
1246
 
1251
- /**
1252
- * @packageDocumentation
1253
- * @module @taquito/sapling
1254
- */
1255
- var _inMemorySpendingKey, _saplingId, _contractAddress, _memoSize, _readProvider, _packer, _saplingForger, _saplingTxBuilder, _saplingTransactionViewer;
1256
- /**
1257
- * @description Class that surfaces all of the sapling capability allowing to read from a sapling state and prepare transactions
1258
- *
1259
- * @param keys.saplingSigner Holds the sapling spending key
1260
- * @param keys.saplingProver (Optional) Allows to generate the proofs with the proving key rather than the spending key
1261
- * @param saplingContractDetails Contains the address of the sapling contract, the memo size, and an optional sapling id that must be defined if the sapling contract contains more than one sapling state
1262
- * @param readProvider Allows to read data from the blockchain
1263
- * @param packer (Optional) Allows packing data. Use the `MichelCodecPacker` by default.
1264
- * @param saplingForger (Optional) Allows serializing the sapling transactions. Use the `SaplingForger` by default.
1265
- * @param saplingTxBuilder (Optional) Allows to prepare the sapling transactions. Use the `SaplingTransactionBuilder` by default.
1266
- * @example
1267
- * ```
1268
- * const inMemorySpendingKey = await InMemorySpendingKey.fromMnemonic('YOUR_MNEMONIC');
1269
- * const readProvider = new RpcReadAdapter(new RpcClient('https://YOUR_PREFERRED_RPC_URL'))
1270
- *
1271
- * const saplingToolkit = new SaplingToolkit(
1272
- * { saplingSigner: inMemorySpendingKey },
1273
- * { contractAddress: SAPLING_CONTRACT_ADDRESS, memoSize: 8 },
1274
- * readProvider
1275
- * )
1276
- * ```
1277
- */
1278
- class SaplingToolkit {
1279
- constructor(keys, saplingContractDetails, readProvider, packer = new taquito.MichelCodecPacker(), saplingForger = new SaplingForger(), saplingTxBuilder = new SaplingTransactionBuilder(keys, saplingForger, saplingContractDetails, readProvider)) {
1280
- _inMemorySpendingKey.set(this, void 0);
1281
- _saplingId.set(this, void 0);
1282
- _contractAddress.set(this, void 0);
1283
- _memoSize.set(this, void 0);
1284
- _readProvider.set(this, void 0);
1285
- _packer.set(this, void 0);
1286
- _saplingForger.set(this, void 0);
1287
- _saplingTxBuilder.set(this, void 0);
1288
- _saplingTransactionViewer.set(this, void 0);
1289
- __classPrivateFieldSet(this, _inMemorySpendingKey, keys.saplingSigner);
1290
- __classPrivateFieldSet(this, _saplingId, saplingContractDetails.saplingId);
1291
- __classPrivateFieldSet(this, _contractAddress, saplingContractDetails.contractAddress);
1292
- __classPrivateFieldSet(this, _memoSize, saplingContractDetails.memoSize);
1293
- __classPrivateFieldSet(this, _readProvider, readProvider);
1294
- __classPrivateFieldSet(this, _packer, packer);
1295
- __classPrivateFieldSet(this, _saplingForger, saplingForger);
1296
- __classPrivateFieldSet(this, _saplingTxBuilder, saplingTxBuilder);
1297
- }
1298
- /**
1299
- * @description Get an instance of `SaplingTransactionViewer` which allows to retrieve and decrypt sapling transactions and calculate the unspent balance.
1300
- */
1301
- getSaplingTransactionViewer() {
1302
- return __awaiter(this, void 0, void 0, function* () {
1303
- let saplingTransactionViewer;
1304
- if (!__classPrivateFieldGet(this, _saplingTransactionViewer)) {
1305
- const saplingViewingKey = yield __classPrivateFieldGet(this, _inMemorySpendingKey).getSaplingViewingKeyProvider();
1306
- saplingTransactionViewer = new SaplingTransactionViewer(saplingViewingKey, this.getSaplingContractId(), __classPrivateFieldGet(this, _readProvider));
1307
- __classPrivateFieldSet(this, _saplingTransactionViewer, saplingTransactionViewer);
1308
- }
1309
- return __classPrivateFieldGet(this, _saplingTransactionViewer);
1310
- });
1311
- }
1312
- /**
1313
- * @description Prepare a shielded transaction
1314
- * @param shieldedTxParams `to` is the payment address that will receive the shielded tokens (zet).
1315
- * `amount` is the amount of shielded tokens in tez by default.
1316
- * `mutez` needs to be set to true if the amount of shielded tokens is in mutez.
1317
- * `memo` is an empty string by default.
1318
- * @returns a string representing the sapling transaction
1319
- */
1320
- prepareShieldedTransaction(shieldedTxParams) {
1321
- return __awaiter(this, void 0, void 0, function* () {
1322
- const { formatedParams, totalAmount } = this.formatTransactionParams(shieldedTxParams, this.validateDestinationSaplingAddress);
1323
- const root = yield this.getRoot();
1324
- const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _saplingTxBuilder).createShieldedTx(formatedParams, totalAmount, DEFAULT_BOUND_DATA);
1325
- const forgedSaplingTx = __classPrivateFieldGet(this, _saplingForger).forgeSaplingTransaction({
1326
- inputs,
1327
- outputs,
1328
- balance,
1329
- root,
1330
- boundData: DEFAULT_BOUND_DATA,
1331
- signature,
1332
- });
1333
- return forgedSaplingTx.toString('hex');
1334
- });
1335
- }
1336
- /**
1337
- * @description Prepare an unshielded transaction
1338
- * @param unshieldedTxParams `to` is the Tezos address that will receive the unshielded tokens (tz1, tz2 or tz3).
1339
- * `amount` is the amount of unshielded tokens in tez by default.
1340
- * `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
1341
- * @returns a string representing the sapling transaction.
1342
- */
1343
- prepareUnshieldedTransaction(unshieldedTxParams) {
1344
- return __awaiter(this, void 0, void 0, function* () {
1345
- const { formatedParams, totalAmount } = this.formatTransactionParams([unshieldedTxParams], this.validateDestinationImplicitAddress);
1346
- const boundData = yield this.createBoundData(formatedParams[0].to);
1347
- const root = yield this.getRoot();
1348
- const chosenInputs = yield this.selectInputsToSpend(new BigNumber__default["default"](formatedParams[0].amount));
1349
- const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _saplingTxBuilder).createSaplingTx([], totalAmount, boundData, chosenInputs);
1350
- const forgedSaplingTx = __classPrivateFieldGet(this, _saplingForger).forgeSaplingTransaction({
1351
- inputs,
1352
- outputs,
1353
- balance,
1354
- root,
1355
- boundData,
1356
- signature,
1357
- });
1358
- return forgedSaplingTx.toString('hex');
1359
- });
1360
- }
1361
- /**
1362
- * @description Prepare a sapling transaction (zet to zet)
1363
- * @param saplingTxParams `to` is the payment address that will receive the shielded tokens (zet).
1364
- * `amount` is the amount of unshielded tokens in tez by default.
1365
- * `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
1366
- * `memo` is an empty string by default.
1367
- * @returns a string representing the sapling transaction.
1368
- */
1369
- prepareSaplingTransaction(saplingTxParams) {
1370
- return __awaiter(this, void 0, void 0, function* () {
1371
- const { formatedParams, totalAmount } = this.formatTransactionParams(saplingTxParams, this.validateDestinationSaplingAddress);
1372
- const root = yield this.getRoot();
1373
- const chosenInputs = yield this.selectInputsToSpend(totalAmount);
1374
- const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _saplingTxBuilder).createSaplingTx(formatedParams, totalAmount, DEFAULT_BOUND_DATA, chosenInputs);
1375
- const forgedSaplingTx = __classPrivateFieldGet(this, _saplingForger).forgeSaplingTransaction({
1376
- inputs,
1377
- outputs,
1378
- balance,
1379
- root,
1380
- boundData: DEFAULT_BOUND_DATA,
1381
- signature,
1382
- });
1383
- return forgedSaplingTx.toString('hex');
1384
- });
1385
- }
1386
- formatTransactionParams(txParams, validateDestination) {
1387
- const formatedParams = [];
1388
- let totalAmount = new BigNumber__default["default"](0);
1389
- txParams.forEach((param) => {
1390
- var _a;
1391
- validateDestination(param.to);
1392
- const amountMutez = param.mutez
1393
- ? param.amount.toString()
1394
- : utils.format('tz', 'mutez', param.amount).toString();
1395
- totalAmount = totalAmount.plus(new BigNumber__default["default"](amountMutez));
1396
- const memo = (_a = param.memo) !== null && _a !== void 0 ? _a : DEFAULT_MEMO;
1397
- if (memo.length > __classPrivateFieldGet(this, _memoSize)) {
1398
- throw new InvalidMemo(memo, `expecting length to be less than ${__classPrivateFieldGet(this, _memoSize)}`);
1399
- }
1400
- formatedParams.push({ to: param.to, amount: amountMutez, memo });
1401
- });
1402
- return { formatedParams, totalAmount };
1403
- }
1404
- getRoot() {
1405
- return __awaiter(this, void 0, void 0, function* () {
1406
- if (__classPrivateFieldGet(this, _saplingId)) {
1407
- const { root } = yield __classPrivateFieldGet(this, _readProvider).getSaplingDiffById({ id: __classPrivateFieldGet(this, _saplingId) }, 'head');
1408
- return root;
1409
- }
1410
- else {
1411
- const { root } = yield __classPrivateFieldGet(this, _readProvider).getSaplingDiffByContract(__classPrivateFieldGet(this, _contractAddress), 'head');
1412
- return root;
1413
- }
1414
- });
1415
- }
1416
- createBoundData(destination) {
1417
- return __awaiter(this, void 0, void 0, function* () {
1418
- const pref = destination.substring(0, 3);
1419
- let pad;
1420
- switch (pref) {
1421
- case 'tz1': {
1422
- pad = Buffer.from('00', 'hex');
1423
- break;
1424
- }
1425
- case 'tz2': {
1426
- pad = Buffer.from('01', 'hex');
1427
- break;
1428
- }
1429
- case 'tz3': {
1430
- pad = Buffer.from('02', 'hex');
1431
- break;
1432
- }
1433
- default: {
1434
- throw new core.InvalidAddressError(destination, utils.invalidDetail(utils.ValidationResult.NO_PREFIX_MATCHED) +
1435
- ` expecting one of the following prefix '${utils.Prefix.TZ1}', '${utils.Prefix.TZ2}' or '${utils.Prefix.TZ3}'.`);
1436
- }
1437
- }
1438
- const decodedDestination = utils.b58cdecode(destination, utils.prefix[pref]);
1439
- const padDestination = Buffer.concat([pad, Buffer.from(decodedDestination)]);
1440
- const packedDestination = yield __classPrivateFieldGet(this, _packer).packData({
1441
- data: { bytes: padDestination.toString('hex') },
1442
- type: { prim: 'bytes' },
1443
- });
1444
- return Buffer.from(packedDestination.packed, 'hex');
1445
- });
1446
- }
1447
- validateDestinationImplicitAddress(to) {
1448
- const toValidation = utils.validateKeyHash(to);
1449
- if (toValidation !== utils.ValidationResult.VALID) {
1450
- throw new core.InvalidKeyHashError(to, utils.invalidDetail(toValidation));
1451
- }
1452
- }
1453
- validateDestinationSaplingAddress(to) {
1454
- if (!to.startsWith(utils.Prefix.ZET1)) {
1455
- throw new core.InvalidAddressError(to, utils.invalidDetail(utils.ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix ${utils.Prefix.ZET1}.`);
1456
- }
1457
- }
1458
- getSaplingContractId() {
1459
- let saplingContractId;
1460
- if (__classPrivateFieldGet(this, _saplingId)) {
1461
- saplingContractId = { saplingId: __classPrivateFieldGet(this, _saplingId) };
1462
- }
1463
- else {
1464
- saplingContractId = { contractAddress: __classPrivateFieldGet(this, _contractAddress) };
1465
- }
1466
- return saplingContractId;
1467
- }
1468
- selectInputsToSpend(amountMutez) {
1469
- return __awaiter(this, void 0, void 0, function* () {
1470
- const saplingTxViewer = yield this.getSaplingTransactionViewer();
1471
- const { incoming } = yield saplingTxViewer.getIncomingAndOutgoingTransactionsRaw();
1472
- const inputsToSpend = [];
1473
- let sumSelectedInputs = new BigNumber__default["default"](0);
1474
- incoming.forEach((input) => {
1475
- if (!input.isSpent && sumSelectedInputs.isLessThan(amountMutez)) {
1476
- const txAmount = convertValueToBigNumber(input.value);
1477
- sumSelectedInputs = sumSelectedInputs.plus(txAmount);
1478
- const rest = __rest(input, ["isSpent"]);
1479
- inputsToSpend.push(rest);
1480
- }
1481
- });
1482
- if (sumSelectedInputs.isLessThan(new BigNumber__default["default"](amountMutez))) {
1483
- throw new InsufficientBalance(sumSelectedInputs.toString(), amountMutez.toString());
1484
- }
1485
- return { inputsToSpend, sumSelectedInputs };
1486
- });
1487
- }
1488
- }
1489
- _inMemorySpendingKey = new WeakMap(), _saplingId = new WeakMap(), _contractAddress = new WeakMap(), _memoSize = new WeakMap(), _readProvider = new WeakMap(), _packer = new WeakMap(), _saplingForger = new WeakMap(), _saplingTxBuilder = new WeakMap(), _saplingTransactionViewer = new WeakMap();
1247
+ /**
1248
+ * @packageDocumentation
1249
+ * @module @taquito/sapling
1250
+ */
1251
+ var _SaplingToolkit_inMemorySpendingKey, _SaplingToolkit_saplingId, _SaplingToolkit_contractAddress, _SaplingToolkit_memoSize, _SaplingToolkit_readProvider, _SaplingToolkit_packer, _SaplingToolkit_saplingForger, _SaplingToolkit_saplingTxBuilder, _SaplingToolkit_saplingTransactionViewer;
1252
+ /**
1253
+ * @description Class that surfaces all of the sapling capability allowing to read from a sapling state and prepare transactions
1254
+ *
1255
+ * @param keys.saplingSigner Holds the sapling spending key
1256
+ * @param keys.saplingProver (Optional) Allows to generate the proofs with the proving key rather than the spending key
1257
+ * @param saplingContractDetails Contains the address of the sapling contract, the memo size, and an optional sapling id that must be defined if the sapling contract contains more than one sapling state
1258
+ * @param readProvider Allows to read data from the blockchain
1259
+ * @param packer (Optional) Allows packing data. Use the `MichelCodecPacker` by default.
1260
+ * @param saplingForger (Optional) Allows serializing the sapling transactions. Use the `SaplingForger` by default.
1261
+ * @param saplingTxBuilder (Optional) Allows to prepare the sapling transactions. Use the `SaplingTransactionBuilder` by default.
1262
+ * @example
1263
+ * ```
1264
+ * const inMemorySpendingKey = await InMemorySpendingKey.fromMnemonic('YOUR_MNEMONIC');
1265
+ * const readProvider = new RpcReadAdapter(new RpcClient('https://YOUR_PREFERRED_RPC_URL'))
1266
+ *
1267
+ * const saplingToolkit = new SaplingToolkit(
1268
+ * { saplingSigner: inMemorySpendingKey },
1269
+ * { contractAddress: SAPLING_CONTRACT_ADDRESS, memoSize: 8 },
1270
+ * readProvider
1271
+ * )
1272
+ * ```
1273
+ */
1274
+ class SaplingToolkit {
1275
+ constructor(keys, saplingContractDetails, readProvider, packer = new taquito.MichelCodecPacker(), saplingForger = new SaplingForger(), saplingTxBuilder = new SaplingTransactionBuilder(keys, saplingForger, saplingContractDetails, readProvider)) {
1276
+ _SaplingToolkit_inMemorySpendingKey.set(this, void 0);
1277
+ _SaplingToolkit_saplingId.set(this, void 0);
1278
+ _SaplingToolkit_contractAddress.set(this, void 0);
1279
+ _SaplingToolkit_memoSize.set(this, void 0);
1280
+ _SaplingToolkit_readProvider.set(this, void 0);
1281
+ _SaplingToolkit_packer.set(this, void 0);
1282
+ _SaplingToolkit_saplingForger.set(this, void 0);
1283
+ _SaplingToolkit_saplingTxBuilder.set(this, void 0);
1284
+ _SaplingToolkit_saplingTransactionViewer.set(this, void 0);
1285
+ __classPrivateFieldSet(this, _SaplingToolkit_inMemorySpendingKey, keys.saplingSigner, "f");
1286
+ __classPrivateFieldSet(this, _SaplingToolkit_saplingId, saplingContractDetails.saplingId, "f");
1287
+ __classPrivateFieldSet(this, _SaplingToolkit_contractAddress, saplingContractDetails.contractAddress, "f");
1288
+ __classPrivateFieldSet(this, _SaplingToolkit_memoSize, saplingContractDetails.memoSize, "f");
1289
+ __classPrivateFieldSet(this, _SaplingToolkit_readProvider, readProvider, "f");
1290
+ __classPrivateFieldSet(this, _SaplingToolkit_packer, packer, "f");
1291
+ __classPrivateFieldSet(this, _SaplingToolkit_saplingForger, saplingForger, "f");
1292
+ __classPrivateFieldSet(this, _SaplingToolkit_saplingTxBuilder, saplingTxBuilder, "f");
1293
+ }
1294
+ /**
1295
+ * @description Get an instance of `SaplingTransactionViewer` which allows to retrieve and decrypt sapling transactions and calculate the unspent balance.
1296
+ */
1297
+ getSaplingTransactionViewer() {
1298
+ return __awaiter(this, void 0, void 0, function* () {
1299
+ let saplingTransactionViewer;
1300
+ if (!__classPrivateFieldGet(this, _SaplingToolkit_saplingTransactionViewer, "f")) {
1301
+ const saplingViewingKey = yield __classPrivateFieldGet(this, _SaplingToolkit_inMemorySpendingKey, "f").getSaplingViewingKeyProvider();
1302
+ saplingTransactionViewer = new SaplingTransactionViewer(saplingViewingKey, this.getSaplingContractId(), __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f"));
1303
+ __classPrivateFieldSet(this, _SaplingToolkit_saplingTransactionViewer, saplingTransactionViewer, "f");
1304
+ }
1305
+ return __classPrivateFieldGet(this, _SaplingToolkit_saplingTransactionViewer, "f");
1306
+ });
1307
+ }
1308
+ /**
1309
+ * @description Prepare a shielded transaction
1310
+ * @param shieldedTxParams `to` is the payment address that will receive the shielded tokens (zet).
1311
+ * `amount` is the amount of shielded tokens in tez by default.
1312
+ * `mutez` needs to be set to true if the amount of shielded tokens is in mutez.
1313
+ * `memo` is an empty string by default.
1314
+ * @returns a string representing the sapling transaction
1315
+ */
1316
+ prepareShieldedTransaction(shieldedTxParams) {
1317
+ return __awaiter(this, void 0, void 0, function* () {
1318
+ const { formatedParams, totalAmount } = this.formatTransactionParams(shieldedTxParams, this.validateDestinationSaplingAddress);
1319
+ const root = yield this.getRoot();
1320
+ const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createShieldedTx(formatedParams, totalAmount, DEFAULT_BOUND_DATA);
1321
+ const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
1322
+ inputs,
1323
+ outputs,
1324
+ balance,
1325
+ root,
1326
+ boundData: DEFAULT_BOUND_DATA,
1327
+ signature,
1328
+ });
1329
+ return forgedSaplingTx.toString('hex');
1330
+ });
1331
+ }
1332
+ /**
1333
+ * @description Prepare an unshielded transaction
1334
+ * @param unshieldedTxParams `to` is the Tezos address that will receive the unshielded tokens (tz1, tz2 or tz3).
1335
+ * `amount` is the amount of unshielded tokens in tez by default.
1336
+ * `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
1337
+ * @returns a string representing the sapling transaction.
1338
+ */
1339
+ prepareUnshieldedTransaction(unshieldedTxParams) {
1340
+ return __awaiter(this, void 0, void 0, function* () {
1341
+ const { formatedParams, totalAmount } = this.formatTransactionParams([unshieldedTxParams], this.validateDestinationImplicitAddress);
1342
+ const boundData = yield this.createBoundData(formatedParams[0].to);
1343
+ const root = yield this.getRoot();
1344
+ const chosenInputs = yield this.selectInputsToSpend(new BigNumber(formatedParams[0].amount));
1345
+ const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createSaplingTx([], totalAmount, boundData, chosenInputs);
1346
+ const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
1347
+ inputs,
1348
+ outputs,
1349
+ balance,
1350
+ root,
1351
+ boundData,
1352
+ signature,
1353
+ });
1354
+ return forgedSaplingTx.toString('hex');
1355
+ });
1356
+ }
1357
+ /**
1358
+ * @description Prepare a sapling transaction (zet to zet)
1359
+ * @param saplingTxParams `to` is the payment address that will receive the shielded tokens (zet).
1360
+ * `amount` is the amount of unshielded tokens in tez by default.
1361
+ * `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
1362
+ * `memo` is an empty string by default.
1363
+ * @returns a string representing the sapling transaction.
1364
+ */
1365
+ prepareSaplingTransaction(saplingTxParams) {
1366
+ return __awaiter(this, void 0, void 0, function* () {
1367
+ const { formatedParams, totalAmount } = this.formatTransactionParams(saplingTxParams, this.validateDestinationSaplingAddress);
1368
+ const root = yield this.getRoot();
1369
+ const chosenInputs = yield this.selectInputsToSpend(totalAmount);
1370
+ const { inputs, outputs, signature, balance } = yield __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createSaplingTx(formatedParams, totalAmount, DEFAULT_BOUND_DATA, chosenInputs);
1371
+ const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
1372
+ inputs,
1373
+ outputs,
1374
+ balance,
1375
+ root,
1376
+ boundData: DEFAULT_BOUND_DATA,
1377
+ signature,
1378
+ });
1379
+ return forgedSaplingTx.toString('hex');
1380
+ });
1381
+ }
1382
+ formatTransactionParams(txParams, validateDestination) {
1383
+ const formatedParams = [];
1384
+ let totalAmount = new BigNumber(0);
1385
+ txParams.forEach((param) => {
1386
+ var _a;
1387
+ validateDestination(param.to);
1388
+ const amountMutez = param.mutez
1389
+ ? param.amount.toString()
1390
+ : utils.format('tz', 'mutez', param.amount).toString();
1391
+ totalAmount = totalAmount.plus(new BigNumber(amountMutez));
1392
+ const memo = (_a = param.memo) !== null && _a !== void 0 ? _a : DEFAULT_MEMO;
1393
+ if (memo.length > __classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")) {
1394
+ throw new InvalidMemo(memo, `expecting length to be less than ${__classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")}`);
1395
+ }
1396
+ formatedParams.push({ to: param.to, amount: amountMutez, memo });
1397
+ });
1398
+ return { formatedParams, totalAmount };
1399
+ }
1400
+ getRoot() {
1401
+ return __awaiter(this, void 0, void 0, function* () {
1402
+ if (__classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f")) {
1403
+ const { root } = yield __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f").getSaplingDiffById({ id: __classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f") }, 'head');
1404
+ return root;
1405
+ }
1406
+ else {
1407
+ const { root } = yield __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f").getSaplingDiffByContract(__classPrivateFieldGet(this, _SaplingToolkit_contractAddress, "f"), 'head');
1408
+ return root;
1409
+ }
1410
+ });
1411
+ }
1412
+ createBoundData(destination) {
1413
+ return __awaiter(this, void 0, void 0, function* () {
1414
+ const pref = destination.substring(0, 3);
1415
+ let pad;
1416
+ switch (pref) {
1417
+ case 'tz1': {
1418
+ pad = Buffer.from('00', 'hex');
1419
+ break;
1420
+ }
1421
+ case 'tz2': {
1422
+ pad = Buffer.from('01', 'hex');
1423
+ break;
1424
+ }
1425
+ case 'tz3': {
1426
+ pad = Buffer.from('02', 'hex');
1427
+ break;
1428
+ }
1429
+ default: {
1430
+ throw new core.InvalidAddressError(destination, utils.invalidDetail(utils.ValidationResult.NO_PREFIX_MATCHED) +
1431
+ ` expecting one of the following prefix '${utils.Prefix.TZ1}', '${utils.Prefix.TZ2}' or '${utils.Prefix.TZ3}'.`);
1432
+ }
1433
+ }
1434
+ const decodedDestination = utils.b58cdecode(destination, utils.prefix[pref]);
1435
+ const padDestination = Buffer.concat([pad, Buffer.from(decodedDestination)]);
1436
+ const packedDestination = yield __classPrivateFieldGet(this, _SaplingToolkit_packer, "f").packData({
1437
+ data: { bytes: padDestination.toString('hex') },
1438
+ type: { prim: 'bytes' },
1439
+ });
1440
+ return Buffer.from(packedDestination.packed, 'hex');
1441
+ });
1442
+ }
1443
+ validateDestinationImplicitAddress(to) {
1444
+ const toValidation = utils.validateKeyHash(to);
1445
+ if (toValidation !== utils.ValidationResult.VALID) {
1446
+ throw new core.InvalidKeyHashError(to, utils.invalidDetail(toValidation));
1447
+ }
1448
+ }
1449
+ validateDestinationSaplingAddress(to) {
1450
+ if (!to.startsWith(utils.Prefix.ZET1)) {
1451
+ throw new core.InvalidAddressError(to, utils.invalidDetail(utils.ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix ${utils.Prefix.ZET1}.`);
1452
+ }
1453
+ }
1454
+ getSaplingContractId() {
1455
+ let saplingContractId;
1456
+ if (__classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f")) {
1457
+ saplingContractId = { saplingId: __classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f") };
1458
+ }
1459
+ else {
1460
+ saplingContractId = { contractAddress: __classPrivateFieldGet(this, _SaplingToolkit_contractAddress, "f") };
1461
+ }
1462
+ return saplingContractId;
1463
+ }
1464
+ selectInputsToSpend(amountMutez) {
1465
+ return __awaiter(this, void 0, void 0, function* () {
1466
+ const saplingTxViewer = yield this.getSaplingTransactionViewer();
1467
+ const { incoming } = yield saplingTxViewer.getIncomingAndOutgoingTransactionsRaw();
1468
+ const inputsToSpend = [];
1469
+ let sumSelectedInputs = new BigNumber(0);
1470
+ incoming.forEach((input) => {
1471
+ if (!input.isSpent && sumSelectedInputs.isLessThan(amountMutez)) {
1472
+ const txAmount = convertValueToBigNumber(input.value);
1473
+ sumSelectedInputs = sumSelectedInputs.plus(txAmount);
1474
+ const rest = __rest(input, ["isSpent"]);
1475
+ inputsToSpend.push(rest);
1476
+ }
1477
+ });
1478
+ if (sumSelectedInputs.isLessThan(new BigNumber(amountMutez))) {
1479
+ throw new InsufficientBalance(sumSelectedInputs.toString(), amountMutez.toString());
1480
+ }
1481
+ return { inputsToSpend, sumSelectedInputs };
1482
+ });
1483
+ }
1484
+ }
1485
+ _SaplingToolkit_inMemorySpendingKey = new WeakMap(), _SaplingToolkit_saplingId = new WeakMap(), _SaplingToolkit_contractAddress = new WeakMap(), _SaplingToolkit_memoSize = new WeakMap(), _SaplingToolkit_readProvider = new WeakMap(), _SaplingToolkit_packer = new WeakMap(), _SaplingToolkit_saplingForger = new WeakMap(), _SaplingToolkit_saplingTxBuilder = new WeakMap(), _SaplingToolkit_saplingTransactionViewer = new WeakMap();
1490
1486
 
1491
1487
  exports.InMemoryProvingKey = InMemoryProvingKey;
1492
1488
  exports.InMemorySpendingKey = InMemorySpendingKey;
@@ -1494,7 +1490,5 @@
1494
1490
  exports.SaplingToolkit = SaplingToolkit;
1495
1491
  exports.SaplingTransactionViewer = SaplingTransactionViewer;
1496
1492
 
1497
- Object.defineProperty(exports, '__esModule', { value: true });
1498
-
1499
1493
  }));
1500
1494
  //# sourceMappingURL=taquito-sapling.umd.js.map