@matterlabs/zksync-js 0.0.1 → 0.0.3
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 +12 -12
- package/dist/adapters/ethers/client.cjs +642 -1
- package/dist/adapters/ethers/client.cjs.map +1 -1
- package/dist/adapters/ethers/client.js +6 -5
- package/dist/adapters/ethers/estimator.d.ts +4 -0
- package/dist/adapters/ethers/index.cjs +1279 -925
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.d.ts +1 -0
- package/dist/adapters/ethers/index.js +9 -8
- package/dist/adapters/ethers/resources/contracts/contracts.d.ts +9 -0
- package/dist/adapters/ethers/resources/contracts/index.d.ts +2 -0
- package/dist/adapters/ethers/resources/contracts/types.d.ts +60 -0
- package/dist/adapters/ethers/resources/deposits/context.d.ts +21 -7
- package/dist/adapters/ethers/resources/deposits/index.d.ts +3 -1
- package/dist/adapters/ethers/resources/deposits/routes/types.d.ts +2 -6
- package/dist/adapters/ethers/resources/deposits/services/fee.d.ts +6 -0
- package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +41 -0
- package/dist/adapters/ethers/resources/tokens/index.d.ts +1 -0
- package/dist/adapters/ethers/resources/tokens/tokens.d.ts +10 -0
- package/dist/adapters/ethers/resources/utils.d.ts +3 -17
- package/dist/adapters/ethers/resources/withdrawals/context.d.ts +15 -7
- package/dist/adapters/ethers/resources/withdrawals/index.d.ts +3 -1
- package/dist/adapters/ethers/resources/withdrawals/routes/types.d.ts +2 -2
- package/dist/adapters/ethers/resources/withdrawals/services/fees.d.ts +14 -0
- package/dist/adapters/ethers/resources/withdrawals/services/gas.d.ts +12 -0
- package/dist/adapters/ethers/sdk.cjs +1388 -1501
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.d.ts +5 -22
- package/dist/adapters/ethers/sdk.js +7 -6
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.d.ts +1 -1
- package/dist/adapters/viem/client.js +4 -5
- package/dist/adapters/viem/estimator.d.ts +4 -0
- package/dist/adapters/viem/index.cjs +1233 -744
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.d.ts +3 -0
- package/dist/adapters/viem/index.js +8 -8
- package/dist/adapters/viem/resources/contracts/contracts.d.ts +9 -0
- package/dist/adapters/viem/resources/contracts/index.d.ts +2 -0
- package/dist/adapters/viem/resources/contracts/types.d.ts +61 -0
- package/dist/adapters/viem/resources/deposits/context.d.ts +21 -7
- package/dist/adapters/viem/resources/deposits/index.d.ts +3 -1
- package/dist/adapters/viem/resources/deposits/routes/types.d.ts +2 -6
- package/dist/adapters/viem/resources/deposits/services/fee.d.ts +6 -0
- package/dist/adapters/viem/resources/deposits/services/gas.d.ts +37 -0
- package/dist/adapters/viem/resources/tokens/index.d.ts +1 -0
- package/dist/adapters/viem/resources/tokens/tokens.d.ts +3 -0
- package/dist/adapters/viem/resources/utils.d.ts +3 -19
- package/dist/adapters/viem/resources/withdrawals/context.d.ts +14 -9
- package/dist/adapters/viem/resources/withdrawals/index.d.ts +3 -1
- package/dist/adapters/viem/resources/withdrawals/routes/types.d.ts +12 -2
- package/dist/adapters/viem/resources/withdrawals/services/fee.d.ts +17 -0
- package/dist/adapters/viem/resources/withdrawals/services/gas.d.ts +12 -0
- package/dist/adapters/viem/sdk.cjs +1225 -699
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +5 -25
- package/dist/adapters/viem/sdk.js +6 -6
- package/dist/{chunk-3LALBFFE.js → chunk-3MRGU4HV.js} +9 -5
- package/dist/{chunk-CGO27P7F.js → chunk-5YWP4CZP.js} +849 -835
- package/dist/{chunk-4HLJJKIY.js → chunk-6K6VJQAL.js} +2 -2
- package/dist/{chunk-6GCT6TLS.js → chunk-F2ENUV3A.js} +13 -1
- package/dist/{chunk-7M4V3FMT.js → chunk-JXUFGIJG.js} +986 -678
- package/dist/chunk-LL3WKCFJ.js +231 -0
- package/dist/{chunk-Y75OMFK6.js → chunk-M5J2MM2U.js} +351 -1
- package/dist/{chunk-263G6636.js → chunk-NCAIVYBR.js} +1 -14
- package/dist/{chunk-DI2CJDPZ.js → chunk-NEC2ZKHI.js} +5 -13
- package/dist/chunk-NTEIA5KA.js +13 -0
- package/dist/chunk-XRE7H466.js +157 -0
- package/dist/{chunk-BD2LUO5T.js → chunk-YUK547UF.js} +3 -3
- package/dist/core/abi.d.ts +9 -0
- package/dist/core/adapters/interfaces.d.ts +25 -0
- package/dist/core/codec/ntv.d.ts +48 -0
- package/dist/core/constants.cjs +12 -0
- package/dist/core/constants.cjs.map +1 -1
- package/dist/core/constants.d.ts +6 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/index.cjs +4508 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +5 -4
- package/dist/core/resources/deposits/fee.d.ts +15 -0
- package/dist/core/resources/deposits/gas.d.ts +38 -0
- package/dist/core/resources/withdrawals/gas.d.ts +14 -0
- package/dist/core/types/errors.d.ts +1 -1
- package/dist/core/types/fees.d.ts +40 -0
- package/dist/core/types/flows/base.d.ts +0 -10
- package/dist/core/types/flows/deposits.d.ts +20 -6
- package/dist/core/types/flows/route.d.ts +2 -3
- package/dist/core/types/flows/token.d.ts +192 -0
- package/dist/core/types/flows/withdrawals.d.ts +12 -6
- package/dist/core/utils/addr.d.ts +2 -0
- package/dist/index.cjs +4520 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -4
- package/package.json +5 -1
- package/dist/adapters/ethers/resources/token-info.d.ts +0 -31
- package/dist/adapters/ethers/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
- package/dist/adapters/viem/resources/token-info.d.ts +0 -34
- package/dist/adapters/viem/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
- package/dist/chunk-B77GWPO5.js +0 -339
- package/dist/core/internal/abi-registry.d.ts +0 -9
- package/dist/core/utils/gas.d.ts +0 -13
|
@@ -217,27 +217,21 @@ var OP_DEPOSITS = {
|
|
|
217
217
|
base: {
|
|
218
218
|
assertErc20Asset: "deposits.erc20-base:assertErc20Asset",
|
|
219
219
|
assertMatchesBase: "deposits.erc20-base:assertMatchesBase",
|
|
220
|
-
baseToken: "deposits.erc20-base:baseToken",
|
|
221
220
|
allowance: "deposits.erc20-base:allowance",
|
|
222
|
-
baseCost: "deposits.erc20-base:l2TransactionBaseCost",
|
|
223
221
|
estGas: "deposits.erc20-base:estimateGas"
|
|
224
222
|
},
|
|
225
223
|
nonbase: {
|
|
226
|
-
baseToken: "deposits.erc20-nonbase:baseToken",
|
|
227
224
|
assertNotEthAsset: "deposits.erc20-nonbase:assertNotEthAsset",
|
|
228
|
-
allowance: "deposits.erc20-nonbase:allowance",
|
|
229
|
-
allowanceFees: "deposits.erc20-nonbase:allowanceFeesBaseToken",
|
|
230
|
-
baseCost: "deposits.erc20-nonbase:l2TransactionBaseCost",
|
|
231
225
|
encodeCalldata: "deposits.erc20-nonbase:encodeSecondBridgeErc20Args",
|
|
232
226
|
estGas: "deposits.erc20-nonbase:estimateGas",
|
|
233
|
-
assertNonBaseToken: "deposits.erc20-nonbase:assertNonBaseToken"
|
|
227
|
+
assertNonBaseToken: "deposits.erc20-nonbase:assertNonBaseToken",
|
|
228
|
+
allowanceToken: "deposits.erc20-nonbase:allowanceToken",
|
|
229
|
+
allowanceBase: "deposits.erc20-nonbase:allowanceBase"
|
|
230
|
+
},
|
|
234
231
|
eth: {
|
|
235
|
-
baseCost: "deposits.eth:l2TransactionBaseCost",
|
|
236
232
|
estGas: "deposits.eth:estimateGas"
|
|
237
233
|
},
|
|
238
234
|
ethNonBase: {
|
|
239
|
-
baseToken: "deposits.eth-nonbase:baseToken",
|
|
240
|
-
baseCost: "deposits.eth-nonbase:l2TransactionBaseCost",
|
|
241
235
|
allowanceBase: "deposits.eth-nonbase:allowanceBaseToken",
|
|
242
236
|
ethBalance: "deposits.eth-nonbase:getEthBalance",
|
|
243
237
|
encodeCalldata: "deposits.eth-nonbase:encodeSecondBridgeEthArgs",
|
|
@@ -595,8 +589,12 @@ var TOPIC_L1_MESSAGE_SENT_NEW = k256hex("L1MessageSent(uint256,bytes32,bytes)");
|
|
|
595
589
|
var TOPIC_L1_MESSAGE_SENT_LEG = k256hex("L1MessageSent(address,bytes32,bytes)");
|
|
596
590
|
var TOPIC_CANONICAL_ASSIGNED = "0x779f441679936c5441b671969f37400b8c3ed0071cb47444431bf985754560df";
|
|
597
591
|
var TOPIC_CANONICAL_SUCCESS = "0xe4def01b981193a97a9e81230d7b9f31812ceaf23f864a828a82c687911cb2df";
|
|
598
|
-
var
|
|
599
|
-
var
|
|
592
|
+
var BUFFER = 20n;
|
|
593
|
+
var TX_OVERHEAD_GAS = 10000n;
|
|
594
|
+
var TX_MEMORY_OVERHEAD_GAS = 10n;
|
|
595
|
+
var DEFAULT_PUBDATA_BYTES = 155n;
|
|
596
|
+
var DEFAULT_ABI_BYTES = 400n;
|
|
597
|
+
var SAFE_L1_BRIDGE_GAS = 600000n;
|
|
600
598
|
|
|
601
599
|
// src/core/internal/abis/IBridgehub.ts
|
|
602
600
|
var IBridgehubABI = [
|
|
@@ -5195,30 +5193,46 @@ function createViemClient(args) {
|
|
|
5195
5193
|
};
|
|
5196
5194
|
}
|
|
5197
5195
|
|
|
5198
|
-
// src/
|
|
5199
|
-
function
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5196
|
+
// src/adapters/viem/resources/deposits/context.ts
|
|
5197
|
+
async function commonCtx(p, client, tokens, contracts) {
|
|
5198
|
+
const { bridgehub, l1AssetRouter } = await contracts.addresses();
|
|
5199
|
+
const chainId = await client.l2.getChainId();
|
|
5200
|
+
const sender = client.account.address;
|
|
5201
|
+
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
5202
|
+
const operatorTip = p.operatorTip ?? 0n;
|
|
5203
|
+
const refundRecipient = p.refundRecipient ?? sender;
|
|
5204
|
+
const resolvedToken = await tokens.resolve(p.token, { chain: "l1" });
|
|
5205
|
+
const baseTokenAssetId = resolvedToken.baseTokenAssetId;
|
|
5206
|
+
const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
|
|
5207
|
+
const baseIsEth = resolvedToken.isChainEthBased;
|
|
5208
|
+
const route = (() => {
|
|
5209
|
+
if (resolvedToken.kind === "eth") {
|
|
5210
|
+
return baseIsEth ? "eth-base" : "eth-nonbase";
|
|
5211
|
+
}
|
|
5212
|
+
if (resolvedToken.kind === "base") {
|
|
5213
|
+
return baseIsEth ? "eth-base" : "erc20-base";
|
|
5214
|
+
}
|
|
5215
|
+
return "erc20-nonbase";
|
|
5216
|
+
})();
|
|
5217
|
+
return {
|
|
5218
|
+
client,
|
|
5219
|
+
tokens,
|
|
5220
|
+
contracts,
|
|
5221
|
+
resolvedToken,
|
|
5222
|
+
baseTokenAssetId,
|
|
5223
|
+
baseTokenL1,
|
|
5224
|
+
baseIsEth,
|
|
5225
|
+
l1AssetRouter,
|
|
5226
|
+
route,
|
|
5227
|
+
bridgehub,
|
|
5228
|
+
chainIdL2: BigInt(chainId),
|
|
5229
|
+
sender,
|
|
5230
|
+
gasOverrides: p.l1TxOverrides,
|
|
5231
|
+
l2GasLimit: p.l2GasLimit,
|
|
5232
|
+
gasPerPubdata,
|
|
5233
|
+
operatorTip,
|
|
5234
|
+
refundRecipient
|
|
5235
|
+
};
|
|
5222
5236
|
}
|
|
5223
5237
|
function encodeNativeTokenVaultTransferData(amount, receiver, token) {
|
|
5224
5238
|
return viem.encodeAbiParameters(
|
|
@@ -5240,123 +5254,6 @@ function encodeSecondBridgeDataV1(assetId, transferData) {
|
|
|
5240
5254
|
);
|
|
5241
5255
|
return viem.concat(["0x01", data]);
|
|
5242
5256
|
}
|
|
5243
|
-
var encodeNTVAssetId = encodeNativeTokenVaultAssetId;
|
|
5244
|
-
var encodeNTVTransferData = encodeNativeTokenVaultTransferData;
|
|
5245
|
-
function scaleGasLimit(gasLimit) {
|
|
5246
|
-
return gasLimit * BigInt(L1_FEE_ESTIMATION_COEF_NUMERATOR) / BigInt(L1_FEE_ESTIMATION_COEF_DENOMINATOR);
|
|
5247
|
-
}
|
|
5248
|
-
async function checkBaseCost(baseCost, value) {
|
|
5249
|
-
const resolved = await value;
|
|
5250
|
-
if (baseCost > resolved) {
|
|
5251
|
-
throw new Error(
|
|
5252
|
-
`The base cost of performing the priority operation is higher than the provided value parameter for the transaction: baseCost: ${String(baseCost)}, provided value: ${String(resolved)}!`
|
|
5253
|
-
);
|
|
5254
|
-
}
|
|
5255
|
-
}
|
|
5256
|
-
async function getFeeOverrides(client, overrides) {
|
|
5257
|
-
assertNoLegacyGas(overrides);
|
|
5258
|
-
let maxFeePerGasFromProvider;
|
|
5259
|
-
let maxPriorityFromProvider;
|
|
5260
|
-
let gasPriceFromProvider;
|
|
5261
|
-
try {
|
|
5262
|
-
const fees = await client.l1.estimateFeesPerGas();
|
|
5263
|
-
const { maxFeePerGas: maxFeePerGas2, maxPriorityFeePerGas: maxPriorityFeePerGas2 } = fees;
|
|
5264
|
-
if (maxFeePerGas2 != null && maxPriorityFeePerGas2 != null) {
|
|
5265
|
-
maxFeePerGasFromProvider = maxFeePerGas2;
|
|
5266
|
-
maxPriorityFromProvider = maxPriorityFeePerGas2;
|
|
5267
|
-
gasPriceFromProvider = fees.gasPrice ?? maxFeePerGas2;
|
|
5268
|
-
} else if (fees.gasPrice != null) {
|
|
5269
|
-
gasPriceFromProvider = fees.gasPrice;
|
|
5270
|
-
}
|
|
5271
|
-
} catch {
|
|
5272
|
-
}
|
|
5273
|
-
if (gasPriceFromProvider == null) {
|
|
5274
|
-
try {
|
|
5275
|
-
gasPriceFromProvider = await client.l1.getGasPrice();
|
|
5276
|
-
} catch {
|
|
5277
|
-
}
|
|
5278
|
-
}
|
|
5279
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeePerGasFromProvider ?? gasPriceFromProvider;
|
|
5280
|
-
if (maxFeePerGas == null) {
|
|
5281
|
-
throw new Error("L1 provider returned no gas price data");
|
|
5282
|
-
}
|
|
5283
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
5284
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
5285
|
-
const gasPriceForBaseCost = overrides?.maxFeePerGas ?? maxFeePerGasFromProvider ?? gasPriceFromProvider ?? maxFeePerGas;
|
|
5286
|
-
return {
|
|
5287
|
-
gasLimit: overrides?.gasLimit,
|
|
5288
|
-
maxFeePerGas,
|
|
5289
|
-
maxPriorityFeePerGas,
|
|
5290
|
-
gasPriceForBaseCost
|
|
5291
|
-
};
|
|
5292
|
-
}
|
|
5293
|
-
async function getL2FeeOverrides(client, overrides) {
|
|
5294
|
-
assertNoLegacyGas(overrides);
|
|
5295
|
-
let maxFeePerGasFromProvider;
|
|
5296
|
-
let maxPriorityFromProvider;
|
|
5297
|
-
let gasPriceFromProvider;
|
|
5298
|
-
try {
|
|
5299
|
-
const fees = await client.l2.estimateFeesPerGas();
|
|
5300
|
-
if (fees?.maxFeePerGas != null && fees.maxPriorityFeePerGas != null) {
|
|
5301
|
-
maxFeePerGasFromProvider = fees.maxFeePerGas;
|
|
5302
|
-
maxPriorityFromProvider = fees.maxPriorityFeePerGas;
|
|
5303
|
-
gasPriceFromProvider = fees.gasPrice ?? fees.maxFeePerGas;
|
|
5304
|
-
} else if (fees?.gasPrice != null) {
|
|
5305
|
-
gasPriceFromProvider = fees.gasPrice;
|
|
5306
|
-
}
|
|
5307
|
-
} catch {
|
|
5308
|
-
}
|
|
5309
|
-
if (gasPriceFromProvider == null) {
|
|
5310
|
-
try {
|
|
5311
|
-
gasPriceFromProvider = await client.l2.getGasPrice();
|
|
5312
|
-
} catch {
|
|
5313
|
-
}
|
|
5314
|
-
}
|
|
5315
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeePerGasFromProvider ?? gasPriceFromProvider;
|
|
5316
|
-
if (maxFeePerGas == null) {
|
|
5317
|
-
throw new Error("provider returned no gas price data");
|
|
5318
|
-
}
|
|
5319
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
5320
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
5321
|
-
return {
|
|
5322
|
-
gasLimit: overrides?.gasLimit,
|
|
5323
|
-
maxFeePerGas,
|
|
5324
|
-
maxPriorityFeePerGas
|
|
5325
|
-
};
|
|
5326
|
-
}
|
|
5327
|
-
function buildViemFeeOverrides(fees) {
|
|
5328
|
-
return {
|
|
5329
|
-
maxFeePerGas: fees.maxFeePerGas,
|
|
5330
|
-
maxPriorityFeePerGas: fees.maxPriorityFeePerGas,
|
|
5331
|
-
gas: fees.gasLimit
|
|
5332
|
-
};
|
|
5333
|
-
}
|
|
5334
|
-
async function getGasPriceWei(client) {
|
|
5335
|
-
try {
|
|
5336
|
-
const gp = await client.l1.getGasPrice();
|
|
5337
|
-
if (gp != null) return gp;
|
|
5338
|
-
} catch {
|
|
5339
|
-
}
|
|
5340
|
-
try {
|
|
5341
|
-
const fees = await client.l1.estimateFeesPerGas();
|
|
5342
|
-
if (fees?.maxFeePerGas != null) return fees.maxFeePerGas;
|
|
5343
|
-
} catch {
|
|
5344
|
-
}
|
|
5345
|
-
throw new Error("provider returned no gas price data");
|
|
5346
|
-
}
|
|
5347
|
-
function buildDirectRequestStruct(args) {
|
|
5348
|
-
return {
|
|
5349
|
-
chainId: args.chainId,
|
|
5350
|
-
l2Contract: args.l2Contract,
|
|
5351
|
-
mintValue: args.mintValue,
|
|
5352
|
-
l2Value: args.l2Value,
|
|
5353
|
-
l2Calldata: "0x",
|
|
5354
|
-
l2GasLimit: args.l2GasLimit,
|
|
5355
|
-
l2GasPerPubdataByteLimit: args.gasPerPubdata,
|
|
5356
|
-
factoryDeps: [],
|
|
5357
|
-
refundRecipient: args.refundRecipient
|
|
5358
|
-
};
|
|
5359
|
-
}
|
|
5360
5257
|
function encodeSecondBridgeArgs(token, amount, l2Receiver) {
|
|
5361
5258
|
return viem.encodeAbiParameters(
|
|
5362
5259
|
[
|
|
@@ -5373,58 +5270,17 @@ function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
|
|
|
5373
5270
|
function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
|
|
5374
5271
|
return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
|
|
5375
5272
|
}
|
|
5376
|
-
|
|
5377
|
-
// src/core/utils/addr.ts
|
|
5378
|
-
var isHash66 = (x) => !!x && x.startsWith("0x") && x.length === 66;
|
|
5379
|
-
function isAddressEq(a, b) {
|
|
5380
|
-
return a.toLowerCase() === b.toLowerCase();
|
|
5381
|
-
}
|
|
5382
|
-
function isETH(token) {
|
|
5383
|
-
return isAddressEq(token, FORMAL_ETH_ADDRESS) || isAddressEq(token, L2_BASE_TOKEN_ADDRESS) || isAddressEq(token, ETH_ADDRESS);
|
|
5384
|
-
}
|
|
5385
|
-
function normalizeAddrEq(a, b) {
|
|
5386
|
-
if (!a || !b) return false;
|
|
5387
|
-
const normalize = (s) => {
|
|
5388
|
-
const hasPrefix = s.slice(0, 2).toLowerCase() === "0x";
|
|
5389
|
-
const body = hasPrefix ? s.slice(2) : s;
|
|
5390
|
-
return `0x${body.toLowerCase()}`;
|
|
5391
|
-
};
|
|
5392
|
-
return normalize(a) === normalize(b);
|
|
5393
|
-
}
|
|
5394
|
-
|
|
5395
|
-
// src/core/resources/deposits/route.ts
|
|
5396
|
-
async function pickDepositRoute(client, chainIdL2, token) {
|
|
5397
|
-
if (isETH(token)) {
|
|
5398
|
-
const base2 = await client.baseToken(chainIdL2);
|
|
5399
|
-
return isETH(base2) ? "eth-base" : "eth-nonbase";
|
|
5400
|
-
}
|
|
5401
|
-
const base = await client.baseToken(chainIdL2);
|
|
5402
|
-
return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
|
|
5403
|
-
}
|
|
5404
|
-
|
|
5405
|
-
// src/adapters/viem/resources/deposits/context.ts
|
|
5406
|
-
async function commonCtx(p, client) {
|
|
5407
|
-
const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
|
|
5408
|
-
const chainId = await client.l2.getChainId();
|
|
5409
|
-
const sender = client.account.address;
|
|
5410
|
-
const fee = await getFeeOverrides(client, p.l1TxOverrides);
|
|
5411
|
-
const l2GasLimit = p.l2GasLimit ?? 300000n;
|
|
5412
|
-
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
5413
|
-
const operatorTip = p.operatorTip ?? 0n;
|
|
5414
|
-
const refundRecipient = p.refundRecipient ?? sender;
|
|
5415
|
-
const route = await pickDepositRoute(client, BigInt(chainId), p.token);
|
|
5273
|
+
function buildDirectRequestStruct(args) {
|
|
5416
5274
|
return {
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
operatorTip,
|
|
5427
|
-
refundRecipient
|
|
5275
|
+
chainId: args.chainId,
|
|
5276
|
+
l2Contract: args.l2Contract,
|
|
5277
|
+
mintValue: args.mintValue,
|
|
5278
|
+
l2Value: args.l2Value,
|
|
5279
|
+
l2Calldata: "0x",
|
|
5280
|
+
l2GasLimit: args.l2GasLimit,
|
|
5281
|
+
l2GasPerPubdataByteLimit: args.gasPerPubdata,
|
|
5282
|
+
factoryDeps: [],
|
|
5283
|
+
refundRecipient: args.refundRecipient
|
|
5428
5284
|
};
|
|
5429
5285
|
}
|
|
5430
5286
|
|
|
@@ -5579,7 +5435,7 @@ function createErrorHandlers(resource) {
|
|
|
5579
5435
|
function wrap2(operation, fn, opts) {
|
|
5580
5436
|
return run("INTERNAL", operation, fn, opts);
|
|
5581
5437
|
}
|
|
5582
|
-
function
|
|
5438
|
+
function wrapAs10(kind, operation, fn, opts) {
|
|
5583
5439
|
return run(kind, operation, fn, opts);
|
|
5584
5440
|
}
|
|
5585
5441
|
async function toResult2(operation, fn, opts) {
|
|
@@ -5600,44 +5456,358 @@ function createErrorHandlers(resource) {
|
|
|
5600
5456
|
return { ok: false, error: shaped };
|
|
5601
5457
|
}
|
|
5602
5458
|
}
|
|
5603
|
-
return { wrap: wrap2, wrapAs:
|
|
5459
|
+
return { wrap: wrap2, wrapAs: wrapAs10, toResult: toResult2 };
|
|
5604
5460
|
}
|
|
5605
5461
|
|
|
5606
|
-
// src/
|
|
5462
|
+
// src/core/resources/deposits/gas.ts
|
|
5463
|
+
function makeGasQuote(p) {
|
|
5464
|
+
const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
|
|
5465
|
+
return {
|
|
5466
|
+
gasLimit: p.gasLimit,
|
|
5467
|
+
maxFeePerGas: p.maxFeePerGas,
|
|
5468
|
+
maxPriorityFeePerGas,
|
|
5469
|
+
gasPerPubdata: p.gasPerPubdata,
|
|
5470
|
+
maxCost: p.gasLimit * p.maxFeePerGas
|
|
5471
|
+
};
|
|
5472
|
+
}
|
|
5473
|
+
async function fetchFees(estimator) {
|
|
5474
|
+
try {
|
|
5475
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
5476
|
+
if (fees.maxFeePerGas != null) {
|
|
5477
|
+
return {
|
|
5478
|
+
maxFeePerGas: fees.maxFeePerGas,
|
|
5479
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
|
|
5480
|
+
};
|
|
5481
|
+
}
|
|
5482
|
+
if (fees.gasPrice != null) {
|
|
5483
|
+
return {
|
|
5484
|
+
maxFeePerGas: fees.gasPrice,
|
|
5485
|
+
maxPriorityFeePerGas: 0n
|
|
5486
|
+
};
|
|
5487
|
+
}
|
|
5488
|
+
} catch {
|
|
5489
|
+
}
|
|
5490
|
+
try {
|
|
5491
|
+
const gp = await estimator.getGasPrice();
|
|
5492
|
+
return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
|
|
5493
|
+
} catch {
|
|
5494
|
+
return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
|
|
5495
|
+
}
|
|
5496
|
+
}
|
|
5497
|
+
async function quoteL1Gas(input) {
|
|
5498
|
+
const { estimator, tx, overrides, fallbackGasLimit } = input;
|
|
5499
|
+
let market;
|
|
5500
|
+
const getMarket = async () => {
|
|
5501
|
+
if (market) return market;
|
|
5502
|
+
market = await fetchFees(estimator);
|
|
5503
|
+
return market;
|
|
5504
|
+
};
|
|
5505
|
+
const maxFeePerGas = overrides?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : (await getMarket()).maxFeePerGas);
|
|
5506
|
+
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : (await getMarket()).maxPriorityFeePerGas);
|
|
5507
|
+
const explicitGasLimit = overrides?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
|
|
5508
|
+
if (explicitGasLimit != null) {
|
|
5509
|
+
return makeGasQuote({ gasLimit: explicitGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
5510
|
+
}
|
|
5511
|
+
try {
|
|
5512
|
+
const est = await estimator.estimateGas(tx);
|
|
5513
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
5514
|
+
return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
|
|
5515
|
+
} catch (err) {
|
|
5516
|
+
if (fallbackGasLimit != null) {
|
|
5517
|
+
return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
5518
|
+
}
|
|
5519
|
+
console.warn("L1 gas estimation failed", err);
|
|
5520
|
+
return void 0;
|
|
5521
|
+
}
|
|
5522
|
+
}
|
|
5523
|
+
async function quoteL2Gas(input) {
|
|
5524
|
+
const { estimator, route, tx, gasPerPubdata, l2GasLimit, overrideGasLimit, stateOverrides } = input;
|
|
5525
|
+
const market = await fetchFees(estimator);
|
|
5526
|
+
const maxFeePerGas = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
|
|
5527
|
+
const txGasLimit = tx?.gasLimit != null ? BigInt(tx.gasLimit) : void 0;
|
|
5528
|
+
const explicit = overrideGasLimit ?? txGasLimit;
|
|
5529
|
+
if (explicit != null) {
|
|
5530
|
+
return makeGasQuote({
|
|
5531
|
+
gasLimit: explicit,
|
|
5532
|
+
maxFeePerGas,
|
|
5533
|
+
gasPerPubdata
|
|
5534
|
+
});
|
|
5535
|
+
}
|
|
5536
|
+
if (!tx) {
|
|
5537
|
+
return makeGasQuote({
|
|
5538
|
+
gasLimit: l2GasLimit ?? 0n,
|
|
5539
|
+
maxFeePerGas,
|
|
5540
|
+
gasPerPubdata
|
|
5541
|
+
});
|
|
5542
|
+
}
|
|
5543
|
+
try {
|
|
5544
|
+
const execEstimate = await estimator.estimateGas(tx, stateOverrides);
|
|
5545
|
+
const memoryBytes = route === "erc20-nonbase" ? 500n : DEFAULT_ABI_BYTES;
|
|
5546
|
+
const pubdataBytes = route === "erc20-nonbase" ? 200n : DEFAULT_PUBDATA_BYTES;
|
|
5547
|
+
const pp = gasPerPubdata ?? 800n;
|
|
5548
|
+
const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
|
|
5549
|
+
const pubdataOverhead = pubdataBytes * pp;
|
|
5550
|
+
let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
|
|
5551
|
+
total = total * (100n + BUFFER) / 100n;
|
|
5552
|
+
return makeGasQuote({
|
|
5553
|
+
gasLimit: total,
|
|
5554
|
+
maxFeePerGas,
|
|
5555
|
+
gasPerPubdata: pp
|
|
5556
|
+
});
|
|
5557
|
+
} catch (err) {
|
|
5558
|
+
console.warn("L2 gas estimation failed", err);
|
|
5559
|
+
return makeGasQuote({
|
|
5560
|
+
gasLimit: l2GasLimit ?? 0n,
|
|
5561
|
+
maxFeePerGas,
|
|
5562
|
+
gasPerPubdata
|
|
5563
|
+
});
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
// src/adapters/viem/estimator.ts
|
|
5568
|
+
function toCoreTx(tx) {
|
|
5569
|
+
return {
|
|
5570
|
+
to: tx.to,
|
|
5571
|
+
from: tx.from,
|
|
5572
|
+
data: tx.data,
|
|
5573
|
+
value: tx.value,
|
|
5574
|
+
gasLimit: tx.gas,
|
|
5575
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
5576
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas
|
|
5577
|
+
};
|
|
5578
|
+
}
|
|
5579
|
+
function viemToGasEstimator(client) {
|
|
5580
|
+
return {
|
|
5581
|
+
async estimateGas(tx, stateOverrides) {
|
|
5582
|
+
if (stateOverrides) {
|
|
5583
|
+
try {
|
|
5584
|
+
const result = await client.request({
|
|
5585
|
+
method: "eth_estimateGas",
|
|
5586
|
+
params: [
|
|
5587
|
+
{
|
|
5588
|
+
from: tx.from,
|
|
5589
|
+
to: tx.to,
|
|
5590
|
+
data: tx.data,
|
|
5591
|
+
value: tx.value,
|
|
5592
|
+
gas: tx.gasLimit,
|
|
5593
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
5594
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas
|
|
5595
|
+
},
|
|
5596
|
+
"latest",
|
|
5597
|
+
stateOverrides
|
|
5598
|
+
]
|
|
5599
|
+
});
|
|
5600
|
+
return BigInt(result);
|
|
5601
|
+
} catch (error) {
|
|
5602
|
+
console.warn(
|
|
5603
|
+
"Failed to estimate gas with state overrides, falling back to standard estimation:",
|
|
5604
|
+
error
|
|
5605
|
+
);
|
|
5606
|
+
}
|
|
5607
|
+
}
|
|
5608
|
+
return await client.estimateGas({
|
|
5609
|
+
account: tx.from,
|
|
5610
|
+
to: tx.to,
|
|
5611
|
+
data: tx.data,
|
|
5612
|
+
value: tx.value,
|
|
5613
|
+
gas: tx.gasLimit,
|
|
5614
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
5615
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas
|
|
5616
|
+
});
|
|
5617
|
+
},
|
|
5618
|
+
async estimateFeesPerGas() {
|
|
5619
|
+
try {
|
|
5620
|
+
const fees = await client.estimateFeesPerGas();
|
|
5621
|
+
return {
|
|
5622
|
+
maxFeePerGas: fees.maxFeePerGas,
|
|
5623
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas
|
|
5624
|
+
};
|
|
5625
|
+
} catch {
|
|
5626
|
+
}
|
|
5627
|
+
try {
|
|
5628
|
+
const gp = await client.getGasPrice();
|
|
5629
|
+
return { gasPrice: gp };
|
|
5630
|
+
} catch {
|
|
5631
|
+
return {};
|
|
5632
|
+
}
|
|
5633
|
+
},
|
|
5634
|
+
async getGasPrice() {
|
|
5635
|
+
return await client.getGasPrice();
|
|
5636
|
+
},
|
|
5637
|
+
async call(tx) {
|
|
5638
|
+
const res = await client.call({
|
|
5639
|
+
to: tx.to,
|
|
5640
|
+
data: tx.data,
|
|
5641
|
+
value: tx.value,
|
|
5642
|
+
account: tx.from
|
|
5643
|
+
});
|
|
5644
|
+
return res.data ?? "0x";
|
|
5645
|
+
}
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
|
|
5649
|
+
// src/adapters/viem/resources/deposits/services/gas.ts
|
|
5650
|
+
async function quoteL1Gas2(input) {
|
|
5651
|
+
const { ctx, tx, overrides, fallbackGasLimit } = input;
|
|
5652
|
+
const estimator = viemToGasEstimator(ctx.client.l1);
|
|
5653
|
+
return quoteL1Gas({
|
|
5654
|
+
estimator,
|
|
5655
|
+
tx: toCoreTx(tx),
|
|
5656
|
+
overrides,
|
|
5657
|
+
fallbackGasLimit
|
|
5658
|
+
});
|
|
5659
|
+
}
|
|
5660
|
+
async function quoteL2Gas2(input) {
|
|
5661
|
+
const { ctx, route, l2TxForModeling, overrideGasLimit } = input;
|
|
5662
|
+
const estimator = viemToGasEstimator(ctx.client.l2);
|
|
5663
|
+
return quoteL2Gas({
|
|
5664
|
+
estimator,
|
|
5665
|
+
route,
|
|
5666
|
+
tx: l2TxForModeling ? toCoreTx(l2TxForModeling) : void 0,
|
|
5667
|
+
gasPerPubdata: ctx.gasPerPubdata,
|
|
5668
|
+
l2GasLimit: ctx.l2GasLimit,
|
|
5669
|
+
// TODO: investigate if this should be passed here; weird viem quirk
|
|
5670
|
+
overrideGasLimit,
|
|
5671
|
+
stateOverrides: input.stateOverrides
|
|
5672
|
+
});
|
|
5673
|
+
}
|
|
5674
|
+
async function determineErc20L2Gas(input) {
|
|
5675
|
+
const { ctx, l1Token } = input;
|
|
5676
|
+
const DEFAULT_SAFE_L2_GAS_LIMIT = 3000000n;
|
|
5677
|
+
if (ctx.l2GasLimit != null) {
|
|
5678
|
+
return quoteL2Gas2({
|
|
5679
|
+
ctx,
|
|
5680
|
+
route: "erc20-nonbase",
|
|
5681
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
5682
|
+
});
|
|
5683
|
+
}
|
|
5684
|
+
try {
|
|
5685
|
+
const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).read.l2TokenAddress([l1Token]);
|
|
5686
|
+
if (l2TokenAddress === viem.zeroAddress) {
|
|
5687
|
+
return quoteL2Gas2({
|
|
5688
|
+
ctx,
|
|
5689
|
+
route: "erc20-nonbase",
|
|
5690
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5691
|
+
});
|
|
5692
|
+
}
|
|
5693
|
+
const modelTx = {
|
|
5694
|
+
to: input.modelTx?.to ?? ctx.sender,
|
|
5695
|
+
from: input.modelTx?.from ?? ctx.sender,
|
|
5696
|
+
data: input.modelTx?.data ?? "0x",
|
|
5697
|
+
value: input.modelTx?.value ?? 0n
|
|
5698
|
+
};
|
|
5699
|
+
const gas = await quoteL2Gas2({
|
|
5700
|
+
ctx,
|
|
5701
|
+
route: "erc20-nonbase",
|
|
5702
|
+
l2TxForModeling: modelTx
|
|
5703
|
+
});
|
|
5704
|
+
if (!gas) {
|
|
5705
|
+
return quoteL2Gas2({
|
|
5706
|
+
ctx,
|
|
5707
|
+
route: "erc20-nonbase",
|
|
5708
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5709
|
+
});
|
|
5710
|
+
}
|
|
5711
|
+
return gas;
|
|
5712
|
+
} catch (err) {
|
|
5713
|
+
console.warn("Failed to determine ERC20 L2 gas; defaulting to safe gas limit.", err);
|
|
5714
|
+
return quoteL2Gas2({
|
|
5715
|
+
ctx,
|
|
5716
|
+
route: "erc20-nonbase",
|
|
5717
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5718
|
+
});
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
|
|
5722
|
+
// src/adapters/viem/resources/deposits/services/fee.ts
|
|
5607
5723
|
var { wrapAs } = createErrorHandlers("deposits");
|
|
5724
|
+
async function quoteL2BaseCost(input) {
|
|
5725
|
+
const { ctx, l2GasLimit } = input;
|
|
5726
|
+
const estimator = viemToGasEstimator(ctx.client.l1);
|
|
5727
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
5728
|
+
const gasPrice = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
|
|
5729
|
+
return wrapAs(
|
|
5730
|
+
"RPC",
|
|
5731
|
+
"deposits.fees.l2BaseCost",
|
|
5732
|
+
async () => {
|
|
5733
|
+
return await ctx.client.l1.readContract({
|
|
5734
|
+
address: ctx.bridgehub,
|
|
5735
|
+
abi: IBridgehub_default,
|
|
5736
|
+
functionName: "l2TransactionBaseCost",
|
|
5737
|
+
args: [ctx.chainIdL2, gasPrice, l2GasLimit, ctx.gasPerPubdata]
|
|
5738
|
+
});
|
|
5739
|
+
},
|
|
5740
|
+
{ ctx: { chainIdL2: ctx.chainIdL2 } }
|
|
5741
|
+
);
|
|
5742
|
+
}
|
|
5743
|
+
|
|
5744
|
+
// src/core/resources/deposits/fee.ts
|
|
5745
|
+
function buildFeeBreakdown(p) {
|
|
5746
|
+
const l1MaxTotal = p.l1Gas?.maxCost ?? 0n;
|
|
5747
|
+
const l2Total = p.l2BaseCost + p.operatorTip;
|
|
5748
|
+
const l1 = {
|
|
5749
|
+
gasLimit: p.l1Gas?.gasLimit ?? 0n,
|
|
5750
|
+
maxFeePerGas: p.l1Gas?.maxFeePerGas ?? 0n,
|
|
5751
|
+
maxPriorityFeePerGas: p.l1Gas?.maxPriorityFeePerGas,
|
|
5752
|
+
maxTotal: l1MaxTotal
|
|
5753
|
+
};
|
|
5754
|
+
const l2 = {
|
|
5755
|
+
total: l2Total,
|
|
5756
|
+
baseCost: p.l2BaseCost,
|
|
5757
|
+
operatorTip: p.operatorTip,
|
|
5758
|
+
gasLimit: p.l2Gas?.gasLimit ?? 0n,
|
|
5759
|
+
maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
|
|
5760
|
+
maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas,
|
|
5761
|
+
gasPerPubdata: p.l2Gas?.gasPerPubdata ?? 0n
|
|
5762
|
+
};
|
|
5763
|
+
return {
|
|
5764
|
+
token: p.feeToken,
|
|
5765
|
+
maxTotal: l1MaxTotal + l2Total,
|
|
5766
|
+
mintValue: p.mintValue,
|
|
5767
|
+
l1,
|
|
5768
|
+
l2
|
|
5769
|
+
};
|
|
5770
|
+
}
|
|
5771
|
+
|
|
5772
|
+
// src/adapters/viem/resources/deposits/routes/eth.ts
|
|
5773
|
+
var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
|
|
5608
5774
|
function routeEthDirect() {
|
|
5609
5775
|
return {
|
|
5610
5776
|
async build(p, ctx) {
|
|
5611
|
-
const
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
"
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
{
|
|
5623
|
-
ctx: {
|
|
5624
|
-
|
|
5777
|
+
const l2TxModel = {
|
|
5778
|
+
to: p.to ?? ctx.sender,
|
|
5779
|
+
from: ctx.sender,
|
|
5780
|
+
data: "0x",
|
|
5781
|
+
value: p.amount
|
|
5782
|
+
};
|
|
5783
|
+
const l2GasParams = await quoteL2Gas2({
|
|
5784
|
+
ctx,
|
|
5785
|
+
route: "eth-base",
|
|
5786
|
+
l2TxForModeling: l2TxModel,
|
|
5787
|
+
overrideGasLimit: ctx.l2GasLimit,
|
|
5788
|
+
stateOverrides: {
|
|
5789
|
+
[ctx.sender]: {
|
|
5790
|
+
balance: "0xffffffffffffffffffff"
|
|
5791
|
+
}
|
|
5625
5792
|
}
|
|
5626
|
-
);
|
|
5627
|
-
|
|
5793
|
+
});
|
|
5794
|
+
if (!l2GasParams) {
|
|
5795
|
+
throw new Error("Failed to estimate L2 gas for deposit.");
|
|
5796
|
+
}
|
|
5797
|
+
const baseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
5628
5798
|
const l2Contract = p.to ?? ctx.sender;
|
|
5629
5799
|
const l2Value = p.amount;
|
|
5630
5800
|
const mintValue = baseCost + ctx.operatorTip + l2Value;
|
|
5631
5801
|
const req = buildDirectRequestStruct({
|
|
5632
5802
|
chainId: ctx.chainIdL2,
|
|
5633
5803
|
mintValue,
|
|
5634
|
-
l2GasLimit:
|
|
5804
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
5635
5805
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
5636
5806
|
refundRecipient: ctx.refundRecipient,
|
|
5637
5807
|
l2Contract,
|
|
5638
5808
|
l2Value
|
|
5639
5809
|
});
|
|
5640
|
-
const sim = await
|
|
5810
|
+
const sim = await wrapAs2(
|
|
5641
5811
|
"RPC",
|
|
5642
5812
|
OP_DEPOSITS.eth.estGas,
|
|
5643
5813
|
() => ctx.client.l1.simulateContract({
|
|
@@ -5653,120 +5823,138 @@ function routeEthDirect() {
|
|
|
5653
5823
|
message: "Failed to simulate Bridgehub.requestL2TransactionDirect."
|
|
5654
5824
|
}
|
|
5655
5825
|
);
|
|
5656
|
-
const
|
|
5826
|
+
const data = viem.encodeFunctionData({
|
|
5827
|
+
abi: sim.request.abi,
|
|
5828
|
+
functionName: sim.request.functionName,
|
|
5829
|
+
args: sim.request.args
|
|
5830
|
+
});
|
|
5831
|
+
const l1TxCandidate = {
|
|
5832
|
+
to: ctx.bridgehub,
|
|
5833
|
+
data,
|
|
5834
|
+
value: mintValue,
|
|
5835
|
+
from: ctx.sender,
|
|
5836
|
+
...ctx.gasOverrides
|
|
5837
|
+
};
|
|
5838
|
+
const l1Gas = await quoteL1Gas2({
|
|
5839
|
+
ctx,
|
|
5840
|
+
tx: l1TxCandidate,
|
|
5841
|
+
overrides: ctx.gasOverrides
|
|
5842
|
+
});
|
|
5657
5843
|
const steps = [
|
|
5658
5844
|
{
|
|
5659
5845
|
key: "bridgehub:direct",
|
|
5660
5846
|
kind: "bridgehub:direct",
|
|
5661
5847
|
description: "Bridge ETH via Bridgehub.requestL2TransactionDirect",
|
|
5662
|
-
tx: { ...sim.request, ...
|
|
5848
|
+
tx: { ...sim.request, ...l1Gas }
|
|
5663
5849
|
}
|
|
5664
5850
|
];
|
|
5851
|
+
const fees = buildFeeBreakdown({
|
|
5852
|
+
feeToken: ETH_ADDRESS,
|
|
5853
|
+
l1Gas,
|
|
5854
|
+
l2Gas: l2GasParams,
|
|
5855
|
+
l2BaseCost: baseCost,
|
|
5856
|
+
operatorTip: ctx.operatorTip,
|
|
5857
|
+
mintValue
|
|
5858
|
+
});
|
|
5665
5859
|
return {
|
|
5666
5860
|
steps,
|
|
5667
5861
|
approvals: [],
|
|
5668
|
-
|
|
5862
|
+
fees
|
|
5669
5863
|
};
|
|
5670
5864
|
}
|
|
5671
5865
|
};
|
|
5672
5866
|
}
|
|
5673
5867
|
|
|
5674
|
-
// src/
|
|
5675
|
-
var
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
function
|
|
5680
|
-
return
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5868
|
+
// src/core/utils/addr.ts
|
|
5869
|
+
var isHash66 = (x) => !!x && x.startsWith("0x") && x.length === 66;
|
|
5870
|
+
function isAddressEq(a, b) {
|
|
5871
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
5872
|
+
}
|
|
5873
|
+
function isETH(token) {
|
|
5874
|
+
return isAddressEq(token, FORMAL_ETH_ADDRESS) || isAddressEq(token, L2_BASE_TOKEN_ADDRESS) || isAddressEq(token, ETH_ADDRESS);
|
|
5875
|
+
}
|
|
5876
|
+
function normalizeAddrEq(a, b) {
|
|
5877
|
+
if (!a || !b) return false;
|
|
5878
|
+
const normalize = (s) => {
|
|
5879
|
+
const hasPrefix = s.slice(0, 2).toLowerCase() === "0x";
|
|
5880
|
+
const body = hasPrefix ? s.slice(2) : s;
|
|
5881
|
+
return `0x${body.toLowerCase()}`;
|
|
5882
|
+
};
|
|
5883
|
+
return normalize(a) === normalize(b);
|
|
5884
|
+
}
|
|
5885
|
+
var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
5886
|
+
var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
|
|
5887
|
+
|
|
5888
|
+
// src/adapters/viem/resources/deposits/routes/erc20-nonbase.ts
|
|
5889
|
+
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
5890
|
+
function routeErc20NonBase() {
|
|
5891
|
+
return {
|
|
5892
|
+
// TODO: do we even need these validations?
|
|
5893
|
+
async preflight(p, ctx) {
|
|
5894
|
+
await wrapAs3(
|
|
5895
|
+
"VALIDATION",
|
|
5896
|
+
OP_DEPOSITS.nonbase.assertNotEthAsset,
|
|
5897
|
+
() => {
|
|
5898
|
+
if (ctx.resolvedToken?.kind === "eth" || isETH(p.token)) {
|
|
5899
|
+
throw new Error("erc20-nonbase route requires an ERC-20 token (not ETH).");
|
|
5900
|
+
}
|
|
5901
|
+
},
|
|
5902
|
+
{ ctx: { token: p.token } }
|
|
5702
5903
|
);
|
|
5703
|
-
await
|
|
5904
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
5905
|
+
await wrapAs3(
|
|
5704
5906
|
"VALIDATION",
|
|
5705
5907
|
OP_DEPOSITS.nonbase.assertNonBaseToken,
|
|
5706
5908
|
() => {
|
|
5707
|
-
if (normalizeAddrEq(baseToken, p.token)) {
|
|
5909
|
+
if (ctx.resolvedToken?.kind === "base" || normalizeAddrEq(baseToken, p.token)) {
|
|
5708
5910
|
throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
|
|
5709
5911
|
}
|
|
5710
5912
|
},
|
|
5711
5913
|
{ ctx: { depositToken: p.token, baseToken } }
|
|
5712
5914
|
);
|
|
5713
|
-
return;
|
|
5714
5915
|
},
|
|
5715
5916
|
async build(p, ctx) {
|
|
5716
|
-
const
|
|
5717
|
-
const
|
|
5718
|
-
const
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
);
|
|
5729
|
-
|
|
5730
|
-
const
|
|
5731
|
-
const
|
|
5732
|
-
"CONTRACT",
|
|
5733
|
-
OP_DEPOSITS.nonbase.baseCost,
|
|
5734
|
-
() => ctx.client.l1.readContract({
|
|
5735
|
-
address: ctx.bridgehub,
|
|
5736
|
-
abi: IBridgehub_default,
|
|
5737
|
-
functionName: "l2TransactionBaseCost",
|
|
5738
|
-
args: [ctx.chainIdL2, gasPriceForBaseCost, l2GasLimitUsed, ctx.gasPerPubdata]
|
|
5739
|
-
}),
|
|
5740
|
-
{ ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 } }
|
|
5741
|
-
);
|
|
5742
|
-
const baseCost = rawBaseCost;
|
|
5743
|
-
const mintValue = withBuffer(baseCost + ctx.operatorTip);
|
|
5917
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
5918
|
+
const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
|
|
5919
|
+
const assetRouter = ctx.l1AssetRouter;
|
|
5920
|
+
const l2Gas = await determineErc20L2Gas({
|
|
5921
|
+
ctx,
|
|
5922
|
+
l1Token: p.token,
|
|
5923
|
+
modelTx: {
|
|
5924
|
+
to: p.to ?? ctx.sender,
|
|
5925
|
+
from: ctx.sender,
|
|
5926
|
+
data: "0x",
|
|
5927
|
+
value: 0n
|
|
5928
|
+
}
|
|
5929
|
+
});
|
|
5930
|
+
if (!l2Gas) throw new Error("Failed to establish L2 gas parameters.");
|
|
5931
|
+
const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
|
|
5932
|
+
const mintValue = l2BaseCost + ctx.operatorTip;
|
|
5744
5933
|
const approvals = [];
|
|
5745
5934
|
const steps = [];
|
|
5746
|
-
const depositAllowance = await
|
|
5935
|
+
const depositAllowance = await wrapAs3(
|
|
5747
5936
|
"CONTRACT",
|
|
5748
|
-
OP_DEPOSITS.nonbase.
|
|
5937
|
+
OP_DEPOSITS.nonbase.allowanceToken,
|
|
5749
5938
|
() => ctx.client.l1.readContract({
|
|
5750
5939
|
address: p.token,
|
|
5751
5940
|
abi: IERC20_default,
|
|
5752
5941
|
functionName: "allowance",
|
|
5753
|
-
args: [ctx.sender,
|
|
5942
|
+
args: [ctx.sender, assetRouter]
|
|
5754
5943
|
}),
|
|
5755
5944
|
{
|
|
5756
|
-
ctx: { where: "erc20.allowance", token: p.token, spender:
|
|
5757
|
-
message: "Failed to read
|
|
5945
|
+
ctx: { where: "erc20.allowance", token: p.token, spender: assetRouter },
|
|
5946
|
+
message: "Failed to read deposit-token allowance."
|
|
5758
5947
|
}
|
|
5759
5948
|
);
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
const approveDepReq = await wrapAs2(
|
|
5949
|
+
if (depositAllowance < p.amount) {
|
|
5950
|
+
const approveSim = await wrapAs3(
|
|
5763
5951
|
"CONTRACT",
|
|
5764
5952
|
OP_DEPOSITS.nonbase.estGas,
|
|
5765
5953
|
() => ctx.client.l1.simulateContract({
|
|
5766
5954
|
address: p.token,
|
|
5767
5955
|
abi: IERC20_default,
|
|
5768
5956
|
functionName: "approve",
|
|
5769
|
-
args: [
|
|
5957
|
+
args: [assetRouter, p.amount],
|
|
5770
5958
|
account: ctx.client.account
|
|
5771
5959
|
}),
|
|
5772
5960
|
{
|
|
@@ -5774,60 +5962,55 @@ function routeErc20NonBase() {
|
|
|
5774
5962
|
message: "Failed to simulate deposit token approve."
|
|
5775
5963
|
}
|
|
5776
5964
|
);
|
|
5777
|
-
approvals.push({ token: p.token, spender:
|
|
5965
|
+
approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
|
|
5778
5966
|
steps.push({
|
|
5779
|
-
key: `approve:${p.token}:${
|
|
5967
|
+
key: `approve:${p.token}:${assetRouter}`,
|
|
5780
5968
|
kind: "approve",
|
|
5781
5969
|
description: `Approve deposit token for amount`,
|
|
5782
|
-
tx: { ...
|
|
5970
|
+
tx: { ...approveSim.request }
|
|
5783
5971
|
});
|
|
5784
5972
|
}
|
|
5785
|
-
const baseIsEth = isETH(baseToken);
|
|
5786
|
-
let msgValue = 0n;
|
|
5787
5973
|
if (!baseIsEth) {
|
|
5788
|
-
const baseAllowance = await
|
|
5974
|
+
const baseAllowance = await wrapAs3(
|
|
5789
5975
|
"CONTRACT",
|
|
5790
|
-
OP_DEPOSITS.nonbase.
|
|
5976
|
+
OP_DEPOSITS.nonbase.allowanceBase,
|
|
5791
5977
|
() => ctx.client.l1.readContract({
|
|
5792
5978
|
address: baseToken,
|
|
5793
5979
|
abi: IERC20_default,
|
|
5794
5980
|
functionName: "allowance",
|
|
5795
|
-
args: [ctx.sender,
|
|
5981
|
+
args: [ctx.sender, assetRouter]
|
|
5796
5982
|
}),
|
|
5797
5983
|
{
|
|
5798
|
-
ctx: { where: "erc20.allowance", token: baseToken, spender:
|
|
5984
|
+
ctx: { where: "erc20.allowance", token: baseToken, spender: assetRouter },
|
|
5799
5985
|
message: "Failed to read base-token allowance."
|
|
5800
5986
|
}
|
|
5801
5987
|
);
|
|
5802
5988
|
if (baseAllowance < mintValue) {
|
|
5803
|
-
const
|
|
5989
|
+
const approveBaseSim = await wrapAs3(
|
|
5804
5990
|
"CONTRACT",
|
|
5805
5991
|
OP_DEPOSITS.nonbase.estGas,
|
|
5806
5992
|
() => ctx.client.l1.simulateContract({
|
|
5807
5993
|
address: baseToken,
|
|
5808
5994
|
abi: IERC20_default,
|
|
5809
5995
|
functionName: "approve",
|
|
5810
|
-
args: [
|
|
5996
|
+
args: [assetRouter, mintValue],
|
|
5811
5997
|
account: ctx.client.account
|
|
5812
5998
|
}),
|
|
5813
5999
|
{
|
|
5814
6000
|
ctx: { where: "l1.simulateContract", to: baseToken },
|
|
5815
|
-
message: "Failed to simulate base
|
|
6001
|
+
message: "Failed to simulate base token approve."
|
|
5816
6002
|
}
|
|
5817
6003
|
);
|
|
5818
|
-
approvals.push({ token: baseToken, spender:
|
|
6004
|
+
approvals.push({ token: baseToken, spender: assetRouter, amount: mintValue });
|
|
5819
6005
|
steps.push({
|
|
5820
|
-
key: `approve:${baseToken}:${
|
|
6006
|
+
key: `approve:${baseToken}:${assetRouter}`,
|
|
5821
6007
|
kind: "approve",
|
|
5822
6008
|
description: `Approve base token for mintValue`,
|
|
5823
|
-
tx: { ...
|
|
6009
|
+
tx: { ...approveBaseSim.request }
|
|
5824
6010
|
});
|
|
5825
6011
|
}
|
|
5826
|
-
msgValue = 0n;
|
|
5827
|
-
} else {
|
|
5828
|
-
msgValue = mintValue;
|
|
5829
6012
|
}
|
|
5830
|
-
const secondBridgeCalldata = await
|
|
6013
|
+
const secondBridgeCalldata = await wrapAs3(
|
|
5831
6014
|
"INTERNAL",
|
|
5832
6015
|
OP_DEPOSITS.nonbase.encodeCalldata,
|
|
5833
6016
|
() => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, p.to ?? ctx.sender)),
|
|
@@ -5836,44 +6019,60 @@ function routeErc20NonBase() {
|
|
|
5836
6019
|
where: "encodeSecondBridgeErc20Args",
|
|
5837
6020
|
token: p.token,
|
|
5838
6021
|
amount: p.amount.toString()
|
|
5839
|
-
}
|
|
6022
|
+
},
|
|
6023
|
+
message: "Failed to encode bridging calldata."
|
|
5840
6024
|
}
|
|
5841
6025
|
);
|
|
5842
|
-
const
|
|
6026
|
+
const requestStruct = {
|
|
5843
6027
|
chainId: ctx.chainIdL2,
|
|
5844
6028
|
mintValue,
|
|
5845
6029
|
l2Value: 0n,
|
|
5846
|
-
l2GasLimit:
|
|
6030
|
+
l2GasLimit: l2Gas.gasLimit,
|
|
5847
6031
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
5848
6032
|
refundRecipient: ctx.refundRecipient,
|
|
5849
|
-
secondBridgeAddress:
|
|
6033
|
+
secondBridgeAddress: assetRouter,
|
|
5850
6034
|
secondBridgeValue: 0n,
|
|
5851
6035
|
secondBridgeCalldata
|
|
5852
6036
|
};
|
|
6037
|
+
const msgValue = baseIsEth ? mintValue : 0n;
|
|
6038
|
+
const calldata = viem.encodeFunctionData({
|
|
6039
|
+
abi: IBridgehub_default,
|
|
6040
|
+
functionName: "requestL2TransactionTwoBridges",
|
|
6041
|
+
args: [requestStruct]
|
|
6042
|
+
});
|
|
6043
|
+
const l1TxCandidate = {
|
|
6044
|
+
to: ctx.bridgehub,
|
|
6045
|
+
data: calldata,
|
|
6046
|
+
value: msgValue,
|
|
6047
|
+
from: ctx.sender,
|
|
6048
|
+
...ctx.gasOverrides
|
|
6049
|
+
};
|
|
6050
|
+
const l1Gas = await quoteL1Gas2({
|
|
6051
|
+
ctx,
|
|
6052
|
+
tx: l1TxCandidate,
|
|
6053
|
+
overrides: ctx.gasOverrides,
|
|
6054
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6055
|
+
});
|
|
5853
6056
|
const approvalsNeeded = approvals.length > 0;
|
|
5854
6057
|
let bridgeTx;
|
|
5855
|
-
let resolvedL1GasLimit;
|
|
5856
|
-
const gasOverride = txFeeOverrides.gas;
|
|
5857
6058
|
if (approvalsNeeded) {
|
|
5858
6059
|
bridgeTx = {
|
|
5859
6060
|
address: ctx.bridgehub,
|
|
5860
6061
|
abi: IBridgehub_default,
|
|
5861
6062
|
functionName: "requestL2TransactionTwoBridges",
|
|
5862
|
-
args: [
|
|
6063
|
+
args: [requestStruct],
|
|
5863
6064
|
value: msgValue,
|
|
5864
|
-
account: ctx.client.account
|
|
5865
|
-
...txFeeOverrides
|
|
6065
|
+
account: ctx.client.account
|
|
5866
6066
|
};
|
|
5867
|
-
resolvedL1GasLimit = gasOverride ?? ctx.l2GasLimit;
|
|
5868
6067
|
} else {
|
|
5869
|
-
const sim = await
|
|
6068
|
+
const sim = await wrapAs3(
|
|
5870
6069
|
"CONTRACT",
|
|
5871
6070
|
OP_DEPOSITS.nonbase.estGas,
|
|
5872
6071
|
() => ctx.client.l1.simulateContract({
|
|
5873
6072
|
address: ctx.bridgehub,
|
|
5874
6073
|
abi: IBridgehub_default,
|
|
5875
6074
|
functionName: "requestL2TransactionTwoBridges",
|
|
5876
|
-
args: [
|
|
6075
|
+
args: [requestStruct],
|
|
5877
6076
|
value: msgValue,
|
|
5878
6077
|
account: ctx.client.account
|
|
5879
6078
|
}),
|
|
@@ -5882,67 +6081,64 @@ function routeErc20NonBase() {
|
|
|
5882
6081
|
message: "Failed to simulate two-bridges request."
|
|
5883
6082
|
}
|
|
5884
6083
|
);
|
|
5885
|
-
bridgeTx = { ...sim.request
|
|
5886
|
-
|
|
6084
|
+
bridgeTx = { ...sim.request };
|
|
6085
|
+
}
|
|
6086
|
+
if (l1Gas) {
|
|
6087
|
+
bridgeTx = {
|
|
6088
|
+
...bridgeTx,
|
|
6089
|
+
gas: l1Gas.gasLimit,
|
|
6090
|
+
maxFeePerGas: l1Gas.maxFeePerGas,
|
|
6091
|
+
maxPriorityFeePerGas: l1Gas.maxPriorityFeePerGas
|
|
6092
|
+
};
|
|
5887
6093
|
}
|
|
5888
6094
|
steps.push({
|
|
5889
|
-
key: "bridgehub:two-bridges:nonbase",
|
|
6095
|
+
key: "bridgehub:two-bridges:erc20-nonbase",
|
|
5890
6096
|
kind: "bridgehub:two-bridges",
|
|
5891
6097
|
description: baseIsEth ? "Bridge ERC-20 (fees in ETH) via Bridgehub.requestL2TransactionTwoBridges" : "Bridge ERC-20 (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
|
|
5892
6098
|
tx: bridgeTx
|
|
5893
6099
|
});
|
|
6100
|
+
const fees = buildFeeBreakdown({
|
|
6101
|
+
feeToken: baseToken,
|
|
6102
|
+
l1Gas,
|
|
6103
|
+
l2Gas,
|
|
6104
|
+
l2BaseCost,
|
|
6105
|
+
operatorTip: ctx.operatorTip,
|
|
6106
|
+
mintValue
|
|
6107
|
+
});
|
|
5894
6108
|
return {
|
|
5895
6109
|
steps,
|
|
5896
6110
|
approvals,
|
|
5897
|
-
|
|
6111
|
+
fees
|
|
5898
6112
|
};
|
|
5899
6113
|
}
|
|
5900
6114
|
};
|
|
5901
6115
|
}
|
|
5902
|
-
|
|
5903
|
-
// src/adapters/viem/resources/deposits/routes/eth-nonbase.ts
|
|
5904
|
-
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
5905
|
-
var BASE_COST_BUFFER_BPS2 = 100n;
|
|
5906
|
-
var BPS2 = 10000n;
|
|
5907
|
-
var withBuffer2 = (x) => x * (BPS2 + BASE_COST_BUFFER_BPS2) / BPS2;
|
|
6116
|
+
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
5908
6117
|
function routeEthNonBase() {
|
|
5909
6118
|
return {
|
|
6119
|
+
// TODO: do we even need these validations?
|
|
5910
6120
|
async preflight(p, ctx) {
|
|
5911
|
-
await
|
|
6121
|
+
await wrapAs4(
|
|
5912
6122
|
"VALIDATION",
|
|
5913
6123
|
OP_DEPOSITS.ethNonBase.assertEthAsset,
|
|
5914
6124
|
() => {
|
|
5915
|
-
if (!isETH(p.token)) {
|
|
6125
|
+
if (ctx.resolvedToken?.kind !== "eth" && !isETH(p.token)) {
|
|
5916
6126
|
throw new Error("eth-nonbase route requires ETH as the deposit asset.");
|
|
5917
6127
|
}
|
|
5918
6128
|
},
|
|
5919
6129
|
{ ctx: { token: p.token } }
|
|
5920
6130
|
);
|
|
5921
|
-
|
|
5922
|
-
"CONTRACT",
|
|
5923
|
-
OP_DEPOSITS.ethNonBase.baseToken,
|
|
5924
|
-
() => ctx.client.l1.readContract({
|
|
5925
|
-
address: ctx.bridgehub,
|
|
5926
|
-
abi: IBridgehub_default,
|
|
5927
|
-
functionName: "baseToken",
|
|
5928
|
-
args: [ctx.chainIdL2]
|
|
5929
|
-
}),
|
|
5930
|
-
{
|
|
5931
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
5932
|
-
message: "Failed to read base token."
|
|
5933
|
-
}
|
|
5934
|
-
);
|
|
5935
|
-
await wrapAs3(
|
|
6131
|
+
await wrapAs4(
|
|
5936
6132
|
"VALIDATION",
|
|
5937
6133
|
OP_DEPOSITS.ethNonBase.assertNonEthBase,
|
|
5938
6134
|
() => {
|
|
5939
|
-
if (
|
|
6135
|
+
if (ctx.baseIsEth) {
|
|
5940
6136
|
throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
|
|
5941
6137
|
}
|
|
5942
6138
|
},
|
|
5943
|
-
{ ctx: {
|
|
6139
|
+
{ ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
|
|
5944
6140
|
);
|
|
5945
|
-
const ethBal = await
|
|
6141
|
+
const ethBal = await wrapAs4(
|
|
5946
6142
|
"RPC",
|
|
5947
6143
|
OP_DEPOSITS.ethNonBase.ethBalance,
|
|
5948
6144
|
() => ctx.client.l1.getBalance({ address: ctx.sender }),
|
|
@@ -5951,7 +6147,7 @@ function routeEthNonBase() {
|
|
|
5951
6147
|
message: "Failed to read L1 ETH balance."
|
|
5952
6148
|
}
|
|
5953
6149
|
);
|
|
5954
|
-
await
|
|
6150
|
+
await wrapAs4(
|
|
5955
6151
|
"VALIDATION",
|
|
5956
6152
|
OP_DEPOSITS.ethNonBase.assertEthBalance,
|
|
5957
6153
|
() => {
|
|
@@ -5961,45 +6157,27 @@ function routeEthNonBase() {
|
|
|
5961
6157
|
},
|
|
5962
6158
|
{ ctx: { required: p.amount.toString(), balance: ethBal.toString() } }
|
|
5963
6159
|
);
|
|
5964
|
-
return;
|
|
5965
6160
|
},
|
|
5966
6161
|
async build(p, ctx) {
|
|
5967
|
-
const
|
|
5968
|
-
const
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
const rawBaseCost = await wrapAs3(
|
|
5984
|
-
"CONTRACT",
|
|
5985
|
-
OP_DEPOSITS.ethNonBase.baseCost,
|
|
5986
|
-
() => ctx.client.l1.readContract({
|
|
5987
|
-
address: ctx.bridgehub,
|
|
5988
|
-
abi: IBridgehub_default,
|
|
5989
|
-
functionName: "l2TransactionBaseCost",
|
|
5990
|
-
args: [ctx.chainIdL2, gasPriceForBaseCost, ctx.l2GasLimit, ctx.gasPerPubdata]
|
|
5991
|
-
}),
|
|
5992
|
-
{
|
|
5993
|
-
ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
|
|
5994
|
-
message: "Could not fetch L2 base cost."
|
|
5995
|
-
}
|
|
5996
|
-
);
|
|
5997
|
-
const baseCost = BigInt(rawBaseCost);
|
|
5998
|
-
const mintValueRaw = baseCost + ctx.operatorTip;
|
|
5999
|
-
const mintValue = withBuffer2(mintValueRaw);
|
|
6162
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
6163
|
+
const l2TxModel = {
|
|
6164
|
+
to: p.to ?? ctx.sender,
|
|
6165
|
+
from: ctx.sender,
|
|
6166
|
+
data: "0x",
|
|
6167
|
+
value: 0n
|
|
6168
|
+
};
|
|
6169
|
+
const l2Gas = await quoteL2Gas2({
|
|
6170
|
+
ctx,
|
|
6171
|
+
route: "eth-nonbase",
|
|
6172
|
+
l2TxForModeling: l2TxModel,
|
|
6173
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
6174
|
+
});
|
|
6175
|
+
if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
|
|
6176
|
+
const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
|
|
6177
|
+
const mintValue = l2BaseCost + ctx.operatorTip;
|
|
6000
6178
|
const approvals = [];
|
|
6001
6179
|
const steps = [];
|
|
6002
|
-
const allowance = await
|
|
6180
|
+
const allowance = await wrapAs4(
|
|
6003
6181
|
"CONTRACT",
|
|
6004
6182
|
OP_DEPOSITS.ethNonBase.allowanceBase,
|
|
6005
6183
|
() => ctx.client.l1.readContract({
|
|
@@ -6015,7 +6193,7 @@ function routeEthNonBase() {
|
|
|
6015
6193
|
);
|
|
6016
6194
|
const needsApprove = allowance < mintValue;
|
|
6017
6195
|
if (needsApprove) {
|
|
6018
|
-
const approveSim = await
|
|
6196
|
+
const approveSim = await wrapAs4(
|
|
6019
6197
|
"CONTRACT",
|
|
6020
6198
|
OP_DEPOSITS.ethNonBase.estGas,
|
|
6021
6199
|
() => ctx.client.l1.simulateContract({
|
|
@@ -6034,11 +6212,11 @@ function routeEthNonBase() {
|
|
|
6034
6212
|
steps.push({
|
|
6035
6213
|
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
6036
6214
|
kind: "approve",
|
|
6037
|
-
description: `Approve base token for mintValue`,
|
|
6215
|
+
description: `Approve base token for fees (mintValue)`,
|
|
6038
6216
|
tx: { ...approveSim.request }
|
|
6039
6217
|
});
|
|
6040
6218
|
}
|
|
6041
|
-
const secondBridgeCalldata = await
|
|
6219
|
+
const secondBridgeCalldata = await wrapAs4(
|
|
6042
6220
|
"INTERNAL",
|
|
6043
6221
|
OP_DEPOSITS.ethNonBase.encodeCalldata,
|
|
6044
6222
|
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, p.to ?? ctx.sender)),
|
|
@@ -6051,11 +6229,11 @@ function routeEthNonBase() {
|
|
|
6051
6229
|
message: "Failed to encode ETH bridging calldata."
|
|
6052
6230
|
}
|
|
6053
6231
|
);
|
|
6054
|
-
const
|
|
6232
|
+
const requestStruct = {
|
|
6055
6233
|
chainId: ctx.chainIdL2,
|
|
6056
6234
|
mintValue,
|
|
6057
|
-
l2Value:
|
|
6058
|
-
l2GasLimit:
|
|
6235
|
+
l2Value: p.amount,
|
|
6236
|
+
l2GasLimit: l2Gas.gasLimit,
|
|
6059
6237
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
6060
6238
|
refundRecipient: ctx.refundRecipient,
|
|
6061
6239
|
secondBridgeAddress: ctx.l1AssetRouter,
|
|
@@ -6063,29 +6241,32 @@ function routeEthNonBase() {
|
|
|
6063
6241
|
secondBridgeCalldata
|
|
6064
6242
|
};
|
|
6065
6243
|
let bridgeTx;
|
|
6066
|
-
let
|
|
6244
|
+
let calldata;
|
|
6067
6245
|
if (needsApprove) {
|
|
6068
6246
|
bridgeTx = {
|
|
6069
6247
|
address: ctx.bridgehub,
|
|
6070
6248
|
abi: IBridgehub_default,
|
|
6071
6249
|
functionName: "requestL2TransactionTwoBridges",
|
|
6072
|
-
args: [
|
|
6250
|
+
args: [requestStruct],
|
|
6073
6251
|
value: p.amount,
|
|
6074
6252
|
// base ≠ ETH ⇒ msg.value == secondBridgeValue
|
|
6075
6253
|
account: ctx.client.account
|
|
6076
6254
|
};
|
|
6077
|
-
|
|
6255
|
+
calldata = viem.encodeFunctionData({
|
|
6256
|
+
abi: IBridgehub_default,
|
|
6257
|
+
functionName: "requestL2TransactionTwoBridges",
|
|
6258
|
+
args: [requestStruct]
|
|
6259
|
+
});
|
|
6078
6260
|
} else {
|
|
6079
|
-
const
|
|
6261
|
+
const sim = await wrapAs4(
|
|
6080
6262
|
"CONTRACT",
|
|
6081
6263
|
OP_DEPOSITS.ethNonBase.estGas,
|
|
6082
6264
|
() => ctx.client.l1.simulateContract({
|
|
6083
6265
|
address: ctx.bridgehub,
|
|
6084
6266
|
abi: IBridgehub_default,
|
|
6085
6267
|
functionName: "requestL2TransactionTwoBridges",
|
|
6086
|
-
args: [
|
|
6268
|
+
args: [requestStruct],
|
|
6087
6269
|
value: p.amount,
|
|
6088
|
-
// base ≠ ETH ⇒ msg.value == secondBridgeValue
|
|
6089
6270
|
account: ctx.client.account
|
|
6090
6271
|
}),
|
|
6091
6272
|
{
|
|
@@ -6093,8 +6274,33 @@ function routeEthNonBase() {
|
|
|
6093
6274
|
message: "Failed to simulate Bridgehub two-bridges request."
|
|
6094
6275
|
}
|
|
6095
6276
|
);
|
|
6096
|
-
|
|
6097
|
-
|
|
6277
|
+
calldata = viem.encodeFunctionData({
|
|
6278
|
+
abi: sim.request.abi,
|
|
6279
|
+
functionName: sim.request.functionName,
|
|
6280
|
+
args: sim.request.args
|
|
6281
|
+
});
|
|
6282
|
+
bridgeTx = { ...sim.request };
|
|
6283
|
+
}
|
|
6284
|
+
const l1TxCandidate = {
|
|
6285
|
+
to: ctx.bridgehub,
|
|
6286
|
+
data: calldata,
|
|
6287
|
+
value: p.amount,
|
|
6288
|
+
from: ctx.sender,
|
|
6289
|
+
...ctx.gasOverrides
|
|
6290
|
+
};
|
|
6291
|
+
const l1Gas = await quoteL1Gas2({
|
|
6292
|
+
ctx,
|
|
6293
|
+
tx: l1TxCandidate,
|
|
6294
|
+
overrides: ctx.gasOverrides,
|
|
6295
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6296
|
+
});
|
|
6297
|
+
if (l1Gas) {
|
|
6298
|
+
bridgeTx = {
|
|
6299
|
+
...bridgeTx,
|
|
6300
|
+
gas: l1Gas.gasLimit,
|
|
6301
|
+
maxFeePerGas: l1Gas.maxFeePerGas,
|
|
6302
|
+
maxPriorityFeePerGas: l1Gas.maxPriorityFeePerGas
|
|
6303
|
+
};
|
|
6098
6304
|
}
|
|
6099
6305
|
steps.push({
|
|
6100
6306
|
key: "bridgehub:two-bridges:eth-nonbase",
|
|
@@ -6102,48 +6308,38 @@ function routeEthNonBase() {
|
|
|
6102
6308
|
description: "Bridge ETH (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
|
|
6103
6309
|
tx: bridgeTx
|
|
6104
6310
|
});
|
|
6311
|
+
const fees = buildFeeBreakdown({
|
|
6312
|
+
feeToken: baseToken,
|
|
6313
|
+
l1Gas,
|
|
6314
|
+
l2Gas,
|
|
6315
|
+
l2BaseCost,
|
|
6316
|
+
operatorTip: ctx.operatorTip,
|
|
6317
|
+
mintValue
|
|
6318
|
+
});
|
|
6105
6319
|
return {
|
|
6106
6320
|
steps,
|
|
6107
6321
|
approvals,
|
|
6108
|
-
|
|
6322
|
+
fees
|
|
6109
6323
|
};
|
|
6110
6324
|
}
|
|
6111
6325
|
};
|
|
6112
6326
|
}
|
|
6113
|
-
|
|
6114
|
-
// src/adapters/viem/resources/deposits/routes/erc20-base.ts
|
|
6115
|
-
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
6116
|
-
var BASE_COST_BUFFER_BPS3 = 100n;
|
|
6117
|
-
var BPS3 = 10000n;
|
|
6118
|
-
var withBuffer3 = (x) => x * (BPS3 + BASE_COST_BUFFER_BPS3) / BPS3;
|
|
6327
|
+
var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
|
|
6119
6328
|
function routeErc20Base() {
|
|
6120
6329
|
return {
|
|
6121
6330
|
async preflight(p, ctx) {
|
|
6122
|
-
await
|
|
6331
|
+
await wrapAs5(
|
|
6123
6332
|
"VALIDATION",
|
|
6124
6333
|
OP_DEPOSITS.base.assertErc20Asset,
|
|
6125
6334
|
() => {
|
|
6126
|
-
if (isETH(p.token)) {
|
|
6335
|
+
if (ctx.resolvedToken?.kind === "eth" || isETH(p.token)) {
|
|
6127
6336
|
throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
|
|
6128
6337
|
}
|
|
6129
6338
|
},
|
|
6130
6339
|
{ ctx: { token: p.token } }
|
|
6131
6340
|
);
|
|
6132
|
-
const baseToken = await
|
|
6133
|
-
|
|
6134
|
-
OP_DEPOSITS.base.baseToken,
|
|
6135
|
-
() => ctx.client.l1.readContract({
|
|
6136
|
-
address: ctx.bridgehub,
|
|
6137
|
-
abi: IBridgehub_default,
|
|
6138
|
-
functionName: "baseToken",
|
|
6139
|
-
args: [ctx.chainIdL2]
|
|
6140
|
-
}),
|
|
6141
|
-
{
|
|
6142
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
6143
|
-
message: "Failed to read base token."
|
|
6144
|
-
}
|
|
6145
|
-
);
|
|
6146
|
-
await wrapAs4(
|
|
6341
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
6342
|
+
await wrapAs5(
|
|
6147
6343
|
"VALIDATION",
|
|
6148
6344
|
OP_DEPOSITS.base.assertMatchesBase,
|
|
6149
6345
|
() => {
|
|
@@ -6153,45 +6349,27 @@ function routeErc20Base() {
|
|
|
6153
6349
|
},
|
|
6154
6350
|
{ ctx: { baseToken, provided: p.token, chainIdL2: ctx.chainIdL2 } }
|
|
6155
6351
|
);
|
|
6156
|
-
return;
|
|
6157
6352
|
},
|
|
6158
6353
|
async build(p, ctx) {
|
|
6159
|
-
const
|
|
6160
|
-
const
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
"
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
const
|
|
6177
|
-
|
|
6178
|
-
OP_DEPOSITS.base.baseCost,
|
|
6179
|
-
() => ctx.client.l1.readContract({
|
|
6180
|
-
address: ctx.bridgehub,
|
|
6181
|
-
abi: IBridgehub_default,
|
|
6182
|
-
functionName: "l2TransactionBaseCost",
|
|
6183
|
-
args: [ctx.chainIdL2, gasPriceForBaseCost, ctx.l2GasLimit, ctx.gasPerPubdata]
|
|
6184
|
-
}),
|
|
6185
|
-
{
|
|
6186
|
-
ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
|
|
6187
|
-
message: "Could not fetch L2 base cost from Bridgehub."
|
|
6188
|
-
}
|
|
6189
|
-
);
|
|
6190
|
-
const baseCost = rawBaseCost;
|
|
6191
|
-
const l2Value = p.amount;
|
|
6192
|
-
const rawMintValue = baseCost + ctx.operatorTip + l2Value;
|
|
6193
|
-
const mintValue = withBuffer3(rawMintValue);
|
|
6194
|
-
const allowance = await wrapAs4(
|
|
6354
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
6355
|
+
const l2TxModel = {
|
|
6356
|
+
to: p.to ?? ctx.sender,
|
|
6357
|
+
from: ctx.sender,
|
|
6358
|
+
data: "0x",
|
|
6359
|
+
value: 0n
|
|
6360
|
+
};
|
|
6361
|
+
const l2Gas = await quoteL2Gas2({
|
|
6362
|
+
ctx,
|
|
6363
|
+
route: "erc20-base",
|
|
6364
|
+
l2TxForModeling: l2TxModel,
|
|
6365
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
6366
|
+
});
|
|
6367
|
+
if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
|
|
6368
|
+
const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
|
|
6369
|
+
const mintValue = l2BaseCost + ctx.operatorTip + p.amount;
|
|
6370
|
+
const approvals = [];
|
|
6371
|
+
const steps = [];
|
|
6372
|
+
const allowance = await wrapAs5(
|
|
6195
6373
|
"CONTRACT",
|
|
6196
6374
|
OP_DEPOSITS.base.allowance,
|
|
6197
6375
|
() => ctx.client.l1.readContract({
|
|
@@ -6205,11 +6383,9 @@ function routeErc20Base() {
|
|
|
6205
6383
|
message: "Failed to read base-token allowance."
|
|
6206
6384
|
}
|
|
6207
6385
|
);
|
|
6208
|
-
const approvals = [];
|
|
6209
|
-
const steps = [];
|
|
6210
6386
|
const needsApprove = allowance < mintValue;
|
|
6211
6387
|
if (needsApprove) {
|
|
6212
|
-
const approveSim = await
|
|
6388
|
+
const approveSim = await wrapAs5(
|
|
6213
6389
|
"CONTRACT",
|
|
6214
6390
|
OP_DEPOSITS.base.estGas,
|
|
6215
6391
|
() => ctx.client.l1.simulateContract({
|
|
@@ -6229,20 +6405,20 @@ function routeErc20Base() {
|
|
|
6229
6405
|
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
6230
6406
|
kind: "approve",
|
|
6231
6407
|
description: "Approve base token for mintValue",
|
|
6232
|
-
tx: { ...approveSim.request
|
|
6408
|
+
tx: { ...approveSim.request }
|
|
6233
6409
|
});
|
|
6234
6410
|
}
|
|
6235
6411
|
const req = buildDirectRequestStruct({
|
|
6236
6412
|
chainId: ctx.chainIdL2,
|
|
6237
6413
|
mintValue,
|
|
6238
|
-
l2GasLimit:
|
|
6414
|
+
l2GasLimit: l2Gas.gasLimit,
|
|
6239
6415
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
6240
6416
|
refundRecipient: ctx.refundRecipient,
|
|
6241
6417
|
l2Contract: p.to ?? ctx.sender,
|
|
6242
|
-
l2Value
|
|
6418
|
+
l2Value: p.amount
|
|
6243
6419
|
});
|
|
6244
6420
|
let bridgeTx;
|
|
6245
|
-
let
|
|
6421
|
+
let calldata;
|
|
6246
6422
|
if (needsApprove) {
|
|
6247
6423
|
bridgeTx = {
|
|
6248
6424
|
address: ctx.bridgehub,
|
|
@@ -6250,13 +6426,16 @@ function routeErc20Base() {
|
|
|
6250
6426
|
functionName: "requestL2TransactionDirect",
|
|
6251
6427
|
args: [req],
|
|
6252
6428
|
value: 0n,
|
|
6253
|
-
// base is ERC-20 ⇒ msg.value MUST be 0
|
|
6254
|
-
account: ctx.client.account
|
|
6255
|
-
...txFeeOverrides
|
|
6429
|
+
// base token is ERC-20 ⇒ msg.value MUST be 0
|
|
6430
|
+
account: ctx.client.account
|
|
6256
6431
|
};
|
|
6257
|
-
|
|
6432
|
+
calldata = viem.encodeFunctionData({
|
|
6433
|
+
abi: IBridgehub_default,
|
|
6434
|
+
functionName: "requestL2TransactionDirect",
|
|
6435
|
+
args: [req]
|
|
6436
|
+
});
|
|
6258
6437
|
} else {
|
|
6259
|
-
const sim = await
|
|
6438
|
+
const sim = await wrapAs5(
|
|
6260
6439
|
"RPC",
|
|
6261
6440
|
OP_DEPOSITS.base.estGas,
|
|
6262
6441
|
() => ctx.client.l1.simulateContract({
|
|
@@ -6272,8 +6451,33 @@ function routeErc20Base() {
|
|
|
6272
6451
|
message: "Failed to simulate Bridgehub.requestL2TransactionDirect."
|
|
6273
6452
|
}
|
|
6274
6453
|
);
|
|
6275
|
-
|
|
6276
|
-
|
|
6454
|
+
calldata = viem.encodeFunctionData({
|
|
6455
|
+
abi: sim.request.abi,
|
|
6456
|
+
functionName: sim.request.functionName,
|
|
6457
|
+
args: sim.request.args
|
|
6458
|
+
});
|
|
6459
|
+
bridgeTx = { ...sim.request };
|
|
6460
|
+
}
|
|
6461
|
+
const l1TxCandidate = {
|
|
6462
|
+
to: ctx.bridgehub,
|
|
6463
|
+
data: calldata,
|
|
6464
|
+
value: 0n,
|
|
6465
|
+
from: ctx.sender,
|
|
6466
|
+
...ctx.gasOverrides
|
|
6467
|
+
};
|
|
6468
|
+
const l1Gas = await quoteL1Gas2({
|
|
6469
|
+
ctx,
|
|
6470
|
+
tx: l1TxCandidate,
|
|
6471
|
+
overrides: ctx.gasOverrides,
|
|
6472
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6473
|
+
});
|
|
6474
|
+
if (l1Gas) {
|
|
6475
|
+
bridgeTx = {
|
|
6476
|
+
...bridgeTx,
|
|
6477
|
+
gas: l1Gas.gasLimit,
|
|
6478
|
+
maxFeePerGas: l1Gas.maxFeePerGas,
|
|
6479
|
+
maxPriorityFeePerGas: l1Gas.maxPriorityFeePerGas
|
|
6480
|
+
};
|
|
6277
6481
|
}
|
|
6278
6482
|
steps.push({
|
|
6279
6483
|
key: "bridgehub:direct:erc20-base",
|
|
@@ -6281,10 +6485,18 @@ function routeErc20Base() {
|
|
|
6281
6485
|
description: "Bridge base ERC-20 via Bridgehub.requestL2TransactionDirect",
|
|
6282
6486
|
tx: bridgeTx
|
|
6283
6487
|
});
|
|
6488
|
+
const fees = buildFeeBreakdown({
|
|
6489
|
+
feeToken: baseToken,
|
|
6490
|
+
l1Gas,
|
|
6491
|
+
l2Gas,
|
|
6492
|
+
l2BaseCost,
|
|
6493
|
+
operatorTip: ctx.operatorTip,
|
|
6494
|
+
mintValue
|
|
6495
|
+
});
|
|
6284
6496
|
return {
|
|
6285
6497
|
steps,
|
|
6286
6498
|
approvals,
|
|
6287
|
-
|
|
6499
|
+
fees
|
|
6288
6500
|
};
|
|
6289
6501
|
}
|
|
6290
6502
|
};
|
|
@@ -6365,6 +6577,276 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
|
|
|
6365
6577
|
return { l2Receipt, l2TxHash };
|
|
6366
6578
|
}
|
|
6367
6579
|
|
|
6580
|
+
// src/core/codec/ntv.ts
|
|
6581
|
+
function createNTVCodec(deps) {
|
|
6582
|
+
function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
|
|
6583
|
+
const encoded = deps.encode(
|
|
6584
|
+
["uint256", "address", "address"],
|
|
6585
|
+
[originChainId, ntvAddress, tokenAddress]
|
|
6586
|
+
);
|
|
6587
|
+
return deps.keccak256(encoded);
|
|
6588
|
+
}
|
|
6589
|
+
return {
|
|
6590
|
+
encodeAssetId
|
|
6591
|
+
};
|
|
6592
|
+
}
|
|
6593
|
+
|
|
6594
|
+
// src/adapters/viem/resources/tokens/tokens.ts
|
|
6595
|
+
var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
|
|
6596
|
+
var ntvCodec = createNTVCodec({
|
|
6597
|
+
encode: (types, values) => viem.encodeAbiParameters(
|
|
6598
|
+
types.map((t, i) => ({ type: t, name: `arg${i}` })),
|
|
6599
|
+
values
|
|
6600
|
+
),
|
|
6601
|
+
keccak256: (data) => viem.keccak256(data)
|
|
6602
|
+
});
|
|
6603
|
+
function createTokensResource(client) {
|
|
6604
|
+
let l2NtvL1ChainIdPromise = null;
|
|
6605
|
+
let baseTokenAssetIdPromise = null;
|
|
6606
|
+
let wethL1Promise = null;
|
|
6607
|
+
let wethL2Promise = null;
|
|
6608
|
+
async function getL1ChainId() {
|
|
6609
|
+
if (!l2NtvL1ChainIdPromise) {
|
|
6610
|
+
l2NtvL1ChainIdPromise = wrapAs6("INTERNAL", "getL1ChainId", async () => {
|
|
6611
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6612
|
+
return await l2NativeTokenVault.read.L1_CHAIN_ID();
|
|
6613
|
+
});
|
|
6614
|
+
}
|
|
6615
|
+
return l2NtvL1ChainIdPromise;
|
|
6616
|
+
}
|
|
6617
|
+
async function getBaseTokenAssetId() {
|
|
6618
|
+
if (!baseTokenAssetIdPromise) {
|
|
6619
|
+
baseTokenAssetIdPromise = wrapAs6("INTERNAL", "baseTokenAssetId", async () => {
|
|
6620
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6621
|
+
const assetId = await l2NativeTokenVault.read.BASE_TOKEN_ASSET_ID();
|
|
6622
|
+
return assetId;
|
|
6623
|
+
});
|
|
6624
|
+
}
|
|
6625
|
+
return baseTokenAssetIdPromise;
|
|
6626
|
+
}
|
|
6627
|
+
async function getWethL1() {
|
|
6628
|
+
if (!wethL1Promise) {
|
|
6629
|
+
wethL1Promise = wrapAs6("INTERNAL", "wethL1", async () => {
|
|
6630
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6631
|
+
const weth = await l1NativeTokenVault.read.WETH_TOKEN();
|
|
6632
|
+
return weth;
|
|
6633
|
+
});
|
|
6634
|
+
}
|
|
6635
|
+
return wethL1Promise;
|
|
6636
|
+
}
|
|
6637
|
+
async function getWethL2() {
|
|
6638
|
+
if (!wethL2Promise) {
|
|
6639
|
+
wethL2Promise = wrapAs6("INTERNAL", "wethL2", async () => {
|
|
6640
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6641
|
+
const weth = await l2NativeTokenVault.read.WETH_TOKEN();
|
|
6642
|
+
return weth;
|
|
6643
|
+
});
|
|
6644
|
+
}
|
|
6645
|
+
return wethL2Promise;
|
|
6646
|
+
}
|
|
6647
|
+
async function toL2Address(l1Token) {
|
|
6648
|
+
return wrapAs6("CONTRACT", "tokens.toL2Address", async () => {
|
|
6649
|
+
const normalized = normalizeL1Token(l1Token);
|
|
6650
|
+
const chainId = BigInt(await client.l2.getChainId());
|
|
6651
|
+
const baseToken = await client.baseToken(chainId);
|
|
6652
|
+
if (isAddressEq(normalized, baseToken)) {
|
|
6653
|
+
return L2_BASE_TOKEN_ADDRESS;
|
|
6654
|
+
}
|
|
6655
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6656
|
+
const l2Token = await l2NativeTokenVault.read.l2TokenAddress([normalized]);
|
|
6657
|
+
return l2Token;
|
|
6658
|
+
});
|
|
6659
|
+
}
|
|
6660
|
+
async function toL1Address(l2Token) {
|
|
6661
|
+
return wrapAs6("CONTRACT", "tokens.toL1Address", async () => {
|
|
6662
|
+
if (isAddressEq(l2Token, ETH_ADDRESS)) return ETH_ADDRESS;
|
|
6663
|
+
if (isAddressEq(l2Token, L2_BASE_TOKEN_ADDRESS)) {
|
|
6664
|
+
const chainId = BigInt(await client.l2.getChainId());
|
|
6665
|
+
return await client.baseToken(chainId);
|
|
6666
|
+
}
|
|
6667
|
+
const { l2AssetRouter } = await client.contracts();
|
|
6668
|
+
const l1Token = await l2AssetRouter.read.l1TokenAddress([l2Token]);
|
|
6669
|
+
return l1Token;
|
|
6670
|
+
});
|
|
6671
|
+
}
|
|
6672
|
+
async function assetIdOfL1(l1Token) {
|
|
6673
|
+
return wrapAs6("CONTRACT", "tokens.assetIdOfL1", async () => {
|
|
6674
|
+
const normalized = normalizeL1Token(l1Token);
|
|
6675
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6676
|
+
return await l1NativeTokenVault.read.assetId([normalized]);
|
|
6677
|
+
});
|
|
6678
|
+
}
|
|
6679
|
+
async function assetIdOfL2(l2Token) {
|
|
6680
|
+
return wrapAs6("CONTRACT", "tokens.assetIdOfL2", async () => {
|
|
6681
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6682
|
+
return await l2NativeTokenVault.read.assetId([l2Token]);
|
|
6683
|
+
});
|
|
6684
|
+
}
|
|
6685
|
+
async function l2TokenFromAssetId(assetId) {
|
|
6686
|
+
return wrapAs6("CONTRACT", "tokens.l2TokenFromAssetId", async () => {
|
|
6687
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6688
|
+
return await l2NativeTokenVault.read.tokenAddress([assetId]);
|
|
6689
|
+
});
|
|
6690
|
+
}
|
|
6691
|
+
async function l1TokenFromAssetId(assetId) {
|
|
6692
|
+
return wrapAs6("CONTRACT", "tokens.l1TokenFromAssetId", async () => {
|
|
6693
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6694
|
+
return await l1NativeTokenVault.read.tokenAddress([assetId]);
|
|
6695
|
+
});
|
|
6696
|
+
}
|
|
6697
|
+
async function originChainId(assetId) {
|
|
6698
|
+
return wrapAs6("CONTRACT", "tokens.originChainId", async () => {
|
|
6699
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6700
|
+
return await l2NativeTokenVault.read.originChainId([assetId]);
|
|
6701
|
+
});
|
|
6702
|
+
}
|
|
6703
|
+
async function baseTokenAssetId() {
|
|
6704
|
+
return getBaseTokenAssetId();
|
|
6705
|
+
}
|
|
6706
|
+
async function isChainEthBased() {
|
|
6707
|
+
return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
|
|
6708
|
+
const baseAssetId = await getBaseTokenAssetId();
|
|
6709
|
+
const l1ChainId = await getL1ChainId();
|
|
6710
|
+
const ethAssetId = ntvCodec.encodeAssetId(
|
|
6711
|
+
l1ChainId,
|
|
6712
|
+
L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
6713
|
+
ETH_ADDRESS
|
|
6714
|
+
);
|
|
6715
|
+
return hexEq(baseAssetId, ethAssetId);
|
|
6716
|
+
});
|
|
6717
|
+
}
|
|
6718
|
+
async function wethL1() {
|
|
6719
|
+
return getWethL1();
|
|
6720
|
+
}
|
|
6721
|
+
async function wethL2() {
|
|
6722
|
+
return getWethL2();
|
|
6723
|
+
}
|
|
6724
|
+
async function computeL2BridgedAddress(args) {
|
|
6725
|
+
return wrapAs6("CONTRACT", "tokens.computeL2BridgedAddress", async () => {
|
|
6726
|
+
const normalized = normalizeL1Token(args.l1Token);
|
|
6727
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6728
|
+
const predicted = await l2NativeTokenVault.read.calculateCreate2TokenAddress([
|
|
6729
|
+
args.originChainId,
|
|
6730
|
+
normalized
|
|
6731
|
+
]);
|
|
6732
|
+
return predicted;
|
|
6733
|
+
});
|
|
6734
|
+
}
|
|
6735
|
+
async function resolve(ref, opts) {
|
|
6736
|
+
return wrapAs6("CONTRACT", "tokens.resolve", async () => {
|
|
6737
|
+
let chain;
|
|
6738
|
+
let address;
|
|
6739
|
+
if (typeof ref === "string") {
|
|
6740
|
+
chain = opts?.chain ?? "l1";
|
|
6741
|
+
address = ref;
|
|
6742
|
+
} else {
|
|
6743
|
+
chain = ref.chain;
|
|
6744
|
+
address = ref.address;
|
|
6745
|
+
}
|
|
6746
|
+
let l1;
|
|
6747
|
+
let l2;
|
|
6748
|
+
if (chain === "l1") {
|
|
6749
|
+
l1 = normalizeL1Token(address);
|
|
6750
|
+
l2 = await toL2Address(address);
|
|
6751
|
+
} else {
|
|
6752
|
+
l2 = address;
|
|
6753
|
+
l1 = await toL1Address(address);
|
|
6754
|
+
}
|
|
6755
|
+
const assetId = await assetIdOfL1(l1);
|
|
6756
|
+
const originChainIdVal = await originChainId(assetId);
|
|
6757
|
+
const [baseAssetId, wethL1Addr, wethL2Addr, ethBased] = await Promise.all([
|
|
6758
|
+
baseTokenAssetId(),
|
|
6759
|
+
wethL1(),
|
|
6760
|
+
wethL2(),
|
|
6761
|
+
isChainEthBased()
|
|
6762
|
+
]);
|
|
6763
|
+
let kind;
|
|
6764
|
+
if (isAddressEq(l1, ETH_ADDRESS)) {
|
|
6765
|
+
kind = "eth";
|
|
6766
|
+
} else if (hexEq(assetId, baseAssetId)) {
|
|
6767
|
+
kind = "base";
|
|
6768
|
+
} else {
|
|
6769
|
+
kind = "erc20";
|
|
6770
|
+
}
|
|
6771
|
+
return {
|
|
6772
|
+
kind,
|
|
6773
|
+
l1,
|
|
6774
|
+
l2,
|
|
6775
|
+
assetId,
|
|
6776
|
+
originChainId: originChainIdVal,
|
|
6777
|
+
isChainEthBased: ethBased,
|
|
6778
|
+
baseTokenAssetId: baseAssetId,
|
|
6779
|
+
wethL1: wethL1Addr,
|
|
6780
|
+
wethL2: wethL2Addr
|
|
6781
|
+
};
|
|
6782
|
+
});
|
|
6783
|
+
}
|
|
6784
|
+
return {
|
|
6785
|
+
resolve,
|
|
6786
|
+
toL2Address,
|
|
6787
|
+
toL1Address,
|
|
6788
|
+
assetIdOfL1,
|
|
6789
|
+
assetIdOfL2,
|
|
6790
|
+
l2TokenFromAssetId,
|
|
6791
|
+
l1TokenFromAssetId,
|
|
6792
|
+
originChainId,
|
|
6793
|
+
baseTokenAssetId,
|
|
6794
|
+
isChainEthBased,
|
|
6795
|
+
wethL1,
|
|
6796
|
+
wethL2,
|
|
6797
|
+
computeL2BridgedAddress
|
|
6798
|
+
};
|
|
6799
|
+
}
|
|
6800
|
+
|
|
6801
|
+
// src/adapters/viem/resources/contracts/contracts.ts
|
|
6802
|
+
function createContractsResource(client) {
|
|
6803
|
+
async function addresses() {
|
|
6804
|
+
return client.ensureAddresses();
|
|
6805
|
+
}
|
|
6806
|
+
async function instances() {
|
|
6807
|
+
return client.contracts();
|
|
6808
|
+
}
|
|
6809
|
+
async function bridgehub() {
|
|
6810
|
+
const { bridgehub: bridgehub2 } = await instances();
|
|
6811
|
+
return bridgehub2;
|
|
6812
|
+
}
|
|
6813
|
+
async function l1AssetRouter() {
|
|
6814
|
+
const { l1AssetRouter: l1AssetRouter2 } = await instances();
|
|
6815
|
+
return l1AssetRouter2;
|
|
6816
|
+
}
|
|
6817
|
+
async function l1NativeTokenVault() {
|
|
6818
|
+
const { l1NativeTokenVault: l1NativeTokenVault2 } = await instances();
|
|
6819
|
+
return l1NativeTokenVault2;
|
|
6820
|
+
}
|
|
6821
|
+
async function l1Nullifier() {
|
|
6822
|
+
const { l1Nullifier: l1Nullifier2 } = await instances();
|
|
6823
|
+
return l1Nullifier2;
|
|
6824
|
+
}
|
|
6825
|
+
async function l2AssetRouter() {
|
|
6826
|
+
const { l2AssetRouter: l2AssetRouter2 } = await instances();
|
|
6827
|
+
return l2AssetRouter2;
|
|
6828
|
+
}
|
|
6829
|
+
async function l2NativeTokenVault() {
|
|
6830
|
+
const { l2NativeTokenVault: l2NativeTokenVault2 } = await instances();
|
|
6831
|
+
return l2NativeTokenVault2;
|
|
6832
|
+
}
|
|
6833
|
+
async function l2BaseTokenSystem() {
|
|
6834
|
+
const { l2BaseTokenSystem: l2BaseTokenSystem2 } = await instances();
|
|
6835
|
+
return l2BaseTokenSystem2;
|
|
6836
|
+
}
|
|
6837
|
+
return {
|
|
6838
|
+
addresses,
|
|
6839
|
+
instances,
|
|
6840
|
+
bridgehub,
|
|
6841
|
+
l1AssetRouter,
|
|
6842
|
+
l1NativeTokenVault,
|
|
6843
|
+
l1Nullifier,
|
|
6844
|
+
l2AssetRouter,
|
|
6845
|
+
l2NativeTokenVault,
|
|
6846
|
+
l2BaseTokenSystem
|
|
6847
|
+
};
|
|
6848
|
+
}
|
|
6849
|
+
|
|
6368
6850
|
// src/adapters/viem/resources/deposits/index.ts
|
|
6369
6851
|
var { wrap, toResult } = createErrorHandlers("deposits");
|
|
6370
6852
|
var ROUTES = {
|
|
@@ -6373,37 +6855,26 @@ var ROUTES = {
|
|
|
6373
6855
|
"erc20-nonbase": routeErc20NonBase(),
|
|
6374
6856
|
"erc20-base": routeErc20Base()
|
|
6375
6857
|
};
|
|
6376
|
-
function createDepositsResource(client) {
|
|
6858
|
+
function createDepositsResource(client, tokens, contracts) {
|
|
6859
|
+
const tokensResource = tokens ?? createTokensResource(client);
|
|
6860
|
+
const contractsResource = contracts ?? createContractsResource(client);
|
|
6377
6861
|
async function buildPlan(p) {
|
|
6378
|
-
const ctx = await commonCtx(p, client);
|
|
6862
|
+
const ctx = await commonCtx(p, client, tokensResource, contractsResource);
|
|
6379
6863
|
const route = ctx.route;
|
|
6380
6864
|
await ROUTES[route].preflight?.(p, ctx);
|
|
6381
|
-
const { steps, approvals,
|
|
6382
|
-
const { baseCost, mintValue } = quoteExtras;
|
|
6383
|
-
const fallbackGasLimit = quoteExtras.l1GasLimit;
|
|
6384
|
-
const resolveGasLimit = () => {
|
|
6385
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
6386
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
6387
|
-
const candidate = steps[i].tx.gas;
|
|
6388
|
-
if (candidate != null) return candidate;
|
|
6389
|
-
}
|
|
6390
|
-
if (fallbackGasLimit != null) return fallbackGasLimit;
|
|
6391
|
-
return ctx.l2GasLimit;
|
|
6392
|
-
};
|
|
6393
|
-
const gasLimit = resolveGasLimit();
|
|
6865
|
+
const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
|
|
6394
6866
|
return {
|
|
6395
6867
|
route: ctx.route,
|
|
6396
6868
|
summary: {
|
|
6397
6869
|
route: ctx.route,
|
|
6398
6870
|
approvalsNeeded: approvals,
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
fees
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
}
|
|
6871
|
+
amounts: {
|
|
6872
|
+
transfer: { token: p.token, amount: p.amount }
|
|
6873
|
+
},
|
|
6874
|
+
fees,
|
|
6875
|
+
// Legacy fields (maintained for backward compatibility)
|
|
6876
|
+
baseCost: fees.l2?.baseCost,
|
|
6877
|
+
mintValue: fees.mintValue
|
|
6407
6878
|
},
|
|
6408
6879
|
steps
|
|
6409
6880
|
};
|
|
@@ -6478,7 +6949,7 @@ function createDepositsResource(client) {
|
|
|
6478
6949
|
step.tx.gas = overrides.gasLimit;
|
|
6479
6950
|
}
|
|
6480
6951
|
}
|
|
6481
|
-
if (
|
|
6952
|
+
if (!p.l1TxOverrides?.gasLimit) {
|
|
6482
6953
|
try {
|
|
6483
6954
|
const feePart = step.tx.maxFeePerGas != null && step.tx.maxPriorityFeePerGas != null ? {
|
|
6484
6955
|
maxFeePerGas: step.tx.maxFeePerGas,
|
|
@@ -6701,36 +7172,12 @@ function normalizeTokenForRouting(token) {
|
|
|
6701
7172
|
function pickWithdrawRoute(args) {
|
|
6702
7173
|
const tokenNorm = normalizeTokenForRouting(args.token);
|
|
6703
7174
|
const isL2BaseAlias = tokenNorm.toLowerCase() === L2_BASE_TOKEN_ADDRESS.toLowerCase();
|
|
6704
|
-
if (isL2BaseAlias) return
|
|
7175
|
+
if (isL2BaseAlias) return "base";
|
|
6705
7176
|
return "erc20-nonbase";
|
|
6706
7177
|
}
|
|
6707
7178
|
|
|
6708
|
-
// src/adapters/viem/resources/token-info.ts
|
|
6709
|
-
async function ntvBaseAssetId(l2, ntv) {
|
|
6710
|
-
return l2.readContract({
|
|
6711
|
-
address: ntv,
|
|
6712
|
-
abi: L2NativeTokenVault_default,
|
|
6713
|
-
functionName: "BASE_TOKEN_ASSET_ID"
|
|
6714
|
-
});
|
|
6715
|
-
}
|
|
6716
|
-
async function ntvL1ChainId(l2, ntv) {
|
|
6717
|
-
return l2.readContract({
|
|
6718
|
-
address: ntv,
|
|
6719
|
-
abi: L2NativeTokenVault_default,
|
|
6720
|
-
functionName: "L1_CHAIN_ID"
|
|
6721
|
-
});
|
|
6722
|
-
}
|
|
6723
|
-
async function isEthBasedChain(l2, ntv) {
|
|
6724
|
-
const [baseAssetId, l1ChainId] = await Promise.all([
|
|
6725
|
-
ntvBaseAssetId(l2, ntv),
|
|
6726
|
-
ntvL1ChainId(l2, ntv)
|
|
6727
|
-
]);
|
|
6728
|
-
const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
|
|
6729
|
-
return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
|
|
6730
|
-
}
|
|
6731
|
-
|
|
6732
7179
|
// src/adapters/viem/resources/withdrawals/context.ts
|
|
6733
|
-
async function commonCtx2(p, client) {
|
|
7180
|
+
async function commonCtx2(p, client, tokens, contracts) {
|
|
6734
7181
|
const sender = client.account.address;
|
|
6735
7182
|
const {
|
|
6736
7183
|
bridgehub,
|
|
@@ -6739,18 +7186,20 @@ async function commonCtx2(p, client) {
|
|
|
6739
7186
|
l2AssetRouter,
|
|
6740
7187
|
l2NativeTokenVault,
|
|
6741
7188
|
l2BaseTokenSystem
|
|
6742
|
-
} = await
|
|
7189
|
+
} = await contracts.addresses();
|
|
6743
7190
|
const chainIdL2 = BigInt(await client.l2.getChainId());
|
|
6744
|
-
const
|
|
6745
|
-
const
|
|
6746
|
-
const
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
});
|
|
6750
|
-
const l2GasLimit = p.l2GasLimit ?? 300000n;
|
|
6751
|
-
const gasBufferPct = 15;
|
|
7191
|
+
const resolvedToken = await tokens.resolve(p.token, { chain: "l2" });
|
|
7192
|
+
const baseTokenAssetId = resolvedToken.baseTokenAssetId;
|
|
7193
|
+
const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
|
|
7194
|
+
const baseIsEth = resolvedToken.isChainEthBased;
|
|
7195
|
+
const route = pickWithdrawRoute({ token: p.token});
|
|
6752
7196
|
return {
|
|
6753
7197
|
client,
|
|
7198
|
+
tokens,
|
|
7199
|
+
contracts,
|
|
7200
|
+
resolvedToken,
|
|
7201
|
+
baseTokenAssetId,
|
|
7202
|
+
baseTokenL1,
|
|
6754
7203
|
bridgehub,
|
|
6755
7204
|
chainIdL2,
|
|
6756
7205
|
sender,
|
|
@@ -6761,56 +7210,162 @@ async function commonCtx2(p, client) {
|
|
|
6761
7210
|
l2NativeTokenVault,
|
|
6762
7211
|
l2BaseTokenSystem,
|
|
6763
7212
|
baseIsEth,
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
7213
|
+
gasOverrides: p.l2TxOverrides
|
|
7214
|
+
};
|
|
7215
|
+
}
|
|
7216
|
+
|
|
7217
|
+
// src/core/resources/withdrawals/gas.ts
|
|
7218
|
+
function makeGasQuote2(p) {
|
|
7219
|
+
return {
|
|
7220
|
+
gasLimit: p.gasLimit,
|
|
7221
|
+
maxFeePerGas: p.maxFeePerGas,
|
|
7222
|
+
maxPriorityFeePerGas: p.maxPriorityFeePerGas,
|
|
7223
|
+
maxCost: p.gasLimit * p.maxFeePerGas
|
|
7224
|
+
};
|
|
7225
|
+
}
|
|
7226
|
+
async function fetchFees2(estimator) {
|
|
7227
|
+
try {
|
|
7228
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
7229
|
+
if (fees.maxFeePerGas != null) {
|
|
7230
|
+
return {
|
|
7231
|
+
maxFeePerGas: fees.maxFeePerGas,
|
|
7232
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
|
|
7233
|
+
};
|
|
7234
|
+
}
|
|
7235
|
+
if (fees.gasPrice != null) {
|
|
7236
|
+
return {
|
|
7237
|
+
maxFeePerGas: fees.gasPrice,
|
|
7238
|
+
maxPriorityFeePerGas: 0n
|
|
7239
|
+
};
|
|
7240
|
+
}
|
|
7241
|
+
} catch {
|
|
7242
|
+
}
|
|
7243
|
+
try {
|
|
7244
|
+
const gp = await estimator.getGasPrice();
|
|
7245
|
+
return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
|
|
7246
|
+
} catch {
|
|
7247
|
+
return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
|
|
7248
|
+
}
|
|
7249
|
+
}
|
|
7250
|
+
async function quoteL2Gas3(input) {
|
|
7251
|
+
const { estimator, tx, overrides } = input;
|
|
7252
|
+
const market = await fetchFees2(estimator);
|
|
7253
|
+
const o = overrides;
|
|
7254
|
+
const maxFeePerGas = o?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : market.maxFeePerGas);
|
|
7255
|
+
const maxPriorityFeePerGas = o?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : market.maxPriorityFeePerGas);
|
|
7256
|
+
const explicitGasLimit = o?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
|
|
7257
|
+
if (explicitGasLimit != null) {
|
|
7258
|
+
return makeGasQuote2({
|
|
7259
|
+
gasLimit: explicitGasLimit,
|
|
7260
|
+
maxFeePerGas,
|
|
7261
|
+
maxPriorityFeePerGas
|
|
7262
|
+
});
|
|
7263
|
+
}
|
|
7264
|
+
try {
|
|
7265
|
+
const est = await estimator.estimateGas(tx);
|
|
7266
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
7267
|
+
return makeGasQuote2({
|
|
7268
|
+
gasLimit: buffered,
|
|
7269
|
+
maxFeePerGas,
|
|
7270
|
+
maxPriorityFeePerGas
|
|
7271
|
+
});
|
|
7272
|
+
} catch (err) {
|
|
7273
|
+
console.warn("Failed to estimate L2 gas for withdrawal.", err);
|
|
7274
|
+
return void 0;
|
|
7275
|
+
}
|
|
7276
|
+
}
|
|
7277
|
+
|
|
7278
|
+
// src/adapters/viem/resources/withdrawals/services/gas.ts
|
|
7279
|
+
async function quoteL2Gas4(input) {
|
|
7280
|
+
const { ctx, tx } = input;
|
|
7281
|
+
const estimator = viemToGasEstimator(ctx.client.l2);
|
|
7282
|
+
return quoteL2Gas3({
|
|
7283
|
+
estimator,
|
|
7284
|
+
tx: toCoreTx(tx),
|
|
7285
|
+
overrides: ctx.gasOverrides
|
|
7286
|
+
});
|
|
7287
|
+
}
|
|
7288
|
+
|
|
7289
|
+
// src/adapters/viem/resources/withdrawals/services/fee.ts
|
|
7290
|
+
function buildFeeBreakdown2(p) {
|
|
7291
|
+
const l2Total = p.l2Gas?.maxCost ?? 0n;
|
|
7292
|
+
const l2 = {
|
|
7293
|
+
total: l2Total,
|
|
7294
|
+
gasLimit: p.l2Gas?.gasLimit ?? 0n,
|
|
7295
|
+
maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
|
|
7296
|
+
maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas
|
|
7297
|
+
};
|
|
7298
|
+
return {
|
|
7299
|
+
token: p.feeToken,
|
|
7300
|
+
maxTotal: l2Total,
|
|
7301
|
+
l2
|
|
6767
7302
|
};
|
|
6768
7303
|
}
|
|
6769
7304
|
|
|
6770
7305
|
// src/adapters/viem/resources/withdrawals/routes/eth.ts
|
|
6771
|
-
var { wrapAs:
|
|
7306
|
+
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
6772
7307
|
function routeEthBase() {
|
|
6773
7308
|
return {
|
|
6774
7309
|
async build(p, ctx) {
|
|
6775
|
-
const
|
|
6776
|
-
const
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
account: ctx.client.account,
|
|
6787
|
-
...txFeeOverrides
|
|
6788
|
-
}),
|
|
7310
|
+
const steps = [];
|
|
7311
|
+
const data = await wrapAs7(
|
|
7312
|
+
"INTERNAL",
|
|
7313
|
+
OP_WITHDRAWALS.eth.encodeWithdraw,
|
|
7314
|
+
() => Promise.resolve(
|
|
7315
|
+
viem.encodeFunctionData({
|
|
7316
|
+
abi: IBaseToken_default,
|
|
7317
|
+
functionName: "withdraw",
|
|
7318
|
+
args: [p.to ?? ctx.sender]
|
|
7319
|
+
})
|
|
7320
|
+
),
|
|
6789
7321
|
{
|
|
6790
|
-
ctx: { where: "
|
|
6791
|
-
message: "Failed to
|
|
7322
|
+
ctx: { where: "L2BaseToken.withdraw", to: p.to ?? ctx.sender },
|
|
7323
|
+
message: "Failed to encode ETH withdraw calldata."
|
|
6792
7324
|
}
|
|
6793
7325
|
);
|
|
6794
|
-
const
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
7326
|
+
const L2tx = {
|
|
7327
|
+
to: L2_BASE_TOKEN_ADDRESS,
|
|
7328
|
+
data,
|
|
7329
|
+
value: p.amount,
|
|
7330
|
+
from: ctx.sender
|
|
7331
|
+
};
|
|
7332
|
+
const l2Gas = await quoteL2Gas4({ ctx, tx: L2tx });
|
|
7333
|
+
if (l2Gas) {
|
|
7334
|
+
L2tx.gas = l2Gas.gasLimit;
|
|
7335
|
+
L2tx.maxFeePerGas = l2Gas.maxFeePerGas;
|
|
7336
|
+
L2tx.maxPriorityFeePerGas = l2Gas.maxPriorityFeePerGas;
|
|
7337
|
+
}
|
|
7338
|
+
const tx = {
|
|
7339
|
+
address: L2_BASE_TOKEN_ADDRESS,
|
|
7340
|
+
abi: IBaseToken_default,
|
|
7341
|
+
functionName: "withdraw",
|
|
7342
|
+
args: [p.to ?? ctx.sender],
|
|
7343
|
+
value: p.amount,
|
|
7344
|
+
account: ctx.client.account,
|
|
7345
|
+
...l2Gas
|
|
7346
|
+
};
|
|
7347
|
+
const fees = buildFeeBreakdown2({
|
|
7348
|
+
feeToken: L2_BASE_TOKEN_ADDRESS,
|
|
7349
|
+
l2Gas
|
|
7350
|
+
});
|
|
7351
|
+
steps.push({
|
|
7352
|
+
key: "l2-base-token:withdraw",
|
|
7353
|
+
kind: "l2-base-token:withdraw",
|
|
7354
|
+
description: "Withdraw ETH via L2 Base Token System",
|
|
7355
|
+
tx
|
|
7356
|
+
});
|
|
7357
|
+
return { steps, approvals: [], fees };
|
|
6803
7358
|
}
|
|
6804
7359
|
};
|
|
6805
7360
|
}
|
|
6806
|
-
var { wrapAs:
|
|
7361
|
+
var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
|
|
6807
7362
|
function routeErc20NonBase2() {
|
|
6808
7363
|
return {
|
|
6809
7364
|
// TODO: add preflight validations here
|
|
6810
7365
|
async build(p, ctx) {
|
|
6811
|
-
const
|
|
6812
|
-
const
|
|
6813
|
-
const current = await
|
|
7366
|
+
const steps = [];
|
|
7367
|
+
const approvals = [];
|
|
7368
|
+
const current = await wrapAs8(
|
|
6814
7369
|
"CONTRACT",
|
|
6815
7370
|
OP_WITHDRAWALS.erc20.allowance,
|
|
6816
7371
|
() => ctx.client.l2.readContract({
|
|
@@ -6830,12 +7385,26 @@ function routeErc20NonBase2() {
|
|
|
6830
7385
|
message: "Failed to read L2 ERC-20 allowance."
|
|
6831
7386
|
}
|
|
6832
7387
|
);
|
|
6833
|
-
|
|
6834
|
-
const steps = [];
|
|
6835
|
-
const approvals = [];
|
|
6836
|
-
if (needsApprove) {
|
|
7388
|
+
if (current < p.amount) {
|
|
6837
7389
|
approvals.push({ token: p.token, spender: ctx.l2NativeTokenVault, amount: p.amount });
|
|
6838
|
-
const
|
|
7390
|
+
const data = viem.encodeFunctionData({
|
|
7391
|
+
abi: IERC20_default,
|
|
7392
|
+
functionName: "approve",
|
|
7393
|
+
args: [ctx.l2NativeTokenVault, p.amount]
|
|
7394
|
+
});
|
|
7395
|
+
const approveTxCandidate = {
|
|
7396
|
+
to: p.token,
|
|
7397
|
+
data,
|
|
7398
|
+
value: 0n,
|
|
7399
|
+
from: ctx.sender
|
|
7400
|
+
};
|
|
7401
|
+
const approveGas = await quoteL2Gas4({ ctx, tx: approveTxCandidate });
|
|
7402
|
+
if (approveGas) {
|
|
7403
|
+
approveTxCandidate.gas = approveGas.gasLimit;
|
|
7404
|
+
approveTxCandidate.maxFeePerGas = approveGas.maxFeePerGas;
|
|
7405
|
+
approveTxCandidate.maxPriorityFeePerGas = approveGas.maxPriorityFeePerGas;
|
|
7406
|
+
}
|
|
7407
|
+
const approveSim = await wrapAs8(
|
|
6839
7408
|
"CONTRACT",
|
|
6840
7409
|
OP_WITHDRAWALS.erc20.estGas,
|
|
6841
7410
|
() => ctx.client.l2.simulateContract({
|
|
@@ -6844,21 +7413,26 @@ function routeErc20NonBase2() {
|
|
|
6844
7413
|
functionName: "approve",
|
|
6845
7414
|
args: [ctx.l2NativeTokenVault, p.amount],
|
|
6846
7415
|
account: ctx.client.account,
|
|
6847
|
-
...
|
|
7416
|
+
...approveGas
|
|
6848
7417
|
}),
|
|
6849
7418
|
{
|
|
6850
7419
|
ctx: { where: "l2.simulateContract", to: p.token },
|
|
6851
7420
|
message: "Failed to simulate L2 ERC-20 approve."
|
|
6852
7421
|
}
|
|
6853
7422
|
);
|
|
7423
|
+
const { ...approveRequest } = approveSim.request;
|
|
7424
|
+
const approveTx = {
|
|
7425
|
+
...approveRequest
|
|
7426
|
+
};
|
|
6854
7427
|
steps.push({
|
|
6855
7428
|
key: `approve:l2:${p.token}:${ctx.l2NativeTokenVault}`,
|
|
6856
7429
|
kind: "approve:l2",
|
|
6857
7430
|
description: `Approve ${p.amount} to NativeTokenVault`,
|
|
6858
|
-
tx:
|
|
7431
|
+
tx: approveTx
|
|
6859
7432
|
});
|
|
6860
7433
|
}
|
|
6861
|
-
const
|
|
7434
|
+
const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l2" }) : void 0);
|
|
7435
|
+
const assetId = resolved?.assetId ?? (await wrapAs8(
|
|
6862
7436
|
"CONTRACT",
|
|
6863
7437
|
OP_WITHDRAWALS.erc20.ensureRegistered,
|
|
6864
7438
|
() => ctx.client.l2.simulateContract({
|
|
@@ -6872,28 +7446,44 @@ function routeErc20NonBase2() {
|
|
|
6872
7446
|
ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
|
|
6873
7447
|
message: "Failed to ensure token is registered in L2NativeTokenVault."
|
|
6874
7448
|
}
|
|
6875
|
-
);
|
|
6876
|
-
const assetId = ensure.result;
|
|
7449
|
+
)).result;
|
|
6877
7450
|
const assetData = viem.encodeAbiParameters(
|
|
6878
7451
|
[
|
|
6879
7452
|
{ type: "uint256", name: "amount" },
|
|
6880
7453
|
{ type: "address", name: "l1Receiver" },
|
|
6881
7454
|
{ type: "address", name: "l2Token" }
|
|
6882
7455
|
],
|
|
6883
|
-
[p.amount,
|
|
7456
|
+
[p.amount, p.to ?? ctx.sender, p.token]
|
|
6884
7457
|
);
|
|
7458
|
+
const withdrawCalldata = viem.encodeFunctionData({
|
|
7459
|
+
abi: IL2AssetRouter_default,
|
|
7460
|
+
functionName: "withdraw",
|
|
7461
|
+
args: [assetId, assetData]
|
|
7462
|
+
});
|
|
7463
|
+
const withdrawTxCandidate = {
|
|
7464
|
+
to: ctx.l2AssetRouter,
|
|
7465
|
+
data: withdrawCalldata,
|
|
7466
|
+
value: 0n,
|
|
7467
|
+
from: ctx.sender
|
|
7468
|
+
};
|
|
7469
|
+
const withdrawGas = await quoteL2Gas4({ ctx, tx: withdrawTxCandidate });
|
|
7470
|
+
if (withdrawGas) {
|
|
7471
|
+
withdrawTxCandidate.gas = withdrawGas.gasLimit;
|
|
7472
|
+
withdrawTxCandidate.maxFeePerGas = withdrawGas.maxFeePerGas;
|
|
7473
|
+
withdrawTxCandidate.maxPriorityFeePerGas = withdrawGas.maxPriorityFeePerGas;
|
|
7474
|
+
}
|
|
6885
7475
|
let withdrawTx;
|
|
6886
|
-
if (
|
|
7476
|
+
if (current < p.amount) {
|
|
6887
7477
|
withdrawTx = {
|
|
6888
7478
|
address: ctx.l2AssetRouter,
|
|
6889
7479
|
abi: IL2AssetRouter_default,
|
|
6890
7480
|
functionName: "withdraw",
|
|
6891
7481
|
args: [assetId, assetData],
|
|
6892
7482
|
account: ctx.client.account,
|
|
6893
|
-
...
|
|
7483
|
+
...withdrawGas
|
|
6894
7484
|
};
|
|
6895
7485
|
} else {
|
|
6896
|
-
const sim = await
|
|
7486
|
+
const sim = await wrapAs8(
|
|
6897
7487
|
"CONTRACT",
|
|
6898
7488
|
OP_WITHDRAWALS.erc20.estGas,
|
|
6899
7489
|
() => ctx.client.l2.simulateContract({
|
|
@@ -6902,14 +7492,18 @@ function routeErc20NonBase2() {
|
|
|
6902
7492
|
functionName: "withdraw",
|
|
6903
7493
|
args: [assetId, assetData],
|
|
6904
7494
|
account: ctx.client.account,
|
|
6905
|
-
...
|
|
7495
|
+
...withdrawGas
|
|
6906
7496
|
}),
|
|
6907
7497
|
{
|
|
6908
7498
|
ctx: { where: "l2.simulateContract", to: ctx.l2AssetRouter },
|
|
6909
7499
|
message: "Failed to simulate L2 ERC-20 withdraw."
|
|
6910
7500
|
}
|
|
6911
7501
|
);
|
|
6912
|
-
|
|
7502
|
+
const { ...withdrawRequest } = sim.request;
|
|
7503
|
+
withdrawTx = {
|
|
7504
|
+
...withdrawRequest,
|
|
7505
|
+
...withdrawGas
|
|
7506
|
+
};
|
|
6913
7507
|
}
|
|
6914
7508
|
steps.push({
|
|
6915
7509
|
key: "l2-asset-router:withdraw",
|
|
@@ -6917,59 +7511,11 @@ function routeErc20NonBase2() {
|
|
|
6917
7511
|
description: "Burn on L2 & send L2\u2192L1 message",
|
|
6918
7512
|
tx: withdrawTx
|
|
6919
7513
|
});
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
}
|
|
6924
|
-
|
|
6925
|
-
// src/adapters/viem/resources/withdrawals/routes/eth-nonbase.ts
|
|
6926
|
-
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
6927
|
-
function routeEthNonBase2() {
|
|
6928
|
-
return {
|
|
6929
|
-
async preflight(p, ctx) {
|
|
6930
|
-
await wrapAs7(
|
|
6931
|
-
"VALIDATION",
|
|
6932
|
-
OP_WITHDRAWALS.ethNonBase.assertNonEthBase,
|
|
6933
|
-
() => {
|
|
6934
|
-
if (p.token.toLowerCase() !== L2_BASE_TOKEN_ADDRESS.toLowerCase()) {
|
|
6935
|
-
throw new Error("eth-nonbase route requires the L2 base-token alias (0x\u2026800A).");
|
|
6936
|
-
}
|
|
6937
|
-
if (ctx.baseIsEth) {
|
|
6938
|
-
throw new Error("eth-nonbase route requires chain base \u2260 ETH.");
|
|
6939
|
-
}
|
|
6940
|
-
},
|
|
6941
|
-
{ ctx: { token: p.token, baseIsEth: ctx.baseIsEth } }
|
|
6942
|
-
);
|
|
6943
|
-
},
|
|
6944
|
-
async build(p, ctx) {
|
|
6945
|
-
const toL1 = p.to ?? ctx.sender;
|
|
6946
|
-
const txFeeOverrides = buildViemFeeOverrides(ctx.fee);
|
|
6947
|
-
const sim = await wrapAs7(
|
|
6948
|
-
"CONTRACT",
|
|
6949
|
-
OP_WITHDRAWALS.ethNonBase.estGas,
|
|
6950
|
-
() => ctx.client.l2.simulateContract({
|
|
6951
|
-
address: L2_BASE_TOKEN_ADDRESS,
|
|
6952
|
-
abi: IBaseToken_default,
|
|
6953
|
-
functionName: "withdraw",
|
|
6954
|
-
args: [toL1],
|
|
6955
|
-
value: p.amount,
|
|
6956
|
-
account: ctx.client.account,
|
|
6957
|
-
...txFeeOverrides
|
|
6958
|
-
}),
|
|
6959
|
-
{
|
|
6960
|
-
ctx: { where: "l2.simulateContract", to: L2_BASE_TOKEN_ADDRESS },
|
|
6961
|
-
message: "Failed to simulate L2 base-token withdraw."
|
|
6962
|
-
}
|
|
6963
|
-
);
|
|
6964
|
-
const steps = [
|
|
6965
|
-
{
|
|
6966
|
-
key: "l2-base-token:withdraw",
|
|
6967
|
-
kind: "l2-base-token:withdraw",
|
|
6968
|
-
description: "Withdraw base token via L2 Base Token System (base \u2260 ETH)",
|
|
6969
|
-
tx: { ...sim.request, ...txFeeOverrides }
|
|
6970
|
-
}
|
|
6971
|
-
];
|
|
6972
|
-
return { steps, approvals: [], quoteExtras: {} };
|
|
7514
|
+
const fees = buildFeeBreakdown2({
|
|
7515
|
+
feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
|
|
7516
|
+
l2Gas: withdrawGas
|
|
7517
|
+
});
|
|
7518
|
+
return { steps, approvals, fees };
|
|
6973
7519
|
}
|
|
6974
7520
|
};
|
|
6975
7521
|
}
|
|
@@ -7005,7 +7551,7 @@ function messengerLogIndex(raw, opts) {
|
|
|
7005
7551
|
}
|
|
7006
7552
|
return (hits[index] ?? hits[0]).i;
|
|
7007
7553
|
}
|
|
7008
|
-
var { wrapAs:
|
|
7554
|
+
var { wrapAs: wrapAs9 } = createErrorHandlers("withdrawals");
|
|
7009
7555
|
var IL1NullifierMini = [
|
|
7010
7556
|
{
|
|
7011
7557
|
type: "function",
|
|
@@ -7022,7 +7568,7 @@ var IL1NullifierMini = [
|
|
|
7022
7568
|
function createFinalizationServices(client) {
|
|
7023
7569
|
return {
|
|
7024
7570
|
async fetchFinalizeDepositParams(l2TxHash) {
|
|
7025
|
-
const parsed = await
|
|
7571
|
+
const parsed = await wrapAs9(
|
|
7026
7572
|
"RPC",
|
|
7027
7573
|
OP_WITHDRAWALS.finalize.fetchParams.receipt,
|
|
7028
7574
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -7039,7 +7585,7 @@ function createFinalizationServices(client) {
|
|
|
7039
7585
|
context: { l2TxHash }
|
|
7040
7586
|
});
|
|
7041
7587
|
}
|
|
7042
|
-
const ev = await
|
|
7588
|
+
const ev = await wrapAs9(
|
|
7043
7589
|
"INTERNAL",
|
|
7044
7590
|
OP_WITHDRAWALS.finalize.fetchParams.findMessage,
|
|
7045
7591
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
@@ -7049,7 +7595,7 @@ function createFinalizationServices(client) {
|
|
|
7049
7595
|
message: "Failed to locate L1MessageSent event in L2 receipt."
|
|
7050
7596
|
}
|
|
7051
7597
|
);
|
|
7052
|
-
const message = await
|
|
7598
|
+
const message = await wrapAs9(
|
|
7053
7599
|
"INTERNAL",
|
|
7054
7600
|
OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
|
|
7055
7601
|
() => {
|
|
@@ -7061,7 +7607,7 @@ function createFinalizationServices(client) {
|
|
|
7061
7607
|
message: "Failed to decode withdrawal message."
|
|
7062
7608
|
}
|
|
7063
7609
|
);
|
|
7064
|
-
const raw = await
|
|
7610
|
+
const raw = await wrapAs9(
|
|
7065
7611
|
"RPC",
|
|
7066
7612
|
OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
|
|
7067
7613
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -7078,7 +7624,7 @@ function createFinalizationServices(client) {
|
|
|
7078
7624
|
context: { l2TxHash }
|
|
7079
7625
|
});
|
|
7080
7626
|
}
|
|
7081
|
-
const idx = await
|
|
7627
|
+
const idx = await wrapAs9(
|
|
7082
7628
|
"INTERNAL",
|
|
7083
7629
|
OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
|
|
7084
7630
|
() => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
|
|
@@ -7087,7 +7633,7 @@ function createFinalizationServices(client) {
|
|
|
7087
7633
|
message: "Failed to derive messenger log index."
|
|
7088
7634
|
}
|
|
7089
7635
|
);
|
|
7090
|
-
const proof = await
|
|
7636
|
+
const proof = await wrapAs9(
|
|
7091
7637
|
"RPC",
|
|
7092
7638
|
OP_WITHDRAWALS.finalize.fetchParams.proof,
|
|
7093
7639
|
() => client.zks.getL2ToL1LogProof(l2TxHash, idx),
|
|
@@ -7096,7 +7642,7 @@ function createFinalizationServices(client) {
|
|
|
7096
7642
|
message: "Failed to fetch L2\u2192L1 log proof."
|
|
7097
7643
|
}
|
|
7098
7644
|
);
|
|
7099
|
-
const chainId = await
|
|
7645
|
+
const chainId = await wrapAs9(
|
|
7100
7646
|
"RPC",
|
|
7101
7647
|
OP_WITHDRAWALS.finalize.fetchParams.network,
|
|
7102
7648
|
() => client.l2.getChainId(),
|
|
@@ -7112,7 +7658,7 @@ function createFinalizationServices(client) {
|
|
|
7112
7658
|
message,
|
|
7113
7659
|
merkleProof: proof.proof
|
|
7114
7660
|
};
|
|
7115
|
-
const { l1Nullifier } = await
|
|
7661
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7116
7662
|
"INTERNAL",
|
|
7117
7663
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
7118
7664
|
() => client.ensureAddresses(),
|
|
@@ -7124,7 +7670,7 @@ function createFinalizationServices(client) {
|
|
|
7124
7670
|
return { params, nullifier: l1Nullifier };
|
|
7125
7671
|
},
|
|
7126
7672
|
async simulateFinalizeReadiness(params) {
|
|
7127
|
-
const { l1Nullifier } = await
|
|
7673
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7128
7674
|
"INTERNAL",
|
|
7129
7675
|
OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
|
|
7130
7676
|
() => client.ensureAddresses(),
|
|
@@ -7135,7 +7681,7 @@ function createFinalizationServices(client) {
|
|
|
7135
7681
|
);
|
|
7136
7682
|
const done = await (async () => {
|
|
7137
7683
|
try {
|
|
7138
|
-
const result = await
|
|
7684
|
+
const result = await wrapAs9(
|
|
7139
7685
|
"RPC",
|
|
7140
7686
|
OP_WITHDRAWALS.finalize.readiness.isFinalized,
|
|
7141
7687
|
() => client.l1.readContract({
|
|
@@ -7169,7 +7715,7 @@ function createFinalizationServices(client) {
|
|
|
7169
7715
|
}
|
|
7170
7716
|
},
|
|
7171
7717
|
async isWithdrawalFinalized(key) {
|
|
7172
|
-
const { l1Nullifier } = await
|
|
7718
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7173
7719
|
"INTERNAL",
|
|
7174
7720
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
7175
7721
|
() => client.ensureAddresses(),
|
|
@@ -7178,7 +7724,7 @@ function createFinalizationServices(client) {
|
|
|
7178
7724
|
message: "Failed to ensure L1 Nullifier address."
|
|
7179
7725
|
}
|
|
7180
7726
|
);
|
|
7181
|
-
return await
|
|
7727
|
+
return await wrapAs9(
|
|
7182
7728
|
"RPC",
|
|
7183
7729
|
OP_WITHDRAWALS.finalize.isFinalized,
|
|
7184
7730
|
() => client.l1.readContract({
|
|
@@ -7194,7 +7740,7 @@ function createFinalizationServices(client) {
|
|
|
7194
7740
|
);
|
|
7195
7741
|
},
|
|
7196
7742
|
async estimateFinalization(params) {
|
|
7197
|
-
const { l1Nullifier } = await
|
|
7743
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7198
7744
|
"INTERNAL",
|
|
7199
7745
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7200
7746
|
() => client.ensureAddresses(),
|
|
@@ -7203,7 +7749,7 @@ function createFinalizationServices(client) {
|
|
|
7203
7749
|
message: "Failed to ensure L1 Nullifier address."
|
|
7204
7750
|
}
|
|
7205
7751
|
);
|
|
7206
|
-
const gasLimit = await
|
|
7752
|
+
const gasLimit = await wrapAs9(
|
|
7207
7753
|
"RPC",
|
|
7208
7754
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7209
7755
|
() => client.l1.estimateContractGas({
|
|
@@ -7227,7 +7773,7 @@ function createFinalizationServices(client) {
|
|
|
7227
7773
|
let maxFeePerGas;
|
|
7228
7774
|
let maxPriorityFeePerGas;
|
|
7229
7775
|
try {
|
|
7230
|
-
const fee = await
|
|
7776
|
+
const fee = await wrapAs9(
|
|
7231
7777
|
"RPC",
|
|
7232
7778
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7233
7779
|
() => client.l1.estimateFeesPerGas(),
|
|
@@ -7246,7 +7792,7 @@ function createFinalizationServices(client) {
|
|
|
7246
7792
|
})();
|
|
7247
7793
|
maxPriorityFeePerGas = fee.maxPriorityFeePerGas ?? 0n;
|
|
7248
7794
|
} catch {
|
|
7249
|
-
const gasPrice = await
|
|
7795
|
+
const gasPrice = await wrapAs9(
|
|
7250
7796
|
"RPC",
|
|
7251
7797
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7252
7798
|
() => client.l1.getGasPrice(),
|
|
@@ -7265,7 +7811,7 @@ function createFinalizationServices(client) {
|
|
|
7265
7811
|
};
|
|
7266
7812
|
},
|
|
7267
7813
|
async finalizeDeposit(params) {
|
|
7268
|
-
const { l1Nullifier } = await
|
|
7814
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7269
7815
|
"INTERNAL",
|
|
7270
7816
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
7271
7817
|
() => client.ensureAddresses(),
|
|
@@ -7324,40 +7870,32 @@ function createFinalizationServices(client) {
|
|
|
7324
7870
|
|
|
7325
7871
|
// src/adapters/viem/resources/withdrawals/index.ts
|
|
7326
7872
|
var ROUTES2 = {
|
|
7327
|
-
|
|
7873
|
+
base: routeEthBase(),
|
|
7328
7874
|
// BaseTokenSystem.withdraw, chain base = ETH
|
|
7329
|
-
"eth-nonbase": routeEthNonBase2(),
|
|
7330
|
-
// BaseTokenSystem.withdraw, chain base ≠ ETH
|
|
7331
7875
|
"erc20-nonbase": routeErc20NonBase2()
|
|
7332
7876
|
// AssetRouter.withdraw for non-base ERC-20s
|
|
7333
7877
|
};
|
|
7334
|
-
function createWithdrawalsResource(client) {
|
|
7878
|
+
function createWithdrawalsResource(client, tokens, contracts) {
|
|
7335
7879
|
const svc = createFinalizationServices(client);
|
|
7336
7880
|
const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
|
|
7881
|
+
const tokensResource = tokens ?? createTokensResource(client);
|
|
7882
|
+
const contractsResource = contracts ?? createContractsResource(client);
|
|
7337
7883
|
async function buildPlan(p) {
|
|
7338
|
-
const ctx = await commonCtx2(p, client);
|
|
7884
|
+
const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
|
|
7339
7885
|
await ROUTES2[ctx.route].preflight?.(p, ctx);
|
|
7340
|
-
const { steps, approvals } = await ROUTES2[ctx.route].build(p, ctx);
|
|
7341
|
-
|
|
7342
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
7343
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
7344
|
-
const candidate = steps[i].tx.gas;
|
|
7345
|
-
if (candidate != null) return candidate;
|
|
7346
|
-
}
|
|
7347
|
-
return void 0;
|
|
7348
|
-
};
|
|
7349
|
-
const gasLimit = resolveGasLimit();
|
|
7350
|
-
const summary = {
|
|
7886
|
+
const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
|
|
7887
|
+
return {
|
|
7351
7888
|
route: ctx.route,
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7889
|
+
summary: {
|
|
7890
|
+
route: ctx.route,
|
|
7891
|
+
approvalsNeeded: approvals,
|
|
7892
|
+
amounts: {
|
|
7893
|
+
transfer: { token: p.token, amount: p.amount }
|
|
7894
|
+
},
|
|
7895
|
+
fees
|
|
7896
|
+
},
|
|
7897
|
+
steps
|
|
7359
7898
|
};
|
|
7360
|
-
return { route: ctx.route, summary, steps };
|
|
7361
7899
|
}
|
|
7362
7900
|
const finalizeCache = /* @__PURE__ */ new Map();
|
|
7363
7901
|
const quote = (p) => wrap2(OP_WITHDRAWALS.quote, async () => (await buildPlan(p)).summary, {
|
|
@@ -7391,7 +7929,7 @@ function createWithdrawalsResource(client) {
|
|
|
7391
7929
|
}
|
|
7392
7930
|
if (overrides.gasLimit != null) step.tx.gas = overrides.gasLimit;
|
|
7393
7931
|
}
|
|
7394
|
-
if (
|
|
7932
|
+
if (!p.l2TxOverrides?.gasLimit) {
|
|
7395
7933
|
try {
|
|
7396
7934
|
const feePart = step.tx.maxFeePerGas != null && step.tx.maxPriorityFeePerGas != null ? {
|
|
7397
7935
|
maxFeePerGas: step.tx.maxFeePerGas,
|
|
@@ -7690,83 +8228,34 @@ function createWithdrawalsResource(client) {
|
|
|
7690
8228
|
|
|
7691
8229
|
// src/adapters/viem/sdk.ts
|
|
7692
8230
|
function createViemSdk(client) {
|
|
8231
|
+
const tokens = createTokensResource(client);
|
|
8232
|
+
const contracts = createContractsResource(client);
|
|
7693
8233
|
return {
|
|
7694
|
-
deposits: createDepositsResource(client),
|
|
7695
|
-
withdrawals: createWithdrawalsResource(client),
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
contracts: () => client.contracts(),
|
|
7699
|
-
async l1AssetRouter() {
|
|
7700
|
-
const { l1AssetRouter } = await client.contracts();
|
|
7701
|
-
return l1AssetRouter;
|
|
7702
|
-
},
|
|
7703
|
-
async l1NativeTokenVault() {
|
|
7704
|
-
const { l1NativeTokenVault } = await client.contracts();
|
|
7705
|
-
return l1NativeTokenVault;
|
|
7706
|
-
},
|
|
7707
|
-
async l1Nullifier() {
|
|
7708
|
-
const { l1Nullifier } = await client.contracts();
|
|
7709
|
-
return l1Nullifier;
|
|
7710
|
-
},
|
|
7711
|
-
async baseToken(chainId) {
|
|
7712
|
-
const id = chainId ?? BigInt(await client.l2.getChainId());
|
|
7713
|
-
return client.baseToken(id);
|
|
7714
|
-
},
|
|
7715
|
-
async l2TokenAddress(l1Token) {
|
|
7716
|
-
if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
|
|
7717
|
-
return ETH_ADDRESS;
|
|
7718
|
-
}
|
|
7719
|
-
const base = await client.baseToken(BigInt(await client.l2.getChainId()));
|
|
7720
|
-
if (isAddressEq(l1Token, base)) {
|
|
7721
|
-
return L2_BASE_TOKEN_ADDRESS;
|
|
7722
|
-
}
|
|
7723
|
-
const { l2NativeTokenVault } = await client.contracts();
|
|
7724
|
-
const addr = await l2NativeTokenVault.read.l2TokenAddress([l1Token]);
|
|
7725
|
-
return addr;
|
|
7726
|
-
},
|
|
7727
|
-
async l1TokenAddress(l2Token) {
|
|
7728
|
-
if (isAddressEq(l2Token, FORMAL_ETH_ADDRESS)) {
|
|
7729
|
-
return FORMAL_ETH_ADDRESS;
|
|
7730
|
-
}
|
|
7731
|
-
const { l2AssetRouter } = await client.contracts();
|
|
7732
|
-
const addr = await l2AssetRouter.read.l1TokenAddress([l2Token]);
|
|
7733
|
-
return addr;
|
|
7734
|
-
},
|
|
7735
|
-
async assetId(l1Token) {
|
|
7736
|
-
const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
|
|
7737
|
-
const { l1NativeTokenVault } = await client.contracts();
|
|
7738
|
-
const id = await l1NativeTokenVault.read.assetId([norm]);
|
|
7739
|
-
return id;
|
|
7740
|
-
}
|
|
7741
|
-
}
|
|
8234
|
+
deposits: createDepositsResource(client, tokens, contracts),
|
|
8235
|
+
withdrawals: createWithdrawalsResource(client, tokens, contracts),
|
|
8236
|
+
tokens,
|
|
8237
|
+
contracts
|
|
7742
8238
|
};
|
|
7743
8239
|
}
|
|
7744
8240
|
|
|
7745
8241
|
exports.buildDirectRequestStruct = buildDirectRequestStruct;
|
|
7746
|
-
exports.buildViemFeeOverrides = buildViemFeeOverrides;
|
|
7747
|
-
exports.checkBaseCost = checkBaseCost;
|
|
7748
8242
|
exports.classifyReadinessFromRevert = classifyReadinessFromRevert;
|
|
7749
8243
|
exports.createClient = createViemClient;
|
|
8244
|
+
exports.createContractsResource = createContractsResource;
|
|
7750
8245
|
exports.createDepositsResource = createDepositsResource;
|
|
7751
8246
|
exports.createErrorHandlers = createErrorHandlers;
|
|
7752
8247
|
exports.createFinalizationServices = createFinalizationServices;
|
|
8248
|
+
exports.createTokensResource = createTokensResource;
|
|
7753
8249
|
exports.createViemClient = createViemClient;
|
|
7754
8250
|
exports.createViemSdk = createViemSdk;
|
|
7755
8251
|
exports.createWithdrawalsResource = createWithdrawalsResource;
|
|
7756
8252
|
exports.decodeRevert = decodeRevert;
|
|
7757
|
-
exports.encodeNTVAssetId = encodeNTVAssetId;
|
|
7758
|
-
exports.encodeNTVTransferData = encodeNTVTransferData;
|
|
7759
|
-
exports.encodeNativeTokenVaultAssetId = encodeNativeTokenVaultAssetId;
|
|
7760
8253
|
exports.encodeNativeTokenVaultTransferData = encodeNativeTokenVaultTransferData;
|
|
7761
8254
|
exports.encodeSecondBridgeArgs = encodeSecondBridgeArgs;
|
|
7762
8255
|
exports.encodeSecondBridgeDataV1 = encodeSecondBridgeDataV1;
|
|
7763
8256
|
exports.encodeSecondBridgeErc20Args = encodeSecondBridgeErc20Args;
|
|
7764
8257
|
exports.encodeSecondBridgeEthArgs = encodeSecondBridgeEthArgs;
|
|
7765
|
-
exports.getFeeOverrides = getFeeOverrides;
|
|
7766
|
-
exports.getGasPriceWei = getGasPriceWei;
|
|
7767
|
-
exports.getL2FeeOverrides = getL2FeeOverrides;
|
|
7768
8258
|
exports.registerErrorAbi = registerErrorAbi;
|
|
7769
|
-
exports.scaleGasLimit = scaleGasLimit;
|
|
7770
8259
|
exports.toZKsyncError = toZKsyncError;
|
|
7771
8260
|
//# sourceMappingURL=index.cjs.map
|
|
7772
8261
|
//# sourceMappingURL=index.cjs.map
|