@veil-cash/sdk 0.6.2 → 0.6.4

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.
@@ -8,35 +8,18 @@ var readline = require('readline');
8
8
  var fs = require('fs');
9
9
  var path = require('path');
10
10
  var ethers = require('ethers');
11
- var crypto = require('crypto');
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 url = require('url');
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 }; }
18
20
 
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
21
- var n = Object.create(null);
22
- if (e) {
23
- Object.keys(e).forEach(function (k) {
24
- if (k !== 'default') {
25
- var d = Object.getOwnPropertyDescriptor(e, k);
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- });
32
- }
33
- n.default = e;
34
- return Object.freeze(n);
35
- }
36
-
37
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
38
- var path__namespace = /*#__PURE__*/_interopNamespace(path);
39
- var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
21
+ var ethSigUtil__default = /*#__PURE__*/_interopDefault(ethSigUtil);
22
+ var circomlib__default = /*#__PURE__*/_interopDefault(circomlib);
40
23
  var MerkleTree__default = /*#__PURE__*/_interopDefault(MerkleTree);
41
24
 
42
25
  var __create = Object.create;
@@ -1234,8 +1217,8 @@ var require_command = __commonJS({
1234
1217
  "node_modules/commander/lib/command.js"(exports$1) {
1235
1218
  var EventEmitter = __require("events").EventEmitter;
1236
1219
  var childProcess = __require("child_process");
1237
- var path2 = __require("path");
1238
- var fs2 = __require("fs");
1220
+ var path = __require("path");
1221
+ var fs = __require("fs");
1239
1222
  var process2 = __require("process");
1240
1223
  var { Argument: Argument2, humanReadableArgName } = require_argument();
1241
1224
  var { CommanderError: CommanderError2 } = require_error();
@@ -2228,7 +2211,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2228
2211
  * @param {string} subcommandName
2229
2212
  */
2230
2213
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2231
- if (fs2.existsSync(executableFile)) return;
2214
+ if (fs.existsSync(executableFile)) return;
2232
2215
  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
2216
  const executableMissing = `'${executableFile}' does not exist
2234
2217
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2246,11 +2229,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2246
2229
  let launchWithNode = false;
2247
2230
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2248
2231
  function findFile(baseDir, baseName) {
2249
- const localBin = path2.resolve(baseDir, baseName);
2250
- if (fs2.existsSync(localBin)) return localBin;
2251
- if (sourceExt.includes(path2.extname(baseName))) return void 0;
2232
+ const localBin = path.resolve(baseDir, baseName);
2233
+ if (fs.existsSync(localBin)) return localBin;
2234
+ if (sourceExt.includes(path.extname(baseName))) return void 0;
2252
2235
  const foundExt = sourceExt.find(
2253
- (ext) => fs2.existsSync(`${localBin}${ext}`)
2236
+ (ext) => fs.existsSync(`${localBin}${ext}`)
2254
2237
  );
2255
2238
  if (foundExt) return `${localBin}${foundExt}`;
2256
2239
  return void 0;
@@ -2262,21 +2245,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2262
2245
  if (this._scriptPath) {
2263
2246
  let resolvedScriptPath;
2264
2247
  try {
2265
- resolvedScriptPath = fs2.realpathSync(this._scriptPath);
2248
+ resolvedScriptPath = fs.realpathSync(this._scriptPath);
2266
2249
  } catch {
2267
2250
  resolvedScriptPath = this._scriptPath;
2268
2251
  }
2269
- executableDir = path2.resolve(
2270
- path2.dirname(resolvedScriptPath),
2252
+ executableDir = path.resolve(
2253
+ path.dirname(resolvedScriptPath),
2271
2254
  executableDir
2272
2255
  );
2273
2256
  }
2274
2257
  if (executableDir) {
2275
2258
  let localFile = findFile(executableDir, executableFile);
2276
2259
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2277
- const legacyName = path2.basename(
2260
+ const legacyName = path.basename(
2278
2261
  this._scriptPath,
2279
- path2.extname(this._scriptPath)
2262
+ path.extname(this._scriptPath)
2280
2263
  );
2281
2264
  if (legacyName !== this._name) {
2282
2265
  localFile = findFile(
@@ -2287,7 +2270,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2287
2270
  }
2288
2271
  executableFile = localFile || executableFile;
2289
2272
  }
2290
- launchWithNode = sourceExt.includes(path2.extname(executableFile));
2273
+ launchWithNode = sourceExt.includes(path.extname(executableFile));
2291
2274
  let proc;
2292
2275
  if (process2.platform !== "win32") {
2293
2276
  if (launchWithNode) {
@@ -3202,7 +3185,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3202
3185
  * @return {Command}
3203
3186
  */
3204
3187
  nameFromFilename(filename) {
3205
- this._name = path2.basename(filename, path2.extname(filename));
3188
+ this._name = path.basename(filename, path.extname(filename));
3206
3189
  return this;
3207
3190
  }
3208
3191
  /**
@@ -3216,9 +3199,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3216
3199
  * @param {string} [path]
3217
3200
  * @return {(string|null|Command)}
3218
3201
  */
3219
- executableDir(path3) {
3220
- if (path3 === void 0) return this._executableDir;
3221
- this._executableDir = path3;
3202
+ executableDir(path2) {
3203
+ if (path2 === void 0) return this._executableDir;
3204
+ this._executableDir = path2;
3222
3205
  return this;
3223
3206
  }
3224
3207
  /**
@@ -3567,10 +3550,10 @@ var require_package = __commonJS({
3567
3550
  // node_modules/dotenv/lib/main.js
3568
3551
  var require_main = __commonJS({
3569
3552
  "node_modules/dotenv/lib/main.js"(exports$1, module) {
3570
- var fs2 = __require("fs");
3571
- var path2 = __require("path");
3553
+ var fs = __require("fs");
3554
+ var path = __require("path");
3572
3555
  var os = __require("os");
3573
- var crypto2 = __require("crypto");
3556
+ var crypto = __require("crypto");
3574
3557
  var packageJson = require_package();
3575
3558
  var version = packageJson.version;
3576
3559
  var TIPS = [
@@ -3709,7 +3692,7 @@ var require_main = __commonJS({
3709
3692
  if (options && options.path && options.path.length > 0) {
3710
3693
  if (Array.isArray(options.path)) {
3711
3694
  for (const filepath of options.path) {
3712
- if (fs2.existsSync(filepath)) {
3695
+ if (fs.existsSync(filepath)) {
3713
3696
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
3714
3697
  }
3715
3698
  }
@@ -3717,15 +3700,15 @@ var require_main = __commonJS({
3717
3700
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
3718
3701
  }
3719
3702
  } else {
3720
- possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
3703
+ possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
3721
3704
  }
3722
- if (fs2.existsSync(possibleVaultPath)) {
3705
+ if (fs.existsSync(possibleVaultPath)) {
3723
3706
  return possibleVaultPath;
3724
3707
  }
3725
3708
  return null;
3726
3709
  }
3727
3710
  function _resolveHome(envPath) {
3728
- return envPath[0] === "~" ? path2.join(os.homedir(), envPath.slice(1)) : envPath;
3711
+ return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
3729
3712
  }
3730
3713
  function _configVault(options) {
3731
3714
  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
@@ -3742,7 +3725,7 @@ var require_main = __commonJS({
3742
3725
  return { parsed };
3743
3726
  }
3744
3727
  function configDotenv(options) {
3745
- const dotenvPath = path2.resolve(process.cwd(), ".env");
3728
+ const dotenvPath = path.resolve(process.cwd(), ".env");
3746
3729
  let encoding = "utf8";
3747
3730
  let processEnv = process.env;
3748
3731
  if (options && options.processEnv != null) {
@@ -3770,13 +3753,13 @@ var require_main = __commonJS({
3770
3753
  }
3771
3754
  let lastError;
3772
3755
  const parsedAll = {};
3773
- for (const path3 of optionPaths) {
3756
+ for (const path2 of optionPaths) {
3774
3757
  try {
3775
- const parsed = DotenvModule.parse(fs2.readFileSync(path3, { encoding }));
3758
+ const parsed = DotenvModule.parse(fs.readFileSync(path2, { encoding }));
3776
3759
  DotenvModule.populate(parsedAll, parsed, options);
3777
3760
  } catch (e) {
3778
3761
  if (debug) {
3779
- _debug(`Failed to load ${path3} ${e.message}`);
3762
+ _debug(`Failed to load ${path2} ${e.message}`);
3780
3763
  }
3781
3764
  lastError = e;
3782
3765
  }
@@ -3789,7 +3772,7 @@ var require_main = __commonJS({
3789
3772
  const shortPaths = [];
3790
3773
  for (const filePath of optionPaths) {
3791
3774
  try {
3792
- const relative = path2.relative(process.cwd(), filePath);
3775
+ const relative = path.relative(process.cwd(), filePath);
3793
3776
  shortPaths.push(relative);
3794
3777
  } catch (e) {
3795
3778
  if (debug) {
@@ -3824,7 +3807,7 @@ var require_main = __commonJS({
3824
3807
  const authTag = ciphertext.subarray(-16);
3825
3808
  ciphertext = ciphertext.subarray(12, -16);
3826
3809
  try {
3827
- const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
3810
+ const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
3828
3811
  aesgcm.setAuthTag(authTag);
3829
3812
  return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
3830
3813
  } catch (error) {
@@ -4203,6 +4186,14 @@ var QUEUE_ABI = [
4203
4186
  outputs: [{ name: "count", type: "uint256" }],
4204
4187
  stateMutability: "view",
4205
4188
  type: "function"
4189
+ },
4190
+ // Get remaining daily free deposits for an address (V3+)
4191
+ {
4192
+ inputs: [{ name: "_depositor", type: "address" }],
4193
+ name: "getDailyFreeRemaining",
4194
+ outputs: [{ name: "remaining", type: "uint256" }],
4195
+ stateMutability: "view",
4196
+ type: "function"
4206
4197
  }
4207
4198
  ];
4208
4199
  var POOL_ABI = [
@@ -5099,15 +5090,18 @@ function loadEnv() {
5099
5090
  } catch {
5100
5091
  }
5101
5092
  }
5102
- var circomlib = __require("circomlib");
5103
- var poseidon = circomlib.poseidon;
5093
+ var poseidon = circomlib__default.default.poseidon;
5104
5094
  var FIELD_SIZE = BigInt(
5105
5095
  "21888242871839275222246405745257275088548364400416034343698204186575808495617"
5106
5096
  );
5107
5097
  var poseidonHash = (items) => BigInt(poseidon(items).toString());
5108
5098
  var poseidonHash2 = (a, b) => poseidonHash([a, b]);
5109
5099
  var randomBN = (nbytes = 31) => {
5110
- const bytes = crypto__namespace.randomBytes(nbytes);
5100
+ const cryptoApi = globalThis.crypto;
5101
+ if (!cryptoApi?.getRandomValues) {
5102
+ throw new Error("Secure random number generation is unavailable in this runtime");
5103
+ }
5104
+ const bytes = cryptoApi.getRandomValues(new Uint8Array(nbytes));
5111
5105
  let hex = "0x";
5112
5106
  for (let i = 0; i < bytes.length; i++) {
5113
5107
  hex += bytes[i].toString(16).padStart(2, "0");
@@ -5116,7 +5110,7 @@ var randomBN = (nbytes = 31) => {
5116
5110
  };
5117
5111
  function toFixedHex(number, length = 32) {
5118
5112
  let hexValue;
5119
- if (number instanceof Buffer) {
5113
+ if (number instanceof buffer.Buffer) {
5120
5114
  hexValue = number.toString("hex");
5121
5115
  } else {
5122
5116
  let bigIntValue = BigInt(number);
@@ -5131,11 +5125,10 @@ function toFixedHex(number, length = 32) {
5131
5125
  var toBuffer = (value, length) => {
5132
5126
  const bigIntValue = BigInt(value);
5133
5127
  const hex = bigIntValue.toString(16).padStart(length * 2, "0");
5134
- return Buffer.from(hex, "hex");
5128
+ return buffer.Buffer.from(hex, "hex");
5135
5129
  };
5136
5130
  function getExtDataHash(extData) {
5137
- const { ethers: ethers2 } = __require("ethers");
5138
- const abi = ethers2.AbiCoder.defaultAbiCoder();
5131
+ const abi = ethers.ethers.AbiCoder.defaultAbiCoder();
5139
5132
  const encodedData = abi.encode(
5140
5133
  ["tuple(address,int256,address,uint256,bytes,bytes)"],
5141
5134
  [[
@@ -5147,7 +5140,7 @@ function getExtDataHash(extData) {
5147
5140
  extData.encryptedOutput2
5148
5141
  ]]
5149
5142
  );
5150
- const hash = ethers2.keccak256(encodedData);
5143
+ const hash = ethers.ethers.keccak256(encodedData);
5151
5144
  return BigInt(hash) % FIELD_SIZE;
5152
5145
  }
5153
5146
  function shuffle(array) {
@@ -5163,15 +5156,14 @@ function shuffle(array) {
5163
5156
 
5164
5157
  // src/keypair.ts
5165
5158
  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.";
5166
- var ethSigUtil = __require("eth-sig-util");
5167
5159
  function packEncryptedMessage(encryptedMessage) {
5168
- const nonceBuf = Buffer.from(encryptedMessage.nonce, "base64");
5169
- const ephemPublicKeyBuf = Buffer.from(encryptedMessage.ephemPublicKey, "base64");
5170
- const ciphertextBuf = Buffer.from(encryptedMessage.ciphertext, "base64");
5171
- const messageBuff = Buffer.concat([
5172
- Buffer.alloc(24 - nonceBuf.length),
5160
+ const nonceBuf = buffer.Buffer.from(encryptedMessage.nonce, "base64");
5161
+ const ephemPublicKeyBuf = buffer.Buffer.from(encryptedMessage.ephemPublicKey, "base64");
5162
+ const ciphertextBuf = buffer.Buffer.from(encryptedMessage.ciphertext, "base64");
5163
+ const messageBuff = buffer.Buffer.concat([
5164
+ buffer.Buffer.alloc(24 - nonceBuf.length),
5173
5165
  nonceBuf,
5174
- Buffer.alloc(32 - ephemPublicKeyBuf.length),
5166
+ buffer.Buffer.alloc(32 - ephemPublicKeyBuf.length),
5175
5167
  ephemPublicKeyBuf,
5176
5168
  ciphertextBuf
5177
5169
  ]);
@@ -5181,7 +5173,7 @@ function unpackEncryptedMessage(encryptedMessage) {
5181
5173
  if (encryptedMessage.slice(0, 2) === "0x") {
5182
5174
  encryptedMessage = encryptedMessage.slice(2);
5183
5175
  }
5184
- const messageBuff = Buffer.from(encryptedMessage, "hex");
5176
+ const messageBuff = buffer.Buffer.from(encryptedMessage, "hex");
5185
5177
  const nonceBuf = messageBuff.slice(0, 24);
5186
5178
  const ephemPublicKeyBuf = messageBuff.slice(24, 56);
5187
5179
  const ciphertextBuf = messageBuff.slice(56);
@@ -5206,7 +5198,7 @@ var Keypair = class _Keypair {
5206
5198
  constructor(privkey = ethers.ethers.Wallet.createRandom().privateKey) {
5207
5199
  this.privkey = privkey;
5208
5200
  this.pubkey = poseidonHash([this.privkey]);
5209
- this.encryptionKey = ethSigUtil.getEncryptionPublicKey(privkey.slice(2));
5201
+ this.encryptionKey = ethSigUtil__default.default.getEncryptionPublicKey(privkey.slice(2));
5210
5202
  }
5211
5203
  /**
5212
5204
  * Get the deposit key for this keypair
@@ -5214,7 +5206,7 @@ var Keypair = class _Keypair {
5214
5206
  * @returns Deposit key as hex string (130 chars with 0x prefix)
5215
5207
  */
5216
5208
  toString() {
5217
- return toFixedHex(this.pubkey) + Buffer.from(this.encryptionKey, "base64").toString("hex");
5209
+ return toFixedHex(this.pubkey) + buffer.Buffer.from(this.encryptionKey, "base64").toString("hex");
5218
5210
  }
5219
5211
  /**
5220
5212
  * Alias for toString() - returns the deposit key
@@ -5239,7 +5231,7 @@ var Keypair = class _Keypair {
5239
5231
  return Object.assign(new _Keypair(), {
5240
5232
  privkey: null,
5241
5233
  pubkey: BigInt("0x" + str.slice(0, 64)),
5242
- encryptionKey: Buffer.from(str.slice(64, 128), "hex").toString("base64")
5234
+ encryptionKey: buffer.Buffer.from(str.slice(64, 128), "hex").toString("base64")
5243
5235
  });
5244
5236
  }
5245
5237
  /**
@@ -5324,7 +5316,7 @@ var Keypair = class _Keypair {
5324
5316
  */
5325
5317
  encrypt(bytes) {
5326
5318
  return packEncryptedMessage(
5327
- ethSigUtil.encrypt(
5319
+ ethSigUtil__default.default.encrypt(
5328
5320
  this.encryptionKey,
5329
5321
  { data: bytes.toString("base64") },
5330
5322
  "x25519-xsalsa20-poly1305"
@@ -5340,8 +5332,8 @@ var Keypair = class _Keypair {
5340
5332
  if (!this.privkey) {
5341
5333
  throw new Error("Cannot decrypt without private key");
5342
5334
  }
5343
- return Buffer.from(
5344
- ethSigUtil.decrypt(unpackEncryptedMessage(data), this.privkey.slice(2)),
5335
+ return buffer.Buffer.from(
5336
+ ethSigUtil__default.default.decrypt(unpackEncryptedMessage(data), this.privkey.slice(2)),
5345
5337
  "base64"
5346
5338
  );
5347
5339
  }
@@ -5415,10 +5407,10 @@ async function confirm(question) {
5415
5407
  input: process.stdin,
5416
5408
  output: process.stdout
5417
5409
  });
5418
- return new Promise((resolve2) => {
5410
+ return new Promise((resolve) => {
5419
5411
  rl.question(`${question} (y/n): `, (answer) => {
5420
5412
  rl.close();
5421
- resolve2(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
5413
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
5422
5414
  });
5423
5415
  });
5424
5416
  }
@@ -5784,176 +5776,6 @@ function createRegisterCommand() {
5784
5776
  });
5785
5777
  return register;
5786
5778
  }
5787
- var MINIMUM_NET = {
5788
- ETH: 0.01,
5789
- USDC: 10
5790
- };
5791
- async function getGrossAmount(netWei, rpcUrl) {
5792
- const publicClient = viem.createPublicClient({
5793
- chain: chains.base,
5794
- transport: viem.http(rpcUrl)
5795
- });
5796
- const grossWei = await publicClient.readContract({
5797
- address: getAddresses().entry,
5798
- abi: ENTRY_ABI,
5799
- functionName: "getDepositAmountWithFee",
5800
- args: [netWei]
5801
- });
5802
- return { grossWei, feeWei: grossWei - netWei };
5803
- }
5804
- var SUPPORTED_ASSETS = ["ETH", "USDC"];
5805
- function createDepositCommand() {
5806
- const deposit = new Command("deposit").description("Deposit ETH or USDC into Veil").argument("<asset>", "Asset to deposit (ETH or USDC)").argument("<amount>", "Amount to deposit \u2014 this is what arrives in your Veil balance").option("--unsigned", "Output unsigned transaction payload instead of sending").option("--json", "Output as JSON").addHelpText("after", `
5807
- The amount you specify is the net amount that lands in your Veil balance.
5808
- The 0.3% protocol fee is automatically added on top.
5809
-
5810
- Examples:
5811
- veil deposit ETH 0.1 # deposits 0.1 ETH (sends ~0.1003 ETH)
5812
- veil deposit USDC 100 # deposits 100 USDC (sends ~100.30 USDC)
5813
- veil deposit ETH 0.1 --unsigned
5814
- veil deposit ETH 0.1 --json
5815
- `).action(async (asset, amount, options) => {
5816
- try {
5817
- const assetUpper = asset.toUpperCase();
5818
- if (!SUPPORTED_ASSETS.includes(assetUpper)) {
5819
- throw new CLIError(ErrorCode.INVALID_AMOUNT, `Unsupported asset: ${asset}. Supported: ${SUPPORTED_ASSETS.join(", ")}`);
5820
- }
5821
- const amountNum = parseFloat(amount);
5822
- const minimumNet = MINIMUM_NET[assetUpper];
5823
- if (amountNum < minimumNet) {
5824
- throw new CLIError(
5825
- ErrorCode.INVALID_AMOUNT,
5826
- `Minimum deposit is ${minimumNet} ${assetUpper}.`
5827
- );
5828
- }
5829
- const rpcUrl = process.env.RPC_URL;
5830
- const poolConfig = POOL_CONFIG[assetUpper.toLowerCase()];
5831
- const netWei = assetUpper === "ETH" ? viem.parseEther(amount) : viem.parseUnits(amount, poolConfig.decimals);
5832
- const progress = createProgressReporter();
5833
- progress("Calculating fee...");
5834
- const { grossWei, feeWei } = await getGrossAmount(netWei, rpcUrl);
5835
- const grossStr = assetUpper === "ETH" ? viem.formatEther(grossWei) : viem.formatUnits(grossWei, poolConfig.decimals);
5836
- const feeStr = assetUpper === "ETH" ? viem.formatEther(feeWei) : viem.formatUnits(feeWei, poolConfig.decimals);
5837
- const depositKey = process.env.DEPOSIT_KEY;
5838
- if (!depositKey) {
5839
- throw new CLIError(ErrorCode.DEPOSIT_KEY_MISSING, 'DEPOSIT_KEY not set. Run "veil init" first.');
5840
- }
5841
- progress("Building transaction...");
5842
- let tx;
5843
- let approveTx = null;
5844
- if (assetUpper === "USDC") {
5845
- approveTx = buildApproveUSDCTx({ amount: grossStr });
5846
- tx = buildDepositUSDCTx({ depositKey, amount: grossStr });
5847
- } else {
5848
- tx = buildDepositETHTx({ depositKey, amount: grossStr });
5849
- }
5850
- if (options.unsigned) {
5851
- clearProgress();
5852
- const payloads = [];
5853
- if (approveTx) {
5854
- payloads.push({
5855
- step: "approve",
5856
- to: approveTx.to,
5857
- data: approveTx.data,
5858
- value: "0",
5859
- chainId: 8453
5860
- });
5861
- }
5862
- payloads.push({
5863
- step: "deposit",
5864
- to: tx.to,
5865
- data: tx.data,
5866
- value: tx.value ? tx.value.toString() : "0",
5867
- chainId: 8453
5868
- });
5869
- printJson(payloads.length === 1 ? payloads[0] : payloads);
5870
- return;
5871
- }
5872
- const config = getConfig(options);
5873
- const address = getAddress(config.privateKey);
5874
- if (assetUpper === "ETH") {
5875
- progress("Checking balance...");
5876
- const balance = await getBalance(address, config.rpcUrl);
5877
- if (balance < grossWei) {
5878
- clearProgress();
5879
- throw new CLIError(
5880
- ErrorCode.INSUFFICIENT_BALANCE,
5881
- `Insufficient ETH balance. Have: ${viem.formatEther(balance)} ETH, Need: ${grossStr} ETH (${amount} + fee)`
5882
- );
5883
- }
5884
- }
5885
- if (approveTx) {
5886
- progress(`Approving ${assetUpper}...`);
5887
- const approvalResult = await sendTransaction(config, approveTx);
5888
- if (assetUpper === "USDC") {
5889
- const publicClient = viem.createPublicClient({
5890
- chain: chains.base,
5891
- transport: viem.http(config.rpcUrl)
5892
- });
5893
- const addresses = getAddresses();
5894
- let allowance = await publicClient.readContract({
5895
- address: getAddresses().usdcToken,
5896
- abi: ERC20_ABI,
5897
- functionName: "allowance",
5898
- args: [address, addresses.entry]
5899
- });
5900
- for (let confirmations = 2; allowance < grossWei && confirmations <= 3; confirmations++) {
5901
- await publicClient.waitForTransactionReceipt({
5902
- hash: approvalResult.hash,
5903
- confirmations
5904
- });
5905
- allowance = await publicClient.readContract({
5906
- address: addresses.usdcToken,
5907
- abi: ERC20_ABI,
5908
- functionName: "allowance",
5909
- args: [address, addresses.entry]
5910
- });
5911
- }
5912
- if (allowance < grossWei) {
5913
- throw new CLIError(
5914
- ErrorCode.CONTRACT_ERROR,
5915
- `USDC approval is not yet visible on RPC after confirmation. Allowance ${allowance.toString()} < required ${grossWei.toString()}.`
5916
- );
5917
- }
5918
- }
5919
- }
5920
- progress("Sending deposit transaction...");
5921
- const result = await sendTransaction(config, tx);
5922
- progress("Confirming...");
5923
- clearProgress();
5924
- const output = {
5925
- success: result.receipt.status === "success",
5926
- hash: result.hash,
5927
- asset: assetUpper,
5928
- amount,
5929
- fee: feeStr,
5930
- totalSent: grossStr,
5931
- blockNumber: result.receipt.blockNumber.toString()
5932
- };
5933
- if (options.json) {
5934
- printJson(output);
5935
- return;
5936
- }
5937
- printHeader("Deposit Submitted");
5938
- printFields([
5939
- { label: "Asset", value: assetUpper },
5940
- { label: "Amount", value: `${amount} ${assetUpper}` },
5941
- { label: "Fee", value: `${feeStr} ${assetUpper} (0.3%)` },
5942
- { label: "Total sent", value: `${grossStr} ${assetUpper}` },
5943
- { label: "From", value: address },
5944
- { label: "Transaction", value: txUrl(result.hash) },
5945
- { label: "Block", value: result.receipt.blockNumber }
5946
- ]);
5947
- printLine();
5948
- } catch (error) {
5949
- clearProgress();
5950
- handleCLIError(error);
5951
- }
5952
- });
5953
- return deposit;
5954
- }
5955
-
5956
- // src/utxo.ts
5957
5779
  var Utxo = class _Utxo {
5958
5780
  amount;
5959
5781
  blinding;
@@ -6004,7 +5826,7 @@ var Utxo = class _Utxo {
6004
5826
  * @returns Encrypted data as 0x-prefixed hex string
6005
5827
  */
6006
5828
  encrypt() {
6007
- const bytes = Buffer.concat([
5829
+ const bytes = buffer.Buffer.concat([
6008
5830
  toBuffer(this.amount, 31),
6009
5831
  toBuffer(this.blinding, 31)
6010
5832
  ]);
@@ -6084,6 +5906,25 @@ async function getQueueBalance(options) {
6084
5906
  pendingCount: pendingDeposits.length
6085
5907
  };
6086
5908
  }
5909
+ async function getDailyFreeRemaining(options) {
5910
+ const { address, pool = "eth", rpcUrl } = options;
5911
+ const queueAddress = getQueueAddress(pool);
5912
+ const publicClient = viem.createPublicClient({
5913
+ chain: chains.base,
5914
+ transport: viem.http(rpcUrl)
5915
+ });
5916
+ try {
5917
+ const remaining = await publicClient.readContract({
5918
+ address: queueAddress,
5919
+ abi: QUEUE_ABI,
5920
+ functionName: "getDailyFreeRemaining",
5921
+ args: [address]
5922
+ });
5923
+ return Number(remaining);
5924
+ } catch {
5925
+ return 0;
5926
+ }
5927
+ }
6087
5928
  async function getPrivateBalance(options) {
6088
5929
  const { keypair, pool = "eth", rpcUrl, onProgress } = options;
6089
5930
  const poolAddress = getPoolAddress(pool);
@@ -6177,6 +6018,206 @@ async function getPrivateBalance(options) {
6177
6018
  utxos: utxoInfos
6178
6019
  };
6179
6020
  }
6021
+ var MINIMUM_NET = {
6022
+ ETH: 0.01,
6023
+ USDC: 10
6024
+ };
6025
+ async function getGrossAmount(netWei, depositor, pool, rpcUrl) {
6026
+ const freeRemaining = await getDailyFreeRemaining({ address: depositor, pool, rpcUrl });
6027
+ if (freeRemaining > 0) {
6028
+ return { grossWei: netWei, feeWei: 0n, dailyFreeUsed: true, dailyFreeRemaining: freeRemaining - 1 };
6029
+ }
6030
+ const publicClient = viem.createPublicClient({
6031
+ chain: chains.base,
6032
+ transport: viem.http(rpcUrl)
6033
+ });
6034
+ const grossWei = await publicClient.readContract({
6035
+ address: getAddresses().entry,
6036
+ abi: ENTRY_ABI,
6037
+ functionName: "getDepositAmountWithFee",
6038
+ args: [netWei]
6039
+ });
6040
+ return { grossWei, feeWei: grossWei - netWei, dailyFreeUsed: false, dailyFreeRemaining: 0 };
6041
+ }
6042
+ var SUPPORTED_ASSETS = ["ETH", "USDC"];
6043
+ function createDepositCommand() {
6044
+ const deposit = new Command("deposit").description("Deposit ETH or USDC into Veil").argument("<asset>", "Asset to deposit (ETH or USDC)").argument("<amount>", "Amount to deposit \u2014 this is what arrives in your Veil balance").option("--address <address>", "Signer address (required in --unsigned mode unless SIGNER_ADDRESS or WALLET_KEY is set)").option("--unsigned", "Output unsigned transaction payload instead of sending").option("--json", "Output as JSON").addHelpText("after", `
6045
+ The amount you specify is the net amount that lands in your Veil balance.
6046
+ A 0.3% protocol fee is normally added on top, but each address gets
6047
+ free daily deposits (fee waived). The CLI checks automatically.
6048
+
6049
+ Examples:
6050
+ veil deposit ETH 0.1 # deposits 0.1 ETH (free or ~0.1003 ETH)
6051
+ veil deposit USDC 100 # deposits 100 USDC (free or ~100.30 USDC)
6052
+ veil deposit ETH 0.1 --unsigned --address 0x...
6053
+ SIGNER_ADDRESS=0x... veil deposit ETH 0.1 --unsigned
6054
+ veil deposit ETH 0.1 --json
6055
+ `).action(async (asset, amount, options) => {
6056
+ try {
6057
+ const assetUpper = asset.toUpperCase();
6058
+ if (!SUPPORTED_ASSETS.includes(assetUpper)) {
6059
+ throw new CLIError(ErrorCode.INVALID_AMOUNT, `Unsupported asset: ${asset}. Supported: ${SUPPORTED_ASSETS.join(", ")}`);
6060
+ }
6061
+ const amountNum = parseFloat(amount);
6062
+ const minimumNet = MINIMUM_NET[assetUpper];
6063
+ if (amountNum < minimumNet) {
6064
+ throw new CLIError(
6065
+ ErrorCode.INVALID_AMOUNT,
6066
+ `Minimum deposit is ${minimumNet} ${assetUpper}.`
6067
+ );
6068
+ }
6069
+ const rpcUrl = process.env.RPC_URL;
6070
+ const pool = assetUpper.toLowerCase();
6071
+ const poolConfig = POOL_CONFIG[pool];
6072
+ const netWei = assetUpper === "ETH" ? viem.parseEther(amount) : viem.parseUnits(amount, poolConfig.decimals);
6073
+ const progress = createProgressReporter();
6074
+ let config = null;
6075
+ let address;
6076
+ let feeRpcUrl = rpcUrl;
6077
+ if (options.unsigned) {
6078
+ const resolved = resolveAddress({ address: options.address }, { required: true });
6079
+ if (!resolved) {
6080
+ throw new CLIError(
6081
+ ErrorCode.WALLET_KEY_MISSING,
6082
+ "Must provide --address, set SIGNER_ADDRESS, or set WALLET_KEY env."
6083
+ );
6084
+ }
6085
+ address = resolved.address;
6086
+ } else {
6087
+ config = getConfig(options);
6088
+ address = getAddress(config.privateKey);
6089
+ feeRpcUrl = config.rpcUrl;
6090
+ }
6091
+ progress("Checking deposit fee...");
6092
+ const { grossWei, feeWei, dailyFreeUsed, dailyFreeRemaining } = await getGrossAmount(
6093
+ netWei,
6094
+ address,
6095
+ pool,
6096
+ feeRpcUrl
6097
+ );
6098
+ const grossStr = assetUpper === "ETH" ? viem.formatEther(grossWei) : viem.formatUnits(grossWei, poolConfig.decimals);
6099
+ const feeStr = assetUpper === "ETH" ? viem.formatEther(feeWei) : viem.formatUnits(feeWei, poolConfig.decimals);
6100
+ const depositKey = process.env.DEPOSIT_KEY;
6101
+ if (!depositKey) {
6102
+ throw new CLIError(ErrorCode.DEPOSIT_KEY_MISSING, 'DEPOSIT_KEY not set. Run "veil init" first.');
6103
+ }
6104
+ progress("Building transaction...");
6105
+ let tx;
6106
+ let approveTx = null;
6107
+ if (assetUpper === "USDC") {
6108
+ approveTx = buildApproveUSDCTx({ amount: grossStr });
6109
+ tx = buildDepositUSDCTx({ depositKey, amount: grossStr });
6110
+ } else {
6111
+ tx = buildDepositETHTx({ depositKey, amount: grossStr });
6112
+ }
6113
+ if (options.unsigned) {
6114
+ clearProgress();
6115
+ const payloads = [];
6116
+ if (approveTx) {
6117
+ payloads.push({
6118
+ step: "approve",
6119
+ to: approveTx.to,
6120
+ data: approveTx.data,
6121
+ value: "0",
6122
+ chainId: 8453
6123
+ });
6124
+ }
6125
+ payloads.push({
6126
+ step: "deposit",
6127
+ to: tx.to,
6128
+ data: tx.data,
6129
+ value: tx.value ? tx.value.toString() : "0",
6130
+ chainId: 8453
6131
+ });
6132
+ printJson(payloads.length === 1 ? payloads[0] : payloads);
6133
+ return;
6134
+ }
6135
+ if (!config) {
6136
+ throw new CLIError(ErrorCode.WALLET_KEY_MISSING, "WALLET_KEY env var required. Set it before running this command.");
6137
+ }
6138
+ if (assetUpper === "ETH") {
6139
+ progress("Checking balance...");
6140
+ const balance = await getBalance(address, config.rpcUrl);
6141
+ if (balance < grossWei) {
6142
+ clearProgress();
6143
+ throw new CLIError(
6144
+ ErrorCode.INSUFFICIENT_BALANCE,
6145
+ `Insufficient ETH balance. Have: ${viem.formatEther(balance)} ETH, Need: ${grossStr} ETH (${amount} + fee)`
6146
+ );
6147
+ }
6148
+ }
6149
+ if (approveTx) {
6150
+ progress(`Approving ${assetUpper}...`);
6151
+ const approvalResult = await sendTransaction(config, approveTx);
6152
+ if (assetUpper === "USDC") {
6153
+ const publicClient = viem.createPublicClient({
6154
+ chain: chains.base,
6155
+ transport: viem.http(config.rpcUrl)
6156
+ });
6157
+ const addresses = getAddresses();
6158
+ let allowance = await publicClient.readContract({
6159
+ address: getAddresses().usdcToken,
6160
+ abi: ERC20_ABI,
6161
+ functionName: "allowance",
6162
+ args: [address, addresses.entry]
6163
+ });
6164
+ for (let confirmations = 2; allowance < grossWei && confirmations <= 3; confirmations++) {
6165
+ await publicClient.waitForTransactionReceipt({
6166
+ hash: approvalResult.hash,
6167
+ confirmations
6168
+ });
6169
+ allowance = await publicClient.readContract({
6170
+ address: addresses.usdcToken,
6171
+ abi: ERC20_ABI,
6172
+ functionName: "allowance",
6173
+ args: [address, addresses.entry]
6174
+ });
6175
+ }
6176
+ if (allowance < grossWei) {
6177
+ throw new CLIError(
6178
+ ErrorCode.CONTRACT_ERROR,
6179
+ `USDC approval is not yet visible on RPC after confirmation. Allowance ${allowance.toString()} < required ${grossWei.toString()}.`
6180
+ );
6181
+ }
6182
+ }
6183
+ }
6184
+ progress("Sending deposit transaction...");
6185
+ const result = await sendTransaction(config, tx);
6186
+ progress("Confirming...");
6187
+ clearProgress();
6188
+ const output = {
6189
+ success: result.receipt.status === "success",
6190
+ hash: result.hash,
6191
+ asset: assetUpper,
6192
+ amount,
6193
+ fee: feeStr,
6194
+ dailyFreeUsed,
6195
+ totalSent: grossStr,
6196
+ blockNumber: result.receipt.blockNumber.toString()
6197
+ };
6198
+ if (options.json) {
6199
+ printJson(output);
6200
+ return;
6201
+ }
6202
+ const feeLabel = dailyFreeUsed ? `0 ${assetUpper} (free \u2014 ${dailyFreeRemaining} remaining today)` : `${feeStr} ${assetUpper} (0.3%)`;
6203
+ printHeader("Deposit Submitted");
6204
+ printFields([
6205
+ { label: "Asset", value: assetUpper },
6206
+ { label: "Amount", value: `${amount} ${assetUpper}` },
6207
+ { label: "Fee", value: feeLabel },
6208
+ { label: "Total sent", value: `${grossStr} ${assetUpper}` },
6209
+ { label: "From", value: address },
6210
+ { label: "Transaction", value: txUrl(result.hash) },
6211
+ { label: "Block", value: result.receipt.blockNumber }
6212
+ ]);
6213
+ printLine();
6214
+ } catch (error) {
6215
+ clearProgress();
6216
+ handleCLIError(error);
6217
+ }
6218
+ });
6219
+ return deposit;
6220
+ }
6180
6221
 
6181
6222
  // src/cli/commands/private-balance.ts
6182
6223
  var SUPPORTED_POOLS = ["eth", "usdc"];
@@ -6474,30 +6515,46 @@ async function buildMerkleTree(commitments) {
6474
6515
  const tree = new MerkleTree__default.default(MERKLE_TREE_HEIGHT, leaves, { hashFunction });
6475
6516
  return tree;
6476
6517
  }
6477
- var utils = null;
6478
- try {
6479
- const ffjavascript = __require("ffjavascript");
6480
- utils = ffjavascript.utils;
6481
- } catch {
6482
- console.warn("ffjavascript not found. Proof generation may not work.");
6518
+ var ffUtils = ffjavascript.utils;
6519
+ function isBrowserRuntime() {
6520
+ return !(typeof process !== "undefined" && !!process.versions?.node);
6521
+ }
6522
+ function stripTrailingSlash(value) {
6523
+ return value.endsWith("/") ? value.slice(0, -1) : value;
6524
+ }
6525
+ function normalizeCircuitBasePath(provingKeyPath, circuitName) {
6526
+ const resolvedPath = typeof provingKeyPath === "function" ? provingKeyPath(circuitName) : provingKeyPath;
6527
+ const withoutExtension = resolvedPath.replace(/\.(wasm|zkey)$/i, "");
6528
+ if (withoutExtension.endsWith(`/${circuitName}`) || withoutExtension.endsWith(`\\${circuitName}`)) {
6529
+ return withoutExtension;
6530
+ }
6531
+ return `${stripTrailingSlash(withoutExtension)}/${circuitName}`;
6532
+ }
6533
+ function importNodeModule(specifier) {
6534
+ const dynamicImport = new Function("specifier", "return import(specifier)");
6535
+ return dynamicImport(specifier);
6483
6536
  }
6484
- function findKeysDirectory() {
6537
+ async function findNodeKeysDirectory() {
6538
+ const [{ existsSync: existsSync2 }, pathModule, { fileURLToPath }] = await Promise.all([
6539
+ importNodeModule("node:fs"),
6540
+ importNodeModule("node:path"),
6541
+ importNodeModule("node:url")
6542
+ ]);
6543
+ const path = pathModule;
6485
6544
  const possiblePaths = [
6486
6545
  // When running from package (installed via npm)
6487
- path__namespace.resolve(__dirname, "..", "keys"),
6488
- path__namespace.resolve(__dirname, "..", "..", "keys"),
6546
+ path.resolve(process.cwd(), "node_modules", "@veil-cash", "sdk", "keys"),
6489
6547
  // When running from source
6490
- path__namespace.resolve(process.cwd(), "keys")
6491
- // ESM module path
6548
+ path.resolve(process.cwd(), "keys")
6492
6549
  ];
6493
6550
  try {
6494
- const currentFilePath = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
6495
- const currentDir = path__namespace.dirname(currentFilePath);
6496
- possiblePaths.unshift(path__namespace.resolve(currentDir, "..", "keys"));
6551
+ 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)));
6552
+ const currentDir = path.dirname(currentFilePath);
6553
+ possiblePaths.unshift(path.resolve(currentDir, "..", "keys"));
6497
6554
  } catch {
6498
6555
  }
6499
6556
  for (const p of possiblePaths) {
6500
- if (fs__namespace.existsSync(p) && fs__namespace.existsSync(path__namespace.join(p, "transaction2.wasm"))) {
6557
+ if (existsSync2(p) && existsSync2(path.join(p, "transaction2.wasm"))) {
6501
6558
  return p;
6502
6559
  }
6503
6560
  }
@@ -6505,26 +6562,48 @@ function findKeysDirectory() {
6505
6562
  "Circuit keys not found. Expected to find keys/ directory with transaction2.wasm and transaction2.zkey files."
6506
6563
  );
6507
6564
  }
6508
- async function prove(input, circuitName) {
6509
- if (!utils) {
6510
- throw new Error("ffjavascript is required for proof generation. Please install it: npm install ffjavascript");
6511
- }
6512
- const keysDir = findKeysDirectory();
6513
- const wasmPath = path__namespace.join(keysDir, `${circuitName}.wasm`);
6514
- const zkeyPath = path__namespace.join(keysDir, `${circuitName}.zkey`);
6515
- if (!fs__namespace.existsSync(wasmPath)) {
6565
+ async function resolveProvingKeyPaths(circuitName, provingKeyPath) {
6566
+ if (provingKeyPath) {
6567
+ const circuitBasePath = normalizeCircuitBasePath(provingKeyPath, circuitName);
6568
+ return {
6569
+ wasmPath: `${circuitBasePath}.wasm`,
6570
+ zkeyPath: `${circuitBasePath}.zkey`
6571
+ };
6572
+ }
6573
+ if (isBrowserRuntime()) {
6574
+ return {
6575
+ wasmPath: `/keys/${circuitName}.wasm`,
6576
+ zkeyPath: `/keys/${circuitName}.zkey`
6577
+ };
6578
+ }
6579
+ const keysDir = await findNodeKeysDirectory();
6580
+ return {
6581
+ wasmPath: `${keysDir}/${circuitName}.wasm`,
6582
+ zkeyPath: `${keysDir}/${circuitName}.zkey`
6583
+ };
6584
+ }
6585
+ async function assertNodeKeyFilesExist(wasmPath, zkeyPath) {
6586
+ if (isBrowserRuntime() || wasmPath.startsWith("http://") || wasmPath.startsWith("https://")) {
6587
+ return;
6588
+ }
6589
+ const { existsSync: existsSync2 } = await importNodeModule("node:fs");
6590
+ if (!existsSync2(wasmPath)) {
6516
6591
  throw new Error(`Circuit WASM file not found: ${wasmPath}`);
6517
6592
  }
6518
- if (!fs__namespace.existsSync(zkeyPath)) {
6593
+ if (!existsSync2(zkeyPath)) {
6519
6594
  throw new Error(`Circuit zkey file not found: ${zkeyPath}`);
6520
6595
  }
6596
+ }
6597
+ async function prove(input, circuitName, options = {}) {
6598
+ const { wasmPath, zkeyPath } = await resolveProvingKeyPaths(circuitName, options.provingKeyPath);
6599
+ await assertNodeKeyFilesExist(wasmPath, zkeyPath);
6521
6600
  const result = await snarkjs.groth16.fullProve(
6522
- utils.stringifyBigInts(input),
6601
+ ffUtils.stringifyBigInts(input),
6523
6602
  wasmPath,
6524
6603
  zkeyPath,
6525
6604
  void 0,
6526
6605
  void 0,
6527
- { singleThread: true }
6606
+ { singleThread: options.singleThread ?? true }
6528
6607
  );
6529
6608
  const proof = result.proof;
6530
6609
  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);
@@ -6548,7 +6627,8 @@ async function getProof({
6548
6627
  fee,
6549
6628
  recipient,
6550
6629
  relayer,
6551
- onProgress
6630
+ onProgress,
6631
+ provingKeyPath
6552
6632
  }) {
6553
6633
  inputs = shuffle([...inputs]);
6554
6634
  outputs = shuffle([...outputs]);
@@ -6608,7 +6688,7 @@ async function getProof({
6608
6688
  };
6609
6689
  onProgress?.("Generating ZK proof...", `${inputs.length} inputs`);
6610
6690
  const circuitName = selectCircuit(inputs.length);
6611
- const proof = await prove(proofInput, circuitName);
6691
+ const proof = await prove(proofInput, circuitName, { provingKeyPath });
6612
6692
  const args = {
6613
6693
  proof,
6614
6694
  root: toFixedHex(proofInput.root),
@@ -6630,7 +6710,8 @@ async function prepareTransaction({
6630
6710
  fee = 0,
6631
6711
  recipient = 0,
6632
6712
  relayer = 0,
6633
- onProgress
6713
+ onProgress,
6714
+ provingKeyPath
6634
6715
  }) {
6635
6716
  if (inputs.length > 16 || outputs.length > 2) {
6636
6717
  throw new Error("Incorrect inputs/outputs count. Maximum: 16 inputs, 2 outputs.");
@@ -6652,7 +6733,8 @@ async function prepareTransaction({
6652
6733
  fee: BigInt(fee),
6653
6734
  recipient: String(recipient),
6654
6735
  relayer: String(relayer),
6655
- onProgress
6736
+ onProgress,
6737
+ provingKeyPath
6656
6738
  });
6657
6739
  return result;
6658
6740
  }
@@ -6802,6 +6884,7 @@ async function buildWithdrawProof(options) {
6802
6884
  keypair,
6803
6885
  pool = "eth",
6804
6886
  rpcUrl,
6887
+ provingKeyPath,
6805
6888
  onProgress
6806
6889
  } = options;
6807
6890
  const poolConfig = POOL_CONFIG[pool];
@@ -6865,7 +6948,8 @@ async function buildWithdrawProof(options) {
6865
6948
  fee: 0,
6866
6949
  recipient,
6867
6950
  relayer: "0x0000000000000000000000000000000000000000",
6868
- onProgress
6951
+ onProgress,
6952
+ provingKeyPath
6869
6953
  });
6870
6954
  return {
6871
6955
  proofArgs: {
@@ -7026,6 +7110,7 @@ async function buildTransferProof(options) {
7026
7110
  senderKeypair,
7027
7111
  pool = "eth",
7028
7112
  rpcUrl,
7113
+ provingKeyPath,
7029
7114
  onProgress
7030
7115
  } = options;
7031
7116
  const poolConfig = POOL_CONFIG[pool];
@@ -7104,7 +7189,8 @@ async function buildTransferProof(options) {
7104
7189
  fee: 0,
7105
7190
  recipient: "0x0000000000000000000000000000000000000000",
7106
7191
  relayer: "0x0000000000000000000000000000000000000000",
7107
- onProgress
7192
+ onProgress,
7193
+ provingKeyPath
7108
7194
  });
7109
7195
  return {
7110
7196
  proofArgs: {
@@ -7146,7 +7232,7 @@ async function transfer(options) {
7146
7232
  };
7147
7233
  }
7148
7234
  async function mergeUtxos(options) {
7149
- const { amount, keypair, pool = "eth", rpcUrl, onProgress } = options;
7235
+ const { amount, keypair, pool = "eth", rpcUrl, provingKeyPath, onProgress } = options;
7150
7236
  const poolConfig = POOL_CONFIG[pool];
7151
7237
  const poolAddress = getPoolAddress(pool);
7152
7238
  onProgress?.("Fetching your UTXOs...");
@@ -7214,7 +7300,8 @@ async function mergeUtxos(options) {
7214
7300
  fee: 0,
7215
7301
  recipient: "0x0000000000000000000000000000000000000000",
7216
7302
  relayer: "0x0000000000000000000000000000000000000000",
7217
- onProgress
7303
+ onProgress,
7304
+ provingKeyPath
7218
7305
  });
7219
7306
  onProgress?.("Submitting to relay...");
7220
7307
  const relayResult = await submitRelay({
@@ -7905,6 +7992,7 @@ async function mergeSubaccount(options) {
7905
7992
  pool = "eth",
7906
7993
  rpcUrl,
7907
7994
  relayUrl,
7995
+ provingKeyPath,
7908
7996
  onProgress
7909
7997
  } = options;
7910
7998
  const normalizedSlot = normalizeSlot(slot);
@@ -7997,7 +8085,8 @@ async function mergeSubaccount(options) {
7997
8085
  fee: 0,
7998
8086
  recipient: "0x0000000000000000000000000000000000000000",
7999
8087
  relayer: "0x0000000000000000000000000000000000000000",
8000
- onProgress
8088
+ onProgress,
8089
+ provingKeyPath
8001
8090
  });
8002
8091
  onProgress?.("Submitting to relay...");
8003
8092
  const relayResult = await submitRelay({