@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.
- package/README.md +8 -6
- package/SDK.md +63 -5
- package/dist/cli/index.cjs +372 -283
- package/dist/index.cjs +141 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +139 -64
- package/dist/index.d.ts +139 -64
- package/dist/index.js +118 -49
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/skills/veil/SKILL.md +6 -4
- package/skills/veil/reference.md +5 -5
- package/src/abi.ts +8 -0
- package/src/balance.ts +48 -0
- package/src/cli/commands/deposit.ts +61 -15
- package/src/ffjavascript.d.ts +28 -0
- package/src/index.ts +2 -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/dist/cli/index.cjs
CHANGED
|
@@ -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
|
|
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 }; }
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
1238
|
-
var
|
|
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 (
|
|
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 =
|
|
2250
|
-
if (
|
|
2251
|
-
if (sourceExt.includes(
|
|
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) =>
|
|
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 =
|
|
2248
|
+
resolvedScriptPath = fs.realpathSync(this._scriptPath);
|
|
2266
2249
|
} catch {
|
|
2267
2250
|
resolvedScriptPath = this._scriptPath;
|
|
2268
2251
|
}
|
|
2269
|
-
executableDir =
|
|
2270
|
-
|
|
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 =
|
|
2260
|
+
const legacyName = path.basename(
|
|
2278
2261
|
this._scriptPath,
|
|
2279
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
3220
|
-
if (
|
|
3221
|
-
this._executableDir =
|
|
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
|
|
3571
|
-
var
|
|
3553
|
+
var fs = __require("fs");
|
|
3554
|
+
var path = __require("path");
|
|
3572
3555
|
var os = __require("os");
|
|
3573
|
-
var
|
|
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 (
|
|
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 =
|
|
3703
|
+
possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
|
|
3721
3704
|
}
|
|
3722
|
-
if (
|
|
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] === "~" ?
|
|
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 =
|
|
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
|
|
3756
|
+
for (const path2 of optionPaths) {
|
|
3774
3757
|
try {
|
|
3775
|
-
const parsed = DotenvModule.parse(
|
|
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 ${
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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((
|
|
5410
|
+
return new Promise((resolve) => {
|
|
5419
5411
|
rl.question(`${question} (y/n): `, (answer) => {
|
|
5420
5412
|
rl.close();
|
|
5421
|
-
|
|
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
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
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
|
|
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
|
-
|
|
6488
|
-
path__namespace.resolve(__dirname, "..", "..", "keys"),
|
|
6546
|
+
path.resolve(process.cwd(), "node_modules", "@veil-cash", "sdk", "keys"),
|
|
6489
6547
|
// When running from source
|
|
6490
|
-
|
|
6491
|
-
// ESM module path
|
|
6548
|
+
path.resolve(process.cwd(), "keys")
|
|
6492
6549
|
];
|
|
6493
6550
|
try {
|
|
6494
|
-
const currentFilePath =
|
|
6495
|
-
const currentDir =
|
|
6496
|
-
possiblePaths.unshift(
|
|
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 (
|
|
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
|
|
6509
|
-
if (
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
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 (!
|
|
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
|
-
|
|
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({
|