@taquito/sapling 24.3.0-beta.1 → 24.3.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/SAPLING_PARAMS_PROVENANCE.md +24 -0
- package/dist/lib/sapling-keys/helpers.js +3 -2
- package/dist/lib/sapling-keys/in-memory-proving-key.js +1 -1
- package/dist/lib/sapling-keys/in-memory-spending-key.js +2 -2
- package/dist/lib/sapling-keys/in-memory-viewing-key.js +1 -1
- package/dist/lib/sapling-module-wrapper.js +12 -4
- package/dist/lib/sapling-state/sapling-state.js +3 -2
- package/dist/lib/sapling-tx-builder/sapling-transactions-builder.js +6 -5
- package/dist/lib/sapling-tx-viewer/sapling-transaction-viewer.js +3 -2
- package/dist/lib/taquito-sapling.js +6 -5
- package/dist/lib/types.js +2 -0
- package/dist/lib/version.js +2 -2
- package/dist/taquito-sapling.es6.js +702 -19
- package/dist/taquito-sapling.es6.js.map +1 -1
- package/dist/taquito-sapling.umd.js +703 -18
- package/dist/taquito-sapling.umd.js.map +1 -1
- package/dist/types/node_modules/@scure/base/index.d.ts +293 -0
- package/dist/types/sapling-module-wrapper.d.ts +1 -1
- package/dist/types/sapling-state/sapling-state.d.ts +4 -1
- package/dist/types/sapling-tx-builder/sapling-transactions-builder.d.ts +6 -3
- package/dist/types/sapling-tx-viewer/sapling-transaction-viewer.d.ts +4 -1
- package/dist/types/src/version.d.ts +4 -0
- package/dist/types/types.d.ts +4 -1
- package/package.json +21 -46
- package/saplingOutputParams.js +13 -0
- package/fetch-sapling-params.js +0 -39
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ The returned balance is in mutez.
|
|
|
24
24
|
import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito';
|
|
25
25
|
import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling';
|
|
26
26
|
|
|
27
|
-
const tezos = new TezosToolkit('https://
|
|
27
|
+
const tezos = new TezosToolkit('https://shadownet.tezos.ecadinfra.com/');
|
|
28
28
|
|
|
29
29
|
const saplingContract = await tezos.contract.at('KT1UYwMR6Q6LZnwQEi77DSBrAjKT1tEJb245');
|
|
30
30
|
|
|
@@ -50,7 +50,7 @@ A shielded transaction allows sending tokens from a Tezos account (tz1, tz2, tz3
|
|
|
50
50
|
import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito';
|
|
51
51
|
import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling';
|
|
52
52
|
|
|
53
|
-
const tezos = new TezosToolkit('https://
|
|
53
|
+
const tezos = new TezosToolkit('https://shadownet.tezos.ecadinfra.com/');
|
|
54
54
|
// set up your signer on the TezosToolkit as usual
|
|
55
55
|
const saplingContract = await tezos.contract.at('KT1UYwMR6Q6LZnwQEi77DSBrAjKT1tEJb245');
|
|
56
56
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Sapling Parameter Provenance
|
|
2
|
+
|
|
3
|
+
The `saplingOutputParams.js` file in this package and the `saplingSpendParams.js` file in the sibling `@taquito/sapling-spend-params` package are vendored copies of the Sapling proving parameters distributed by the Zcash project.
|
|
4
|
+
|
|
5
|
+
Source:
|
|
6
|
+
- `https://download.z.cash/downloads/sapling-spend.params`
|
|
7
|
+
- `https://download.z.cash/downloads/sapling-output.params`
|
|
8
|
+
|
|
9
|
+
Verification data:
|
|
10
|
+
- `sapling-spend.params`
|
|
11
|
+
- Size: `47,958,396` bytes
|
|
12
|
+
- SHA-256: `8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13`
|
|
13
|
+
- `sapling-output.params`
|
|
14
|
+
- Size: `3,592,860` bytes
|
|
15
|
+
- SHA-256: `2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4`
|
|
16
|
+
|
|
17
|
+
Why these files are vendored:
|
|
18
|
+
- `@taquito/sapling` previously fetched them during `postinstall`, which made installs network-dependent.
|
|
19
|
+
- Vendoring keeps published packages self-contained and makes builds reproducible.
|
|
20
|
+
- These parameters are treated as fixed trusted setup artifacts, not routine updatable assets.
|
|
21
|
+
|
|
22
|
+
Maintainer note:
|
|
23
|
+
- `fetch-sapling-params.js` is retained only as a repo-maintenance helper to regenerate the vendored wrapper files from the exact raw parameter files above.
|
|
24
|
+
- Any regeneration should be exceptional, manually reviewed, and accompanied by explicit provenance updates in this file.
|
|
@@ -4,7 +4,8 @@ exports.decryptKey = decryptKey;
|
|
|
4
4
|
const errors_1 = require("../errors");
|
|
5
5
|
const typedarray_to_buffer_1 = require("typedarray-to-buffer");
|
|
6
6
|
const nacl_1 = require("@stablelib/nacl");
|
|
7
|
-
const
|
|
7
|
+
const pbkdf2_js_1 = require("@noble/hashes/pbkdf2.js");
|
|
8
|
+
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
|
8
9
|
const utils_1 = require("@taquito/utils");
|
|
9
10
|
const core_1 = require("@taquito/core");
|
|
10
11
|
function decryptKey(spendingKey, password) {
|
|
@@ -30,7 +31,7 @@ function decryptKey(spendingKey, password) {
|
|
|
30
31
|
}
|
|
31
32
|
const salt = (0, typedarray_to_buffer_1.default)(keyArr.slice(0, 8));
|
|
32
33
|
const encryptedSk = (0, typedarray_to_buffer_1.default)(keyArr.slice(8));
|
|
33
|
-
const encryptionKey =
|
|
34
|
+
const encryptionKey = (0, pbkdf2_js_1.pbkdf2)(sha2_js_1.sha512, password, salt, { c: 32768, dkLen: 32 });
|
|
34
35
|
// Zero nonce is safe: fresh random salt per encryption produces unique PBKDF2-derived key.
|
|
35
36
|
// See: https://gitlab.com/tezos/tezos/-/blob/master/src/lib_signer_backends/encrypted.ml
|
|
36
37
|
const decrypted = (0, nacl_1.openSecretBox)(new Uint8Array(encryptionKey), new Uint8Array(24), // zero nonce - uniqueness provided by per-encryption derived key
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _InMemoryProvingKey_provingKey;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.InMemoryProvingKey = void 0;
|
|
16
|
-
const sapling = require("@
|
|
16
|
+
const sapling = require("@taquito/sapling-wasm");
|
|
17
17
|
const helpers_1 = require("./helpers");
|
|
18
18
|
/**
|
|
19
19
|
* holds the proving key, create proof for spend descriptions
|
|
@@ -14,9 +14,9 @@ var _InMemorySpendingKey_spendingKeyBuf, _InMemorySpendingKey_saplingViewingKey;
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.InMemorySpendingKey = void 0;
|
|
16
16
|
const in_memory_viewing_key_1 = require("./in-memory-viewing-key");
|
|
17
|
-
const sapling = require("@
|
|
17
|
+
const sapling = require("@taquito/sapling-wasm");
|
|
18
18
|
const utils_1 = require("@taquito/utils");
|
|
19
|
-
const bip39 = require("bip39");
|
|
19
|
+
const bip39 = require("@scure/bip39");
|
|
20
20
|
const helpers_1 = require("./helpers");
|
|
21
21
|
/**
|
|
22
22
|
* holds the spending key, create proof and signature for spend descriptions
|
|
@@ -14,7 +14,7 @@ var _InMemoryViewingKey_fullViewingKey;
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.InMemoryViewingKey = void 0;
|
|
16
16
|
const utils_1 = require("@taquito/utils");
|
|
17
|
-
const sapling = require("@
|
|
17
|
+
const sapling = require("@taquito/sapling-wasm");
|
|
18
18
|
const helpers_1 = require("./helpers");
|
|
19
19
|
/**
|
|
20
20
|
* Holds the viewing key
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SaplingWrapper = void 0;
|
|
4
|
-
const sapling = require("@
|
|
5
|
-
const random_1 = require("@stablelib/random");
|
|
4
|
+
const sapling = require("@taquito/sapling-wasm");
|
|
6
5
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
7
6
|
const saplingOutputParams = require('../saplingOutputParams');
|
|
8
7
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
9
|
-
const saplingSpendParams = require('
|
|
8
|
+
const saplingSpendParams = require('@taquito/sapling-spend-params');
|
|
10
9
|
let cachedParams;
|
|
10
|
+
const getRandomValueSource = () => {
|
|
11
|
+
const crypto = globalThis.crypto;
|
|
12
|
+
if (!crypto?.getRandomValues) {
|
|
13
|
+
throw new Error('Sapling randomness requires globalThis.crypto.getRandomValues');
|
|
14
|
+
}
|
|
15
|
+
return crypto;
|
|
16
|
+
};
|
|
11
17
|
class SaplingWrapper {
|
|
12
18
|
async withProvingContext(action) {
|
|
13
19
|
await this.initSaplingParameters();
|
|
14
20
|
return sapling.withProvingContext(action);
|
|
15
21
|
}
|
|
16
22
|
getRandomBytes(length) {
|
|
17
|
-
|
|
23
|
+
const bytes = new Uint8Array(length);
|
|
24
|
+
getRandomValueSource().getRandomValues(bytes);
|
|
25
|
+
return bytes;
|
|
18
26
|
}
|
|
19
27
|
async randR() {
|
|
20
28
|
return sapling.randR();
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.SaplingState = void 0;
|
|
9
9
|
const errors_1 = require("../errors");
|
|
10
|
-
const sapling_wasm_1 = require("@
|
|
10
|
+
const sapling_wasm_1 = require("@taquito/sapling-wasm");
|
|
11
11
|
const utils_1 = require("./utils");
|
|
12
12
|
const utils_2 = require("@taquito/utils");
|
|
13
13
|
const bignumber_js_1 = require("bignumber.js");
|
|
14
|
+
const BigNumber = bignumber_js_1.default;
|
|
14
15
|
/**
|
|
15
16
|
* 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
|
|
16
17
|
*
|
|
@@ -130,7 +131,7 @@ class SaplingState {
|
|
|
130
131
|
}
|
|
131
132
|
else {
|
|
132
133
|
let nextPos, nextTree, otherTree;
|
|
133
|
-
const fullTree = new
|
|
134
|
+
const fullTree = new BigNumber(2).pow(height - 1);
|
|
134
135
|
if (position.lt(fullTree)) {
|
|
135
136
|
nextPos = position;
|
|
136
137
|
nextTree = tree[1];
|
|
@@ -17,6 +17,7 @@ const blakejs_1 = require("blakejs");
|
|
|
17
17
|
const nacl_1 = require("@stablelib/nacl");
|
|
18
18
|
const constants_1 = require("../constants");
|
|
19
19
|
const bignumber_js_1 = require("bignumber.js");
|
|
20
|
+
const BigNumber = bignumber_js_1.default;
|
|
20
21
|
const utils_1 = require("@taquito/utils");
|
|
21
22
|
const helpers_1 = require("../sapling-tx-viewer/helpers");
|
|
22
23
|
const sapling_state_1 = require("../sapling-state/sapling-state");
|
|
@@ -85,9 +86,9 @@ class SaplingTransactionBuilder {
|
|
|
85
86
|
const outputs = [];
|
|
86
87
|
const inputs = [];
|
|
87
88
|
inputs.push(...(await this.prepareSaplingSpendDescription(saplingContext, chosenInputs.inputsToSpend)));
|
|
88
|
-
let sumAmountOutput = new
|
|
89
|
+
let sumAmountOutput = new BigNumber(0);
|
|
89
90
|
for (const i in saplingTransactionParams) {
|
|
90
|
-
sumAmountOutput = sumAmountOutput.plus(new
|
|
91
|
+
sumAmountOutput = sumAmountOutput.plus(new BigNumber(saplingTransactionParams[i].amount));
|
|
91
92
|
const [address] = (0, utils_1.b58DecodeAndCheckPrefix)(saplingTransactionParams[i].to, [
|
|
92
93
|
utils_1.PrefixV2.SaplingAddress,
|
|
93
94
|
]);
|
|
@@ -111,7 +112,7 @@ class SaplingTransactionBuilder {
|
|
|
111
112
|
randomCommitmentTrapdoor: randomCommitmentTrapdoor,
|
|
112
113
|
outgoingViewingKey: outgoingViewingKey,
|
|
113
114
|
}, chosenInputs.sumSelectedInputs);
|
|
114
|
-
sumAmountOutput = sumAmountOutput.plus(new
|
|
115
|
+
sumAmountOutput = sumAmountOutput.plus(new BigNumber(payBackAmount));
|
|
115
116
|
outputs.push(payBackOutput);
|
|
116
117
|
}
|
|
117
118
|
const balance = this.calculateTransactionBalance(chosenInputs.sumSelectedInputs.toString(), sumAmountOutput.toString());
|
|
@@ -133,7 +134,7 @@ class SaplingTransactionBuilder {
|
|
|
133
134
|
}
|
|
134
135
|
// sum of values of inputs minus sums of values of output equals balance
|
|
135
136
|
calculateTransactionBalance(inputTotal, outputTotal) {
|
|
136
|
-
return new
|
|
137
|
+
return new BigNumber(inputTotal).minus(new BigNumber(outputTotal));
|
|
137
138
|
}
|
|
138
139
|
async prepareSaplingOutputDescription(parametersOutputDescription) {
|
|
139
140
|
const ephemeralPrivateKey = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
|
|
@@ -186,7 +187,7 @@ class SaplingTransactionBuilder {
|
|
|
186
187
|
const saplingSpendDescriptions = [];
|
|
187
188
|
for (let i = 0; i < inputsToSpend.length; i++) {
|
|
188
189
|
const amount = (0, helpers_1.convertValueToBigNumber)(inputsToSpend[i].value).toString();
|
|
189
|
-
const witness = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getWitness(stateTree, new
|
|
190
|
+
const witness = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getWitness(stateTree, new BigNumber(inputsToSpend[i].position));
|
|
190
191
|
const unsignedSpendDescription = __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f")
|
|
191
192
|
? await __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f").prepareSpendDescription({
|
|
192
193
|
saplingContext,
|
|
@@ -13,8 +13,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _SaplingTransactionViewer_viewingKeyProvider, _SaplingTransactionViewer_readProvider, _SaplingTransactionViewer_saplingContractId;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.SaplingTransactionViewer = void 0;
|
|
16
|
-
const sapling = require("@
|
|
16
|
+
const sapling = require("@taquito/sapling-wasm");
|
|
17
17
|
const bignumber_js_1 = require("bignumber.js");
|
|
18
|
+
const BigNumber = bignumber_js_1.default;
|
|
18
19
|
const utils_1 = require("@taquito/utils");
|
|
19
20
|
const blakejs_1 = require("blakejs");
|
|
20
21
|
const nacl_1 = require("@stablelib/nacl");
|
|
@@ -44,7 +45,7 @@ class SaplingTransactionViewer {
|
|
|
44
45
|
*
|
|
45
46
|
*/
|
|
46
47
|
async getBalance() {
|
|
47
|
-
let balance = new
|
|
48
|
+
let balance = new BigNumber(0);
|
|
48
49
|
const { commitments_and_ciphertexts, nullifiers } = await this.getSaplingDiff();
|
|
49
50
|
for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
|
|
50
51
|
const decrypted = await this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
|
|
@@ -18,6 +18,7 @@ var _SaplingToolkit_inMemorySpendingKey, _SaplingToolkit_saplingId, _SaplingTool
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.SaplingToolkit = exports.InMemoryProvingKey = exports.InMemorySpendingKey = exports.InMemoryViewingKey = exports.SaplingTransactionViewer = void 0;
|
|
20
20
|
const bignumber_js_1 = require("bignumber.js");
|
|
21
|
+
const BigNumber = bignumber_js_1.default;
|
|
21
22
|
const taquito_1 = require("@taquito/taquito");
|
|
22
23
|
const utils_1 = require("@taquito/utils");
|
|
23
24
|
const errors_1 = require("./errors");
|
|
@@ -122,7 +123,7 @@ class SaplingToolkit {
|
|
|
122
123
|
const { formatedParams, totalAmount } = this.formatTransactionParams([unshieldedTxParams], this.validateDestinationImplicitAddress);
|
|
123
124
|
const boundData = await this.createBoundData(formatedParams[0].to);
|
|
124
125
|
const root = await this.getRoot();
|
|
125
|
-
const chosenInputs = await this.selectInputsToSpend(new
|
|
126
|
+
const chosenInputs = await this.selectInputsToSpend(new BigNumber(formatedParams[0].amount));
|
|
126
127
|
const { inputs, outputs, signature, balance } = await __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createSaplingTx([], totalAmount, boundData, chosenInputs);
|
|
127
128
|
const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
|
|
128
129
|
inputs,
|
|
@@ -159,13 +160,13 @@ class SaplingToolkit {
|
|
|
159
160
|
}
|
|
160
161
|
formatTransactionParams(txParams, validateDestination) {
|
|
161
162
|
const formatedParams = [];
|
|
162
|
-
let totalAmount = new
|
|
163
|
+
let totalAmount = new BigNumber(0);
|
|
163
164
|
txParams.forEach((param) => {
|
|
164
165
|
validateDestination(param.to);
|
|
165
166
|
const amountMutez = param.mutez
|
|
166
167
|
? param.amount.toString()
|
|
167
168
|
: (0, utils_1.format)('tz', 'mutez', param.amount).toString();
|
|
168
|
-
totalAmount = totalAmount.plus(new
|
|
169
|
+
totalAmount = totalAmount.plus(new BigNumber(amountMutez));
|
|
169
170
|
const memo = param.memo ?? constants_1.DEFAULT_MEMO;
|
|
170
171
|
if (memo.length > __classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")) {
|
|
171
172
|
throw new errors_1.InvalidMemo(memo, `expecting length to be less than ${__classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")}`);
|
|
@@ -220,7 +221,7 @@ class SaplingToolkit {
|
|
|
220
221
|
const saplingTxViewer = await this.getSaplingTransactionViewer();
|
|
221
222
|
const { incoming } = await saplingTxViewer.getIncomingAndOutgoingTransactionsRaw();
|
|
222
223
|
const inputsToSpend = [];
|
|
223
|
-
let sumSelectedInputs = new
|
|
224
|
+
let sumSelectedInputs = new BigNumber(0);
|
|
224
225
|
incoming.forEach((input) => {
|
|
225
226
|
if (!input.isSpent && sumSelectedInputs.isLessThan(amountMutez)) {
|
|
226
227
|
const txAmount = (0, helpers_1.convertValueToBigNumber)(input.value);
|
|
@@ -229,7 +230,7 @@ class SaplingToolkit {
|
|
|
229
230
|
inputsToSpend.push(rest);
|
|
230
231
|
}
|
|
231
232
|
});
|
|
232
|
-
if (sumSelectedInputs.isLessThan(new
|
|
233
|
+
if (sumSelectedInputs.isLessThan(new BigNumber(amountMutez))) {
|
|
233
234
|
throw new errors_1.InsufficientBalance(sumSelectedInputs.toString(), amountMutez.toString());
|
|
234
235
|
}
|
|
235
236
|
return { inputsToSpend, sumSelectedInputs };
|
package/dist/lib/types.js
CHANGED
package/dist/lib/version.js
CHANGED
|
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VERSION = void 0;
|
|
4
4
|
// IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT!
|
|
5
5
|
exports.VERSION = {
|
|
6
|
-
"commitHash": "
|
|
7
|
-
"version": "24.3.0-beta.
|
|
6
|
+
"commitHash": "a312cd3f4fc0ab0fb3351bfffe6ad855772cb077",
|
|
7
|
+
"version": "24.3.0-beta.3"
|
|
8
8
|
};
|