@kohaku-eth/tornado-cash 0.0.2-alpha.16 → 0.0.2-alpha.17
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/dist/state-manager.worker.js +161 -71
- package/dist/state-manager.worker.node.js +161 -71
- package/package.json +1 -1
|
@@ -22194,6 +22194,15 @@ var withdrawThunk = createAsyncThunk("withdraw/executeWithdrawals", async ({
|
|
|
22194
22194
|
return getWithdrawalsProofs();
|
|
22195
22195
|
});
|
|
22196
22196
|
|
|
22197
|
+
// ../provider/dist/index.js
|
|
22198
|
+
var createTx = (address, payload, value = BigInt(0)) => {
|
|
22199
|
+
return {
|
|
22200
|
+
to: address,
|
|
22201
|
+
data: payload,
|
|
22202
|
+
value
|
|
22203
|
+
};
|
|
22204
|
+
};
|
|
22205
|
+
|
|
22197
22206
|
// ../../node_modules/.pnpm/viem@2.48.4_typescript@5.9.3_zod@4.4.3/node_modules/viem/_esm/index.js
|
|
22198
22207
|
init_exports();
|
|
22199
22208
|
init_encodeAbiParameters2();
|
|
@@ -22368,8 +22377,14 @@ function privateKeyToAccount(privateKey, options = {}) {
|
|
|
22368
22377
|
};
|
|
22369
22378
|
}
|
|
22370
22379
|
|
|
22380
|
+
// src/state/thunks/paymasterWithdrawThunk.ts
|
|
22381
|
+
init_esm();
|
|
22382
|
+
|
|
22371
22383
|
// src/paymaster/fee.ts
|
|
22372
22384
|
var ERC20_TRANSFER_GAS = 100000n;
|
|
22385
|
+
var PER_DIRECT_WITHDRAW_GAS = 400000n;
|
|
22386
|
+
var PER_DIRECT_WITHDRAW_GAS_ERC20 = 500000n;
|
|
22387
|
+
var FORWARD_GAS = 60000n;
|
|
22373
22388
|
var baseGasUnits = {
|
|
22374
22389
|
preVerificationGas: 80000n,
|
|
22375
22390
|
verificationGasLimit: 50000n,
|
|
@@ -22384,6 +22399,15 @@ function reasonableGasUnits(isERC20) {
|
|
|
22384
22399
|
paymasterVerificationGasLimit: baseGasUnits.paymasterVerificationGasLimit + ERC20_TRANSFER_GAS
|
|
22385
22400
|
};
|
|
22386
22401
|
}
|
|
22402
|
+
function reasonableGasUnitsForBatch(isERC20, extraWithdrawals, hasUserTailCalls) {
|
|
22403
|
+
const base = reasonableGasUnits(isERC20);
|
|
22404
|
+
const perWithdraw = isERC20 ? PER_DIRECT_WITHDRAW_GAS_ERC20 : PER_DIRECT_WITHDRAW_GAS;
|
|
22405
|
+
const executionTail = hasUserTailCalls ? base.callGasLimit : FORWARD_GAS;
|
|
22406
|
+
return {
|
|
22407
|
+
...base,
|
|
22408
|
+
callGasLimit: BigInt(extraWithdrawals) * perWithdraw + executionTail
|
|
22409
|
+
};
|
|
22410
|
+
}
|
|
22387
22411
|
function computeMinimumViableFee(reasonableGasUnits2, maxFeePerGas) {
|
|
22388
22412
|
const baseFeeMultiplier = 1.2;
|
|
22389
22413
|
const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
@@ -22391,10 +22415,6 @@ function computeMinimumViableFee(reasonableGasUnits2, maxFeePerGas) {
|
|
|
22391
22415
|
const multiply = (base) => base * BigInt(Math.ceil(baseFeeMultiplier * denominator)) / BigInt(denominator);
|
|
22392
22416
|
const requiredGas = reasonableGasUnits2.verificationGasLimit + reasonableGasUnits2.callGasLimit + reasonableGasUnits2.paymasterVerificationGasLimit + reasonableGasUnits2.preVerificationGas + reasonableGasUnits2.paymasterPostOpGasLimit;
|
|
22393
22417
|
const requiredPrefund = requiredGas * maxFeePerGas;
|
|
22394
|
-
console.log("totalGasUnits", requiredGas);
|
|
22395
|
-
console.log("maxFeePerGas", maxFeePerGas);
|
|
22396
|
-
console.log("requiredPrefund", requiredPrefund);
|
|
22397
|
-
console.log("multiply", 1.2);
|
|
22398
22418
|
return multiply(requiredPrefund);
|
|
22399
22419
|
}
|
|
22400
22420
|
|
|
@@ -24091,6 +24111,19 @@ async function getUserOperationGasPrice(client) {
|
|
|
24091
24111
|
fast: parse(result.fast)
|
|
24092
24112
|
};
|
|
24093
24113
|
}
|
|
24114
|
+
async function estimateUserOperationGas2(client, op, entryPoint) {
|
|
24115
|
+
const result = await client.request({
|
|
24116
|
+
method: "eth_estimateUserOperationGas",
|
|
24117
|
+
params: [op, entryPoint]
|
|
24118
|
+
});
|
|
24119
|
+
return {
|
|
24120
|
+
callGasLimit: BigInt(result.callGasLimit),
|
|
24121
|
+
verificationGasLimit: BigInt(result.verificationGasLimit),
|
|
24122
|
+
preVerificationGas: BigInt(result.preVerificationGas),
|
|
24123
|
+
paymasterVerificationGasLimit: BigInt(result.paymasterVerificationGasLimit ?? 0),
|
|
24124
|
+
paymasterPostOpGasLimit: BigInt(result.paymasterPostOpGasLimit ?? 0)
|
|
24125
|
+
};
|
|
24126
|
+
}
|
|
24094
24127
|
async function buildSignedTornadoUserOp({
|
|
24095
24128
|
signer,
|
|
24096
24129
|
chainId,
|
|
@@ -24221,12 +24254,32 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
24221
24254
|
);
|
|
24222
24255
|
const bundlerClient = createPaymasterBundlerClient(bundlerUrl);
|
|
24223
24256
|
const { standard: { maxFeePerGas, maxPriorityFeePerGas } } = await getUserOperationGasPrice(bundlerClient);
|
|
24224
|
-
const gasUnits = reasonableGasUnits(poolInfo.isERC20);
|
|
24225
|
-
const ethFee = computeMinimumViableFee(gasUnits, maxFeePerGas);
|
|
24226
|
-
const fee = poolInfo.isERC20 ? await dataService.quoteWeiInToken(BigInt(paymasterAddress), poolInfo.asset, ethFee) : ethFee;
|
|
24227
24257
|
const relayerAddress = BigInt(paymasterAddress);
|
|
24228
24258
|
const bigintChainId = await dataService.getChainId();
|
|
24229
24259
|
const { recipient: originalRecipient, ...restWithoutRecipient } = rest;
|
|
24260
|
+
const quoteFee = async (ethFee) => poolInfo.isERC20 ? dataService.quoteWeiInToken(BigInt(paymasterAddress), poolInfo.asset, ethFee) : ethFee;
|
|
24261
|
+
const prove = async (deposit, recipient, relayer, depositFee) => unwrapResult(await dispatch(withdrawalsProofThunk({
|
|
24262
|
+
...restWithoutRecipient,
|
|
24263
|
+
recipient,
|
|
24264
|
+
deposit,
|
|
24265
|
+
relayerAddress: relayer,
|
|
24266
|
+
fee: depositFee
|
|
24267
|
+
})));
|
|
24268
|
+
const buildPaymasterData = (poolAddress, proof) => {
|
|
24269
|
+
const [root, nullifierHash, proofRecipient, relayerArg, feeArg, refundArg] = proof.args;
|
|
24270
|
+
return encodePaymasterData(
|
|
24271
|
+
poolAcountsMap.get(poolAddress),
|
|
24272
|
+
encodeTornadoAdapterData(
|
|
24273
|
+
proof.proof,
|
|
24274
|
+
root,
|
|
24275
|
+
nullifierHash,
|
|
24276
|
+
proofRecipient,
|
|
24277
|
+
relayerArg,
|
|
24278
|
+
BigInt(feeArg),
|
|
24279
|
+
BigInt(refundArg)
|
|
24280
|
+
)
|
|
24281
|
+
);
|
|
24282
|
+
};
|
|
24230
24283
|
const ephemeralSigner = async (deposit) => privateKeyToAccount(await secretManager.deriveEphemeralSigner({
|
|
24231
24284
|
depositIndex: deposit.index,
|
|
24232
24285
|
chainId: bigintChainId,
|
|
@@ -24241,78 +24294,115 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
24241
24294
|
return ephemeralSigner(deposits[0]);
|
|
24242
24295
|
};
|
|
24243
24296
|
const resolveIndependentSigner = (deposit) => delegation?.mode === "deterministic" ? ephemeralSigner(deposit) : Promise.resolve(privateKeyToAccount(generatePrivateKey()));
|
|
24244
|
-
const
|
|
24245
|
-
|
|
24246
|
-
|
|
24247
|
-
|
|
24248
|
-
const
|
|
24249
|
-
const
|
|
24250
|
-
const
|
|
24251
|
-
const
|
|
24252
|
-
|
|
24253
|
-
|
|
24254
|
-
|
|
24255
|
-
|
|
24256
|
-
|
|
24257
|
-
|
|
24258
|
-
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
|
|
24278
|
-
|
|
24279
|
-
|
|
24280
|
-
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
|
|
24287
|
-
|
|
24288
|
-
|
|
24289
|
-
|
|
24290
|
-
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
24297
|
+
const needsConsolidation = deposits.length > 1 || tailCalls != null;
|
|
24298
|
+
if (!needsConsolidation) {
|
|
24299
|
+
const deposit = deposits[0];
|
|
24300
|
+
const signer2 = await resolveIndependentSigner(deposit);
|
|
24301
|
+
const gasUnits = reasonableGasUnits(poolInfo.isERC20);
|
|
24302
|
+
const fee2 = await quoteFee(computeMinimumViableFee(gasUnits, maxFeePerGas));
|
|
24303
|
+
const proof = await prove(deposit, originalRecipient, relayerAddress, fee2);
|
|
24304
|
+
const userOperation2 = await buildSignedTornadoUserOp({
|
|
24305
|
+
signer: signer2,
|
|
24306
|
+
chainId,
|
|
24307
|
+
paymasterAddress,
|
|
24308
|
+
paymasterData: buildPaymasterData(deposit.pool, proof),
|
|
24309
|
+
gas: { ...gasUnits, callGasLimit: 0n },
|
|
24310
|
+
maxFeePerGas,
|
|
24311
|
+
maxPriorityFeePerGas,
|
|
24312
|
+
nonce: 0n
|
|
24313
|
+
});
|
|
24314
|
+
return [{
|
|
24315
|
+
mode: "paymaster",
|
|
24316
|
+
proof,
|
|
24317
|
+
poolAddress: deposit.pool,
|
|
24318
|
+
isERC20: poolInfo.isERC20,
|
|
24319
|
+
paymasterAddress,
|
|
24320
|
+
entryPointAddress,
|
|
24321
|
+
bundlerUrl,
|
|
24322
|
+
userOperation: userOperation2
|
|
24323
|
+
}];
|
|
24324
|
+
}
|
|
24325
|
+
const signer = await resolveBatchDelegator();
|
|
24326
|
+
const senderAddress = BigInt(signer.address);
|
|
24327
|
+
const sponsoringDeposit = deposits[0];
|
|
24328
|
+
const directDeposits = deposits.slice(1);
|
|
24329
|
+
const ZERO_ADDRESS = 0n;
|
|
24330
|
+
const directWithdrawCalls = [];
|
|
24331
|
+
for (const deposit of directDeposits) {
|
|
24332
|
+
const proof = await prove(deposit, senderAddress, ZERO_ADDRESS, 0n);
|
|
24333
|
+
const [root, nullifierHash, proofRecipient, relayerArg, feeArg, refundArg] = proof.args;
|
|
24334
|
+
const data = encodeFunctionData({
|
|
24335
|
+
abi: poolAbi,
|
|
24336
|
+
functionName: "withdraw",
|
|
24337
|
+
args: [proof.proof, root, nullifierHash, proofRecipient, relayerArg, BigInt(feeArg), BigInt(refundArg)]
|
|
24338
|
+
});
|
|
24339
|
+
directWithdrawCalls.push(createTx(addressToHex(deposit.pool), data, 0n));
|
|
24340
|
+
}
|
|
24341
|
+
const totalDenomination = deposits.reduce(
|
|
24342
|
+
(sum, d) => sum + pools.get(d.pool).denomination,
|
|
24343
|
+
0n
|
|
24344
|
+
);
|
|
24345
|
+
const forwardCalls = (fee2) => {
|
|
24346
|
+
const amount2 = totalDenomination - fee2;
|
|
24347
|
+
if (poolInfo.isERC20) {
|
|
24348
|
+
const data = encodeFunctionData({
|
|
24349
|
+
abi: erc20Abi,
|
|
24350
|
+
functionName: "transfer",
|
|
24351
|
+
args: [addressToHex(originalRecipient), amount2]
|
|
24352
|
+
});
|
|
24353
|
+
return [createTx(addressToHex(poolInfo.asset), data, 0n)];
|
|
24354
|
+
}
|
|
24355
|
+
return [createTx(addressToHex(originalRecipient), "0x", amount2)];
|
|
24356
|
+
};
|
|
24357
|
+
const composeTailCalls = (fee2) => async (addr) => [
|
|
24358
|
+
...directWithdrawCalls,
|
|
24359
|
+
...tailCalls ? await tailCalls(addr) : forwardCalls(fee2)
|
|
24360
|
+
];
|
|
24361
|
+
const buildOp = (gas2, fee2, paymasterData) => buildSignedTornadoUserOp({
|
|
24362
|
+
signer,
|
|
24363
|
+
chainId,
|
|
24364
|
+
paymasterAddress,
|
|
24365
|
+
paymasterData,
|
|
24366
|
+
gas: gas2,
|
|
24367
|
+
maxFeePerGas,
|
|
24368
|
+
maxPriorityFeePerGas,
|
|
24369
|
+
tailCalls: composeTailCalls(fee2),
|
|
24370
|
+
nonce: 0n
|
|
24371
|
+
});
|
|
24372
|
+
const baselineGas = reasonableGasUnitsForBatch(poolInfo.isERC20, directDeposits.length, tailCalls != null);
|
|
24373
|
+
let fee = await quoteFee(computeMinimumViableFee(baselineGas, maxFeePerGas));
|
|
24374
|
+
let gas = baselineGas;
|
|
24375
|
+
let sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
24376
|
+
let userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
24377
|
+
try {
|
|
24378
|
+
const estimated = await estimateUserOperationGas2(bundlerClient, userOperation, entryPointAddress);
|
|
24379
|
+
const buffer2 = (x) => x * 12n / 10n;
|
|
24380
|
+
const orBaseline = (e, b) => e > 0n ? buffer2(e) : b;
|
|
24381
|
+
const refinedGas = {
|
|
24382
|
+
callGasLimit: orBaseline(estimated.callGasLimit, baselineGas.callGasLimit),
|
|
24383
|
+
verificationGasLimit: orBaseline(estimated.verificationGasLimit, baselineGas.verificationGasLimit),
|
|
24384
|
+
preVerificationGas: orBaseline(estimated.preVerificationGas, baselineGas.preVerificationGas),
|
|
24385
|
+
paymasterVerificationGasLimit: orBaseline(estimated.paymasterVerificationGasLimit, baselineGas.paymasterVerificationGasLimit),
|
|
24386
|
+
paymasterPostOpGasLimit: orBaseline(estimated.paymasterPostOpGasLimit, baselineGas.paymasterPostOpGasLimit)
|
|
24387
|
+
};
|
|
24388
|
+
fee = await quoteFee(computeMinimumViableFee(refinedGas, maxFeePerGas));
|
|
24389
|
+
gas = refinedGas;
|
|
24390
|
+
sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
24391
|
+
userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
24392
|
+
} catch {
|
|
24294
24393
|
}
|
|
24295
|
-
return
|
|
24394
|
+
return [{
|
|
24296
24395
|
mode: "paymaster",
|
|
24297
|
-
proof,
|
|
24298
|
-
poolAddress,
|
|
24396
|
+
proof: sponsoringProof,
|
|
24397
|
+
poolAddress: sponsoringDeposit.pool,
|
|
24299
24398
|
isERC20: poolInfo.isERC20,
|
|
24300
24399
|
paymasterAddress,
|
|
24301
24400
|
entryPointAddress,
|
|
24302
24401
|
bundlerUrl,
|
|
24303
|
-
userOperation
|
|
24304
|
-
}
|
|
24402
|
+
userOperation
|
|
24403
|
+
}];
|
|
24305
24404
|
});
|
|
24306
24405
|
|
|
24307
|
-
// ../provider/dist/index.js
|
|
24308
|
-
var createTx = (address, payload, value = BigInt(0)) => {
|
|
24309
|
-
return {
|
|
24310
|
-
to: address,
|
|
24311
|
-
data: payload,
|
|
24312
|
-
value
|
|
24313
|
-
};
|
|
24314
|
-
};
|
|
24315
|
-
|
|
24316
24406
|
// src/account/tx/shield.ts
|
|
24317
24407
|
init_esm();
|
|
24318
24408
|
init_esm();
|
|
@@ -21420,6 +21420,15 @@ var withdrawThunk = createAsyncThunk("withdraw/executeWithdrawals", async ({
|
|
|
21420
21420
|
return getWithdrawalsProofs();
|
|
21421
21421
|
});
|
|
21422
21422
|
|
|
21423
|
+
// ../provider/dist/index.js
|
|
21424
|
+
var createTx = (address, payload, value = BigInt(0)) => {
|
|
21425
|
+
return {
|
|
21426
|
+
to: address,
|
|
21427
|
+
data: payload,
|
|
21428
|
+
value
|
|
21429
|
+
};
|
|
21430
|
+
};
|
|
21431
|
+
|
|
21423
21432
|
// ../../node_modules/.pnpm/viem@2.48.4_typescript@5.9.3_zod@4.4.3/node_modules/viem/_esm/index.js
|
|
21424
21433
|
init_exports();
|
|
21425
21434
|
init_encodeAbiParameters2();
|
|
@@ -21594,8 +21603,14 @@ function privateKeyToAccount(privateKey, options = {}) {
|
|
|
21594
21603
|
};
|
|
21595
21604
|
}
|
|
21596
21605
|
|
|
21606
|
+
// src/state/thunks/paymasterWithdrawThunk.ts
|
|
21607
|
+
init_esm();
|
|
21608
|
+
|
|
21597
21609
|
// src/paymaster/fee.ts
|
|
21598
21610
|
var ERC20_TRANSFER_GAS = 100000n;
|
|
21611
|
+
var PER_DIRECT_WITHDRAW_GAS = 400000n;
|
|
21612
|
+
var PER_DIRECT_WITHDRAW_GAS_ERC20 = 500000n;
|
|
21613
|
+
var FORWARD_GAS = 60000n;
|
|
21599
21614
|
var baseGasUnits = {
|
|
21600
21615
|
preVerificationGas: 80000n,
|
|
21601
21616
|
verificationGasLimit: 50000n,
|
|
@@ -21610,6 +21625,15 @@ function reasonableGasUnits(isERC20) {
|
|
|
21610
21625
|
paymasterVerificationGasLimit: baseGasUnits.paymasterVerificationGasLimit + ERC20_TRANSFER_GAS
|
|
21611
21626
|
};
|
|
21612
21627
|
}
|
|
21628
|
+
function reasonableGasUnitsForBatch(isERC20, extraWithdrawals, hasUserTailCalls) {
|
|
21629
|
+
const base = reasonableGasUnits(isERC20);
|
|
21630
|
+
const perWithdraw = isERC20 ? PER_DIRECT_WITHDRAW_GAS_ERC20 : PER_DIRECT_WITHDRAW_GAS;
|
|
21631
|
+
const executionTail = hasUserTailCalls ? base.callGasLimit : FORWARD_GAS;
|
|
21632
|
+
return {
|
|
21633
|
+
...base,
|
|
21634
|
+
callGasLimit: BigInt(extraWithdrawals) * perWithdraw + executionTail
|
|
21635
|
+
};
|
|
21636
|
+
}
|
|
21613
21637
|
function computeMinimumViableFee(reasonableGasUnits2, maxFeePerGas) {
|
|
21614
21638
|
const baseFeeMultiplier = 1.2;
|
|
21615
21639
|
const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
@@ -21617,10 +21641,6 @@ function computeMinimumViableFee(reasonableGasUnits2, maxFeePerGas) {
|
|
|
21617
21641
|
const multiply = (base) => base * BigInt(Math.ceil(baseFeeMultiplier * denominator)) / BigInt(denominator);
|
|
21618
21642
|
const requiredGas = reasonableGasUnits2.verificationGasLimit + reasonableGasUnits2.callGasLimit + reasonableGasUnits2.paymasterVerificationGasLimit + reasonableGasUnits2.preVerificationGas + reasonableGasUnits2.paymasterPostOpGasLimit;
|
|
21619
21643
|
const requiredPrefund = requiredGas * maxFeePerGas;
|
|
21620
|
-
console.log("totalGasUnits", requiredGas);
|
|
21621
|
-
console.log("maxFeePerGas", maxFeePerGas);
|
|
21622
|
-
console.log("requiredPrefund", requiredPrefund);
|
|
21623
|
-
console.log("multiply", 1.2);
|
|
21624
21644
|
return multiply(requiredPrefund);
|
|
21625
21645
|
}
|
|
21626
21646
|
|
|
@@ -23317,6 +23337,19 @@ async function getUserOperationGasPrice(client) {
|
|
|
23317
23337
|
fast: parse(result.fast)
|
|
23318
23338
|
};
|
|
23319
23339
|
}
|
|
23340
|
+
async function estimateUserOperationGas2(client, op, entryPoint) {
|
|
23341
|
+
const result = await client.request({
|
|
23342
|
+
method: "eth_estimateUserOperationGas",
|
|
23343
|
+
params: [op, entryPoint]
|
|
23344
|
+
});
|
|
23345
|
+
return {
|
|
23346
|
+
callGasLimit: BigInt(result.callGasLimit),
|
|
23347
|
+
verificationGasLimit: BigInt(result.verificationGasLimit),
|
|
23348
|
+
preVerificationGas: BigInt(result.preVerificationGas),
|
|
23349
|
+
paymasterVerificationGasLimit: BigInt(result.paymasterVerificationGasLimit ?? 0),
|
|
23350
|
+
paymasterPostOpGasLimit: BigInt(result.paymasterPostOpGasLimit ?? 0)
|
|
23351
|
+
};
|
|
23352
|
+
}
|
|
23320
23353
|
async function buildSignedTornadoUserOp({
|
|
23321
23354
|
signer,
|
|
23322
23355
|
chainId,
|
|
@@ -23447,12 +23480,32 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23447
23480
|
);
|
|
23448
23481
|
const bundlerClient = createPaymasterBundlerClient(bundlerUrl);
|
|
23449
23482
|
const { standard: { maxFeePerGas, maxPriorityFeePerGas } } = await getUserOperationGasPrice(bundlerClient);
|
|
23450
|
-
const gasUnits = reasonableGasUnits(poolInfo.isERC20);
|
|
23451
|
-
const ethFee = computeMinimumViableFee(gasUnits, maxFeePerGas);
|
|
23452
|
-
const fee = poolInfo.isERC20 ? await dataService.quoteWeiInToken(BigInt(paymasterAddress), poolInfo.asset, ethFee) : ethFee;
|
|
23453
23483
|
const relayerAddress = BigInt(paymasterAddress);
|
|
23454
23484
|
const bigintChainId = await dataService.getChainId();
|
|
23455
23485
|
const { recipient: originalRecipient, ...restWithoutRecipient } = rest;
|
|
23486
|
+
const quoteFee = async (ethFee) => poolInfo.isERC20 ? dataService.quoteWeiInToken(BigInt(paymasterAddress), poolInfo.asset, ethFee) : ethFee;
|
|
23487
|
+
const prove = async (deposit, recipient, relayer, depositFee) => unwrapResult(await dispatch(withdrawalsProofThunk({
|
|
23488
|
+
...restWithoutRecipient,
|
|
23489
|
+
recipient,
|
|
23490
|
+
deposit,
|
|
23491
|
+
relayerAddress: relayer,
|
|
23492
|
+
fee: depositFee
|
|
23493
|
+
})));
|
|
23494
|
+
const buildPaymasterData = (poolAddress, proof) => {
|
|
23495
|
+
const [root, nullifierHash, proofRecipient, relayerArg, feeArg, refundArg] = proof.args;
|
|
23496
|
+
return encodePaymasterData(
|
|
23497
|
+
poolAcountsMap.get(poolAddress),
|
|
23498
|
+
encodeTornadoAdapterData(
|
|
23499
|
+
proof.proof,
|
|
23500
|
+
root,
|
|
23501
|
+
nullifierHash,
|
|
23502
|
+
proofRecipient,
|
|
23503
|
+
relayerArg,
|
|
23504
|
+
BigInt(feeArg),
|
|
23505
|
+
BigInt(refundArg)
|
|
23506
|
+
)
|
|
23507
|
+
);
|
|
23508
|
+
};
|
|
23456
23509
|
const ephemeralSigner = async (deposit) => privateKeyToAccount(await secretManager.deriveEphemeralSigner({
|
|
23457
23510
|
depositIndex: deposit.index,
|
|
23458
23511
|
chainId: bigintChainId,
|
|
@@ -23467,78 +23520,115 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23467
23520
|
return ephemeralSigner(deposits[0]);
|
|
23468
23521
|
};
|
|
23469
23522
|
const resolveIndependentSigner = (deposit) => delegation?.mode === "deterministic" ? ephemeralSigner(deposit) : Promise.resolve(privateKeyToAccount(generatePrivateKey()));
|
|
23470
|
-
const
|
|
23471
|
-
|
|
23472
|
-
|
|
23473
|
-
|
|
23474
|
-
const
|
|
23475
|
-
const
|
|
23476
|
-
const
|
|
23477
|
-
const
|
|
23478
|
-
|
|
23479
|
-
|
|
23480
|
-
|
|
23481
|
-
|
|
23482
|
-
|
|
23483
|
-
|
|
23484
|
-
|
|
23485
|
-
|
|
23486
|
-
|
|
23487
|
-
|
|
23488
|
-
|
|
23489
|
-
|
|
23490
|
-
|
|
23491
|
-
|
|
23492
|
-
|
|
23493
|
-
|
|
23494
|
-
|
|
23495
|
-
|
|
23496
|
-
|
|
23497
|
-
|
|
23498
|
-
|
|
23499
|
-
|
|
23500
|
-
|
|
23501
|
-
|
|
23502
|
-
|
|
23503
|
-
|
|
23504
|
-
|
|
23505
|
-
|
|
23506
|
-
|
|
23507
|
-
|
|
23508
|
-
|
|
23509
|
-
|
|
23510
|
-
|
|
23511
|
-
|
|
23512
|
-
|
|
23513
|
-
|
|
23514
|
-
|
|
23515
|
-
|
|
23516
|
-
|
|
23517
|
-
|
|
23518
|
-
|
|
23519
|
-
|
|
23523
|
+
const needsConsolidation = deposits.length > 1 || tailCalls != null;
|
|
23524
|
+
if (!needsConsolidation) {
|
|
23525
|
+
const deposit = deposits[0];
|
|
23526
|
+
const signer2 = await resolveIndependentSigner(deposit);
|
|
23527
|
+
const gasUnits = reasonableGasUnits(poolInfo.isERC20);
|
|
23528
|
+
const fee2 = await quoteFee(computeMinimumViableFee(gasUnits, maxFeePerGas));
|
|
23529
|
+
const proof = await prove(deposit, originalRecipient, relayerAddress, fee2);
|
|
23530
|
+
const userOperation2 = await buildSignedTornadoUserOp({
|
|
23531
|
+
signer: signer2,
|
|
23532
|
+
chainId,
|
|
23533
|
+
paymasterAddress,
|
|
23534
|
+
paymasterData: buildPaymasterData(deposit.pool, proof),
|
|
23535
|
+
gas: { ...gasUnits, callGasLimit: 0n },
|
|
23536
|
+
maxFeePerGas,
|
|
23537
|
+
maxPriorityFeePerGas,
|
|
23538
|
+
nonce: 0n
|
|
23539
|
+
});
|
|
23540
|
+
return [{
|
|
23541
|
+
mode: "paymaster",
|
|
23542
|
+
proof,
|
|
23543
|
+
poolAddress: deposit.pool,
|
|
23544
|
+
isERC20: poolInfo.isERC20,
|
|
23545
|
+
paymasterAddress,
|
|
23546
|
+
entryPointAddress,
|
|
23547
|
+
bundlerUrl,
|
|
23548
|
+
userOperation: userOperation2
|
|
23549
|
+
}];
|
|
23550
|
+
}
|
|
23551
|
+
const signer = await resolveBatchDelegator();
|
|
23552
|
+
const senderAddress = BigInt(signer.address);
|
|
23553
|
+
const sponsoringDeposit = deposits[0];
|
|
23554
|
+
const directDeposits = deposits.slice(1);
|
|
23555
|
+
const ZERO_ADDRESS = 0n;
|
|
23556
|
+
const directWithdrawCalls = [];
|
|
23557
|
+
for (const deposit of directDeposits) {
|
|
23558
|
+
const proof = await prove(deposit, senderAddress, ZERO_ADDRESS, 0n);
|
|
23559
|
+
const [root, nullifierHash, proofRecipient, relayerArg, feeArg, refundArg] = proof.args;
|
|
23560
|
+
const data = encodeFunctionData({
|
|
23561
|
+
abi: poolAbi,
|
|
23562
|
+
functionName: "withdraw",
|
|
23563
|
+
args: [proof.proof, root, nullifierHash, proofRecipient, relayerArg, BigInt(feeArg), BigInt(refundArg)]
|
|
23564
|
+
});
|
|
23565
|
+
directWithdrawCalls.push(createTx(addressToHex(deposit.pool), data, 0n));
|
|
23566
|
+
}
|
|
23567
|
+
const totalDenomination = deposits.reduce(
|
|
23568
|
+
(sum, d) => sum + pools.get(d.pool).denomination,
|
|
23569
|
+
0n
|
|
23570
|
+
);
|
|
23571
|
+
const forwardCalls = (fee2) => {
|
|
23572
|
+
const amount2 = totalDenomination - fee2;
|
|
23573
|
+
if (poolInfo.isERC20) {
|
|
23574
|
+
const data = encodeFunctionData({
|
|
23575
|
+
abi: erc20Abi,
|
|
23576
|
+
functionName: "transfer",
|
|
23577
|
+
args: [addressToHex(originalRecipient), amount2]
|
|
23578
|
+
});
|
|
23579
|
+
return [createTx(addressToHex(poolInfo.asset), data, 0n)];
|
|
23580
|
+
}
|
|
23581
|
+
return [createTx(addressToHex(originalRecipient), "0x", amount2)];
|
|
23582
|
+
};
|
|
23583
|
+
const composeTailCalls = (fee2) => async (addr) => [
|
|
23584
|
+
...directWithdrawCalls,
|
|
23585
|
+
...tailCalls ? await tailCalls(addr) : forwardCalls(fee2)
|
|
23586
|
+
];
|
|
23587
|
+
const buildOp = (gas2, fee2, paymasterData) => buildSignedTornadoUserOp({
|
|
23588
|
+
signer,
|
|
23589
|
+
chainId,
|
|
23590
|
+
paymasterAddress,
|
|
23591
|
+
paymasterData,
|
|
23592
|
+
gas: gas2,
|
|
23593
|
+
maxFeePerGas,
|
|
23594
|
+
maxPriorityFeePerGas,
|
|
23595
|
+
tailCalls: composeTailCalls(fee2),
|
|
23596
|
+
nonce: 0n
|
|
23597
|
+
});
|
|
23598
|
+
const baselineGas = reasonableGasUnitsForBatch(poolInfo.isERC20, directDeposits.length, tailCalls != null);
|
|
23599
|
+
let fee = await quoteFee(computeMinimumViableFee(baselineGas, maxFeePerGas));
|
|
23600
|
+
let gas = baselineGas;
|
|
23601
|
+
let sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
23602
|
+
let userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
23603
|
+
try {
|
|
23604
|
+
const estimated = await estimateUserOperationGas2(bundlerClient, userOperation, entryPointAddress);
|
|
23605
|
+
const buffer2 = (x) => x * 12n / 10n;
|
|
23606
|
+
const orBaseline = (e, b) => e > 0n ? buffer2(e) : b;
|
|
23607
|
+
const refinedGas = {
|
|
23608
|
+
callGasLimit: orBaseline(estimated.callGasLimit, baselineGas.callGasLimit),
|
|
23609
|
+
verificationGasLimit: orBaseline(estimated.verificationGasLimit, baselineGas.verificationGasLimit),
|
|
23610
|
+
preVerificationGas: orBaseline(estimated.preVerificationGas, baselineGas.preVerificationGas),
|
|
23611
|
+
paymasterVerificationGasLimit: orBaseline(estimated.paymasterVerificationGasLimit, baselineGas.paymasterVerificationGasLimit),
|
|
23612
|
+
paymasterPostOpGasLimit: orBaseline(estimated.paymasterPostOpGasLimit, baselineGas.paymasterPostOpGasLimit)
|
|
23613
|
+
};
|
|
23614
|
+
fee = await quoteFee(computeMinimumViableFee(refinedGas, maxFeePerGas));
|
|
23615
|
+
gas = refinedGas;
|
|
23616
|
+
sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
23617
|
+
userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
23618
|
+
} catch {
|
|
23520
23619
|
}
|
|
23521
|
-
return
|
|
23620
|
+
return [{
|
|
23522
23621
|
mode: "paymaster",
|
|
23523
|
-
proof,
|
|
23524
|
-
poolAddress,
|
|
23622
|
+
proof: sponsoringProof,
|
|
23623
|
+
poolAddress: sponsoringDeposit.pool,
|
|
23525
23624
|
isERC20: poolInfo.isERC20,
|
|
23526
23625
|
paymasterAddress,
|
|
23527
23626
|
entryPointAddress,
|
|
23528
23627
|
bundlerUrl,
|
|
23529
|
-
userOperation
|
|
23530
|
-
}
|
|
23628
|
+
userOperation
|
|
23629
|
+
}];
|
|
23531
23630
|
});
|
|
23532
23631
|
|
|
23533
|
-
// ../provider/dist/index.js
|
|
23534
|
-
var createTx = (address, payload, value = BigInt(0)) => {
|
|
23535
|
-
return {
|
|
23536
|
-
to: address,
|
|
23537
|
-
data: payload,
|
|
23538
|
-
value
|
|
23539
|
-
};
|
|
23540
|
-
};
|
|
23541
|
-
|
|
23542
23632
|
// src/account/tx/shield.ts
|
|
23543
23633
|
init_esm();
|
|
23544
23634
|
init_esm();
|