@veil-cash/sdk 0.6.4 → 0.7.0
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 +47 -5
- package/SDK.md +77 -11
- package/dist/cli/index.cjs +229 -237
- package/dist/index.cjs +386 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -38
- package/dist/index.d.ts +131 -38
- package/dist/index.js +355 -40
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/skills/veil/SKILL.md +1 -3
- package/skills/veil/reference.md +3 -3
- package/src/abi.ts +0 -8
- package/src/balance.ts +0 -48
- package/src/cli/commands/deposit.ts +8 -27
- package/src/compat.ts +23 -0
- package/src/ffjavascript.d.ts +13 -8
- package/src/index.ts +21 -1
- package/src/keypair.ts +1 -1
- package/src/types.ts +5 -0
- package/src/utils.ts +4 -2
- package/src/withdraw.ts +2 -1
- package/src/x402.ts +546 -0
package/dist/cli/index.cjs
CHANGED
|
@@ -9,8 +9,8 @@ var fs = require('fs');
|
|
|
9
9
|
var path = require('path');
|
|
10
10
|
var ethers = require('ethers');
|
|
11
11
|
var buffer = require('buffer');
|
|
12
|
-
var
|
|
13
|
-
var
|
|
12
|
+
var _ethSigUtil = require('eth-sig-util');
|
|
13
|
+
var _circomlib = require('circomlib');
|
|
14
14
|
var MerkleTree = require('fixed-merkle-tree-legacy');
|
|
15
15
|
var snarkjs = require('snarkjs');
|
|
16
16
|
var ffjavascript = require('ffjavascript');
|
|
@@ -18,8 +18,26 @@ var ffjavascript = require('ffjavascript');
|
|
|
18
18
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
19
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function _interopNamespace(e) {
|
|
22
|
+
if (e && e.__esModule) return e;
|
|
23
|
+
var n = Object.create(null);
|
|
24
|
+
if (e) {
|
|
25
|
+
Object.keys(e).forEach(function (k) {
|
|
26
|
+
if (k !== 'default') {
|
|
27
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
28
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return e[k]; }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
n.default = e;
|
|
36
|
+
return Object.freeze(n);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var _ethSigUtil__namespace = /*#__PURE__*/_interopNamespace(_ethSigUtil);
|
|
40
|
+
var _circomlib__namespace = /*#__PURE__*/_interopNamespace(_circomlib);
|
|
23
41
|
var MerkleTree__default = /*#__PURE__*/_interopDefault(MerkleTree);
|
|
24
42
|
|
|
25
43
|
var __create = Object.create;
|
|
@@ -4186,14 +4204,6 @@ var QUEUE_ABI = [
|
|
|
4186
4204
|
outputs: [{ name: "count", type: "uint256" }],
|
|
4187
4205
|
stateMutability: "view",
|
|
4188
4206
|
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"
|
|
4197
4207
|
}
|
|
4198
4208
|
];
|
|
4199
4209
|
var POOL_ABI = [
|
|
@@ -5090,7 +5100,16 @@ function loadEnv() {
|
|
|
5090
5100
|
} catch {
|
|
5091
5101
|
}
|
|
5092
5102
|
}
|
|
5093
|
-
|
|
5103
|
+
function resolveInterop(mod) {
|
|
5104
|
+
if (mod && typeof mod === "object" && "default" in mod) {
|
|
5105
|
+
const defaultVal = mod.default;
|
|
5106
|
+
if (defaultVal != null) return defaultVal;
|
|
5107
|
+
}
|
|
5108
|
+
return mod;
|
|
5109
|
+
}
|
|
5110
|
+
var ethSigUtil = resolveInterop(_ethSigUtil__namespace);
|
|
5111
|
+
var circomlib = resolveInterop(_circomlib__namespace);
|
|
5112
|
+
var poseidon = circomlib.poseidon;
|
|
5094
5113
|
var FIELD_SIZE = BigInt(
|
|
5095
5114
|
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
|
5096
5115
|
);
|
|
@@ -5099,7 +5118,9 @@ var poseidonHash2 = (a, b) => poseidonHash([a, b]);
|
|
|
5099
5118
|
var randomBN = (nbytes = 31) => {
|
|
5100
5119
|
const cryptoApi = globalThis.crypto;
|
|
5101
5120
|
if (!cryptoApi?.getRandomValues) {
|
|
5102
|
-
throw new Error(
|
|
5121
|
+
throw new Error(
|
|
5122
|
+
"Secure random number generation is unavailable. Provide globalThis.crypto.getRandomValues in this runtime."
|
|
5123
|
+
);
|
|
5103
5124
|
}
|
|
5104
5125
|
const bytes = cryptoApi.getRandomValues(new Uint8Array(nbytes));
|
|
5105
5126
|
let hex = "0x";
|
|
@@ -5198,7 +5219,7 @@ var Keypair = class _Keypair {
|
|
|
5198
5219
|
constructor(privkey = ethers.ethers.Wallet.createRandom().privateKey) {
|
|
5199
5220
|
this.privkey = privkey;
|
|
5200
5221
|
this.pubkey = poseidonHash([this.privkey]);
|
|
5201
|
-
this.encryptionKey =
|
|
5222
|
+
this.encryptionKey = ethSigUtil.getEncryptionPublicKey(privkey.slice(2));
|
|
5202
5223
|
}
|
|
5203
5224
|
/**
|
|
5204
5225
|
* Get the deposit key for this keypair
|
|
@@ -5316,7 +5337,7 @@ var Keypair = class _Keypair {
|
|
|
5316
5337
|
*/
|
|
5317
5338
|
encrypt(bytes) {
|
|
5318
5339
|
return packEncryptedMessage(
|
|
5319
|
-
|
|
5340
|
+
ethSigUtil.encrypt(
|
|
5320
5341
|
this.encryptionKey,
|
|
5321
5342
|
{ data: bytes.toString("base64") },
|
|
5322
5343
|
"x25519-xsalsa20-poly1305"
|
|
@@ -5333,7 +5354,7 @@ var Keypair = class _Keypair {
|
|
|
5333
5354
|
throw new Error("Cannot decrypt without private key");
|
|
5334
5355
|
}
|
|
5335
5356
|
return buffer.Buffer.from(
|
|
5336
|
-
|
|
5357
|
+
ethSigUtil.decrypt(unpackEncryptedMessage(data), this.privkey.slice(2)),
|
|
5337
5358
|
"base64"
|
|
5338
5359
|
);
|
|
5339
5360
|
}
|
|
@@ -5776,6 +5797,195 @@ function createRegisterCommand() {
|
|
|
5776
5797
|
});
|
|
5777
5798
|
return register;
|
|
5778
5799
|
}
|
|
5800
|
+
var MINIMUM_NET = {
|
|
5801
|
+
ETH: 0.01,
|
|
5802
|
+
USDC: 10
|
|
5803
|
+
};
|
|
5804
|
+
async function getGrossAmount(netWei, rpcUrl) {
|
|
5805
|
+
const publicClient = viem.createPublicClient({
|
|
5806
|
+
chain: chains.base,
|
|
5807
|
+
transport: viem.http(rpcUrl)
|
|
5808
|
+
});
|
|
5809
|
+
const grossWei = await publicClient.readContract({
|
|
5810
|
+
address: getAddresses().entry,
|
|
5811
|
+
abi: ENTRY_ABI,
|
|
5812
|
+
functionName: "getDepositAmountWithFee",
|
|
5813
|
+
args: [netWei]
|
|
5814
|
+
});
|
|
5815
|
+
return { grossWei, feeWei: grossWei - netWei };
|
|
5816
|
+
}
|
|
5817
|
+
var SUPPORTED_ASSETS = ["ETH", "USDC"];
|
|
5818
|
+
function createDepositCommand() {
|
|
5819
|
+
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", `
|
|
5820
|
+
The amount you specify is the net amount that lands in your Veil balance.
|
|
5821
|
+
A 0.3% protocol fee is added on top.
|
|
5822
|
+
|
|
5823
|
+
Examples:
|
|
5824
|
+
veil deposit ETH 0.1 # deposits 0.1 ETH (~0.1003 ETH sent)
|
|
5825
|
+
veil deposit USDC 100 # deposits 100 USDC (~100.30 USDC sent)
|
|
5826
|
+
veil deposit ETH 0.1 --unsigned --address 0x...
|
|
5827
|
+
SIGNER_ADDRESS=0x... veil deposit ETH 0.1 --unsigned
|
|
5828
|
+
veil deposit ETH 0.1 --json
|
|
5829
|
+
`).action(async (asset, amount, options) => {
|
|
5830
|
+
try {
|
|
5831
|
+
const assetUpper = asset.toUpperCase();
|
|
5832
|
+
if (!SUPPORTED_ASSETS.includes(assetUpper)) {
|
|
5833
|
+
throw new CLIError(ErrorCode.INVALID_AMOUNT, `Unsupported asset: ${asset}. Supported: ${SUPPORTED_ASSETS.join(", ")}`);
|
|
5834
|
+
}
|
|
5835
|
+
const amountNum = parseFloat(amount);
|
|
5836
|
+
const minimumNet = MINIMUM_NET[assetUpper];
|
|
5837
|
+
if (amountNum < minimumNet) {
|
|
5838
|
+
throw new CLIError(
|
|
5839
|
+
ErrorCode.INVALID_AMOUNT,
|
|
5840
|
+
`Minimum deposit is ${minimumNet} ${assetUpper}.`
|
|
5841
|
+
);
|
|
5842
|
+
}
|
|
5843
|
+
const rpcUrl = process.env.RPC_URL;
|
|
5844
|
+
const pool = assetUpper.toLowerCase();
|
|
5845
|
+
const poolConfig = POOL_CONFIG[pool];
|
|
5846
|
+
const netWei = assetUpper === "ETH" ? viem.parseEther(amount) : viem.parseUnits(amount, poolConfig.decimals);
|
|
5847
|
+
const progress = createProgressReporter();
|
|
5848
|
+
let config = null;
|
|
5849
|
+
let address;
|
|
5850
|
+
let feeRpcUrl = rpcUrl;
|
|
5851
|
+
if (options.unsigned) {
|
|
5852
|
+
const resolved = resolveAddress({ address: options.address }, { required: true });
|
|
5853
|
+
if (!resolved) {
|
|
5854
|
+
throw new CLIError(
|
|
5855
|
+
ErrorCode.WALLET_KEY_MISSING,
|
|
5856
|
+
"Must provide --address, set SIGNER_ADDRESS, or set WALLET_KEY env."
|
|
5857
|
+
);
|
|
5858
|
+
}
|
|
5859
|
+
address = resolved.address;
|
|
5860
|
+
} else {
|
|
5861
|
+
config = getConfig(options);
|
|
5862
|
+
address = getAddress(config.privateKey);
|
|
5863
|
+
feeRpcUrl = config.rpcUrl;
|
|
5864
|
+
}
|
|
5865
|
+
progress("Checking deposit fee...");
|
|
5866
|
+
const { grossWei, feeWei } = await getGrossAmount(netWei, feeRpcUrl);
|
|
5867
|
+
const grossStr = assetUpper === "ETH" ? viem.formatEther(grossWei) : viem.formatUnits(grossWei, poolConfig.decimals);
|
|
5868
|
+
const feeStr = assetUpper === "ETH" ? viem.formatEther(feeWei) : viem.formatUnits(feeWei, poolConfig.decimals);
|
|
5869
|
+
const depositKey = process.env.DEPOSIT_KEY;
|
|
5870
|
+
if (!depositKey) {
|
|
5871
|
+
throw new CLIError(ErrorCode.DEPOSIT_KEY_MISSING, 'DEPOSIT_KEY not set. Run "veil init" first.');
|
|
5872
|
+
}
|
|
5873
|
+
progress("Building transaction...");
|
|
5874
|
+
let tx;
|
|
5875
|
+
let approveTx = null;
|
|
5876
|
+
if (assetUpper === "USDC") {
|
|
5877
|
+
approveTx = buildApproveUSDCTx({ amount: grossStr });
|
|
5878
|
+
tx = buildDepositUSDCTx({ depositKey, amount: grossStr });
|
|
5879
|
+
} else {
|
|
5880
|
+
tx = buildDepositETHTx({ depositKey, amount: grossStr });
|
|
5881
|
+
}
|
|
5882
|
+
if (options.unsigned) {
|
|
5883
|
+
clearProgress();
|
|
5884
|
+
const payloads = [];
|
|
5885
|
+
if (approveTx) {
|
|
5886
|
+
payloads.push({
|
|
5887
|
+
step: "approve",
|
|
5888
|
+
to: approveTx.to,
|
|
5889
|
+
data: approveTx.data,
|
|
5890
|
+
value: "0",
|
|
5891
|
+
chainId: 8453
|
|
5892
|
+
});
|
|
5893
|
+
}
|
|
5894
|
+
payloads.push({
|
|
5895
|
+
step: "deposit",
|
|
5896
|
+
to: tx.to,
|
|
5897
|
+
data: tx.data,
|
|
5898
|
+
value: tx.value ? tx.value.toString() : "0",
|
|
5899
|
+
chainId: 8453
|
|
5900
|
+
});
|
|
5901
|
+
printJson(payloads.length === 1 ? payloads[0] : payloads);
|
|
5902
|
+
return;
|
|
5903
|
+
}
|
|
5904
|
+
if (!config) {
|
|
5905
|
+
throw new CLIError(ErrorCode.WALLET_KEY_MISSING, "WALLET_KEY env var required. Set it before running this command.");
|
|
5906
|
+
}
|
|
5907
|
+
if (assetUpper === "ETH") {
|
|
5908
|
+
progress("Checking balance...");
|
|
5909
|
+
const balance = await getBalance(address, config.rpcUrl);
|
|
5910
|
+
if (balance < grossWei) {
|
|
5911
|
+
clearProgress();
|
|
5912
|
+
throw new CLIError(
|
|
5913
|
+
ErrorCode.INSUFFICIENT_BALANCE,
|
|
5914
|
+
`Insufficient ETH balance. Have: ${viem.formatEther(balance)} ETH, Need: ${grossStr} ETH (${amount} + fee)`
|
|
5915
|
+
);
|
|
5916
|
+
}
|
|
5917
|
+
}
|
|
5918
|
+
if (approveTx) {
|
|
5919
|
+
progress(`Approving ${assetUpper}...`);
|
|
5920
|
+
const approvalResult = await sendTransaction(config, approveTx);
|
|
5921
|
+
if (assetUpper === "USDC") {
|
|
5922
|
+
const publicClient = viem.createPublicClient({
|
|
5923
|
+
chain: chains.base,
|
|
5924
|
+
transport: viem.http(config.rpcUrl)
|
|
5925
|
+
});
|
|
5926
|
+
const addresses = getAddresses();
|
|
5927
|
+
let allowance = await publicClient.readContract({
|
|
5928
|
+
address: getAddresses().usdcToken,
|
|
5929
|
+
abi: ERC20_ABI,
|
|
5930
|
+
functionName: "allowance",
|
|
5931
|
+
args: [address, addresses.entry]
|
|
5932
|
+
});
|
|
5933
|
+
for (let confirmations = 2; allowance < grossWei && confirmations <= 3; confirmations++) {
|
|
5934
|
+
await publicClient.waitForTransactionReceipt({
|
|
5935
|
+
hash: approvalResult.hash,
|
|
5936
|
+
confirmations
|
|
5937
|
+
});
|
|
5938
|
+
allowance = await publicClient.readContract({
|
|
5939
|
+
address: addresses.usdcToken,
|
|
5940
|
+
abi: ERC20_ABI,
|
|
5941
|
+
functionName: "allowance",
|
|
5942
|
+
args: [address, addresses.entry]
|
|
5943
|
+
});
|
|
5944
|
+
}
|
|
5945
|
+
if (allowance < grossWei) {
|
|
5946
|
+
throw new CLIError(
|
|
5947
|
+
ErrorCode.CONTRACT_ERROR,
|
|
5948
|
+
`USDC approval is not yet visible on RPC after confirmation. Allowance ${allowance.toString()} < required ${grossWei.toString()}.`
|
|
5949
|
+
);
|
|
5950
|
+
}
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
progress("Sending deposit transaction...");
|
|
5954
|
+
const result = await sendTransaction(config, tx);
|
|
5955
|
+
progress("Confirming...");
|
|
5956
|
+
clearProgress();
|
|
5957
|
+
const output = {
|
|
5958
|
+
success: result.receipt.status === "success",
|
|
5959
|
+
hash: result.hash,
|
|
5960
|
+
asset: assetUpper,
|
|
5961
|
+
amount,
|
|
5962
|
+
fee: feeStr,
|
|
5963
|
+
totalSent: grossStr,
|
|
5964
|
+
blockNumber: result.receipt.blockNumber.toString()
|
|
5965
|
+
};
|
|
5966
|
+
if (options.json) {
|
|
5967
|
+
printJson(output);
|
|
5968
|
+
return;
|
|
5969
|
+
}
|
|
5970
|
+
const feeLabel = `${feeStr} ${assetUpper} (0.3%)`;
|
|
5971
|
+
printHeader("Deposit Submitted");
|
|
5972
|
+
printFields([
|
|
5973
|
+
{ label: "Asset", value: assetUpper },
|
|
5974
|
+
{ label: "Amount", value: `${amount} ${assetUpper}` },
|
|
5975
|
+
{ label: "Fee", value: feeLabel },
|
|
5976
|
+
{ label: "Total sent", value: `${grossStr} ${assetUpper}` },
|
|
5977
|
+
{ label: "From", value: address },
|
|
5978
|
+
{ label: "Transaction", value: txUrl(result.hash) },
|
|
5979
|
+
{ label: "Block", value: result.receipt.blockNumber }
|
|
5980
|
+
]);
|
|
5981
|
+
printLine();
|
|
5982
|
+
} catch (error) {
|
|
5983
|
+
clearProgress();
|
|
5984
|
+
handleCLIError(error);
|
|
5985
|
+
}
|
|
5986
|
+
});
|
|
5987
|
+
return deposit;
|
|
5988
|
+
}
|
|
5779
5989
|
var Utxo = class _Utxo {
|
|
5780
5990
|
amount;
|
|
5781
5991
|
blinding;
|
|
@@ -5906,25 +6116,6 @@ async function getQueueBalance(options) {
|
|
|
5906
6116
|
pendingCount: pendingDeposits.length
|
|
5907
6117
|
};
|
|
5908
6118
|
}
|
|
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
|
-
}
|
|
5928
6119
|
async function getPrivateBalance(options) {
|
|
5929
6120
|
const { keypair, pool = "eth", rpcUrl, onProgress } = options;
|
|
5930
6121
|
const poolAddress = getPoolAddress(pool);
|
|
@@ -6018,206 +6209,6 @@ async function getPrivateBalance(options) {
|
|
|
6018
6209
|
utxos: utxoInfos
|
|
6019
6210
|
};
|
|
6020
6211
|
}
|
|
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
|
-
}
|
|
6221
6212
|
|
|
6222
6213
|
// src/cli/commands/private-balance.ts
|
|
6223
6214
|
var SUPPORTED_POOLS = ["eth", "usdc"];
|
|
@@ -6967,12 +6958,13 @@ async function buildWithdrawProof(options) {
|
|
|
6967
6958
|
};
|
|
6968
6959
|
}
|
|
6969
6960
|
async function withdraw(options) {
|
|
6970
|
-
const { amount, recipient, pool = "eth", onProgress } = options;
|
|
6961
|
+
const { amount, recipient, pool = "eth", onProgress, relayUrl } = options;
|
|
6971
6962
|
const proof = await buildWithdrawProof(options);
|
|
6972
6963
|
onProgress?.("Submitting to relay...");
|
|
6973
6964
|
const relayResult = await submitRelay({
|
|
6974
6965
|
type: "withdraw",
|
|
6975
6966
|
pool,
|
|
6967
|
+
relayUrl,
|
|
6976
6968
|
proofArgs: proof.proofArgs,
|
|
6977
6969
|
extData: proof.extData,
|
|
6978
6970
|
metadata: {
|