@veil-cash/sdk 0.6.3 → 0.6.5
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 +1 -0
- package/SDK.md +45 -0
- package/dist/cli/index.cjs +149 -92
- package/dist/index.cjs +118 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -64
- package/dist/index.d.ts +102 -64
- package/dist/index.js +99 -48
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/compat.ts +23 -0
- package/src/ffjavascript.d.ts +33 -0
- package/src/index.ts +1 -1
- package/src/keypair.ts +2 -4
- package/src/prover.ts +108 -36
- package/src/subaccount.ts +2 -0
- package/src/transaction.ts +8 -2
- package/src/transfer.ts +5 -1
- package/src/types.ts +21 -0
- package/src/utils.ts +12 -5
- package/src/utxo.ts +1 -0
- package/src/withdraw.ts +2 -0
package/README.md
CHANGED
|
@@ -288,6 +288,7 @@ Commands print human-readable success output by default. Errors are standardized
|
|
|
288
288
|
The CLI is the main entrypoint for most users. If you are integrating Veil programmatically, use the dedicated SDK guide:
|
|
289
289
|
|
|
290
290
|
- [SDK Quick Start and API Reference](./SDK.md)
|
|
291
|
+
- [Browser proof generation](./SDK.md#browser-proof-generation)
|
|
291
292
|
- [AI agent and signer integration notes](./SDK.md#for-ai-agents)
|
|
292
293
|
|
|
293
294
|
## Deposit Flow
|
package/SDK.md
CHANGED
|
@@ -182,6 +182,51 @@ const mergeResult = await mergeUtxos({
|
|
|
182
182
|
});
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
+
### Browser Proof Generation
|
|
186
|
+
|
|
187
|
+
`withdraw()`, `transfer()`, `mergeUtxos()`, `mergeSubaccount()`, `buildWithdrawProof()`,
|
|
188
|
+
`buildTransferProof()`, and `prepareTransaction()` can generate proofs in browser
|
|
189
|
+
runtimes.
|
|
190
|
+
|
|
191
|
+
In Node, the SDK uses the packaged `keys/` directory by default. In browsers,
|
|
192
|
+
the SDK defaults to same-origin hosted proving keys:
|
|
193
|
+
|
|
194
|
+
```text
|
|
195
|
+
/keys/transaction2.wasm
|
|
196
|
+
/keys/transaction2.zkey
|
|
197
|
+
/keys/transaction16.wasm
|
|
198
|
+
/keys/transaction16.zkey
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
For most web apps, copy the SDK `keys/` files into your app's public assets
|
|
202
|
+
directory. For example, in Next.js/Vite, serving them from `public/keys` makes
|
|
203
|
+
the default path work.
|
|
204
|
+
|
|
205
|
+
If you host keys elsewhere, pass `provingKeyPath`:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
await withdraw({
|
|
209
|
+
amount: '0.05',
|
|
210
|
+
recipient: '0xRecipientAddress',
|
|
211
|
+
keypair,
|
|
212
|
+
provingKeyPath: 'https://cdn.example.com/veil-keys',
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
await transfer({
|
|
216
|
+
amount: '0.02',
|
|
217
|
+
recipientAddress: '0xRecipientAddress',
|
|
218
|
+
senderKeypair: keypair,
|
|
219
|
+
provingKeyPath: (circuitName) => `/static/zk/${circuitName}`,
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`provingKeyPath` may be a directory/base URL (`/keys`) or a resolver returning
|
|
224
|
+
the circuit base path without the `.wasm` / `.zkey` extension.
|
|
225
|
+
|
|
226
|
+
This removes Node `fs` key lookup from the browser proof path. Some bundlers
|
|
227
|
+
may still require standard Node-core polyfills for existing legacy dependencies
|
|
228
|
+
such as `circomlib`, `eth-sig-util`, and `fixed-merkle-tree`.
|
|
229
|
+
|
|
185
230
|
### Balance Queries
|
|
186
231
|
|
|
187
232
|
Balance functions accept an optional `pool` parameter (`'eth'` | `'usdc'`), defaulting to `'eth'`.
|
package/dist/cli/index.cjs
CHANGED
|
@@ -8,10 +8,12 @@ var readline = require('readline');
|
|
|
8
8
|
var fs = require('fs');
|
|
9
9
|
var path = require('path');
|
|
10
10
|
var ethers = require('ethers');
|
|
11
|
-
var
|
|
11
|
+
var buffer = require('buffer');
|
|
12
|
+
var _ethSigUtil = require('eth-sig-util');
|
|
13
|
+
var _circomlib = require('circomlib');
|
|
12
14
|
var MerkleTree = require('fixed-merkle-tree-legacy');
|
|
13
15
|
var snarkjs = require('snarkjs');
|
|
14
|
-
var
|
|
16
|
+
var ffjavascript = require('ffjavascript');
|
|
15
17
|
|
|
16
18
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
17
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -34,9 +36,8 @@ function _interopNamespace(e) {
|
|
|
34
36
|
return Object.freeze(n);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
39
|
+
var _ethSigUtil__namespace = /*#__PURE__*/_interopNamespace(_ethSigUtil);
|
|
40
|
+
var _circomlib__namespace = /*#__PURE__*/_interopNamespace(_circomlib);
|
|
40
41
|
var MerkleTree__default = /*#__PURE__*/_interopDefault(MerkleTree);
|
|
41
42
|
|
|
42
43
|
var __create = Object.create;
|
|
@@ -1234,8 +1235,8 @@ var require_command = __commonJS({
|
|
|
1234
1235
|
"node_modules/commander/lib/command.js"(exports$1) {
|
|
1235
1236
|
var EventEmitter = __require("events").EventEmitter;
|
|
1236
1237
|
var childProcess = __require("child_process");
|
|
1237
|
-
var
|
|
1238
|
-
var
|
|
1238
|
+
var path = __require("path");
|
|
1239
|
+
var fs = __require("fs");
|
|
1239
1240
|
var process2 = __require("process");
|
|
1240
1241
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1241
1242
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -2228,7 +2229,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2228
2229
|
* @param {string} subcommandName
|
|
2229
2230
|
*/
|
|
2230
2231
|
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
2231
|
-
if (
|
|
2232
|
+
if (fs.existsSync(executableFile)) return;
|
|
2232
2233
|
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
|
|
2233
2234
|
const executableMissing = `'${executableFile}' does not exist
|
|
2234
2235
|
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
@@ -2246,11 +2247,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2246
2247
|
let launchWithNode = false;
|
|
2247
2248
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2248
2249
|
function findFile(baseDir, baseName) {
|
|
2249
|
-
const localBin =
|
|
2250
|
-
if (
|
|
2251
|
-
if (sourceExt.includes(
|
|
2250
|
+
const localBin = path.resolve(baseDir, baseName);
|
|
2251
|
+
if (fs.existsSync(localBin)) return localBin;
|
|
2252
|
+
if (sourceExt.includes(path.extname(baseName))) return void 0;
|
|
2252
2253
|
const foundExt = sourceExt.find(
|
|
2253
|
-
(ext) =>
|
|
2254
|
+
(ext) => fs.existsSync(`${localBin}${ext}`)
|
|
2254
2255
|
);
|
|
2255
2256
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
2256
2257
|
return void 0;
|
|
@@ -2262,21 +2263,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2262
2263
|
if (this._scriptPath) {
|
|
2263
2264
|
let resolvedScriptPath;
|
|
2264
2265
|
try {
|
|
2265
|
-
resolvedScriptPath =
|
|
2266
|
+
resolvedScriptPath = fs.realpathSync(this._scriptPath);
|
|
2266
2267
|
} catch {
|
|
2267
2268
|
resolvedScriptPath = this._scriptPath;
|
|
2268
2269
|
}
|
|
2269
|
-
executableDir =
|
|
2270
|
-
|
|
2270
|
+
executableDir = path.resolve(
|
|
2271
|
+
path.dirname(resolvedScriptPath),
|
|
2271
2272
|
executableDir
|
|
2272
2273
|
);
|
|
2273
2274
|
}
|
|
2274
2275
|
if (executableDir) {
|
|
2275
2276
|
let localFile = findFile(executableDir, executableFile);
|
|
2276
2277
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2277
|
-
const legacyName =
|
|
2278
|
+
const legacyName = path.basename(
|
|
2278
2279
|
this._scriptPath,
|
|
2279
|
-
|
|
2280
|
+
path.extname(this._scriptPath)
|
|
2280
2281
|
);
|
|
2281
2282
|
if (legacyName !== this._name) {
|
|
2282
2283
|
localFile = findFile(
|
|
@@ -2287,7 +2288,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2287
2288
|
}
|
|
2288
2289
|
executableFile = localFile || executableFile;
|
|
2289
2290
|
}
|
|
2290
|
-
launchWithNode = sourceExt.includes(
|
|
2291
|
+
launchWithNode = sourceExt.includes(path.extname(executableFile));
|
|
2291
2292
|
let proc;
|
|
2292
2293
|
if (process2.platform !== "win32") {
|
|
2293
2294
|
if (launchWithNode) {
|
|
@@ -3202,7 +3203,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3202
3203
|
* @return {Command}
|
|
3203
3204
|
*/
|
|
3204
3205
|
nameFromFilename(filename) {
|
|
3205
|
-
this._name =
|
|
3206
|
+
this._name = path.basename(filename, path.extname(filename));
|
|
3206
3207
|
return this;
|
|
3207
3208
|
}
|
|
3208
3209
|
/**
|
|
@@ -3216,9 +3217,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3216
3217
|
* @param {string} [path]
|
|
3217
3218
|
* @return {(string|null|Command)}
|
|
3218
3219
|
*/
|
|
3219
|
-
executableDir(
|
|
3220
|
-
if (
|
|
3221
|
-
this._executableDir =
|
|
3220
|
+
executableDir(path2) {
|
|
3221
|
+
if (path2 === void 0) return this._executableDir;
|
|
3222
|
+
this._executableDir = path2;
|
|
3222
3223
|
return this;
|
|
3223
3224
|
}
|
|
3224
3225
|
/**
|
|
@@ -3567,10 +3568,10 @@ var require_package = __commonJS({
|
|
|
3567
3568
|
// node_modules/dotenv/lib/main.js
|
|
3568
3569
|
var require_main = __commonJS({
|
|
3569
3570
|
"node_modules/dotenv/lib/main.js"(exports$1, module) {
|
|
3570
|
-
var
|
|
3571
|
-
var
|
|
3571
|
+
var fs = __require("fs");
|
|
3572
|
+
var path = __require("path");
|
|
3572
3573
|
var os = __require("os");
|
|
3573
|
-
var
|
|
3574
|
+
var crypto = __require("crypto");
|
|
3574
3575
|
var packageJson = require_package();
|
|
3575
3576
|
var version = packageJson.version;
|
|
3576
3577
|
var TIPS = [
|
|
@@ -3709,7 +3710,7 @@ var require_main = __commonJS({
|
|
|
3709
3710
|
if (options && options.path && options.path.length > 0) {
|
|
3710
3711
|
if (Array.isArray(options.path)) {
|
|
3711
3712
|
for (const filepath of options.path) {
|
|
3712
|
-
if (
|
|
3713
|
+
if (fs.existsSync(filepath)) {
|
|
3713
3714
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
3714
3715
|
}
|
|
3715
3716
|
}
|
|
@@ -3717,15 +3718,15 @@ var require_main = __commonJS({
|
|
|
3717
3718
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
3718
3719
|
}
|
|
3719
3720
|
} else {
|
|
3720
|
-
possibleVaultPath =
|
|
3721
|
+
possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
|
|
3721
3722
|
}
|
|
3722
|
-
if (
|
|
3723
|
+
if (fs.existsSync(possibleVaultPath)) {
|
|
3723
3724
|
return possibleVaultPath;
|
|
3724
3725
|
}
|
|
3725
3726
|
return null;
|
|
3726
3727
|
}
|
|
3727
3728
|
function _resolveHome(envPath) {
|
|
3728
|
-
return envPath[0] === "~" ?
|
|
3729
|
+
return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
3729
3730
|
}
|
|
3730
3731
|
function _configVault(options) {
|
|
3731
3732
|
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
@@ -3742,7 +3743,7 @@ var require_main = __commonJS({
|
|
|
3742
3743
|
return { parsed };
|
|
3743
3744
|
}
|
|
3744
3745
|
function configDotenv(options) {
|
|
3745
|
-
const dotenvPath =
|
|
3746
|
+
const dotenvPath = path.resolve(process.cwd(), ".env");
|
|
3746
3747
|
let encoding = "utf8";
|
|
3747
3748
|
let processEnv = process.env;
|
|
3748
3749
|
if (options && options.processEnv != null) {
|
|
@@ -3770,13 +3771,13 @@ var require_main = __commonJS({
|
|
|
3770
3771
|
}
|
|
3771
3772
|
let lastError;
|
|
3772
3773
|
const parsedAll = {};
|
|
3773
|
-
for (const
|
|
3774
|
+
for (const path2 of optionPaths) {
|
|
3774
3775
|
try {
|
|
3775
|
-
const parsed = DotenvModule.parse(
|
|
3776
|
+
const parsed = DotenvModule.parse(fs.readFileSync(path2, { encoding }));
|
|
3776
3777
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
3777
3778
|
} catch (e) {
|
|
3778
3779
|
if (debug) {
|
|
3779
|
-
_debug(`Failed to load ${
|
|
3780
|
+
_debug(`Failed to load ${path2} ${e.message}`);
|
|
3780
3781
|
}
|
|
3781
3782
|
lastError = e;
|
|
3782
3783
|
}
|
|
@@ -3789,7 +3790,7 @@ var require_main = __commonJS({
|
|
|
3789
3790
|
const shortPaths = [];
|
|
3790
3791
|
for (const filePath of optionPaths) {
|
|
3791
3792
|
try {
|
|
3792
|
-
const relative =
|
|
3793
|
+
const relative = path.relative(process.cwd(), filePath);
|
|
3793
3794
|
shortPaths.push(relative);
|
|
3794
3795
|
} catch (e) {
|
|
3795
3796
|
if (debug) {
|
|
@@ -3824,7 +3825,7 @@ var require_main = __commonJS({
|
|
|
3824
3825
|
const authTag = ciphertext.subarray(-16);
|
|
3825
3826
|
ciphertext = ciphertext.subarray(12, -16);
|
|
3826
3827
|
try {
|
|
3827
|
-
const aesgcm =
|
|
3828
|
+
const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
3828
3829
|
aesgcm.setAuthTag(authTag);
|
|
3829
3830
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
3830
3831
|
} catch (error) {
|
|
@@ -5107,7 +5108,15 @@ function loadEnv() {
|
|
|
5107
5108
|
} catch {
|
|
5108
5109
|
}
|
|
5109
5110
|
}
|
|
5110
|
-
|
|
5111
|
+
function resolveInterop(mod) {
|
|
5112
|
+
if (mod && typeof mod === "object" && "default" in mod) {
|
|
5113
|
+
const defaultVal = mod.default;
|
|
5114
|
+
if (defaultVal != null) return defaultVal;
|
|
5115
|
+
}
|
|
5116
|
+
return mod;
|
|
5117
|
+
}
|
|
5118
|
+
var ethSigUtil = resolveInterop(_ethSigUtil__namespace);
|
|
5119
|
+
var circomlib = resolveInterop(_circomlib__namespace);
|
|
5111
5120
|
var poseidon = circomlib.poseidon;
|
|
5112
5121
|
var FIELD_SIZE = BigInt(
|
|
5113
5122
|
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
|
@@ -5115,7 +5124,11 @@ var FIELD_SIZE = BigInt(
|
|
|
5115
5124
|
var poseidonHash = (items) => BigInt(poseidon(items).toString());
|
|
5116
5125
|
var poseidonHash2 = (a, b) => poseidonHash([a, b]);
|
|
5117
5126
|
var randomBN = (nbytes = 31) => {
|
|
5118
|
-
const
|
|
5127
|
+
const cryptoApi = globalThis.crypto;
|
|
5128
|
+
if (!cryptoApi?.getRandomValues) {
|
|
5129
|
+
throw new Error("Secure random number generation is unavailable in this runtime");
|
|
5130
|
+
}
|
|
5131
|
+
const bytes = cryptoApi.getRandomValues(new Uint8Array(nbytes));
|
|
5119
5132
|
let hex = "0x";
|
|
5120
5133
|
for (let i = 0; i < bytes.length; i++) {
|
|
5121
5134
|
hex += bytes[i].toString(16).padStart(2, "0");
|
|
@@ -5124,7 +5137,7 @@ var randomBN = (nbytes = 31) => {
|
|
|
5124
5137
|
};
|
|
5125
5138
|
function toFixedHex(number, length = 32) {
|
|
5126
5139
|
let hexValue;
|
|
5127
|
-
if (number instanceof Buffer) {
|
|
5140
|
+
if (number instanceof buffer.Buffer) {
|
|
5128
5141
|
hexValue = number.toString("hex");
|
|
5129
5142
|
} else {
|
|
5130
5143
|
let bigIntValue = BigInt(number);
|
|
@@ -5139,11 +5152,10 @@ function toFixedHex(number, length = 32) {
|
|
|
5139
5152
|
var toBuffer = (value, length) => {
|
|
5140
5153
|
const bigIntValue = BigInt(value);
|
|
5141
5154
|
const hex = bigIntValue.toString(16).padStart(length * 2, "0");
|
|
5142
|
-
return Buffer.from(hex, "hex");
|
|
5155
|
+
return buffer.Buffer.from(hex, "hex");
|
|
5143
5156
|
};
|
|
5144
5157
|
function getExtDataHash(extData) {
|
|
5145
|
-
const
|
|
5146
|
-
const abi = ethers2.AbiCoder.defaultAbiCoder();
|
|
5158
|
+
const abi = ethers.ethers.AbiCoder.defaultAbiCoder();
|
|
5147
5159
|
const encodedData = abi.encode(
|
|
5148
5160
|
["tuple(address,int256,address,uint256,bytes,bytes)"],
|
|
5149
5161
|
[[
|
|
@@ -5155,7 +5167,7 @@ function getExtDataHash(extData) {
|
|
|
5155
5167
|
extData.encryptedOutput2
|
|
5156
5168
|
]]
|
|
5157
5169
|
);
|
|
5158
|
-
const hash =
|
|
5170
|
+
const hash = ethers.ethers.keccak256(encodedData);
|
|
5159
5171
|
return BigInt(hash) % FIELD_SIZE;
|
|
5160
5172
|
}
|
|
5161
5173
|
function shuffle(array) {
|
|
@@ -5171,15 +5183,14 @@ function shuffle(array) {
|
|
|
5171
5183
|
|
|
5172
5184
|
// src/keypair.ts
|
|
5173
5185
|
var VEIL_SIGNED_MESSAGE = "Sign this message to create your Veil Wallet private key. This will be used to decrypt your balances. Ensure you are signing this message on the Veil Cash website.";
|
|
5174
|
-
var ethSigUtil = __require("eth-sig-util");
|
|
5175
5186
|
function packEncryptedMessage(encryptedMessage) {
|
|
5176
|
-
const nonceBuf = Buffer.from(encryptedMessage.nonce, "base64");
|
|
5177
|
-
const ephemPublicKeyBuf = Buffer.from(encryptedMessage.ephemPublicKey, "base64");
|
|
5178
|
-
const ciphertextBuf = Buffer.from(encryptedMessage.ciphertext, "base64");
|
|
5179
|
-
const messageBuff = Buffer.concat([
|
|
5180
|
-
Buffer.alloc(24 - nonceBuf.length),
|
|
5187
|
+
const nonceBuf = buffer.Buffer.from(encryptedMessage.nonce, "base64");
|
|
5188
|
+
const ephemPublicKeyBuf = buffer.Buffer.from(encryptedMessage.ephemPublicKey, "base64");
|
|
5189
|
+
const ciphertextBuf = buffer.Buffer.from(encryptedMessage.ciphertext, "base64");
|
|
5190
|
+
const messageBuff = buffer.Buffer.concat([
|
|
5191
|
+
buffer.Buffer.alloc(24 - nonceBuf.length),
|
|
5181
5192
|
nonceBuf,
|
|
5182
|
-
Buffer.alloc(32 - ephemPublicKeyBuf.length),
|
|
5193
|
+
buffer.Buffer.alloc(32 - ephemPublicKeyBuf.length),
|
|
5183
5194
|
ephemPublicKeyBuf,
|
|
5184
5195
|
ciphertextBuf
|
|
5185
5196
|
]);
|
|
@@ -5189,7 +5200,7 @@ function unpackEncryptedMessage(encryptedMessage) {
|
|
|
5189
5200
|
if (encryptedMessage.slice(0, 2) === "0x") {
|
|
5190
5201
|
encryptedMessage = encryptedMessage.slice(2);
|
|
5191
5202
|
}
|
|
5192
|
-
const messageBuff = Buffer.from(encryptedMessage, "hex");
|
|
5203
|
+
const messageBuff = buffer.Buffer.from(encryptedMessage, "hex");
|
|
5193
5204
|
const nonceBuf = messageBuff.slice(0, 24);
|
|
5194
5205
|
const ephemPublicKeyBuf = messageBuff.slice(24, 56);
|
|
5195
5206
|
const ciphertextBuf = messageBuff.slice(56);
|
|
@@ -5222,7 +5233,7 @@ var Keypair = class _Keypair {
|
|
|
5222
5233
|
* @returns Deposit key as hex string (130 chars with 0x prefix)
|
|
5223
5234
|
*/
|
|
5224
5235
|
toString() {
|
|
5225
|
-
return toFixedHex(this.pubkey) + Buffer.from(this.encryptionKey, "base64").toString("hex");
|
|
5236
|
+
return toFixedHex(this.pubkey) + buffer.Buffer.from(this.encryptionKey, "base64").toString("hex");
|
|
5226
5237
|
}
|
|
5227
5238
|
/**
|
|
5228
5239
|
* Alias for toString() - returns the deposit key
|
|
@@ -5247,7 +5258,7 @@ var Keypair = class _Keypair {
|
|
|
5247
5258
|
return Object.assign(new _Keypair(), {
|
|
5248
5259
|
privkey: null,
|
|
5249
5260
|
pubkey: BigInt("0x" + str.slice(0, 64)),
|
|
5250
|
-
encryptionKey: Buffer.from(str.slice(64, 128), "hex").toString("base64")
|
|
5261
|
+
encryptionKey: buffer.Buffer.from(str.slice(64, 128), "hex").toString("base64")
|
|
5251
5262
|
});
|
|
5252
5263
|
}
|
|
5253
5264
|
/**
|
|
@@ -5348,7 +5359,7 @@ var Keypair = class _Keypair {
|
|
|
5348
5359
|
if (!this.privkey) {
|
|
5349
5360
|
throw new Error("Cannot decrypt without private key");
|
|
5350
5361
|
}
|
|
5351
|
-
return Buffer.from(
|
|
5362
|
+
return buffer.Buffer.from(
|
|
5352
5363
|
ethSigUtil.decrypt(unpackEncryptedMessage(data), this.privkey.slice(2)),
|
|
5353
5364
|
"base64"
|
|
5354
5365
|
);
|
|
@@ -5423,10 +5434,10 @@ async function confirm(question) {
|
|
|
5423
5434
|
input: process.stdin,
|
|
5424
5435
|
output: process.stdout
|
|
5425
5436
|
});
|
|
5426
|
-
return new Promise((
|
|
5437
|
+
return new Promise((resolve) => {
|
|
5427
5438
|
rl.question(`${question} (y/n): `, (answer) => {
|
|
5428
5439
|
rl.close();
|
|
5429
|
-
|
|
5440
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
5430
5441
|
});
|
|
5431
5442
|
});
|
|
5432
5443
|
}
|
|
@@ -5792,8 +5803,6 @@ function createRegisterCommand() {
|
|
|
5792
5803
|
});
|
|
5793
5804
|
return register;
|
|
5794
5805
|
}
|
|
5795
|
-
|
|
5796
|
-
// src/utxo.ts
|
|
5797
5806
|
var Utxo = class _Utxo {
|
|
5798
5807
|
amount;
|
|
5799
5808
|
blinding;
|
|
@@ -5844,7 +5853,7 @@ var Utxo = class _Utxo {
|
|
|
5844
5853
|
* @returns Encrypted data as 0x-prefixed hex string
|
|
5845
5854
|
*/
|
|
5846
5855
|
encrypt() {
|
|
5847
|
-
const bytes = Buffer.concat([
|
|
5856
|
+
const bytes = buffer.Buffer.concat([
|
|
5848
5857
|
toBuffer(this.amount, 31),
|
|
5849
5858
|
toBuffer(this.blinding, 31)
|
|
5850
5859
|
]);
|
|
@@ -6533,30 +6542,46 @@ async function buildMerkleTree(commitments) {
|
|
|
6533
6542
|
const tree = new MerkleTree__default.default(MERKLE_TREE_HEIGHT, leaves, { hashFunction });
|
|
6534
6543
|
return tree;
|
|
6535
6544
|
}
|
|
6536
|
-
var
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6545
|
+
var ffUtils = ffjavascript.utils;
|
|
6546
|
+
function isBrowserRuntime() {
|
|
6547
|
+
return !(typeof process !== "undefined" && !!process.versions?.node);
|
|
6548
|
+
}
|
|
6549
|
+
function stripTrailingSlash(value) {
|
|
6550
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
6551
|
+
}
|
|
6552
|
+
function normalizeCircuitBasePath(provingKeyPath, circuitName) {
|
|
6553
|
+
const resolvedPath = typeof provingKeyPath === "function" ? provingKeyPath(circuitName) : provingKeyPath;
|
|
6554
|
+
const withoutExtension = resolvedPath.replace(/\.(wasm|zkey)$/i, "");
|
|
6555
|
+
if (withoutExtension.endsWith(`/${circuitName}`) || withoutExtension.endsWith(`\\${circuitName}`)) {
|
|
6556
|
+
return withoutExtension;
|
|
6557
|
+
}
|
|
6558
|
+
return `${stripTrailingSlash(withoutExtension)}/${circuitName}`;
|
|
6542
6559
|
}
|
|
6543
|
-
function
|
|
6560
|
+
function importNodeModule(specifier) {
|
|
6561
|
+
const dynamicImport = new Function("specifier", "return import(specifier)");
|
|
6562
|
+
return dynamicImport(specifier);
|
|
6563
|
+
}
|
|
6564
|
+
async function findNodeKeysDirectory() {
|
|
6565
|
+
const [{ existsSync: existsSync2 }, pathModule, { fileURLToPath }] = await Promise.all([
|
|
6566
|
+
importNodeModule("node:fs"),
|
|
6567
|
+
importNodeModule("node:path"),
|
|
6568
|
+
importNodeModule("node:url")
|
|
6569
|
+
]);
|
|
6570
|
+
const path = pathModule;
|
|
6544
6571
|
const possiblePaths = [
|
|
6545
6572
|
// When running from package (installed via npm)
|
|
6546
|
-
|
|
6547
|
-
path__namespace.resolve(__dirname, "..", "..", "keys"),
|
|
6573
|
+
path.resolve(process.cwd(), "node_modules", "@veil-cash", "sdk", "keys"),
|
|
6548
6574
|
// When running from source
|
|
6549
|
-
|
|
6550
|
-
// ESM module path
|
|
6575
|
+
path.resolve(process.cwd(), "keys")
|
|
6551
6576
|
];
|
|
6552
6577
|
try {
|
|
6553
|
-
const currentFilePath =
|
|
6554
|
-
const currentDir =
|
|
6555
|
-
possiblePaths.unshift(
|
|
6578
|
+
const currentFilePath = fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
6579
|
+
const currentDir = path.dirname(currentFilePath);
|
|
6580
|
+
possiblePaths.unshift(path.resolve(currentDir, "..", "keys"));
|
|
6556
6581
|
} catch {
|
|
6557
6582
|
}
|
|
6558
6583
|
for (const p of possiblePaths) {
|
|
6559
|
-
if (
|
|
6584
|
+
if (existsSync2(p) && existsSync2(path.join(p, "transaction2.wasm"))) {
|
|
6560
6585
|
return p;
|
|
6561
6586
|
}
|
|
6562
6587
|
}
|
|
@@ -6564,26 +6589,48 @@ function findKeysDirectory() {
|
|
|
6564
6589
|
"Circuit keys not found. Expected to find keys/ directory with transaction2.wasm and transaction2.zkey files."
|
|
6565
6590
|
);
|
|
6566
6591
|
}
|
|
6567
|
-
async function
|
|
6568
|
-
if (
|
|
6569
|
-
|
|
6592
|
+
async function resolveProvingKeyPaths(circuitName, provingKeyPath) {
|
|
6593
|
+
if (provingKeyPath) {
|
|
6594
|
+
const circuitBasePath = normalizeCircuitBasePath(provingKeyPath, circuitName);
|
|
6595
|
+
return {
|
|
6596
|
+
wasmPath: `${circuitBasePath}.wasm`,
|
|
6597
|
+
zkeyPath: `${circuitBasePath}.zkey`
|
|
6598
|
+
};
|
|
6570
6599
|
}
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6600
|
+
if (isBrowserRuntime()) {
|
|
6601
|
+
return {
|
|
6602
|
+
wasmPath: `/keys/${circuitName}.wasm`,
|
|
6603
|
+
zkeyPath: `/keys/${circuitName}.zkey`
|
|
6604
|
+
};
|
|
6605
|
+
}
|
|
6606
|
+
const keysDir = await findNodeKeysDirectory();
|
|
6607
|
+
return {
|
|
6608
|
+
wasmPath: `${keysDir}/${circuitName}.wasm`,
|
|
6609
|
+
zkeyPath: `${keysDir}/${circuitName}.zkey`
|
|
6610
|
+
};
|
|
6611
|
+
}
|
|
6612
|
+
async function assertNodeKeyFilesExist(wasmPath, zkeyPath) {
|
|
6613
|
+
if (isBrowserRuntime() || wasmPath.startsWith("http://") || wasmPath.startsWith("https://")) {
|
|
6614
|
+
return;
|
|
6615
|
+
}
|
|
6616
|
+
const { existsSync: existsSync2 } = await importNodeModule("node:fs");
|
|
6617
|
+
if (!existsSync2(wasmPath)) {
|
|
6575
6618
|
throw new Error(`Circuit WASM file not found: ${wasmPath}`);
|
|
6576
6619
|
}
|
|
6577
|
-
if (!
|
|
6620
|
+
if (!existsSync2(zkeyPath)) {
|
|
6578
6621
|
throw new Error(`Circuit zkey file not found: ${zkeyPath}`);
|
|
6579
6622
|
}
|
|
6623
|
+
}
|
|
6624
|
+
async function prove(input, circuitName, options = {}) {
|
|
6625
|
+
const { wasmPath, zkeyPath } = await resolveProvingKeyPaths(circuitName, options.provingKeyPath);
|
|
6626
|
+
await assertNodeKeyFilesExist(wasmPath, zkeyPath);
|
|
6580
6627
|
const result = await snarkjs.groth16.fullProve(
|
|
6581
|
-
|
|
6628
|
+
ffUtils.stringifyBigInts(input),
|
|
6582
6629
|
wasmPath,
|
|
6583
6630
|
zkeyPath,
|
|
6584
6631
|
void 0,
|
|
6585
6632
|
void 0,
|
|
6586
|
-
{ singleThread: true }
|
|
6633
|
+
{ singleThread: options.singleThread ?? true }
|
|
6587
6634
|
);
|
|
6588
6635
|
const proof = result.proof;
|
|
6589
6636
|
return "0x" + toFixedHex(proof.pi_a[0]).slice(2) + toFixedHex(proof.pi_a[1]).slice(2) + toFixedHex(proof.pi_b[0][1]).slice(2) + toFixedHex(proof.pi_b[0][0]).slice(2) + toFixedHex(proof.pi_b[1][1]).slice(2) + toFixedHex(proof.pi_b[1][0]).slice(2) + toFixedHex(proof.pi_c[0]).slice(2) + toFixedHex(proof.pi_c[1]).slice(2);
|
|
@@ -6607,7 +6654,8 @@ async function getProof({
|
|
|
6607
6654
|
fee,
|
|
6608
6655
|
recipient,
|
|
6609
6656
|
relayer,
|
|
6610
|
-
onProgress
|
|
6657
|
+
onProgress,
|
|
6658
|
+
provingKeyPath
|
|
6611
6659
|
}) {
|
|
6612
6660
|
inputs = shuffle([...inputs]);
|
|
6613
6661
|
outputs = shuffle([...outputs]);
|
|
@@ -6667,7 +6715,7 @@ async function getProof({
|
|
|
6667
6715
|
};
|
|
6668
6716
|
onProgress?.("Generating ZK proof...", `${inputs.length} inputs`);
|
|
6669
6717
|
const circuitName = selectCircuit(inputs.length);
|
|
6670
|
-
const proof = await prove(proofInput, circuitName);
|
|
6718
|
+
const proof = await prove(proofInput, circuitName, { provingKeyPath });
|
|
6671
6719
|
const args = {
|
|
6672
6720
|
proof,
|
|
6673
6721
|
root: toFixedHex(proofInput.root),
|
|
@@ -6689,7 +6737,8 @@ async function prepareTransaction({
|
|
|
6689
6737
|
fee = 0,
|
|
6690
6738
|
recipient = 0,
|
|
6691
6739
|
relayer = 0,
|
|
6692
|
-
onProgress
|
|
6740
|
+
onProgress,
|
|
6741
|
+
provingKeyPath
|
|
6693
6742
|
}) {
|
|
6694
6743
|
if (inputs.length > 16 || outputs.length > 2) {
|
|
6695
6744
|
throw new Error("Incorrect inputs/outputs count. Maximum: 16 inputs, 2 outputs.");
|
|
@@ -6711,7 +6760,8 @@ async function prepareTransaction({
|
|
|
6711
6760
|
fee: BigInt(fee),
|
|
6712
6761
|
recipient: String(recipient),
|
|
6713
6762
|
relayer: String(relayer),
|
|
6714
|
-
onProgress
|
|
6763
|
+
onProgress,
|
|
6764
|
+
provingKeyPath
|
|
6715
6765
|
});
|
|
6716
6766
|
return result;
|
|
6717
6767
|
}
|
|
@@ -6861,6 +6911,7 @@ async function buildWithdrawProof(options) {
|
|
|
6861
6911
|
keypair,
|
|
6862
6912
|
pool = "eth",
|
|
6863
6913
|
rpcUrl,
|
|
6914
|
+
provingKeyPath,
|
|
6864
6915
|
onProgress
|
|
6865
6916
|
} = options;
|
|
6866
6917
|
const poolConfig = POOL_CONFIG[pool];
|
|
@@ -6924,7 +6975,8 @@ async function buildWithdrawProof(options) {
|
|
|
6924
6975
|
fee: 0,
|
|
6925
6976
|
recipient,
|
|
6926
6977
|
relayer: "0x0000000000000000000000000000000000000000",
|
|
6927
|
-
onProgress
|
|
6978
|
+
onProgress,
|
|
6979
|
+
provingKeyPath
|
|
6928
6980
|
});
|
|
6929
6981
|
return {
|
|
6930
6982
|
proofArgs: {
|
|
@@ -7085,6 +7137,7 @@ async function buildTransferProof(options) {
|
|
|
7085
7137
|
senderKeypair,
|
|
7086
7138
|
pool = "eth",
|
|
7087
7139
|
rpcUrl,
|
|
7140
|
+
provingKeyPath,
|
|
7088
7141
|
onProgress
|
|
7089
7142
|
} = options;
|
|
7090
7143
|
const poolConfig = POOL_CONFIG[pool];
|
|
@@ -7163,7 +7216,8 @@ async function buildTransferProof(options) {
|
|
|
7163
7216
|
fee: 0,
|
|
7164
7217
|
recipient: "0x0000000000000000000000000000000000000000",
|
|
7165
7218
|
relayer: "0x0000000000000000000000000000000000000000",
|
|
7166
|
-
onProgress
|
|
7219
|
+
onProgress,
|
|
7220
|
+
provingKeyPath
|
|
7167
7221
|
});
|
|
7168
7222
|
return {
|
|
7169
7223
|
proofArgs: {
|
|
@@ -7205,7 +7259,7 @@ async function transfer(options) {
|
|
|
7205
7259
|
};
|
|
7206
7260
|
}
|
|
7207
7261
|
async function mergeUtxos(options) {
|
|
7208
|
-
const { amount, keypair, pool = "eth", rpcUrl, onProgress } = options;
|
|
7262
|
+
const { amount, keypair, pool = "eth", rpcUrl, provingKeyPath, onProgress } = options;
|
|
7209
7263
|
const poolConfig = POOL_CONFIG[pool];
|
|
7210
7264
|
const poolAddress = getPoolAddress(pool);
|
|
7211
7265
|
onProgress?.("Fetching your UTXOs...");
|
|
@@ -7273,7 +7327,8 @@ async function mergeUtxos(options) {
|
|
|
7273
7327
|
fee: 0,
|
|
7274
7328
|
recipient: "0x0000000000000000000000000000000000000000",
|
|
7275
7329
|
relayer: "0x0000000000000000000000000000000000000000",
|
|
7276
|
-
onProgress
|
|
7330
|
+
onProgress,
|
|
7331
|
+
provingKeyPath
|
|
7277
7332
|
});
|
|
7278
7333
|
onProgress?.("Submitting to relay...");
|
|
7279
7334
|
const relayResult = await submitRelay({
|
|
@@ -7964,6 +8019,7 @@ async function mergeSubaccount(options) {
|
|
|
7964
8019
|
pool = "eth",
|
|
7965
8020
|
rpcUrl,
|
|
7966
8021
|
relayUrl,
|
|
8022
|
+
provingKeyPath,
|
|
7967
8023
|
onProgress
|
|
7968
8024
|
} = options;
|
|
7969
8025
|
const normalizedSlot = normalizeSlot(slot);
|
|
@@ -8056,7 +8112,8 @@ async function mergeSubaccount(options) {
|
|
|
8056
8112
|
fee: 0,
|
|
8057
8113
|
recipient: "0x0000000000000000000000000000000000000000",
|
|
8058
8114
|
relayer: "0x0000000000000000000000000000000000000000",
|
|
8059
|
-
onProgress
|
|
8115
|
+
onProgress,
|
|
8116
|
+
provingKeyPath
|
|
8060
8117
|
});
|
|
8061
8118
|
onProgress?.("Submitting to relay...");
|
|
8062
8119
|
const relayResult = await submitRelay({
|