@taquito/sapling 24.3.0-rc.1 → 24.3.0-rc.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/SAPLING_PARAMS_PROVENANCE.md +16 -10
- package/dist/lib/sapling-module-wrapper.js +3 -12
- package/dist/lib/sapling-params-loader.js +180 -0
- package/dist/lib/sapling-params-manifest.json +15 -0
- package/dist/lib/taquito-sapling.js +5 -1
- package/dist/lib/version.js +2 -2
- package/dist/taquito-sapling.es6.js +189 -21
- package/dist/taquito-sapling.es6.js.map +1 -1
- package/dist/taquito-sapling.umd.js +194 -21
- package/dist/taquito-sapling.umd.js.map +1 -1
- package/dist/types/sapling-params-loader.d.ts +9 -0
- package/dist/types/taquito-sapling.d.ts +2 -0
- package/dist/types/types.d.ts +28 -0
- package/package.json +9 -10
- package/src/sapling-params-manifest.json +15 -0
- package/dist/lib/sapling-output-params.js +0 -12
- package/dist/types/sapling-output-params.d.ts +0 -6
- package/saplingOutputParams.d.ts +0 -5
- package/saplingOutputParams.js +0 -16
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
## Sapling Parameter Provenance
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Taquito now treats the Sapling proving parameters as immutable release artifacts served from the first-party host at `https://sapling.taquito.io`, not as vendored package payloads.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Original source:
|
|
6
6
|
- `https://download.z.cash/downloads/sapling-spend.params`
|
|
7
7
|
- `https://download.z.cash/downloads/sapling-output.params`
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Hosted release paths:
|
|
10
|
+
- `https://sapling.taquito.io/params/groth16-mainnet-1/spend.params`
|
|
11
|
+
- `https://sapling.taquito.io/params/groth16-mainnet-1/output.params`
|
|
12
|
+
- `https://sapling.taquito.io/manifests/groth16-mainnet-1.json`
|
|
13
|
+
|
|
14
|
+
Pinned verification data:
|
|
10
15
|
- `sapling-spend.params`
|
|
11
16
|
- Size: `47,958,396` bytes
|
|
12
17
|
- SHA-256: `8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13`
|
|
@@ -14,11 +19,12 @@ Verification data:
|
|
|
14
19
|
- Size: `3,592,860` bytes
|
|
15
20
|
- SHA-256: `2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4`
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
22
|
+
Release source of truth:
|
|
23
|
+
- the pinned manifest lives in `src/sapling-params-manifest.json`
|
|
24
|
+
- `src/sapling-params-loader.ts` imports that manifest for the default runtime URLs and digests
|
|
25
|
+
- `prepare-sapling-release-artifacts.js` emits the exact upload set for the current parameter version
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
27
|
+
Operational note:
|
|
28
|
+
- upload only immutable, versioned objects
|
|
29
|
+
- verify the public bytes against the pinned hashes after upload
|
|
30
|
+
- the Cloudflare rollout and verification steps are documented in `docs/infra/sapling-cloudflare-r2-rollout.md`
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SaplingWrapper = void 0;
|
|
4
|
-
const buffer_1 = require("buffer");
|
|
5
4
|
const sapling = require("./sapling-wasm");
|
|
6
|
-
const
|
|
7
|
-
const sapling_spend_params_1 = require("@taquito/sapling-spend-params");
|
|
8
|
-
let cachedParams;
|
|
5
|
+
const sapling_params_loader_1 = require("./sapling-params-loader");
|
|
9
6
|
const getRandomValueSource = () => {
|
|
10
7
|
const crypto = globalThis.crypto;
|
|
11
8
|
if (!crypto?.getRandomValues) {
|
|
@@ -15,7 +12,7 @@ const getRandomValueSource = () => {
|
|
|
15
12
|
};
|
|
16
13
|
class SaplingWrapper {
|
|
17
14
|
async withProvingContext(action) {
|
|
18
|
-
await
|
|
15
|
+
await (0, sapling_params_loader_1.preloadSaplingParams)();
|
|
19
16
|
return sapling.withProvingContext(action);
|
|
20
17
|
}
|
|
21
18
|
getRandomBytes(length) {
|
|
@@ -53,13 +50,7 @@ class SaplingWrapper {
|
|
|
53
50
|
return sapling.createBindingSignature(saplingContext, balance, transactionSigHash);
|
|
54
51
|
}
|
|
55
52
|
async initSaplingParameters() {
|
|
56
|
-
|
|
57
|
-
cachedParams = {
|
|
58
|
-
spend: buffer_1.Buffer.from(sapling_spend_params_1.default.saplingSpendParams, 'base64'),
|
|
59
|
-
output: buffer_1.Buffer.from(sapling_output_params_1.default.saplingOutputParams, 'base64'),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
return sapling.initParameters(cachedParams.spend, cachedParams.output);
|
|
53
|
+
return (0, sapling_params_loader_1.preloadSaplingParams)();
|
|
63
54
|
}
|
|
64
55
|
}
|
|
65
56
|
exports.SaplingWrapper = SaplingWrapper;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SaplingParamsError = void 0;
|
|
4
|
+
exports.initSapling = initSapling;
|
|
5
|
+
exports.preloadSaplingParams = preloadSaplingParams;
|
|
6
|
+
const buffer_1 = require("buffer");
|
|
7
|
+
const sapling = require("./sapling-wasm");
|
|
8
|
+
const sapling_params_manifest_json_1 = require("./sapling-params-manifest.json");
|
|
9
|
+
const DEFAULT_SAPLING_PARAMS_MANIFEST = sapling_params_manifest_json_1.default;
|
|
10
|
+
class SaplingParamsError extends Error {
|
|
11
|
+
constructor(code, message, source, cause) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.source = source;
|
|
15
|
+
this.name = 'SaplingParamsError';
|
|
16
|
+
this.cause = cause;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.SaplingParamsError = SaplingParamsError;
|
|
20
|
+
let configuredSaplingParamsSource;
|
|
21
|
+
let frozenSaplingParamsSource;
|
|
22
|
+
let loadedSaplingParams;
|
|
23
|
+
let saplingParamsLoadPromise;
|
|
24
|
+
let saplingParamsInitPromise;
|
|
25
|
+
async function initSapling(options = {}) {
|
|
26
|
+
const nextSource = resolveSaplingParamsSource(options.params);
|
|
27
|
+
if (frozenSaplingParamsSource || saplingParamsLoadPromise || saplingParamsInitPromise) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
configuredSaplingParamsSource = nextSource;
|
|
31
|
+
}
|
|
32
|
+
async function preloadSaplingParams() {
|
|
33
|
+
if (!saplingParamsInitPromise) {
|
|
34
|
+
saplingParamsInitPromise = initializeSaplingParams().catch((error) => {
|
|
35
|
+
saplingParamsInitPromise = undefined;
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return saplingParamsInitPromise;
|
|
40
|
+
}
|
|
41
|
+
async function initializeSaplingParams() {
|
|
42
|
+
const { spend, output } = await loadSaplingParams();
|
|
43
|
+
await sapling.initParameters(spend, output);
|
|
44
|
+
}
|
|
45
|
+
async function loadSaplingParams() {
|
|
46
|
+
if (loadedSaplingParams) {
|
|
47
|
+
return loadedSaplingParams;
|
|
48
|
+
}
|
|
49
|
+
if (!saplingParamsLoadPromise) {
|
|
50
|
+
const source = frozenSaplingParamsSource ?? configuredSaplingParamsSource ?? resolveSaplingParamsSource();
|
|
51
|
+
saplingParamsLoadPromise = loadSaplingParamsFromSource(source)
|
|
52
|
+
.then((params) => {
|
|
53
|
+
frozenSaplingParamsSource = source;
|
|
54
|
+
loadedSaplingParams = params;
|
|
55
|
+
return params;
|
|
56
|
+
})
|
|
57
|
+
.catch((error) => {
|
|
58
|
+
saplingParamsLoadPromise = undefined;
|
|
59
|
+
throw error;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return saplingParamsLoadPromise;
|
|
63
|
+
}
|
|
64
|
+
async function loadSaplingParamsFromSource(source) {
|
|
65
|
+
if (source.kind === 'local') {
|
|
66
|
+
const [spend, output] = await Promise.all([
|
|
67
|
+
loadLocalParam(source.spend.path, source.spend.sha256, 'spend', source.source),
|
|
68
|
+
loadLocalParam(source.output.path, source.output.sha256, 'output', source.source),
|
|
69
|
+
]);
|
|
70
|
+
return { spend, output };
|
|
71
|
+
}
|
|
72
|
+
const [spend, output] = await Promise.all([
|
|
73
|
+
loadRemoteParam(source.spend.url, source.spend.sha256, 'spend', source.source),
|
|
74
|
+
loadRemoteParam(source.output.url, source.output.sha256, 'output', source.source),
|
|
75
|
+
]);
|
|
76
|
+
return { spend, output };
|
|
77
|
+
}
|
|
78
|
+
async function loadRemoteParam(url, expectedSha256, label, source) {
|
|
79
|
+
let response;
|
|
80
|
+
try {
|
|
81
|
+
response = await fetch(url);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new SaplingParamsError('SAPLING_PARAMS_FETCH_FAILED', `Failed to fetch Sapling ${label} params from ${url}`, source, error);
|
|
85
|
+
}
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new SaplingParamsError('SAPLING_PARAMS_FETCH_FAILED', `Failed to fetch Sapling ${label} params from ${url}: ${response.status}`, source);
|
|
88
|
+
}
|
|
89
|
+
const bytes = buffer_1.Buffer.from(await response.arrayBuffer());
|
|
90
|
+
await assertSha256(bytes, expectedSha256, label, source, url);
|
|
91
|
+
return bytes;
|
|
92
|
+
}
|
|
93
|
+
async function loadLocalParam(path, expectedSha256, label, source) {
|
|
94
|
+
if (!isNodeLikeRuntime()) {
|
|
95
|
+
throw new SaplingParamsError('SAPLING_PARAMS_UNSUPPORTED_RUNTIME', `Sapling local ${label} params are only supported in Node.js and CI environments`, source);
|
|
96
|
+
}
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
98
|
+
const { readFile } = require(getNodeFsPromisesModuleId());
|
|
99
|
+
const bytes = buffer_1.Buffer.from(await readFile(path));
|
|
100
|
+
if (expectedSha256) {
|
|
101
|
+
await assertSha256(bytes, expectedSha256, label, source, path);
|
|
102
|
+
}
|
|
103
|
+
return bytes;
|
|
104
|
+
}
|
|
105
|
+
async function assertSha256(bytes, expectedSha256, label, source, location) {
|
|
106
|
+
const subtle = globalThis.crypto?.subtle;
|
|
107
|
+
if (!subtle) {
|
|
108
|
+
throw new SaplingParamsError('SAPLING_PARAMS_UNSUPPORTED_RUNTIME', `Sapling ${label} params verification requires globalThis.crypto.subtle`, source);
|
|
109
|
+
}
|
|
110
|
+
const digest = await subtle.digest('SHA-256', Uint8Array.from(bytes));
|
|
111
|
+
const actualSha256 = buffer_1.Buffer.from(digest).toString('hex');
|
|
112
|
+
if (actualSha256 !== expectedSha256) {
|
|
113
|
+
throw new SaplingParamsError('SAPLING_PARAMS_HASH_MISMATCH', `Sapling ${label} params from ${source} failed integrity verification for ${location} (expected SHA-256 ${expectedSha256}, got ${actualSha256})`, source);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function resolveSaplingParamsSource(params = undefined) {
|
|
117
|
+
if (!params || typeof params.source !== 'undefined') {
|
|
118
|
+
const source = params?.source ?? 'taquito';
|
|
119
|
+
return {
|
|
120
|
+
kind: 'remote',
|
|
121
|
+
source,
|
|
122
|
+
spend: {
|
|
123
|
+
url: source === 'zcash'
|
|
124
|
+
? DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.zcashUrl
|
|
125
|
+
: DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.taquitoUrl,
|
|
126
|
+
sha256: DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.sha256,
|
|
127
|
+
},
|
|
128
|
+
output: {
|
|
129
|
+
url: source === 'zcash'
|
|
130
|
+
? DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.zcashUrl
|
|
131
|
+
: DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.taquitoUrl,
|
|
132
|
+
sha256: DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.sha256,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if ('spendParamsPath' in params || 'outputParamsPath' in params) {
|
|
137
|
+
if (!params.spendParamsPath || !params.outputParamsPath) {
|
|
138
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling local params configuration requires both spendParamsPath and outputParamsPath', 'local');
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
kind: 'local',
|
|
142
|
+
source: 'local',
|
|
143
|
+
spend: {
|
|
144
|
+
path: params.spendParamsPath,
|
|
145
|
+
sha256: params.spendParamsSha256,
|
|
146
|
+
},
|
|
147
|
+
output: {
|
|
148
|
+
path: params.outputParamsPath,
|
|
149
|
+
sha256: params.outputParamsSha256,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (!params.spendParamsUrl || !params.outputParamsUrl) {
|
|
154
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling remote params configuration requires both spendParamsUrl and outputParamsUrl', 'custom');
|
|
155
|
+
}
|
|
156
|
+
if (!params.spendParamsSha256 || !params.outputParamsSha256) {
|
|
157
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling remote params configuration requires explicit SHA-256 digests', 'custom');
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
kind: 'remote',
|
|
161
|
+
source: 'custom',
|
|
162
|
+
spend: {
|
|
163
|
+
url: params.spendParamsUrl,
|
|
164
|
+
sha256: params.spendParamsSha256,
|
|
165
|
+
},
|
|
166
|
+
output: {
|
|
167
|
+
url: params.outputParamsUrl,
|
|
168
|
+
sha256: params.outputParamsSha256,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function isNodeLikeRuntime() {
|
|
173
|
+
const runtimeProcess = globalThis.process;
|
|
174
|
+
return !!runtimeProcess?.versions?.node;
|
|
175
|
+
}
|
|
176
|
+
function getNodeFsPromisesModuleId() {
|
|
177
|
+
// Keep this module id opaque enough that browser bundlers do not eagerly
|
|
178
|
+
// try to resolve a Node-only dependency into the browser build.
|
|
179
|
+
return ['node', 'fs', 'promises'].join(':').replace('fs:promises', 'fs/promises');
|
|
180
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"saplingParamsVersion": "groth16-mainnet-1",
|
|
3
|
+
"spendParams": {
|
|
4
|
+
"sha256": "8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13",
|
|
5
|
+
"bytes": 47958396,
|
|
6
|
+
"taquitoUrl": "https://sapling.taquito.io/params/groth16-mainnet-1/spend.params",
|
|
7
|
+
"zcashUrl": "https://download.z.cash/downloads/sapling-spend.params"
|
|
8
|
+
},
|
|
9
|
+
"outputParams": {
|
|
10
|
+
"sha256": "2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4",
|
|
11
|
+
"bytes": 3592860,
|
|
12
|
+
"taquitoUrl": "https://sapling.taquito.io/params/groth16-mainnet-1/output.params",
|
|
13
|
+
"zcashUrl": "https://download.z.cash/downloads/sapling-output.params"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -16,7 +16,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
16
16
|
};
|
|
17
17
|
var _SaplingToolkit_inMemorySpendingKey, _SaplingToolkit_saplingId, _SaplingToolkit_contractAddress, _SaplingToolkit_memoSize, _SaplingToolkit_readProvider, _SaplingToolkit_packer, _SaplingToolkit_saplingForger, _SaplingToolkit_saplingTxBuilder, _SaplingToolkit_saplingTransactionViewer;
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.SaplingToolkit = exports.InMemoryProvingKey = exports.InMemorySpendingKey = exports.InMemoryViewingKey = exports.SaplingTransactionViewer = void 0;
|
|
19
|
+
exports.SaplingToolkit = exports.InMemoryProvingKey = exports.InMemorySpendingKey = exports.InMemoryViewingKey = exports.SaplingTransactionViewer = exports.SaplingParamsError = exports.preloadSaplingParams = exports.initSapling = void 0;
|
|
20
20
|
const buffer_1 = require("buffer");
|
|
21
21
|
const bignumber_js_1 = require("bignumber.js");
|
|
22
22
|
const BigNumber = bignumber_js_1.default;
|
|
@@ -29,6 +29,10 @@ const sapling_transaction_viewer_1 = require("./sapling-tx-viewer/sapling-transa
|
|
|
29
29
|
const sapling_transactions_builder_1 = require("./sapling-tx-builder/sapling-transactions-builder");
|
|
30
30
|
const constants_1 = require("./constants");
|
|
31
31
|
const core_1 = require("@taquito/core");
|
|
32
|
+
var sapling_params_loader_1 = require("./sapling-params-loader");
|
|
33
|
+
Object.defineProperty(exports, "initSapling", { enumerable: true, get: function () { return sapling_params_loader_1.initSapling; } });
|
|
34
|
+
Object.defineProperty(exports, "preloadSaplingParams", { enumerable: true, get: function () { return sapling_params_loader_1.preloadSaplingParams; } });
|
|
35
|
+
Object.defineProperty(exports, "SaplingParamsError", { enumerable: true, get: function () { return sapling_params_loader_1.SaplingParamsError; } });
|
|
32
36
|
var sapling_transaction_viewer_2 = require("./sapling-tx-viewer/sapling-transaction-viewer");
|
|
33
37
|
Object.defineProperty(exports, "SaplingTransactionViewer", { enumerable: true, get: function () { return sapling_transaction_viewer_2.SaplingTransactionViewer; } });
|
|
34
38
|
var in_memory_viewing_key_1 = require("./sapling-keys/in-memory-viewing-key");
|
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-rc.
|
|
6
|
+
"commitHash": "17a8431576e7c428f69f4bcb79687903a9d354ea",
|
|
7
|
+
"version": "24.3.0-rc.3"
|
|
8
8
|
};
|
|
@@ -2,11 +2,9 @@ import BigNumberJs from 'bignumber.js';
|
|
|
2
2
|
import { MichelCodecPacker } from '@taquito/taquito';
|
|
3
3
|
import { b58Encode, PrefixV2, bytesToString, toHexBuf, stringToBytes, hex2buf, mergebuf, hex2Bytes, num2PaddedHex, b58DecodeAndCheckPrefix, format, b58DecodePublicKeyHash, validateKeyHash, ValidationResult } from '@taquito/utils';
|
|
4
4
|
import { ParameterValidationError, TaquitoError, InvalidKeyHashError, InvalidAddressError } from '@taquito/core';
|
|
5
|
-
import { keyAgreement, getRawPaymentAddressFromIncomingViewingKey, verifyCommitment, computeNullifier, merkleHash, withProvingContext, randR, getOutgoingViewingKey, preparePartialOutputDescription, getDiversifiedFromRawPaymentAddress, deriveEphemeralPublicKey, getPkdFromRawPaymentAddress, createBindingSignature,
|
|
5
|
+
import { keyAgreement, getRawPaymentAddressFromIncomingViewingKey, verifyCommitment, computeNullifier, merkleHash, initParameters, withProvingContext, randR, getOutgoingViewingKey, preparePartialOutputDescription, getDiversifiedFromRawPaymentAddress, deriveEphemeralPublicKey, getPkdFromRawPaymentAddress, createBindingSignature, getExtendedFullViewingKeyFromSpendingKey, getIncomingViewingKey, getPaymentAddressFromViewingKey, getExtendedSpendingKey, prepareSpendDescriptionWithSpendingKey, signSpendDescription, getProofAuthorizingKey, prepareSpendDescriptionWithAuthorizingKey } from '@taquito/sapling-wasm';
|
|
6
6
|
import blake from 'blakejs';
|
|
7
7
|
import { openSecretBox, secretBox } from '@stablelib/nacl';
|
|
8
|
-
import '../saplingOutputParams.js';
|
|
9
|
-
import saplingSpendParams from '@taquito/sapling-spend-params';
|
|
10
8
|
import toBuffer from 'typedarray-to-buffer';
|
|
11
9
|
|
|
12
10
|
/******************************************************************************
|
|
@@ -2969,17 +2967,193 @@ class SaplingState {
|
|
|
2969
2967
|
}
|
|
2970
2968
|
}
|
|
2971
2969
|
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2970
|
+
var spendParams = {
|
|
2971
|
+
sha256: "8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13",
|
|
2972
|
+
taquitoUrl: "https://sapling.taquito.io/params/groth16-mainnet-1/spend.params",
|
|
2973
|
+
zcashUrl: "https://download.z.cash/downloads/sapling-spend.params"
|
|
2974
|
+
};
|
|
2975
|
+
var outputParams = {
|
|
2976
|
+
sha256: "2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4",
|
|
2977
|
+
taquitoUrl: "https://sapling.taquito.io/params/groth16-mainnet-1/output.params",
|
|
2978
|
+
zcashUrl: "https://download.z.cash/downloads/sapling-output.params"
|
|
2979
|
+
};
|
|
2980
|
+
var saplingParamsManifest = {
|
|
2981
|
+
spendParams: spendParams,
|
|
2982
|
+
outputParams: outputParams
|
|
2979
2983
|
};
|
|
2980
|
-
var saplingOutputParams = loadSaplingOutputParams();
|
|
2981
2984
|
|
|
2982
|
-
|
|
2985
|
+
const DEFAULT_SAPLING_PARAMS_MANIFEST = saplingParamsManifest;
|
|
2986
|
+
class SaplingParamsError extends Error {
|
|
2987
|
+
constructor(code, message, source, cause) {
|
|
2988
|
+
super(message);
|
|
2989
|
+
this.code = code;
|
|
2990
|
+
this.source = source;
|
|
2991
|
+
this.name = 'SaplingParamsError';
|
|
2992
|
+
this.cause = cause;
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
let configuredSaplingParamsSource;
|
|
2996
|
+
let frozenSaplingParamsSource;
|
|
2997
|
+
let loadedSaplingParams;
|
|
2998
|
+
let saplingParamsLoadPromise;
|
|
2999
|
+
let saplingParamsInitPromise;
|
|
3000
|
+
async function initSapling(options = {}) {
|
|
3001
|
+
const nextSource = resolveSaplingParamsSource(options.params);
|
|
3002
|
+
if (frozenSaplingParamsSource || saplingParamsLoadPromise || saplingParamsInitPromise) {
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
configuredSaplingParamsSource = nextSource;
|
|
3006
|
+
}
|
|
3007
|
+
async function preloadSaplingParams() {
|
|
3008
|
+
if (!saplingParamsInitPromise) {
|
|
3009
|
+
saplingParamsInitPromise = initializeSaplingParams().catch((error) => {
|
|
3010
|
+
saplingParamsInitPromise = undefined;
|
|
3011
|
+
throw error;
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3014
|
+
return saplingParamsInitPromise;
|
|
3015
|
+
}
|
|
3016
|
+
async function initializeSaplingParams() {
|
|
3017
|
+
const { spend, output } = await loadSaplingParams();
|
|
3018
|
+
await initParameters(spend, output);
|
|
3019
|
+
}
|
|
3020
|
+
async function loadSaplingParams() {
|
|
3021
|
+
if (loadedSaplingParams) {
|
|
3022
|
+
return loadedSaplingParams;
|
|
3023
|
+
}
|
|
3024
|
+
if (!saplingParamsLoadPromise) {
|
|
3025
|
+
const source = frozenSaplingParamsSource ?? configuredSaplingParamsSource ?? resolveSaplingParamsSource();
|
|
3026
|
+
saplingParamsLoadPromise = loadSaplingParamsFromSource(source)
|
|
3027
|
+
.then((params) => {
|
|
3028
|
+
frozenSaplingParamsSource = source;
|
|
3029
|
+
loadedSaplingParams = params;
|
|
3030
|
+
return params;
|
|
3031
|
+
})
|
|
3032
|
+
.catch((error) => {
|
|
3033
|
+
saplingParamsLoadPromise = undefined;
|
|
3034
|
+
throw error;
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
3037
|
+
return saplingParamsLoadPromise;
|
|
3038
|
+
}
|
|
3039
|
+
async function loadSaplingParamsFromSource(source) {
|
|
3040
|
+
if (source.kind === 'local') {
|
|
3041
|
+
const [spend, output] = await Promise.all([
|
|
3042
|
+
loadLocalParam(source.spend.path, source.spend.sha256, 'spend', source.source),
|
|
3043
|
+
loadLocalParam(source.output.path, source.output.sha256, 'output', source.source),
|
|
3044
|
+
]);
|
|
3045
|
+
return { spend, output };
|
|
3046
|
+
}
|
|
3047
|
+
const [spend, output] = await Promise.all([
|
|
3048
|
+
loadRemoteParam(source.spend.url, source.spend.sha256, 'spend', source.source),
|
|
3049
|
+
loadRemoteParam(source.output.url, source.output.sha256, 'output', source.source),
|
|
3050
|
+
]);
|
|
3051
|
+
return { spend, output };
|
|
3052
|
+
}
|
|
3053
|
+
async function loadRemoteParam(url, expectedSha256, label, source) {
|
|
3054
|
+
let response;
|
|
3055
|
+
try {
|
|
3056
|
+
response = await fetch(url);
|
|
3057
|
+
}
|
|
3058
|
+
catch (error) {
|
|
3059
|
+
throw new SaplingParamsError('SAPLING_PARAMS_FETCH_FAILED', `Failed to fetch Sapling ${label} params from ${url}`, source, error);
|
|
3060
|
+
}
|
|
3061
|
+
if (!response.ok) {
|
|
3062
|
+
throw new SaplingParamsError('SAPLING_PARAMS_FETCH_FAILED', `Failed to fetch Sapling ${label} params from ${url}: ${response.status}`, source);
|
|
3063
|
+
}
|
|
3064
|
+
const bytes = bufferExports.Buffer.from(await response.arrayBuffer());
|
|
3065
|
+
await assertSha256(bytes, expectedSha256, label, source, url);
|
|
3066
|
+
return bytes;
|
|
3067
|
+
}
|
|
3068
|
+
async function loadLocalParam(path, expectedSha256, label, source) {
|
|
3069
|
+
if (!isNodeLikeRuntime()) {
|
|
3070
|
+
throw new SaplingParamsError('SAPLING_PARAMS_UNSUPPORTED_RUNTIME', `Sapling local ${label} params are only supported in Node.js and CI environments`, source);
|
|
3071
|
+
}
|
|
3072
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
3073
|
+
const { readFile } = require(getNodeFsPromisesModuleId());
|
|
3074
|
+
const bytes = bufferExports.Buffer.from(await readFile(path));
|
|
3075
|
+
if (expectedSha256) {
|
|
3076
|
+
await assertSha256(bytes, expectedSha256, label, source, path);
|
|
3077
|
+
}
|
|
3078
|
+
return bytes;
|
|
3079
|
+
}
|
|
3080
|
+
async function assertSha256(bytes, expectedSha256, label, source, location) {
|
|
3081
|
+
const subtle = globalThis.crypto?.subtle;
|
|
3082
|
+
if (!subtle) {
|
|
3083
|
+
throw new SaplingParamsError('SAPLING_PARAMS_UNSUPPORTED_RUNTIME', `Sapling ${label} params verification requires globalThis.crypto.subtle`, source);
|
|
3084
|
+
}
|
|
3085
|
+
const digest = await subtle.digest('SHA-256', Uint8Array.from(bytes));
|
|
3086
|
+
const actualSha256 = bufferExports.Buffer.from(digest).toString('hex');
|
|
3087
|
+
if (actualSha256 !== expectedSha256) {
|
|
3088
|
+
throw new SaplingParamsError('SAPLING_PARAMS_HASH_MISMATCH', `Sapling ${label} params from ${source} failed integrity verification for ${location} (expected SHA-256 ${expectedSha256}, got ${actualSha256})`, source);
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
function resolveSaplingParamsSource(params = undefined) {
|
|
3092
|
+
if (!params || typeof params.source !== 'undefined') {
|
|
3093
|
+
const source = params?.source ?? 'taquito';
|
|
3094
|
+
return {
|
|
3095
|
+
kind: 'remote',
|
|
3096
|
+
source,
|
|
3097
|
+
spend: {
|
|
3098
|
+
url: source === 'zcash'
|
|
3099
|
+
? DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.zcashUrl
|
|
3100
|
+
: DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.taquitoUrl,
|
|
3101
|
+
sha256: DEFAULT_SAPLING_PARAMS_MANIFEST.spendParams.sha256,
|
|
3102
|
+
},
|
|
3103
|
+
output: {
|
|
3104
|
+
url: source === 'zcash'
|
|
3105
|
+
? DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.zcashUrl
|
|
3106
|
+
: DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.taquitoUrl,
|
|
3107
|
+
sha256: DEFAULT_SAPLING_PARAMS_MANIFEST.outputParams.sha256,
|
|
3108
|
+
},
|
|
3109
|
+
};
|
|
3110
|
+
}
|
|
3111
|
+
if ('spendParamsPath' in params || 'outputParamsPath' in params) {
|
|
3112
|
+
if (!params.spendParamsPath || !params.outputParamsPath) {
|
|
3113
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling local params configuration requires both spendParamsPath and outputParamsPath', 'local');
|
|
3114
|
+
}
|
|
3115
|
+
return {
|
|
3116
|
+
kind: 'local',
|
|
3117
|
+
source: 'local',
|
|
3118
|
+
spend: {
|
|
3119
|
+
path: params.spendParamsPath,
|
|
3120
|
+
sha256: params.spendParamsSha256,
|
|
3121
|
+
},
|
|
3122
|
+
output: {
|
|
3123
|
+
path: params.outputParamsPath,
|
|
3124
|
+
sha256: params.outputParamsSha256,
|
|
3125
|
+
},
|
|
3126
|
+
};
|
|
3127
|
+
}
|
|
3128
|
+
if (!params.spendParamsUrl || !params.outputParamsUrl) {
|
|
3129
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling remote params configuration requires both spendParamsUrl and outputParamsUrl', 'custom');
|
|
3130
|
+
}
|
|
3131
|
+
if (!params.spendParamsSha256 || !params.outputParamsSha256) {
|
|
3132
|
+
throw new SaplingParamsError('SAPLING_PARAMS_INVALID_CONFIG', 'Sapling remote params configuration requires explicit SHA-256 digests', 'custom');
|
|
3133
|
+
}
|
|
3134
|
+
return {
|
|
3135
|
+
kind: 'remote',
|
|
3136
|
+
source: 'custom',
|
|
3137
|
+
spend: {
|
|
3138
|
+
url: params.spendParamsUrl,
|
|
3139
|
+
sha256: params.spendParamsSha256,
|
|
3140
|
+
},
|
|
3141
|
+
output: {
|
|
3142
|
+
url: params.outputParamsUrl,
|
|
3143
|
+
sha256: params.outputParamsSha256,
|
|
3144
|
+
},
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
function isNodeLikeRuntime() {
|
|
3148
|
+
const runtimeProcess = globalThis.process;
|
|
3149
|
+
return !!runtimeProcess?.versions?.node;
|
|
3150
|
+
}
|
|
3151
|
+
function getNodeFsPromisesModuleId() {
|
|
3152
|
+
// Keep this module id opaque enough that browser bundlers do not eagerly
|
|
3153
|
+
// try to resolve a Node-only dependency into the browser build.
|
|
3154
|
+
return ['node', 'fs', 'promises'].join(':').replace('fs:promises', 'fs/promises');
|
|
3155
|
+
}
|
|
3156
|
+
|
|
2983
3157
|
const getRandomValueSource = () => {
|
|
2984
3158
|
const crypto = globalThis.crypto;
|
|
2985
3159
|
if (!crypto?.getRandomValues) {
|
|
@@ -2989,7 +3163,7 @@ const getRandomValueSource = () => {
|
|
|
2989
3163
|
};
|
|
2990
3164
|
class SaplingWrapper {
|
|
2991
3165
|
async withProvingContext(action) {
|
|
2992
|
-
await
|
|
3166
|
+
await preloadSaplingParams();
|
|
2993
3167
|
return withProvingContext(action);
|
|
2994
3168
|
}
|
|
2995
3169
|
getRandomBytes(length) {
|
|
@@ -3027,13 +3201,7 @@ class SaplingWrapper {
|
|
|
3027
3201
|
return createBindingSignature(saplingContext, balance, transactionSigHash);
|
|
3028
3202
|
}
|
|
3029
3203
|
async initSaplingParameters() {
|
|
3030
|
-
|
|
3031
|
-
cachedParams = {
|
|
3032
|
-
spend: bufferExports.Buffer.from(saplingSpendParams.saplingSpendParams, 'base64'),
|
|
3033
|
-
output: bufferExports.Buffer.from(saplingOutputParams.saplingOutputParams, 'base64'),
|
|
3034
|
-
};
|
|
3035
|
-
}
|
|
3036
|
-
return initParameters(cachedParams.spend, cachedParams.output);
|
|
3204
|
+
return preloadSaplingParams();
|
|
3037
3205
|
}
|
|
3038
3206
|
}
|
|
3039
3207
|
|
|
@@ -4422,5 +4590,5 @@ class SaplingToolkit {
|
|
|
4422
4590
|
}
|
|
4423
4591
|
_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();
|
|
4424
4592
|
|
|
4425
|
-
export { InMemoryProvingKey, InMemorySpendingKey, InMemoryViewingKey, SaplingToolkit, SaplingTransactionViewer };
|
|
4593
|
+
export { InMemoryProvingKey, InMemorySpendingKey, InMemoryViewingKey, SaplingParamsError, SaplingToolkit, SaplingTransactionViewer, initSapling, preloadSaplingParams };
|
|
4426
4594
|
//# sourceMappingURL=taquito-sapling.es6.js.map
|