@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/index.js
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
2
|
import { Buffer } from 'buffer';
|
|
3
3
|
import { privateKeyToAccount, privateKeyToAddress } from 'viem/accounts';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import * as _ethSigUtil from 'eth-sig-util';
|
|
5
|
+
import * as _circomlib from 'circomlib';
|
|
6
6
|
import { encodeFunctionData, parseEther, parseUnits, createPublicClient, http, formatUnits, keccak256, encodePacked, isAddress, formatEther } from 'viem';
|
|
7
7
|
import { base } from 'viem/chains';
|
|
8
8
|
import MerkleTree from 'fixed-merkle-tree-legacy';
|
|
9
9
|
import { groth16 } from 'snarkjs';
|
|
10
10
|
import { utils } from 'ffjavascript';
|
|
11
|
+
import { x402Client, x402HTTPClient } from '@x402/core/client';
|
|
12
|
+
import { registerExactEvmScheme } from '@x402/evm/exact/client';
|
|
13
|
+
import { toClientEvmSigner } from '@x402/evm';
|
|
11
14
|
|
|
12
15
|
// src/keypair.ts
|
|
16
|
+
function resolveInterop(mod) {
|
|
17
|
+
if (mod && typeof mod === "object" && "default" in mod) {
|
|
18
|
+
const defaultVal = mod.default;
|
|
19
|
+
if (defaultVal != null) return defaultVal;
|
|
20
|
+
}
|
|
21
|
+
return mod;
|
|
22
|
+
}
|
|
23
|
+
var ethSigUtil = resolveInterop(_ethSigUtil);
|
|
24
|
+
var circomlib = resolveInterop(_circomlib);
|
|
13
25
|
var poseidon = circomlib.poseidon;
|
|
14
26
|
var FIELD_SIZE = BigInt(
|
|
15
27
|
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
|
@@ -19,7 +31,9 @@ var poseidonHash2 = (a, b) => poseidonHash([a, b]);
|
|
|
19
31
|
var randomBN = (nbytes = 31) => {
|
|
20
32
|
const cryptoApi = globalThis.crypto;
|
|
21
33
|
if (!cryptoApi?.getRandomValues) {
|
|
22
|
-
throw new Error(
|
|
34
|
+
throw new Error(
|
|
35
|
+
"Secure random number generation is unavailable. Provide globalThis.crypto.getRandomValues in this runtime."
|
|
36
|
+
);
|
|
23
37
|
}
|
|
24
38
|
const bytes = cryptoApi.getRandomValues(new Uint8Array(nbytes));
|
|
25
39
|
let hex = "0x";
|
|
@@ -591,14 +605,6 @@ var QUEUE_ABI = [
|
|
|
591
605
|
outputs: [{ name: "count", type: "uint256" }],
|
|
592
606
|
stateMutability: "view",
|
|
593
607
|
type: "function"
|
|
594
|
-
},
|
|
595
|
-
// Get remaining daily free deposits for an address (V3+)
|
|
596
|
-
{
|
|
597
|
-
inputs: [{ name: "_depositor", type: "address" }],
|
|
598
|
-
name: "getDailyFreeRemaining",
|
|
599
|
-
outputs: [{ name: "remaining", type: "uint256" }],
|
|
600
|
-
stateMutability: "view",
|
|
601
|
-
type: "function"
|
|
602
608
|
}
|
|
603
609
|
];
|
|
604
610
|
var POOL_ABI = [
|
|
@@ -1316,25 +1322,6 @@ async function getQueueBalance(options) {
|
|
|
1316
1322
|
pendingCount: pendingDeposits.length
|
|
1317
1323
|
};
|
|
1318
1324
|
}
|
|
1319
|
-
async function getDailyFreeRemaining(options) {
|
|
1320
|
-
const { address, pool = "eth", rpcUrl } = options;
|
|
1321
|
-
const queueAddress = getQueueAddress(pool);
|
|
1322
|
-
const publicClient = createPublicClient({
|
|
1323
|
-
chain: base,
|
|
1324
|
-
transport: http(rpcUrl)
|
|
1325
|
-
});
|
|
1326
|
-
try {
|
|
1327
|
-
const remaining = await publicClient.readContract({
|
|
1328
|
-
address: queueAddress,
|
|
1329
|
-
abi: QUEUE_ABI,
|
|
1330
|
-
functionName: "getDailyFreeRemaining",
|
|
1331
|
-
args: [address]
|
|
1332
|
-
});
|
|
1333
|
-
return Number(remaining);
|
|
1334
|
-
} catch {
|
|
1335
|
-
return 0;
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
1325
|
async function getPrivateBalance(options) {
|
|
1339
1326
|
const { keypair, pool = "eth", rpcUrl, onProgress } = options;
|
|
1340
1327
|
const poolAddress = getPoolAddress(pool);
|
|
@@ -1914,12 +1901,13 @@ async function buildWithdrawProof(options) {
|
|
|
1914
1901
|
};
|
|
1915
1902
|
}
|
|
1916
1903
|
async function withdraw(options) {
|
|
1917
|
-
const { amount, recipient, pool = "eth", onProgress } = options;
|
|
1904
|
+
const { amount, recipient, pool = "eth", onProgress, relayUrl } = options;
|
|
1918
1905
|
const proof = await buildWithdrawProof(options);
|
|
1919
1906
|
onProgress?.("Submitting to relay...");
|
|
1920
1907
|
const relayResult = await submitRelay({
|
|
1921
1908
|
type: "withdraw",
|
|
1922
1909
|
pool,
|
|
1910
|
+
relayUrl,
|
|
1923
1911
|
proofArgs: proof.proofArgs,
|
|
1924
1912
|
extData: proof.extData,
|
|
1925
1913
|
metadata: {
|
|
@@ -1937,6 +1925,333 @@ async function withdraw(options) {
|
|
|
1937
1925
|
recipient
|
|
1938
1926
|
};
|
|
1939
1927
|
}
|
|
1928
|
+
var X402_PAYER_DOMAIN = "veil-x402-payer";
|
|
1929
|
+
var BASE_NETWORK = `eip155:${ADDRESSES.chainId}`;
|
|
1930
|
+
var USDC_DECIMALS = POOL_CONFIG.usdc.decimals;
|
|
1931
|
+
var X402_MIN_WITHDRAW_ATOMIC = 1000n;
|
|
1932
|
+
function assertPrivateKey(value, label) {
|
|
1933
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(value)) {
|
|
1934
|
+
throw new Error(`${label} must be a 0x-prefixed 32-byte hex string`);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
function normalizePayerIndex(index) {
|
|
1938
|
+
const normalized = typeof index === "bigint" ? index : typeof index === "number" ? BigInt(index) : BigInt(index);
|
|
1939
|
+
if (normalized < 0n) {
|
|
1940
|
+
throw new Error("payerIndex must be non-negative");
|
|
1941
|
+
}
|
|
1942
|
+
return normalized;
|
|
1943
|
+
}
|
|
1944
|
+
function normalizeAtomicAmount(amount) {
|
|
1945
|
+
if (!/^\d+$/.test(amount)) {
|
|
1946
|
+
throw new Error(`x402 amount must be an atomic integer string, received: ${amount}`);
|
|
1947
|
+
}
|
|
1948
|
+
if (BigInt(amount) <= 0n) {
|
|
1949
|
+
throw new Error("x402 amount must be greater than 0");
|
|
1950
|
+
}
|
|
1951
|
+
return amount;
|
|
1952
|
+
}
|
|
1953
|
+
function usdcAtomicToDecimalString(amountAtomic) {
|
|
1954
|
+
const atomic = typeof amountAtomic === "bigint" ? amountAtomic.toString() : normalizeAtomicAmount(amountAtomic);
|
|
1955
|
+
return formatUnits(BigInt(atomic), USDC_DECIMALS);
|
|
1956
|
+
}
|
|
1957
|
+
function usdcDecimalToAtomic(amount) {
|
|
1958
|
+
if (!/^\d+(\.\d+)?$/.test(amount.trim())) {
|
|
1959
|
+
throw new Error(`Invalid USDC amount: ${amount}`);
|
|
1960
|
+
}
|
|
1961
|
+
return parseUnits(amount.trim(), USDC_DECIMALS);
|
|
1962
|
+
}
|
|
1963
|
+
function deriveX402PayerKey(rootPrivateKey, index) {
|
|
1964
|
+
assertPrivateKey(rootPrivateKey, "rootPrivateKey");
|
|
1965
|
+
const normalizedIndex = normalizePayerIndex(index);
|
|
1966
|
+
return keccak256(
|
|
1967
|
+
encodePacked(
|
|
1968
|
+
["bytes32", "string", "uint256"],
|
|
1969
|
+
[rootPrivateKey, X402_PAYER_DOMAIN, normalizedIndex]
|
|
1970
|
+
)
|
|
1971
|
+
);
|
|
1972
|
+
}
|
|
1973
|
+
function deriveX402PayerAddress(rootPrivateKey, index) {
|
|
1974
|
+
return privateKeyToAddress(deriveX402PayerKey(rootPrivateKey, index));
|
|
1975
|
+
}
|
|
1976
|
+
function selectBaseUsdcExactRequirement(paymentRequired) {
|
|
1977
|
+
if (paymentRequired.x402Version !== 2) {
|
|
1978
|
+
throw new Error(`Unsupported x402 version ${paymentRequired.x402Version}; expected v2`);
|
|
1979
|
+
}
|
|
1980
|
+
const requirement = paymentRequired.accepts.find(
|
|
1981
|
+
(candidate) => candidate.scheme === "exact" && candidate.network === BASE_NETWORK && candidate.asset.toLowerCase() === ADDRESSES.usdcToken.toLowerCase()
|
|
1982
|
+
);
|
|
1983
|
+
if (!requirement) {
|
|
1984
|
+
throw new Error("No supported x402 payment requirement found. Veil supports x402 v2 exact Base USDC only.");
|
|
1985
|
+
}
|
|
1986
|
+
if (!isAddress(requirement.payTo)) {
|
|
1987
|
+
throw new Error("Selected x402 requirement has an invalid payTo address");
|
|
1988
|
+
}
|
|
1989
|
+
normalizeAtomicAmount(requirement.amount);
|
|
1990
|
+
return requirement;
|
|
1991
|
+
}
|
|
1992
|
+
async function parsePaymentRequired(response, httpClient) {
|
|
1993
|
+
let body;
|
|
1994
|
+
try {
|
|
1995
|
+
body = await response.clone().json();
|
|
1996
|
+
} catch {
|
|
1997
|
+
body = void 0;
|
|
1998
|
+
}
|
|
1999
|
+
return httpClient.getPaymentRequiredResponse(
|
|
2000
|
+
(name) => response.headers.get(name),
|
|
2001
|
+
body
|
|
2002
|
+
);
|
|
2003
|
+
}
|
|
2004
|
+
async function payX402Resource(options) {
|
|
2005
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
2006
|
+
if (!fetchImpl) {
|
|
2007
|
+
throw new Error("fetch is not available; pass fetchImpl");
|
|
2008
|
+
}
|
|
2009
|
+
const payerIndex = normalizePayerIndex(options.payerIndex);
|
|
2010
|
+
const payerPrivateKey = deriveX402PayerKey(options.rootPrivateKey, payerIndex);
|
|
2011
|
+
const payerAccount = privateKeyToAccount(payerPrivateKey);
|
|
2012
|
+
const publicClient = createPublicClient({
|
|
2013
|
+
chain: base,
|
|
2014
|
+
transport: http(options.rpcUrl)
|
|
2015
|
+
});
|
|
2016
|
+
const signer = toClientEvmSigner(payerAccount, publicClient);
|
|
2017
|
+
const client = new x402Client(
|
|
2018
|
+
(_version, requirements) => selectBaseUsdcExactRequirement({
|
|
2019
|
+
x402Version: 2,
|
|
2020
|
+
resource: { url: options.url },
|
|
2021
|
+
accepts: requirements
|
|
2022
|
+
})
|
|
2023
|
+
);
|
|
2024
|
+
registerExactEvmScheme(client, {
|
|
2025
|
+
signer,
|
|
2026
|
+
networks: [BASE_NETWORK],
|
|
2027
|
+
schemeOptions: options.rpcUrl ? { rpcUrl: options.rpcUrl } : void 0
|
|
2028
|
+
});
|
|
2029
|
+
const httpClient = new x402HTTPClient(client);
|
|
2030
|
+
options.onProgress?.("Fetching x402 requirement...");
|
|
2031
|
+
const initialResponse = await fetchImpl(options.url, options.init);
|
|
2032
|
+
if (initialResponse.status !== 402) {
|
|
2033
|
+
return {
|
|
2034
|
+
response: initialResponse,
|
|
2035
|
+
payerAddress: payerAccount.address,
|
|
2036
|
+
payerIndex: payerIndex.toString(),
|
|
2037
|
+
amount: "0",
|
|
2038
|
+
amountAtomic: "0",
|
|
2039
|
+
relayTransactionHash: "",
|
|
2040
|
+
relayBlockNumber: ""
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
const paymentRequired = await parsePaymentRequired(initialResponse, httpClient);
|
|
2044
|
+
const requirement = selectBaseUsdcExactRequirement(paymentRequired);
|
|
2045
|
+
const amountAtomic = normalizeAtomicAmount(requirement.amount);
|
|
2046
|
+
const amount = usdcAtomicToDecimalString(amountAtomic);
|
|
2047
|
+
if (options.maxPayment !== void 0) {
|
|
2048
|
+
const maxAtomic = usdcDecimalToAtomic(options.maxPayment);
|
|
2049
|
+
if (BigInt(amountAtomic) > maxAtomic) {
|
|
2050
|
+
throw new Error(
|
|
2051
|
+
`x402 payment of ${amount} USDC exceeds maxPayment cap of ${usdcAtomicToDecimalString(maxAtomic)} USDC. Payment was not sent.`
|
|
2052
|
+
);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
let relayTransactionHash = "";
|
|
2056
|
+
let relayBlockNumber = "";
|
|
2057
|
+
let fundAtomic = BigInt(amountAtomic);
|
|
2058
|
+
if (options.reuseExistingBalance) {
|
|
2059
|
+
const payerBalance = await publicClient.readContract({
|
|
2060
|
+
address: ADDRESSES.usdcToken,
|
|
2061
|
+
abi: ERC20_ABI,
|
|
2062
|
+
functionName: "balanceOf",
|
|
2063
|
+
args: [payerAccount.address]
|
|
2064
|
+
});
|
|
2065
|
+
if (payerBalance >= BigInt(amountAtomic)) {
|
|
2066
|
+
fundAtomic = 0n;
|
|
2067
|
+
} else if (options.reuseExistingBalance === "topup") {
|
|
2068
|
+
fundAtomic = BigInt(amountAtomic) - payerBalance;
|
|
2069
|
+
} else {
|
|
2070
|
+
throw new Error(
|
|
2071
|
+
`Cannot reuse payer index ${payerIndex.toString()}: holds ${formatUnits(payerBalance, USDC_DECIMALS)} USDC but the resource requires ${amount} USDC. Pass reuseExistingBalance: 'topup' to fund the shortfall.`
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
if (fundAtomic === 0n) {
|
|
2076
|
+
options.onProgress?.("Reusing funded x402 payer...", `${amount} USDC on ${payerAccount.address}`);
|
|
2077
|
+
} else {
|
|
2078
|
+
if (fundAtomic < X402_MIN_WITHDRAW_ATOMIC) {
|
|
2079
|
+
fundAtomic = X402_MIN_WITHDRAW_ATOMIC;
|
|
2080
|
+
}
|
|
2081
|
+
const fundAmount = usdcAtomicToDecimalString(fundAtomic);
|
|
2082
|
+
options.onProgress?.("Funding x402 payer...", `${fundAmount} USDC to ${payerAccount.address}`);
|
|
2083
|
+
const proof = await buildWithdrawProof({
|
|
2084
|
+
amount: fundAmount,
|
|
2085
|
+
recipient: payerAccount.address,
|
|
2086
|
+
keypair: new Keypair(options.rootPrivateKey),
|
|
2087
|
+
pool: "usdc",
|
|
2088
|
+
rpcUrl: options.rpcUrl,
|
|
2089
|
+
provingKeyPath: options.provingKeyPath,
|
|
2090
|
+
onProgress: options.onProgress
|
|
2091
|
+
});
|
|
2092
|
+
const relayResult = await submitRelay({
|
|
2093
|
+
type: "withdraw",
|
|
2094
|
+
pool: "usdc",
|
|
2095
|
+
// x402 funding must target the low-minimum /x402 relay route. Default to it
|
|
2096
|
+
// so direct SDK consumers do not silently hit the main relay's 5 USDC floor.
|
|
2097
|
+
relayUrl: options.relayUrl ?? `${getRelayUrl()}/x402`,
|
|
2098
|
+
proofArgs: proof.proofArgs,
|
|
2099
|
+
extData: proof.extData,
|
|
2100
|
+
metadata: {
|
|
2101
|
+
amount: fundAmount,
|
|
2102
|
+
amountAtomic: fundAtomic.toString(),
|
|
2103
|
+
recipient: payerAccount.address,
|
|
2104
|
+
inputUtxoCount: proof.inputCount,
|
|
2105
|
+
outputUtxoCount: proof.outputCount,
|
|
2106
|
+
x402: true,
|
|
2107
|
+
payerIndex: payerIndex.toString()
|
|
2108
|
+
}
|
|
2109
|
+
});
|
|
2110
|
+
relayTransactionHash = relayResult.transactionHash;
|
|
2111
|
+
relayBlockNumber = relayResult.blockNumber;
|
|
2112
|
+
if (options.onPayerFunded) {
|
|
2113
|
+
try {
|
|
2114
|
+
options.onPayerFunded({
|
|
2115
|
+
payerAddress: payerAccount.address,
|
|
2116
|
+
payerIndex: payerIndex.toString(),
|
|
2117
|
+
amount,
|
|
2118
|
+
amountAtomic,
|
|
2119
|
+
relayTransactionHash,
|
|
2120
|
+
relayBlockNumber
|
|
2121
|
+
});
|
|
2122
|
+
} catch {
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
options.onProgress?.("Signing x402 payment...");
|
|
2127
|
+
const paymentPayload = await httpClient.createPaymentPayload({
|
|
2128
|
+
...paymentRequired,
|
|
2129
|
+
accepts: [requirement]
|
|
2130
|
+
});
|
|
2131
|
+
const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);
|
|
2132
|
+
const headers = new Headers(options.init?.headers);
|
|
2133
|
+
for (const [key, value] of Object.entries(paymentHeaders)) {
|
|
2134
|
+
headers.set(key, value);
|
|
2135
|
+
}
|
|
2136
|
+
options.onProgress?.("Requesting paid resource...");
|
|
2137
|
+
const paidResponse = await fetchImpl(options.url, {
|
|
2138
|
+
...options.init,
|
|
2139
|
+
headers
|
|
2140
|
+
});
|
|
2141
|
+
let paymentResponse;
|
|
2142
|
+
try {
|
|
2143
|
+
paymentResponse = httpClient.getPaymentSettleResponse((name) => paidResponse.headers.get(name));
|
|
2144
|
+
} catch {
|
|
2145
|
+
paymentResponse = void 0;
|
|
2146
|
+
}
|
|
2147
|
+
return {
|
|
2148
|
+
response: paidResponse,
|
|
2149
|
+
payerAddress: payerAccount.address,
|
|
2150
|
+
payerIndex: payerIndex.toString(),
|
|
2151
|
+
amount,
|
|
2152
|
+
amountAtomic,
|
|
2153
|
+
relayTransactionHash,
|
|
2154
|
+
relayBlockNumber,
|
|
2155
|
+
paymentResponse,
|
|
2156
|
+
paymentTransactionHash: paymentResponse?.transaction
|
|
2157
|
+
};
|
|
2158
|
+
}
|
|
2159
|
+
async function quoteX402Resource(options) {
|
|
2160
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
2161
|
+
if (!fetchImpl) {
|
|
2162
|
+
throw new Error("fetch is not available; pass fetchImpl");
|
|
2163
|
+
}
|
|
2164
|
+
const client = new x402Client(
|
|
2165
|
+
(_version, requirements) => selectBaseUsdcExactRequirement({
|
|
2166
|
+
x402Version: 2,
|
|
2167
|
+
resource: { url: options.url },
|
|
2168
|
+
accepts: requirements
|
|
2169
|
+
})
|
|
2170
|
+
);
|
|
2171
|
+
const httpClient = new x402HTTPClient(client);
|
|
2172
|
+
const initialResponse = await fetchImpl(options.url, options.init);
|
|
2173
|
+
if (initialResponse.status !== 402) {
|
|
2174
|
+
let body;
|
|
2175
|
+
try {
|
|
2176
|
+
body = await initialResponse.clone().json();
|
|
2177
|
+
} catch {
|
|
2178
|
+
try {
|
|
2179
|
+
body = await initialResponse.clone().text();
|
|
2180
|
+
} catch {
|
|
2181
|
+
body = void 0;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
return {
|
|
2185
|
+
requiresPayment: false,
|
|
2186
|
+
supported: false,
|
|
2187
|
+
status: initialResponse.status,
|
|
2188
|
+
body
|
|
2189
|
+
};
|
|
2190
|
+
}
|
|
2191
|
+
let requirement;
|
|
2192
|
+
try {
|
|
2193
|
+
const paymentRequired = await parsePaymentRequired(initialResponse, httpClient);
|
|
2194
|
+
requirement = selectBaseUsdcExactRequirement(paymentRequired);
|
|
2195
|
+
} catch (error) {
|
|
2196
|
+
return {
|
|
2197
|
+
requiresPayment: true,
|
|
2198
|
+
supported: false,
|
|
2199
|
+
status: 402,
|
|
2200
|
+
error: error instanceof Error ? error.message : "Unsupported x402 requirement"
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
const amountAtomic = normalizeAtomicAmount(requirement.amount);
|
|
2204
|
+
const amount = usdcAtomicToDecimalString(amountAtomic);
|
|
2205
|
+
let exceedsMax;
|
|
2206
|
+
if (options.maxPayment !== void 0) {
|
|
2207
|
+
exceedsMax = BigInt(amountAtomic) > usdcDecimalToAtomic(options.maxPayment);
|
|
2208
|
+
}
|
|
2209
|
+
return {
|
|
2210
|
+
requiresPayment: true,
|
|
2211
|
+
supported: true,
|
|
2212
|
+
status: 402,
|
|
2213
|
+
amount,
|
|
2214
|
+
amountAtomic,
|
|
2215
|
+
payTo: requirement.payTo,
|
|
2216
|
+
network: requirement.network,
|
|
2217
|
+
asset: requirement.asset,
|
|
2218
|
+
exceedsMax,
|
|
2219
|
+
maxPayment: options.maxPayment
|
|
2220
|
+
};
|
|
2221
|
+
}
|
|
2222
|
+
async function getX402PayerBalances(options) {
|
|
2223
|
+
assertPrivateKey(options.rootPrivateKey, "rootPrivateKey");
|
|
2224
|
+
const start = normalizePayerIndex(options.startIndex ?? 0n);
|
|
2225
|
+
const count = options.count ?? 16;
|
|
2226
|
+
if (!Number.isInteger(count) || count <= 0 || count > 256) {
|
|
2227
|
+
throw new Error("count must be an integer between 1 and 256");
|
|
2228
|
+
}
|
|
2229
|
+
const publicClient = createPublicClient({
|
|
2230
|
+
chain: base,
|
|
2231
|
+
transport: http(options.rpcUrl)
|
|
2232
|
+
});
|
|
2233
|
+
const results = [];
|
|
2234
|
+
for (let i = 0; i < count; i++) {
|
|
2235
|
+
const index = start + BigInt(i);
|
|
2236
|
+
const payerAddress = deriveX402PayerAddress(options.rootPrivateKey, index);
|
|
2237
|
+
const balance = await publicClient.readContract({
|
|
2238
|
+
address: ADDRESSES.usdcToken,
|
|
2239
|
+
abi: ERC20_ABI,
|
|
2240
|
+
functionName: "balanceOf",
|
|
2241
|
+
args: [payerAddress]
|
|
2242
|
+
});
|
|
2243
|
+
if (options.nonZeroOnly && balance === 0n) {
|
|
2244
|
+
continue;
|
|
2245
|
+
}
|
|
2246
|
+
results.push({
|
|
2247
|
+
payerIndex: index.toString(),
|
|
2248
|
+
payerAddress,
|
|
2249
|
+
usdc: formatUnits(balance, USDC_DECIMALS),
|
|
2250
|
+
usdcAtomic: balance.toString()
|
|
2251
|
+
});
|
|
2252
|
+
}
|
|
2253
|
+
return results;
|
|
2254
|
+
}
|
|
1940
2255
|
async function checkRecipientRegistration(address, rpcUrl) {
|
|
1941
2256
|
const addresses = getAddresses();
|
|
1942
2257
|
const publicClient = createPublicClient({
|
|
@@ -2225,7 +2540,7 @@ function createBaseClient(rpcUrl) {
|
|
|
2225
2540
|
transport: http(rpcUrl)
|
|
2226
2541
|
});
|
|
2227
2542
|
}
|
|
2228
|
-
function
|
|
2543
|
+
function assertPrivateKey2(value, label) {
|
|
2229
2544
|
if (!/^0x[a-fA-F0-9]{64}$/.test(value)) {
|
|
2230
2545
|
throw new Error(`${label} must be a 0x-prefixed 32-byte hex string`);
|
|
2231
2546
|
}
|
|
@@ -2260,7 +2575,7 @@ function normalizeDeadline(deadline) {
|
|
|
2260
2575
|
return nextDeadline;
|
|
2261
2576
|
}
|
|
2262
2577
|
function deriveSubaccountChildPrivateKey(rootPrivateKey, slot) {
|
|
2263
|
-
|
|
2578
|
+
assertPrivateKey2(rootPrivateKey, "rootPrivateKey");
|
|
2264
2579
|
const normalizedSlot = normalizeSlot(slot);
|
|
2265
2580
|
return keccak256(
|
|
2266
2581
|
encodePacked(
|
|
@@ -2270,7 +2585,7 @@ function deriveSubaccountChildPrivateKey(rootPrivateKey, slot) {
|
|
|
2270
2585
|
);
|
|
2271
2586
|
}
|
|
2272
2587
|
function deriveSubaccountSalt(rootPrivateKey, slot) {
|
|
2273
|
-
|
|
2588
|
+
assertPrivateKey2(rootPrivateKey, "rootPrivateKey");
|
|
2274
2589
|
const normalizedSlot = normalizeSlot(slot);
|
|
2275
2590
|
return keccak256(
|
|
2276
2591
|
encodePacked(
|
|
@@ -2280,11 +2595,11 @@ function deriveSubaccountSalt(rootPrivateKey, slot) {
|
|
|
2280
2595
|
);
|
|
2281
2596
|
}
|
|
2282
2597
|
function deriveSubaccountChildOwner(childPrivateKey) {
|
|
2283
|
-
|
|
2598
|
+
assertPrivateKey2(childPrivateKey, "childPrivateKey");
|
|
2284
2599
|
return privateKeyToAddress(childPrivateKey);
|
|
2285
2600
|
}
|
|
2286
2601
|
function deriveSubaccountChildDepositKey(childPrivateKey) {
|
|
2287
|
-
|
|
2602
|
+
assertPrivateKey2(childPrivateKey, "childPrivateKey");
|
|
2288
2603
|
return new Keypair(childPrivateKey).depositKey();
|
|
2289
2604
|
}
|
|
2290
2605
|
async function predictSubaccountForwarder(options) {
|
|
@@ -2377,7 +2692,7 @@ function toPrivateBalanceStatus(result) {
|
|
|
2377
2692
|
}
|
|
2378
2693
|
async function getSubaccountPrivateBalance(options) {
|
|
2379
2694
|
const normalizedSlot = normalizeSlot(options.slot);
|
|
2380
|
-
|
|
2695
|
+
assertPrivateKey2(options.rootPrivateKey, "rootPrivateKey");
|
|
2381
2696
|
const childPrivateKey = deriveSubaccountChildPrivateKey(options.rootPrivateKey, normalizedSlot);
|
|
2382
2697
|
const childKeypair = new Keypair(childPrivateKey);
|
|
2383
2698
|
return getPrivateBalance({
|
|
@@ -2487,7 +2802,7 @@ function buildSubaccountWithdrawTypedData(options) {
|
|
|
2487
2802
|
};
|
|
2488
2803
|
}
|
|
2489
2804
|
async function signSubaccountWithdraw(options) {
|
|
2490
|
-
|
|
2805
|
+
assertPrivateKey2(options.childPrivateKey, "childPrivateKey");
|
|
2491
2806
|
const account = privateKeyToAccount(options.childPrivateKey);
|
|
2492
2807
|
return account.signTypedData({
|
|
2493
2808
|
domain: options.typedData.domain,
|
|
@@ -2600,7 +2915,7 @@ async function mergeSubaccount(options) {
|
|
|
2600
2915
|
onProgress
|
|
2601
2916
|
} = options;
|
|
2602
2917
|
const normalizedSlot = normalizeSlot(slot);
|
|
2603
|
-
|
|
2918
|
+
assertPrivateKey2(rootPrivateKey, "rootPrivateKey");
|
|
2604
2919
|
const poolConfig = POOL_CONFIG[pool];
|
|
2605
2920
|
const poolAddress = getPoolAddress(pool);
|
|
2606
2921
|
const childPrivateKey = deriveSubaccountChildPrivateKey(rootPrivateKey, normalizedSlot);
|
|
@@ -2723,6 +3038,6 @@ async function mergeSubaccount(options) {
|
|
|
2723
3038
|
};
|
|
2724
3039
|
}
|
|
2725
3040
|
|
|
2726
|
-
export { ADDRESSES, CIRCUIT_CONFIG, ENTRY_ABI, ERC20_ABI, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, POOL_ABI, POOL_CONFIG, QUEUE_ABI, RelayError, Utxo, VEIL_SIGNED_MESSAGE, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses,
|
|
3041
|
+
export { ADDRESSES, CIRCUIT_CONFIG, ENTRY_ABI, ERC20_ABI, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, POOL_ABI, POOL_CONFIG, QUEUE_ABI, RelayError, Utxo, VEIL_SIGNED_MESSAGE, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, deriveX402PayerAddress, deriveX402PayerKey, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountPrivateBalance, getSubaccountStatus, getX402PayerBalances, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeSubaccount, mergeUtxos, packEncryptedMessage, payX402Resource, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, quoteX402Resource, randomBN, selectBaseUsdcExactRequirement, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, usdcAtomicToDecimalString, usdcDecimalToAtomic, withdraw };
|
|
2727
3042
|
//# sourceMappingURL=index.js.map
|
|
2728
3043
|
//# sourceMappingURL=index.js.map
|