@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.
Files changed (103) hide show
  1. package/README.md +12 -12
  2. package/dist/adapters/ethers/client.cjs +642 -1
  3. package/dist/adapters/ethers/client.cjs.map +1 -1
  4. package/dist/adapters/ethers/client.js +6 -5
  5. package/dist/adapters/ethers/estimator.d.ts +4 -0
  6. package/dist/adapters/ethers/index.cjs +1279 -925
  7. package/dist/adapters/ethers/index.cjs.map +1 -1
  8. package/dist/adapters/ethers/index.d.ts +1 -0
  9. package/dist/adapters/ethers/index.js +9 -8
  10. package/dist/adapters/ethers/resources/contracts/contracts.d.ts +9 -0
  11. package/dist/adapters/ethers/resources/contracts/index.d.ts +2 -0
  12. package/dist/adapters/ethers/resources/contracts/types.d.ts +60 -0
  13. package/dist/adapters/ethers/resources/deposits/context.d.ts +21 -7
  14. package/dist/adapters/ethers/resources/deposits/index.d.ts +3 -1
  15. package/dist/adapters/ethers/resources/deposits/routes/types.d.ts +2 -6
  16. package/dist/adapters/ethers/resources/deposits/services/fee.d.ts +6 -0
  17. package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +41 -0
  18. package/dist/adapters/ethers/resources/tokens/index.d.ts +1 -0
  19. package/dist/adapters/ethers/resources/tokens/tokens.d.ts +10 -0
  20. package/dist/adapters/ethers/resources/utils.d.ts +3 -17
  21. package/dist/adapters/ethers/resources/withdrawals/context.d.ts +15 -7
  22. package/dist/adapters/ethers/resources/withdrawals/index.d.ts +3 -1
  23. package/dist/adapters/ethers/resources/withdrawals/routes/types.d.ts +2 -2
  24. package/dist/adapters/ethers/resources/withdrawals/services/fees.d.ts +14 -0
  25. package/dist/adapters/ethers/resources/withdrawals/services/gas.d.ts +12 -0
  26. package/dist/adapters/ethers/sdk.cjs +1388 -1501
  27. package/dist/adapters/ethers/sdk.cjs.map +1 -1
  28. package/dist/adapters/ethers/sdk.d.ts +5 -22
  29. package/dist/adapters/ethers/sdk.js +7 -6
  30. package/dist/adapters/viem/client.cjs.map +1 -1
  31. package/dist/adapters/viem/client.d.ts +1 -1
  32. package/dist/adapters/viem/client.js +4 -5
  33. package/dist/adapters/viem/estimator.d.ts +4 -0
  34. package/dist/adapters/viem/index.cjs +1233 -744
  35. package/dist/adapters/viem/index.cjs.map +1 -1
  36. package/dist/adapters/viem/index.d.ts +3 -0
  37. package/dist/adapters/viem/index.js +8 -8
  38. package/dist/adapters/viem/resources/contracts/contracts.d.ts +9 -0
  39. package/dist/adapters/viem/resources/contracts/index.d.ts +2 -0
  40. package/dist/adapters/viem/resources/contracts/types.d.ts +61 -0
  41. package/dist/adapters/viem/resources/deposits/context.d.ts +21 -7
  42. package/dist/adapters/viem/resources/deposits/index.d.ts +3 -1
  43. package/dist/adapters/viem/resources/deposits/routes/types.d.ts +2 -6
  44. package/dist/adapters/viem/resources/deposits/services/fee.d.ts +6 -0
  45. package/dist/adapters/viem/resources/deposits/services/gas.d.ts +37 -0
  46. package/dist/adapters/viem/resources/tokens/index.d.ts +1 -0
  47. package/dist/adapters/viem/resources/tokens/tokens.d.ts +3 -0
  48. package/dist/adapters/viem/resources/utils.d.ts +3 -19
  49. package/dist/adapters/viem/resources/withdrawals/context.d.ts +14 -9
  50. package/dist/adapters/viem/resources/withdrawals/index.d.ts +3 -1
  51. package/dist/adapters/viem/resources/withdrawals/routes/types.d.ts +12 -2
  52. package/dist/adapters/viem/resources/withdrawals/services/fee.d.ts +17 -0
  53. package/dist/adapters/viem/resources/withdrawals/services/gas.d.ts +12 -0
  54. package/dist/adapters/viem/sdk.cjs +1225 -699
  55. package/dist/adapters/viem/sdk.cjs.map +1 -1
  56. package/dist/adapters/viem/sdk.d.ts +5 -25
  57. package/dist/adapters/viem/sdk.js +6 -6
  58. package/dist/{chunk-3LALBFFE.js → chunk-3MRGU4HV.js} +9 -5
  59. package/dist/{chunk-CGO27P7F.js → chunk-5YWP4CZP.js} +849 -835
  60. package/dist/{chunk-4HLJJKIY.js → chunk-6K6VJQAL.js} +2 -2
  61. package/dist/{chunk-6GCT6TLS.js → chunk-F2ENUV3A.js} +13 -1
  62. package/dist/{chunk-7M4V3FMT.js → chunk-JXUFGIJG.js} +986 -678
  63. package/dist/chunk-LL3WKCFJ.js +231 -0
  64. package/dist/{chunk-Y75OMFK6.js → chunk-M5J2MM2U.js} +351 -1
  65. package/dist/{chunk-263G6636.js → chunk-NCAIVYBR.js} +1 -14
  66. package/dist/{chunk-DI2CJDPZ.js → chunk-NEC2ZKHI.js} +5 -13
  67. package/dist/chunk-NTEIA5KA.js +13 -0
  68. package/dist/chunk-XRE7H466.js +157 -0
  69. package/dist/{chunk-BD2LUO5T.js → chunk-YUK547UF.js} +3 -3
  70. package/dist/core/abi.d.ts +9 -0
  71. package/dist/core/adapters/interfaces.d.ts +25 -0
  72. package/dist/core/codec/ntv.d.ts +48 -0
  73. package/dist/core/constants.cjs +12 -0
  74. package/dist/core/constants.cjs.map +1 -1
  75. package/dist/core/constants.d.ts +6 -0
  76. package/dist/core/constants.js +1 -1
  77. package/dist/core/index.cjs +4508 -1
  78. package/dist/core/index.cjs.map +1 -1
  79. package/dist/core/index.d.ts +2 -0
  80. package/dist/core/index.js +5 -4
  81. package/dist/core/resources/deposits/fee.d.ts +15 -0
  82. package/dist/core/resources/deposits/gas.d.ts +38 -0
  83. package/dist/core/resources/withdrawals/gas.d.ts +14 -0
  84. package/dist/core/types/errors.d.ts +1 -1
  85. package/dist/core/types/fees.d.ts +40 -0
  86. package/dist/core/types/flows/base.d.ts +0 -10
  87. package/dist/core/types/flows/deposits.d.ts +20 -6
  88. package/dist/core/types/flows/route.d.ts +2 -3
  89. package/dist/core/types/flows/token.d.ts +192 -0
  90. package/dist/core/types/flows/withdrawals.d.ts +12 -6
  91. package/dist/core/utils/addr.d.ts +2 -0
  92. package/dist/index.cjs +4520 -1
  93. package/dist/index.cjs.map +1 -1
  94. package/dist/index.d.ts +2 -0
  95. package/dist/index.js +5 -4
  96. package/package.json +5 -1
  97. package/dist/adapters/ethers/resources/token-info.d.ts +0 -31
  98. package/dist/adapters/ethers/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
  99. package/dist/adapters/viem/resources/token-info.d.ts +0 -34
  100. package/dist/adapters/viem/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
  101. package/dist/chunk-B77GWPO5.js +0 -339
  102. package/dist/core/internal/abi-registry.d.ts +0 -9
  103. package/dist/core/utils/gas.d.ts +0 -13
@@ -16,6 +16,12 @@ var TOPIC_L1_MESSAGE_SENT_NEW = k256hex("L1MessageSent(uint256,bytes32,bytes)");
16
16
  var TOPIC_L1_MESSAGE_SENT_LEG = k256hex("L1MessageSent(address,bytes32,bytes)");
17
17
  var TOPIC_CANONICAL_ASSIGNED = "0x779f441679936c5441b671969f37400b8c3ed0071cb47444431bf985754560df";
18
18
  var TOPIC_CANONICAL_SUCCESS = "0xe4def01b981193a97a9e81230d7b9f31812ceaf23f864a828a82c687911cb2df";
19
+ var BUFFER = 20n;
20
+ var TX_OVERHEAD_GAS = 10000n;
21
+ var TX_MEMORY_OVERHEAD_GAS = 10n;
22
+ var DEFAULT_PUBDATA_BYTES = 155n;
23
+ var DEFAULT_ABI_BYTES = 400n;
24
+ var SAFE_L1_BRIDGE_GAS = 600000n;
19
25
 
20
26
  // src/core/utils/addr.ts
21
27
  var isHash66 = (x) => !!x && x.startsWith("0x") && x.length === 66;
@@ -34,6 +40,8 @@ function normalizeAddrEq(a, b) {
34
40
  };
35
41
  return normalize(a) === normalize(b);
36
42
  }
43
+ var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
44
+ var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
37
45
 
38
46
  // src/core/errors/formatter.ts
39
47
  function elideMiddle(s, max = 96) {
@@ -246,36 +254,17 @@ var OP_DEPOSITS = {
246
254
  base: {
247
255
  assertErc20Asset: "deposits.erc20-base:assertErc20Asset",
248
256
  assertMatchesBase: "deposits.erc20-base:assertMatchesBase",
249
- baseToken: "deposits.erc20-base:baseToken",
250
- allowance: "deposits.erc20-base:allowance",
251
- baseCost: "deposits.erc20-base:l2TransactionBaseCost",
252
- estGas: "deposits.erc20-base:estimateGas"
253
- },
257
+ allowance: "deposits.erc20-base:allowance"},
254
258
  nonbase: {
255
- baseToken: "deposits.erc20-nonbase:baseToken",
256
- assertNotEthAsset: "deposits.erc20-nonbase:assertNotEthAsset",
257
- allowance: "deposits.erc20-nonbase:allowance",
258
- allowanceFees: "deposits.erc20-nonbase:allowanceFeesBaseToken",
259
- baseCost: "deposits.erc20-nonbase:l2TransactionBaseCost",
260
259
  encodeCalldata: "deposits.erc20-nonbase:encodeSecondBridgeErc20Args",
261
- estGas: "deposits.erc20-nonbase:estimateGas",
262
- assertBaseIsEth: "deposits.erc20-nonbase:assertBaseIsEth",
263
- assertBaseIsErc20: "deposits.erc20-nonbase:assertBaseIsErc20",
264
260
  assertNonBaseToken: "deposits.erc20-nonbase:assertNonBaseToken",
265
261
  allowanceToken: "deposits.erc20-nonbase:allowanceToken",
266
262
  allowanceBase: "deposits.erc20-nonbase:allowanceBase"
267
263
  },
268
- eth: {
269
- baseCost: "deposits.eth:l2TransactionBaseCost",
270
- estGas: "deposits.eth:estimateGas"
271
- },
272
264
  ethNonBase: {
273
- baseToken: "deposits.eth-nonbase:baseToken",
274
- baseCost: "deposits.eth-nonbase:l2TransactionBaseCost",
275
265
  allowanceBase: "deposits.eth-nonbase:allowanceBaseToken",
276
266
  ethBalance: "deposits.eth-nonbase:getEthBalance",
277
267
  encodeCalldata: "deposits.eth-nonbase:encodeSecondBridgeEthArgs",
278
- estGas: "deposits.eth-nonbase:estimateGas",
279
268
  assertEthAsset: "deposits.eth-nonbase:assertEthAsset",
280
269
  assertNonEthBase: "deposits.eth-nonbase:assertNonEthBase",
281
270
  assertEthBalance: "deposits.eth-nonbase:assertEthBalance"
@@ -2203,39 +2192,49 @@ var IL1NullifierABI = [
2203
2192
  ];
2204
2193
  var IL1Nullifier_default = IL1NullifierABI;
2205
2194
 
2206
- // src/core/internal/abis/IL2AssetRouter.ts
2207
- var IL2AssetRouterABI = [
2195
+ // src/core/internal/abis/L1NativeTokenVault.ts
2196
+ var L1NativeTokenVaultABI = [
2197
+ {
2198
+ type: "constructor",
2199
+ inputs: [
2200
+ { name: "_l1WethAddress", type: "address", internalType: "address" },
2201
+ { name: "_l1AssetRouter", type: "address", internalType: "address" },
2202
+ { name: "_l1Nullifier", type: "address", internalType: "contract IL1Nullifier" }
2203
+ ],
2204
+ stateMutability: "nonpayable"
2205
+ },
2206
+ { type: "receive", stateMutability: "payable" },
2208
2207
  {
2209
2208
  type: "function",
2210
- name: "BASE_TOKEN_ASSET_ID",
2209
+ name: "ASSET_ROUTER",
2211
2210
  inputs: [],
2212
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2211
+ outputs: [{ name: "", type: "address", internalType: "contract IAssetRouterBase" }],
2213
2212
  stateMutability: "view"
2214
2213
  },
2215
2214
  {
2216
2215
  type: "function",
2217
- name: "BRIDGE_HUB",
2216
+ name: "BASE_TOKEN_ASSET_ID",
2218
2217
  inputs: [],
2219
- outputs: [{ name: "", type: "address", internalType: "contract IBridgehub" }],
2218
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2220
2219
  stateMutability: "view"
2221
2220
  },
2222
2221
  {
2223
2222
  type: "function",
2224
- name: "L1_ASSET_ROUTER",
2223
+ name: "L1_CHAIN_ID",
2225
2224
  inputs: [],
2226
- outputs: [{ name: "", type: "address", internalType: "address" }],
2225
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2227
2226
  stateMutability: "view"
2228
2227
  },
2229
2228
  {
2230
2229
  type: "function",
2231
- name: "L1_CHAIN_ID",
2230
+ name: "L1_NULLIFIER",
2232
2231
  inputs: [],
2233
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2232
+ outputs: [{ name: "", type: "address", internalType: "contract IL1Nullifier" }],
2234
2233
  stateMutability: "view"
2235
2234
  },
2236
2235
  {
2237
2236
  type: "function",
2238
- name: "L2_LEGACY_SHARED_BRIDGE",
2237
+ name: "WETH_TOKEN",
2239
2238
  inputs: [],
2240
2239
  outputs: [{ name: "", type: "address", internalType: "address" }],
2241
2240
  stateMutability: "view"
@@ -2249,44 +2248,53 @@ var IL2AssetRouterABI = [
2249
2248
  },
2250
2249
  {
2251
2250
  type: "function",
2252
- name: "assetDeploymentTracker",
2253
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2254
- outputs: [{ name: "assetDeploymentTracker", type: "address", internalType: "address" }],
2255
- stateMutability: "view"
2251
+ name: "addLegacyTokenToBridgedTokensList",
2252
+ inputs: [{ name: "_token", type: "address", internalType: "address" }],
2253
+ outputs: [],
2254
+ stateMutability: "nonpayable"
2256
2255
  },
2257
2256
  {
2258
2257
  type: "function",
2259
- name: "assetHandlerAddress",
2260
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2261
- outputs: [{ name: "assetHandlerAddress", type: "address", internalType: "address" }],
2258
+ name: "assetId",
2259
+ inputs: [{ name: "tokenAddress", type: "address", internalType: "address" }],
2260
+ outputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2262
2261
  stateMutability: "view"
2263
2262
  },
2264
2263
  {
2265
2264
  type: "function",
2266
- name: "eraChainId",
2267
- inputs: [],
2268
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2269
- stateMutability: "view"
2265
+ name: "bridgeBurn",
2266
+ inputs: [
2267
+ { name: "_chainId", type: "uint256", internalType: "uint256" },
2268
+ { name: "_l2MsgValue", type: "uint256", internalType: "uint256" },
2269
+ { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2270
+ { name: "_originalCaller", type: "address", internalType: "address" },
2271
+ { name: "_data", type: "bytes", internalType: "bytes" }
2272
+ ],
2273
+ outputs: [{ name: "_bridgeMintData", type: "bytes", internalType: "bytes" }],
2274
+ stateMutability: "payable"
2270
2275
  },
2271
2276
  {
2272
2277
  type: "function",
2273
- name: "finalizeDeposit",
2278
+ name: "bridgeCheckCounterpartAddress",
2274
2279
  inputs: [
2275
2280
  { name: "", type: "uint256", internalType: "uint256" },
2276
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2277
- { name: "_transferData", type: "bytes", internalType: "bytes" }
2281
+ { name: "", type: "bytes32", internalType: "bytes32" },
2282
+ { name: "", type: "address", internalType: "address" },
2283
+ {
2284
+ name: "_assetHandlerAddressOnCounterpart",
2285
+ type: "address",
2286
+ internalType: "address"
2287
+ }
2278
2288
  ],
2279
2289
  outputs: [],
2280
- stateMutability: "payable"
2290
+ stateMutability: "view"
2281
2291
  },
2282
2292
  {
2283
2293
  type: "function",
2284
- name: "finalizeDeposit",
2294
+ name: "bridgeMint",
2285
2295
  inputs: [
2286
- { name: "_l1Sender", type: "address", internalType: "address" },
2287
- { name: "_l2Receiver", type: "address", internalType: "address" },
2288
- { name: "_l1Token", type: "address", internalType: "address" },
2289
- { name: "_amount", type: "uint256", internalType: "uint256" },
2296
+ { name: "_chainId", type: "uint256", internalType: "uint256" },
2297
+ { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2290
2298
  { name: "_data", type: "bytes", internalType: "bytes" }
2291
2299
  ],
2292
2300
  outputs: [],
@@ -2294,50 +2302,96 @@ var IL2AssetRouterABI = [
2294
2302
  },
2295
2303
  {
2296
2304
  type: "function",
2297
- name: "finalizeDepositLegacyBridge",
2305
+ name: "bridgeRecoverFailedTransfer",
2298
2306
  inputs: [
2299
- { name: "_l1Sender", type: "address", internalType: "address" },
2300
- { name: "_l2Receiver", type: "address", internalType: "address" },
2301
- { name: "_l1Token", type: "address", internalType: "address" },
2302
- { name: "_amount", type: "uint256", internalType: "uint256" },
2307
+ { name: "_chainId", type: "uint256", internalType: "uint256" },
2308
+ { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2309
+ { name: "_depositSender", type: "address", internalType: "address" },
2303
2310
  { name: "_data", type: "bytes", internalType: "bytes" }
2304
2311
  ],
2305
2312
  outputs: [],
2306
- stateMutability: "nonpayable"
2313
+ stateMutability: "payable"
2314
+ },
2315
+ {
2316
+ type: "function",
2317
+ name: "bridgedTokenBeacon",
2318
+ inputs: [],
2319
+ outputs: [{ name: "", type: "address", internalType: "contract IBeacon" }],
2320
+ stateMutability: "view"
2321
+ },
2322
+ {
2323
+ type: "function",
2324
+ name: "bridgedTokens",
2325
+ inputs: [{ name: "count", type: "uint256", internalType: "uint256" }],
2326
+ outputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2327
+ stateMutability: "view"
2328
+ },
2329
+ {
2330
+ type: "function",
2331
+ name: "bridgedTokensCount",
2332
+ inputs: [],
2333
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2334
+ stateMutability: "view"
2307
2335
  },
2308
2336
  {
2309
2337
  type: "function",
2310
- name: "initL2",
2338
+ name: "calculateCreate2TokenAddress",
2311
2339
  inputs: [
2312
- { name: "_l1ChainId", type: "uint256", internalType: "uint256" },
2313
- { name: "_eraChainId", type: "uint256", internalType: "uint256" },
2314
- { name: "_l1AssetRouter", type: "address", internalType: "address" },
2315
- { name: "_legacySharedBridge", type: "address", internalType: "address" },
2316
- { name: "_baseTokenAssetId", type: "bytes32", internalType: "bytes32" },
2317
- { name: "_aliasedOwner", type: "address", internalType: "address" }
2340
+ { name: "_originChainId", type: "uint256", internalType: "uint256" },
2341
+ { name: "_nonNativeToken", type: "address", internalType: "address" }
2318
2342
  ],
2319
- outputs: [],
2343
+ outputs: [{ name: "", type: "address", internalType: "address" }],
2344
+ stateMutability: "view"
2345
+ },
2346
+ {
2347
+ type: "function",
2348
+ name: "chainBalance",
2349
+ inputs: [
2350
+ { name: "_chainId", type: "uint256", internalType: "uint256" },
2351
+ { name: "_assetId", type: "bytes32", internalType: "bytes32" }
2352
+ ],
2353
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2354
+ stateMutability: "view"
2355
+ },
2356
+ {
2357
+ type: "function",
2358
+ name: "ensureTokenIsRegistered",
2359
+ inputs: [{ name: "_nativeToken", type: "address", internalType: "address" }],
2360
+ outputs: [{ name: "tokenAssetId", type: "bytes32", internalType: "bytes32" }],
2320
2361
  stateMutability: "nonpayable"
2321
2362
  },
2322
2363
  {
2323
2364
  type: "function",
2324
- name: "l1Bridge",
2325
- inputs: [],
2326
- outputs: [{ name: "", type: "address", internalType: "address" }],
2365
+ name: "getERC20Getters",
2366
+ inputs: [
2367
+ { name: "_token", type: "address", internalType: "address" },
2368
+ { name: "_originChainId", type: "uint256", internalType: "uint256" }
2369
+ ],
2370
+ outputs: [{ name: "", type: "bytes", internalType: "bytes" }],
2327
2371
  stateMutability: "view"
2328
2372
  },
2329
2373
  {
2330
2374
  type: "function",
2331
- name: "l1TokenAddress",
2332
- inputs: [{ name: "_l2Token", type: "address", internalType: "address" }],
2333
- outputs: [{ name: "", type: "address", internalType: "address" }],
2375
+ name: "initialize",
2376
+ inputs: [
2377
+ { name: "_owner", type: "address", internalType: "address" },
2378
+ { name: "_bridgedTokenBeacon", type: "address", internalType: "address" }
2379
+ ],
2380
+ outputs: [],
2381
+ stateMutability: "nonpayable"
2382
+ },
2383
+ {
2384
+ type: "function",
2385
+ name: "l1AssetTracker",
2386
+ inputs: [],
2387
+ outputs: [{ name: "", type: "address", internalType: "contract IL1AssetTracker" }],
2334
2388
  stateMutability: "view"
2335
2389
  },
2336
2390
  {
2337
2391
  type: "function",
2338
- name: "l2TokenAddress",
2339
- inputs: [{ name: "_l1Token", type: "address", internalType: "address" }],
2340
- outputs: [{ name: "", type: "address", internalType: "address" }],
2392
+ name: "originChainId",
2393
+ inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2394
+ outputs: [{ name: "originChainId", type: "uint256", internalType: "uint256" }],
2341
2395
  stateMutability: "view"
2342
2396
  },
2343
2397
  {
@@ -2370,200 +2424,146 @@ var IL2AssetRouterABI = [
2370
2424
  },
2371
2425
  {
2372
2426
  type: "function",
2373
- name: "renounceOwnership",
2427
+ name: "registerEthToken",
2374
2428
  inputs: [],
2375
2429
  outputs: [],
2376
2430
  stateMutability: "nonpayable"
2377
2431
  },
2378
2432
  {
2379
2433
  type: "function",
2380
- name: "setAssetHandlerAddress",
2381
- inputs: [
2382
- { name: "_originChainId", type: "uint256", internalType: "uint256" },
2383
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2384
- { name: "_assetHandlerAddress", type: "address", internalType: "address" }
2385
- ],
2434
+ name: "registerToken",
2435
+ inputs: [{ name: "_nativeToken", type: "address", internalType: "address" }],
2386
2436
  outputs: [],
2387
2437
  stateMutability: "nonpayable"
2388
2438
  },
2389
2439
  {
2390
2440
  type: "function",
2391
- name: "setAssetHandlerAddressThisChain",
2392
- inputs: [
2393
- { name: "_assetRegistrationData", type: "bytes32", internalType: "bytes32" },
2394
- { name: "_assetHandlerAddress", type: "address", internalType: "address" }
2395
- ],
2441
+ name: "renounceOwnership",
2442
+ inputs: [],
2396
2443
  outputs: [],
2397
2444
  stateMutability: "nonpayable"
2398
2445
  },
2399
2446
  {
2400
2447
  type: "function",
2401
- name: "setLegacyTokenAssetHandler",
2402
- inputs: [{ name: "_assetId", type: "bytes32", internalType: "bytes32" }],
2448
+ name: "setAssetTracker",
2449
+ inputs: [{ name: "_l1AssetTracker", type: "address", internalType: "address" }],
2403
2450
  outputs: [],
2404
2451
  stateMutability: "nonpayable"
2405
2452
  },
2406
2453
  {
2407
2454
  type: "function",
2408
- name: "transferOwnership",
2409
- inputs: [{ name: "newOwner", type: "address", internalType: "address" }],
2410
- outputs: [],
2411
- stateMutability: "nonpayable"
2455
+ name: "tokenAddress",
2456
+ inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
2457
+ outputs: [{ name: "tokenAddress", type: "address", internalType: "address" }],
2458
+ stateMutability: "view"
2412
2459
  },
2413
2460
  {
2414
2461
  type: "function",
2415
- name: "unpause",
2416
- inputs: [],
2417
- outputs: [],
2418
- stateMutability: "nonpayable"
2462
+ name: "tokenDataOriginChainId",
2463
+ inputs: [{ name: "_erc20Data", type: "bytes", internalType: "bytes" }],
2464
+ outputs: [{ name: "tokenOriginChainId", type: "uint256", internalType: "uint256" }],
2465
+ stateMutability: "view"
2419
2466
  },
2420
2467
  {
2421
2468
  type: "function",
2422
- name: "updateL2",
2423
- inputs: [
2424
- { name: "_l1ChainId", type: "uint256", internalType: "uint256" },
2425
- { name: "_eraChainId", type: "uint256", internalType: "uint256" },
2426
- { name: "_l1AssetRouter", type: "address", internalType: "address" },
2427
- { name: "_legacySharedBridge", type: "address", internalType: "address" },
2428
- { name: "_baseTokenAssetId", type: "bytes32", internalType: "bytes32" }
2429
- ],
2469
+ name: "transferOwnership",
2470
+ inputs: [{ name: "newOwner", type: "address", internalType: "address" }],
2430
2471
  outputs: [],
2431
2472
  stateMutability: "nonpayable"
2432
2473
  },
2433
2474
  {
2434
2475
  type: "function",
2435
- name: "withdraw",
2476
+ name: "tryRegisterTokenFromBurnData",
2436
2477
  inputs: [
2437
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2438
- { name: "_assetData", type: "bytes", internalType: "bytes" }
2478
+ { name: "_burnData", type: "bytes", internalType: "bytes" },
2479
+ { name: "_expectedAssetId", type: "bytes32", internalType: "bytes32" }
2439
2480
  ],
2440
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2481
+ outputs: [],
2441
2482
  stateMutability: "nonpayable"
2442
2483
  },
2443
2484
  {
2444
2485
  type: "function",
2445
- name: "withdraw",
2446
- inputs: [
2447
- { name: "_l1Receiver", type: "address", internalType: "address" },
2448
- { name: "_l2Token", type: "address", internalType: "address" },
2449
- { name: "_amount", type: "uint256", internalType: "uint256" }
2450
- ],
2486
+ name: "unpause",
2487
+ inputs: [],
2451
2488
  outputs: [],
2452
2489
  stateMutability: "nonpayable"
2453
2490
  },
2454
2491
  {
2455
- type: "function",
2456
- name: "withdrawLegacyBridge",
2492
+ type: "event",
2493
+ name: "BridgeBurn",
2457
2494
  inputs: [
2458
- { name: "_l1Receiver", type: "address", internalType: "address" },
2459
- { name: "_l2Token", type: "address", internalType: "address" },
2460
- { name: "_amount", type: "uint256", internalType: "uint256" },
2461
- { name: "_sender", type: "address", internalType: "address" }
2495
+ { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
2496
+ { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2497
+ { name: "sender", type: "address", indexed: true, internalType: "address" },
2498
+ { name: "receiver", type: "address", indexed: false, internalType: "address" },
2499
+ { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
2462
2500
  ],
2463
- outputs: [],
2464
- stateMutability: "nonpayable"
2501
+ anonymous: false
2465
2502
  },
2466
2503
  {
2467
2504
  type: "event",
2468
- name: "AssetDeploymentTrackerRegistered",
2505
+ name: "BridgeMint",
2469
2506
  inputs: [
2507
+ { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
2470
2508
  { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2471
- { name: "additionalData", type: "bytes32", indexed: true, internalType: "bytes32" },
2472
- {
2473
- name: "assetDeploymentTracker",
2474
- type: "address",
2475
- indexed: false,
2476
- internalType: "address"
2477
- }
2509
+ { name: "receiver", type: "address", indexed: false, internalType: "address" },
2510
+ { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
2478
2511
  ],
2479
2512
  anonymous: false
2480
2513
  },
2481
2514
  {
2482
2515
  type: "event",
2483
- name: "AssetHandlerRegistered",
2516
+ name: "BridgedTokenBeaconUpdated",
2484
2517
  inputs: [
2485
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2486
2518
  {
2487
- name: "_assetHandlerAddress",
2519
+ name: "bridgedTokenBeacon",
2488
2520
  type: "address",
2489
- indexed: true,
2521
+ indexed: false,
2490
2522
  internalType: "address"
2523
+ },
2524
+ {
2525
+ name: "bridgedTokenProxyBytecodeHash",
2526
+ type: "bytes32",
2527
+ indexed: false,
2528
+ internalType: "bytes32"
2491
2529
  }
2492
2530
  ],
2493
2531
  anonymous: false
2494
2532
  },
2495
2533
  {
2496
2534
  type: "event",
2497
- name: "BridgehubDepositBaseTokenInitiated",
2498
- inputs: [
2499
- { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
2500
- { name: "from", type: "address", indexed: true, internalType: "address" },
2501
- { name: "assetId", type: "bytes32", indexed: false, internalType: "bytes32" },
2502
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
2503
- ],
2535
+ name: "Initialized",
2536
+ inputs: [{ name: "version", type: "uint8", indexed: false, internalType: "uint8" }],
2504
2537
  anonymous: false
2505
2538
  },
2506
2539
  {
2507
2540
  type: "event",
2508
- name: "BridgehubDepositInitiated",
2541
+ name: "OwnershipTransferStarted",
2509
2542
  inputs: [
2510
- { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
2511
- { name: "txDataHash", type: "bytes32", indexed: true, internalType: "bytes32" },
2512
- { name: "from", type: "address", indexed: true, internalType: "address" },
2513
- { name: "assetId", type: "bytes32", indexed: false, internalType: "bytes32" },
2514
- { name: "bridgeMintCalldata", type: "bytes", indexed: false, internalType: "bytes" }
2543
+ { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
2544
+ { name: "newOwner", type: "address", indexed: true, internalType: "address" }
2515
2545
  ],
2516
2546
  anonymous: false
2517
2547
  },
2518
2548
  {
2519
2549
  type: "event",
2520
- name: "BridgehubWithdrawalInitiated",
2550
+ name: "OwnershipTransferred",
2521
2551
  inputs: [
2522
- { name: "chainId", type: "uint256", indexed: false, internalType: "uint256" },
2523
- { name: "sender", type: "address", indexed: true, internalType: "address" },
2524
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2525
- { name: "assetDataHash", type: "bytes32", indexed: false, internalType: "bytes32" }
2552
+ { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
2553
+ { name: "newOwner", type: "address", indexed: true, internalType: "address" }
2526
2554
  ],
2527
2555
  anonymous: false
2528
2556
  },
2529
2557
  {
2530
2558
  type: "event",
2531
- name: "DepositFinalizedAssetRouter",
2532
- inputs: [
2533
- { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
2534
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2535
- { name: "assetData", type: "bytes", indexed: false, internalType: "bytes" }
2536
- ],
2559
+ name: "Paused",
2560
+ inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
2537
2561
  anonymous: false
2538
2562
  },
2539
2563
  {
2540
2564
  type: "event",
2541
- name: "Initialized",
2542
- inputs: [{ name: "version", type: "uint8", indexed: false, internalType: "uint8" }],
2543
- anonymous: false
2544
- },
2545
- {
2546
- type: "event",
2547
- name: "OwnershipTransferStarted",
2548
- inputs: [
2549
- { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
2550
- { name: "newOwner", type: "address", indexed: true, internalType: "address" }
2551
- ],
2552
- anonymous: false
2553
- },
2554
- {
2555
- type: "event",
2556
- name: "OwnershipTransferred",
2557
- inputs: [
2558
- { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
2559
- { name: "newOwner", type: "address", indexed: true, internalType: "address" }
2560
- ],
2561
- anonymous: false
2562
- },
2563
- {
2564
- type: "event",
2565
- name: "Paused",
2566
- inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
2565
+ name: "TokenBeaconUpdated",
2566
+ inputs: [{ name: "l2TokenBeacon", type: "address", indexed: true, internalType: "address" }],
2567
2567
  anonymous: false
2568
2568
  },
2569
2569
  {
@@ -2573,53 +2573,75 @@ var IL2AssetRouterABI = [
2573
2573
  anonymous: false
2574
2574
  },
2575
2575
  {
2576
- type: "event",
2577
- name: "WithdrawalInitiatedAssetRouter",
2576
+ type: "error",
2577
+ name: "AddressMismatch",
2578
2578
  inputs: [
2579
- { name: "chainId", type: "uint256", indexed: false, internalType: "uint256" },
2580
- { name: "l2Sender", type: "address", indexed: true, internalType: "address" },
2581
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
2582
- { name: "assetData", type: "bytes", indexed: false, internalType: "bytes" }
2583
- ],
2584
- anonymous: false
2579
+ { name: "expected", type: "address", internalType: "address" },
2580
+ { name: "supplied", type: "address", internalType: "address" }
2581
+ ]
2585
2582
  },
2586
2583
  { type: "error", name: "AmountMustBeGreaterThanZero", inputs: [] },
2584
+ { type: "error", name: "AssetIdAlreadyRegistered", inputs: [] },
2587
2585
  {
2588
2586
  type: "error",
2589
- name: "AssetIdNotSupported",
2590
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }]
2587
+ name: "AssetIdMismatch",
2588
+ inputs: [
2589
+ { name: "expected", type: "bytes32", internalType: "bytes32" },
2590
+ { name: "supplied", type: "bytes32", internalType: "bytes32" }
2591
+ ]
2591
2592
  },
2592
- { type: "error", name: "EmptyAddress", inputs: [] },
2593
+ { type: "error", name: "BurningNativeWETHNotSupported", inputs: [] },
2594
+ { type: "error", name: "ClaimFailedDepositFailed", inputs: [] },
2595
+ { type: "error", name: "DeployingBridgedTokenForNativeToken", inputs: [] },
2596
+ { type: "error", name: "EmptyDeposit", inputs: [] },
2597
+ { type: "error", name: "EmptyToken", inputs: [] },
2598
+ { type: "error", name: "InvalidNTVBurnData", inputs: [] },
2599
+ { type: "error", name: "NoFundsTransferred", inputs: [] },
2600
+ { type: "error", name: "NonEmptyMsgValue", inputs: [] },
2601
+ { type: "error", name: "OriginChainIdNotFound", inputs: [] },
2602
+ { type: "error", name: "TokenNotLegacy", inputs: [] },
2593
2603
  {
2594
2604
  type: "error",
2595
- name: "InvalidCaller",
2596
- inputs: [{ name: "", type: "address", internalType: "address" }]
2605
+ name: "TokenNotSupported",
2606
+ inputs: [{ name: "token", type: "address", internalType: "address" }]
2597
2607
  },
2598
- { type: "error", name: "InvalidNTVBurnData", inputs: [] },
2599
- { type: "error", name: "NotInitializedReentrancyGuard", inputs: [] },
2600
- { type: "error", name: "Reentrancy", inputs: [] },
2601
- { type: "error", name: "SlotOccupied", inputs: [] },
2602
- { type: "error", name: "TokenNotLegacy", inputs: [] },
2608
+ { type: "error", name: "TokensWithFeesNotSupported", inputs: [] },
2603
2609
  {
2604
2610
  type: "error",
2605
2611
  name: "Unauthorized",
2606
2612
  inputs: [{ name: "caller", type: "address", internalType: "address" }]
2607
- }
2613
+ },
2614
+ { type: "error", name: "UnsupportedEncodingVersion", inputs: [] },
2615
+ {
2616
+ type: "error",
2617
+ name: "ValueMismatch",
2618
+ inputs: [
2619
+ { name: "expected", type: "uint256", internalType: "uint256" },
2620
+ { name: "actual", type: "uint256", internalType: "uint256" }
2621
+ ]
2622
+ },
2623
+ { type: "error", name: "WithdrawFailed", inputs: [] },
2624
+ { type: "error", name: "WrongCounterpart", inputs: [] },
2625
+ { type: "error", name: "ZeroAddress", inputs: [] }
2608
2626
  ];
2609
- var IL2AssetRouter_default = IL2AssetRouterABI;
2627
+ var L1NativeTokenVault_default = L1NativeTokenVaultABI;
2610
2628
 
2611
- // src/core/internal/abis/L1NativeTokenVault.ts
2612
- var L1NativeTokenVaultABI = [
2629
+ // src/core/internal/abis/L2NativeTokenVault.ts
2630
+ var L2NativeTokenVaultABI = [
2613
2631
  {
2614
2632
  type: "constructor",
2615
2633
  inputs: [
2616
- { name: "_l1WethAddress", type: "address", internalType: "address" },
2617
- { name: "_l1AssetRouter", type: "address", internalType: "address" },
2618
- { name: "_l1Nullifier", type: "address", internalType: "contract IL1Nullifier" }
2634
+ { name: "_l1ChainId", type: "uint256", internalType: "uint256" },
2635
+ { name: "_aliasedOwner", type: "address", internalType: "address" },
2636
+ { name: "_l2TokenProxyBytecodeHash", type: "bytes32", internalType: "bytes32" },
2637
+ { name: "_legacySharedBridge", type: "address", internalType: "address" },
2638
+ { name: "_bridgedTokenBeacon", type: "address", internalType: "address" },
2639
+ { name: "_contractsDeployedAlready", type: "bool", internalType: "bool" },
2640
+ { name: "_wethToken", type: "address", internalType: "address" },
2641
+ { name: "_baseTokenAssetId", type: "bytes32", internalType: "bytes32" }
2619
2642
  ],
2620
2643
  stateMutability: "nonpayable"
2621
2644
  },
2622
- { type: "receive", stateMutability: "payable" },
2623
2645
  {
2624
2646
  type: "function",
2625
2647
  name: "ASSET_ROUTER",
@@ -2643,9 +2665,16 @@ var L1NativeTokenVaultABI = [
2643
2665
  },
2644
2666
  {
2645
2667
  type: "function",
2646
- name: "L1_NULLIFIER",
2668
+ name: "L2_LEGACY_SHARED_BRIDGE",
2647
2669
  inputs: [],
2648
- outputs: [{ name: "", type: "address", internalType: "contract IL1Nullifier" }],
2670
+ outputs: [{ name: "", type: "address", internalType: "contract IL2SharedBridgeLegacy" }],
2671
+ stateMutability: "view"
2672
+ },
2673
+ {
2674
+ type: "function",
2675
+ name: "L2_TOKEN_PROXY_BYTECODE_HASH",
2676
+ inputs: [],
2677
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2649
2678
  stateMutability: "view"
2650
2679
  },
2651
2680
  {
@@ -2689,22 +2718,6 @@ var L1NativeTokenVaultABI = [
2689
2718
  outputs: [{ name: "_bridgeMintData", type: "bytes", internalType: "bytes" }],
2690
2719
  stateMutability: "payable"
2691
2720
  },
2692
- {
2693
- type: "function",
2694
- name: "bridgeCheckCounterpartAddress",
2695
- inputs: [
2696
- { name: "", type: "uint256", internalType: "uint256" },
2697
- { name: "", type: "bytes32", internalType: "bytes32" },
2698
- { name: "", type: "address", internalType: "address" },
2699
- {
2700
- name: "_assetHandlerAddressOnCounterpart",
2701
- type: "address",
2702
- internalType: "address"
2703
- }
2704
- ],
2705
- outputs: [],
2706
- stateMutability: "view"
2707
- },
2708
2721
  {
2709
2722
  type: "function",
2710
2723
  name: "bridgeMint",
@@ -2716,18 +2729,6 @@ var L1NativeTokenVaultABI = [
2716
2729
  outputs: [],
2717
2730
  stateMutability: "payable"
2718
2731
  },
2719
- {
2720
- type: "function",
2721
- name: "bridgeRecoverFailedTransfer",
2722
- inputs: [
2723
- { name: "_chainId", type: "uint256", internalType: "uint256" },
2724
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
2725
- { name: "_depositSender", type: "address", internalType: "address" },
2726
- { name: "_data", type: "bytes", internalType: "bytes" }
2727
- ],
2728
- outputs: [],
2729
- stateMutability: "payable"
2730
- },
2731
2732
  {
2732
2733
  type: "function",
2733
2734
  name: "bridgedTokenBeacon",
@@ -2753,22 +2754,12 @@ var L1NativeTokenVaultABI = [
2753
2754
  type: "function",
2754
2755
  name: "calculateCreate2TokenAddress",
2755
2756
  inputs: [
2756
- { name: "_originChainId", type: "uint256", internalType: "uint256" },
2757
+ { name: "_tokenOriginChainId", type: "uint256", internalType: "uint256" },
2757
2758
  { name: "_nonNativeToken", type: "address", internalType: "address" }
2758
2759
  ],
2759
2760
  outputs: [{ name: "", type: "address", internalType: "address" }],
2760
2761
  stateMutability: "view"
2761
2762
  },
2762
- {
2763
- type: "function",
2764
- name: "chainBalance",
2765
- inputs: [
2766
- { name: "_chainId", type: "uint256", internalType: "uint256" },
2767
- { name: "_assetId", type: "bytes32", internalType: "bytes32" }
2768
- ],
2769
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2770
- stateMutability: "view"
2771
- },
2772
2763
  {
2773
2764
  type: "function",
2774
2765
  name: "ensureTokenIsRegistered",
@@ -2788,19 +2779,9 @@ var L1NativeTokenVaultABI = [
2788
2779
  },
2789
2780
  {
2790
2781
  type: "function",
2791
- name: "initialize",
2792
- inputs: [
2793
- { name: "_owner", type: "address", internalType: "address" },
2794
- { name: "_bridgedTokenBeacon", type: "address", internalType: "address" }
2795
- ],
2796
- outputs: [],
2797
- stateMutability: "nonpayable"
2798
- },
2799
- {
2800
- type: "function",
2801
- name: "l1AssetTracker",
2802
- inputs: [],
2803
- outputs: [{ name: "", type: "address", internalType: "contract IL1AssetTracker" }],
2782
+ name: "l2TokenAddress",
2783
+ inputs: [{ name: "_l1Token", type: "address", internalType: "address" }],
2784
+ outputs: [{ name: "expectedToken", type: "address", internalType: "address" }],
2804
2785
  stateMutability: "view"
2805
2786
  },
2806
2787
  {
@@ -2838,13 +2819,6 @@ var L1NativeTokenVaultABI = [
2838
2819
  outputs: [{ name: "", type: "address", internalType: "address" }],
2839
2820
  stateMutability: "view"
2840
2821
  },
2841
- {
2842
- type: "function",
2843
- name: "registerEthToken",
2844
- inputs: [],
2845
- outputs: [],
2846
- stateMutability: "nonpayable"
2847
- },
2848
2822
  {
2849
2823
  type: "function",
2850
2824
  name: "registerToken",
@@ -2861,8 +2835,8 @@ var L1NativeTokenVaultABI = [
2861
2835
  },
2862
2836
  {
2863
2837
  type: "function",
2864
- name: "setAssetTracker",
2865
- inputs: [{ name: "_l1AssetTracker", type: "address", internalType: "address" }],
2838
+ name: "setLegacyTokenAssetId",
2839
+ inputs: [{ name: "_l2TokenAddress", type: "address", internalType: "address" }],
2866
2840
  outputs: [],
2867
2841
  stateMutability: "nonpayable"
2868
2842
  },
@@ -2946,12 +2920,37 @@ var L1NativeTokenVaultABI = [
2946
2920
  ],
2947
2921
  anonymous: false
2948
2922
  },
2923
+ {
2924
+ type: "event",
2925
+ name: "FinalizeDeposit",
2926
+ inputs: [
2927
+ { name: "l1Sender", type: "address", indexed: true, internalType: "address" },
2928
+ { name: "l2Receiver", type: "address", indexed: true, internalType: "address" },
2929
+ { name: "l2Token", type: "address", indexed: true, internalType: "address" },
2930
+ { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
2931
+ ],
2932
+ anonymous: false
2933
+ },
2949
2934
  {
2950
2935
  type: "event",
2951
2936
  name: "Initialized",
2952
2937
  inputs: [{ name: "version", type: "uint8", indexed: false, internalType: "uint8" }],
2953
2938
  anonymous: false
2954
2939
  },
2940
+ {
2941
+ type: "event",
2942
+ name: "L2TokenBeaconUpdated",
2943
+ inputs: [
2944
+ { name: "l2TokenBeacon", type: "address", indexed: true, internalType: "address" },
2945
+ {
2946
+ name: "l2TokenProxyBytecodeHash",
2947
+ type: "bytes32",
2948
+ indexed: true,
2949
+ internalType: "bytes32"
2950
+ }
2951
+ ],
2952
+ anonymous: false
2953
+ },
2955
2954
  {
2956
2955
  type: "event",
2957
2956
  name: "OwnershipTransferStarted",
@@ -2978,14 +2977,19 @@ var L1NativeTokenVaultABI = [
2978
2977
  },
2979
2978
  {
2980
2979
  type: "event",
2981
- name: "TokenBeaconUpdated",
2982
- inputs: [{ name: "l2TokenBeacon", type: "address", indexed: true, internalType: "address" }],
2980
+ name: "Unpaused",
2981
+ inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
2983
2982
  anonymous: false
2984
2983
  },
2985
2984
  {
2986
2985
  type: "event",
2987
- name: "Unpaused",
2988
- inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
2986
+ name: "WithdrawalInitiated",
2987
+ inputs: [
2988
+ { name: "l2Sender", type: "address", indexed: true, internalType: "address" },
2989
+ { name: "l1Receiver", type: "address", indexed: true, internalType: "address" },
2990
+ { name: "l2Token", type: "address", indexed: true, internalType: "address" },
2991
+ { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
2992
+ ],
2989
2993
  anonymous: false
2990
2994
  },
2991
2995
  {
@@ -3006,15 +3010,22 @@ var L1NativeTokenVaultABI = [
3006
3010
  { name: "supplied", type: "bytes32", internalType: "bytes32" }
3007
3011
  ]
3008
3012
  },
3013
+ {
3014
+ type: "error",
3015
+ name: "AssetIdNotSupported",
3016
+ inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }]
3017
+ },
3009
3018
  { type: "error", name: "BurningNativeWETHNotSupported", inputs: [] },
3010
- { type: "error", name: "ClaimFailedDepositFailed", inputs: [] },
3019
+ { type: "error", name: "DeployFailed", inputs: [] },
3011
3020
  { type: "error", name: "DeployingBridgedTokenForNativeToken", inputs: [] },
3021
+ { type: "error", name: "EmptyAddress", inputs: [] },
3022
+ { type: "error", name: "EmptyBytes32", inputs: [] },
3012
3023
  { type: "error", name: "EmptyDeposit", inputs: [] },
3013
3024
  { type: "error", name: "EmptyToken", inputs: [] },
3014
3025
  { type: "error", name: "InvalidNTVBurnData", inputs: [] },
3015
- { type: "error", name: "NoFundsTransferred", inputs: [] },
3026
+ { type: "error", name: "NoLegacySharedBridge", inputs: [] },
3016
3027
  { type: "error", name: "NonEmptyMsgValue", inputs: [] },
3017
- { type: "error", name: "OriginChainIdNotFound", inputs: [] },
3028
+ { type: "error", name: "TokenIsLegacy", inputs: [] },
3018
3029
  { type: "error", name: "TokenNotLegacy", inputs: [] },
3019
3030
  {
3020
3031
  type: "error",
@@ -3022,6 +3033,7 @@ var L1NativeTokenVaultABI = [
3022
3033
  inputs: [{ name: "token", type: "address", internalType: "address" }]
3023
3034
  },
3024
3035
  { type: "error", name: "TokensWithFeesNotSupported", inputs: [] },
3036
+ { type: "error", name: "U32CastOverflow", inputs: [] },
3025
3037
  {
3026
3038
  type: "error",
3027
3039
  name: "Unauthorized",
@@ -3036,554 +3048,29 @@ var L1NativeTokenVaultABI = [
3036
3048
  { name: "actual", type: "uint256", internalType: "uint256" }
3037
3049
  ]
3038
3050
  },
3039
- { type: "error", name: "WithdrawFailed", inputs: [] },
3040
- { type: "error", name: "WrongCounterpart", inputs: [] },
3041
3051
  { type: "error", name: "ZeroAddress", inputs: [] }
3042
3052
  ];
3043
- var L1NativeTokenVault_default = L1NativeTokenVaultABI;
3053
+ var L2NativeTokenVault_default = L2NativeTokenVaultABI;
3044
3054
 
3045
- // src/core/internal/abis/L2NativeTokenVault.ts
3046
- var L2NativeTokenVaultABI = [
3055
+ // src/core/internal/abis/IERC20.ts
3056
+ var IERC20ABI = [
3047
3057
  {
3048
3058
  type: "constructor",
3049
3059
  inputs: [
3050
- { name: "_l1ChainId", type: "uint256", internalType: "uint256" },
3051
- { name: "_aliasedOwner", type: "address", internalType: "address" },
3052
- { name: "_l2TokenProxyBytecodeHash", type: "bytes32", internalType: "bytes32" },
3053
- { name: "_legacySharedBridge", type: "address", internalType: "address" },
3054
- { name: "_bridgedTokenBeacon", type: "address", internalType: "address" },
3055
- { name: "_contractsDeployedAlready", type: "bool", internalType: "bool" },
3056
- { name: "_wethToken", type: "address", internalType: "address" },
3057
- { name: "_baseTokenAssetId", type: "bytes32", internalType: "bytes32" }
3060
+ { name: "_name", type: "string", internalType: "string" },
3061
+ { name: "_symbol", type: "string", internalType: "string" },
3062
+ { name: "_decimals", type: "uint8", internalType: "uint8" }
3058
3063
  ],
3059
3064
  stateMutability: "nonpayable"
3060
3065
  },
3061
3066
  {
3062
3067
  type: "function",
3063
- name: "ASSET_ROUTER",
3064
- inputs: [],
3065
- outputs: [{ name: "", type: "address", internalType: "contract IAssetRouterBase" }],
3066
- stateMutability: "view"
3067
- },
3068
- {
3069
- type: "function",
3070
- name: "BASE_TOKEN_ASSET_ID",
3071
- inputs: [],
3072
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
3073
- stateMutability: "view"
3074
- },
3075
- {
3076
- type: "function",
3077
- name: "L1_CHAIN_ID",
3078
- inputs: [],
3079
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3080
- stateMutability: "view"
3081
- },
3082
- {
3083
- type: "function",
3084
- name: "L2_LEGACY_SHARED_BRIDGE",
3085
- inputs: [],
3086
- outputs: [{ name: "", type: "address", internalType: "contract IL2SharedBridgeLegacy" }],
3087
- stateMutability: "view"
3088
- },
3089
- {
3090
- type: "function",
3091
- name: "L2_TOKEN_PROXY_BYTECODE_HASH",
3092
- inputs: [],
3093
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
3094
- stateMutability: "view"
3095
- },
3096
- {
3097
- type: "function",
3098
- name: "WETH_TOKEN",
3099
- inputs: [],
3100
- outputs: [{ name: "", type: "address", internalType: "address" }],
3101
- stateMutability: "view"
3102
- },
3103
- {
3104
- type: "function",
3105
- name: "acceptOwnership",
3106
- inputs: [],
3107
- outputs: [],
3108
- stateMutability: "nonpayable"
3109
- },
3110
- {
3111
- type: "function",
3112
- name: "addLegacyTokenToBridgedTokensList",
3113
- inputs: [{ name: "_token", type: "address", internalType: "address" }],
3114
- outputs: [],
3115
- stateMutability: "nonpayable"
3116
- },
3117
- {
3118
- type: "function",
3119
- name: "assetId",
3120
- inputs: [{ name: "tokenAddress", type: "address", internalType: "address" }],
3121
- outputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
3122
- stateMutability: "view"
3123
- },
3124
- {
3125
- type: "function",
3126
- name: "bridgeBurn",
3127
- inputs: [
3128
- { name: "_chainId", type: "uint256", internalType: "uint256" },
3129
- { name: "_l2MsgValue", type: "uint256", internalType: "uint256" },
3130
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
3131
- { name: "_originalCaller", type: "address", internalType: "address" },
3132
- { name: "_data", type: "bytes", internalType: "bytes" }
3133
- ],
3134
- outputs: [{ name: "_bridgeMintData", type: "bytes", internalType: "bytes" }],
3135
- stateMutability: "payable"
3136
- },
3137
- {
3138
- type: "function",
3139
- name: "bridgeMint",
3140
- inputs: [
3141
- { name: "_chainId", type: "uint256", internalType: "uint256" },
3142
- { name: "_assetId", type: "bytes32", internalType: "bytes32" },
3143
- { name: "_data", type: "bytes", internalType: "bytes" }
3144
- ],
3145
- outputs: [],
3146
- stateMutability: "payable"
3147
- },
3148
- {
3149
- type: "function",
3150
- name: "bridgedTokenBeacon",
3151
- inputs: [],
3152
- outputs: [{ name: "", type: "address", internalType: "contract IBeacon" }],
3153
- stateMutability: "view"
3154
- },
3155
- {
3156
- type: "function",
3157
- name: "bridgedTokens",
3158
- inputs: [{ name: "count", type: "uint256", internalType: "uint256" }],
3159
- outputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
3160
- stateMutability: "view"
3161
- },
3162
- {
3163
- type: "function",
3164
- name: "bridgedTokensCount",
3165
- inputs: [],
3166
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3167
- stateMutability: "view"
3168
- },
3169
- {
3170
- type: "function",
3171
- name: "calculateCreate2TokenAddress",
3172
- inputs: [
3173
- { name: "_tokenOriginChainId", type: "uint256", internalType: "uint256" },
3174
- { name: "_nonNativeToken", type: "address", internalType: "address" }
3175
- ],
3176
- outputs: [{ name: "", type: "address", internalType: "address" }],
3177
- stateMutability: "view"
3178
- },
3179
- {
3180
- type: "function",
3181
- name: "ensureTokenIsRegistered",
3182
- inputs: [{ name: "_nativeToken", type: "address", internalType: "address" }],
3183
- outputs: [{ name: "tokenAssetId", type: "bytes32", internalType: "bytes32" }],
3184
- stateMutability: "nonpayable"
3185
- },
3186
- {
3187
- type: "function",
3188
- name: "getERC20Getters",
3189
- inputs: [
3190
- { name: "_token", type: "address", internalType: "address" },
3191
- { name: "_originChainId", type: "uint256", internalType: "uint256" }
3192
- ],
3193
- outputs: [{ name: "", type: "bytes", internalType: "bytes" }],
3194
- stateMutability: "view"
3195
- },
3196
- {
3197
- type: "function",
3198
- name: "l2TokenAddress",
3199
- inputs: [{ name: "_l1Token", type: "address", internalType: "address" }],
3200
- outputs: [{ name: "expectedToken", type: "address", internalType: "address" }],
3201
- stateMutability: "view"
3202
- },
3203
- {
3204
- type: "function",
3205
- name: "originChainId",
3206
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
3207
- outputs: [{ name: "originChainId", type: "uint256", internalType: "uint256" }],
3208
- stateMutability: "view"
3209
- },
3210
- {
3211
- type: "function",
3212
- name: "owner",
3213
- inputs: [],
3214
- outputs: [{ name: "", type: "address", internalType: "address" }],
3215
- stateMutability: "view"
3216
- },
3217
- {
3218
- type: "function",
3219
- name: "pause",
3220
- inputs: [],
3221
- outputs: [],
3222
- stateMutability: "nonpayable"
3223
- },
3224
- {
3225
- type: "function",
3226
- name: "paused",
3227
- inputs: [],
3228
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
3229
- stateMutability: "view"
3230
- },
3231
- {
3232
- type: "function",
3233
- name: "pendingOwner",
3234
- inputs: [],
3235
- outputs: [{ name: "", type: "address", internalType: "address" }],
3236
- stateMutability: "view"
3237
- },
3238
- {
3239
- type: "function",
3240
- name: "registerToken",
3241
- inputs: [{ name: "_nativeToken", type: "address", internalType: "address" }],
3242
- outputs: [],
3243
- stateMutability: "nonpayable"
3244
- },
3245
- {
3246
- type: "function",
3247
- name: "renounceOwnership",
3248
- inputs: [],
3249
- outputs: [],
3250
- stateMutability: "nonpayable"
3251
- },
3252
- {
3253
- type: "function",
3254
- name: "setLegacyTokenAssetId",
3255
- inputs: [{ name: "_l2TokenAddress", type: "address", internalType: "address" }],
3256
- outputs: [],
3257
- stateMutability: "nonpayable"
3258
- },
3259
- {
3260
- type: "function",
3261
- name: "tokenAddress",
3262
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }],
3263
- outputs: [{ name: "tokenAddress", type: "address", internalType: "address" }],
3264
- stateMutability: "view"
3265
- },
3266
- {
3267
- type: "function",
3268
- name: "tokenDataOriginChainId",
3269
- inputs: [{ name: "_erc20Data", type: "bytes", internalType: "bytes" }],
3270
- outputs: [{ name: "tokenOriginChainId", type: "uint256", internalType: "uint256" }],
3271
- stateMutability: "view"
3272
- },
3273
- {
3274
- type: "function",
3275
- name: "transferOwnership",
3276
- inputs: [{ name: "newOwner", type: "address", internalType: "address" }],
3277
- outputs: [],
3278
- stateMutability: "nonpayable"
3279
- },
3280
- {
3281
- type: "function",
3282
- name: "tryRegisterTokenFromBurnData",
3283
- inputs: [
3284
- { name: "_burnData", type: "bytes", internalType: "bytes" },
3285
- { name: "_expectedAssetId", type: "bytes32", internalType: "bytes32" }
3286
- ],
3287
- outputs: [],
3288
- stateMutability: "nonpayable"
3289
- },
3290
- {
3291
- type: "function",
3292
- name: "unpause",
3293
- inputs: [],
3294
- outputs: [],
3295
- stateMutability: "nonpayable"
3296
- },
3297
- {
3298
- type: "event",
3299
- name: "BridgeBurn",
3300
- inputs: [
3301
- { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
3302
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
3303
- { name: "sender", type: "address", indexed: true, internalType: "address" },
3304
- { name: "receiver", type: "address", indexed: false, internalType: "address" },
3305
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
3306
- ],
3307
- anonymous: false
3308
- },
3309
- {
3310
- type: "event",
3311
- name: "BridgeMint",
3312
- inputs: [
3313
- { name: "chainId", type: "uint256", indexed: true, internalType: "uint256" },
3314
- { name: "assetId", type: "bytes32", indexed: true, internalType: "bytes32" },
3315
- { name: "receiver", type: "address", indexed: false, internalType: "address" },
3316
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
3317
- ],
3318
- anonymous: false
3319
- },
3320
- {
3321
- type: "event",
3322
- name: "BridgedTokenBeaconUpdated",
3323
- inputs: [
3324
- {
3325
- name: "bridgedTokenBeacon",
3326
- type: "address",
3327
- indexed: false,
3328
- internalType: "address"
3329
- },
3330
- {
3331
- name: "bridgedTokenProxyBytecodeHash",
3332
- type: "bytes32",
3333
- indexed: false,
3334
- internalType: "bytes32"
3335
- }
3336
- ],
3337
- anonymous: false
3338
- },
3339
- {
3340
- type: "event",
3341
- name: "FinalizeDeposit",
3342
- inputs: [
3343
- { name: "l1Sender", type: "address", indexed: true, internalType: "address" },
3344
- { name: "l2Receiver", type: "address", indexed: true, internalType: "address" },
3345
- { name: "l2Token", type: "address", indexed: true, internalType: "address" },
3346
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
3347
- ],
3348
- anonymous: false
3349
- },
3350
- {
3351
- type: "event",
3352
- name: "Initialized",
3353
- inputs: [{ name: "version", type: "uint8", indexed: false, internalType: "uint8" }],
3354
- anonymous: false
3355
- },
3356
- {
3357
- type: "event",
3358
- name: "L2TokenBeaconUpdated",
3359
- inputs: [
3360
- { name: "l2TokenBeacon", type: "address", indexed: true, internalType: "address" },
3361
- {
3362
- name: "l2TokenProxyBytecodeHash",
3363
- type: "bytes32",
3364
- indexed: true,
3365
- internalType: "bytes32"
3366
- }
3367
- ],
3368
- anonymous: false
3369
- },
3370
- {
3371
- type: "event",
3372
- name: "OwnershipTransferStarted",
3373
- inputs: [
3374
- { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
3375
- { name: "newOwner", type: "address", indexed: true, internalType: "address" }
3376
- ],
3377
- anonymous: false
3378
- },
3379
- {
3380
- type: "event",
3381
- name: "OwnershipTransferred",
3382
- inputs: [
3383
- { name: "previousOwner", type: "address", indexed: true, internalType: "address" },
3384
- { name: "newOwner", type: "address", indexed: true, internalType: "address" }
3385
- ],
3386
- anonymous: false
3387
- },
3388
- {
3389
- type: "event",
3390
- name: "Paused",
3391
- inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
3392
- anonymous: false
3393
- },
3394
- {
3395
- type: "event",
3396
- name: "Unpaused",
3397
- inputs: [{ name: "account", type: "address", indexed: false, internalType: "address" }],
3398
- anonymous: false
3399
- },
3400
- {
3401
- type: "event",
3402
- name: "WithdrawalInitiated",
3403
- inputs: [
3404
- { name: "l2Sender", type: "address", indexed: true, internalType: "address" },
3405
- { name: "l1Receiver", type: "address", indexed: true, internalType: "address" },
3406
- { name: "l2Token", type: "address", indexed: true, internalType: "address" },
3407
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
3408
- ],
3409
- anonymous: false
3410
- },
3411
- {
3412
- type: "error",
3413
- name: "AddressMismatch",
3414
- inputs: [
3415
- { name: "expected", type: "address", internalType: "address" },
3416
- { name: "supplied", type: "address", internalType: "address" }
3417
- ]
3418
- },
3419
- { type: "error", name: "AmountMustBeGreaterThanZero", inputs: [] },
3420
- { type: "error", name: "AssetIdAlreadyRegistered", inputs: [] },
3421
- {
3422
- type: "error",
3423
- name: "AssetIdMismatch",
3424
- inputs: [
3425
- { name: "expected", type: "bytes32", internalType: "bytes32" },
3426
- { name: "supplied", type: "bytes32", internalType: "bytes32" }
3427
- ]
3428
- },
3429
- {
3430
- type: "error",
3431
- name: "AssetIdNotSupported",
3432
- inputs: [{ name: "assetId", type: "bytes32", internalType: "bytes32" }]
3433
- },
3434
- { type: "error", name: "BurningNativeWETHNotSupported", inputs: [] },
3435
- { type: "error", name: "DeployFailed", inputs: [] },
3436
- { type: "error", name: "DeployingBridgedTokenForNativeToken", inputs: [] },
3437
- { type: "error", name: "EmptyAddress", inputs: [] },
3438
- { type: "error", name: "EmptyBytes32", inputs: [] },
3439
- { type: "error", name: "EmptyDeposit", inputs: [] },
3440
- { type: "error", name: "EmptyToken", inputs: [] },
3441
- { type: "error", name: "InvalidNTVBurnData", inputs: [] },
3442
- { type: "error", name: "NoLegacySharedBridge", inputs: [] },
3443
- { type: "error", name: "NonEmptyMsgValue", inputs: [] },
3444
- { type: "error", name: "TokenIsLegacy", inputs: [] },
3445
- { type: "error", name: "TokenNotLegacy", inputs: [] },
3446
- {
3447
- type: "error",
3448
- name: "TokenNotSupported",
3449
- inputs: [{ name: "token", type: "address", internalType: "address" }]
3450
- },
3451
- { type: "error", name: "TokensWithFeesNotSupported", inputs: [] },
3452
- { type: "error", name: "U32CastOverflow", inputs: [] },
3453
- {
3454
- type: "error",
3455
- name: "Unauthorized",
3456
- inputs: [{ name: "caller", type: "address", internalType: "address" }]
3457
- },
3458
- { type: "error", name: "UnsupportedEncodingVersion", inputs: [] },
3459
- {
3460
- type: "error",
3461
- name: "ValueMismatch",
3462
- inputs: [
3463
- { name: "expected", type: "uint256", internalType: "uint256" },
3464
- { name: "actual", type: "uint256", internalType: "uint256" }
3465
- ]
3466
- },
3467
- { type: "error", name: "ZeroAddress", inputs: [] }
3468
- ];
3469
- var L2NativeTokenVault_default = L2NativeTokenVaultABI;
3470
-
3471
- // src/core/internal/abis/IBaseToken.ts
3472
- var IBaseTokenABI = [
3473
- {
3474
- type: "function",
3475
- name: "balanceOf",
3476
- inputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3477
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3478
- stateMutability: "view"
3479
- },
3480
- {
3481
- type: "function",
3482
- name: "mint",
3483
- inputs: [
3484
- { name: "_account", type: "address", internalType: "address" },
3485
- { name: "_amount", type: "uint256", internalType: "uint256" }
3486
- ],
3487
- outputs: [],
3488
- stateMutability: "nonpayable"
3489
- },
3490
- {
3491
- type: "function",
3492
- name: "totalSupply",
3493
- inputs: [],
3494
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3495
- stateMutability: "view"
3496
- },
3497
- {
3498
- type: "function",
3499
- name: "transferFromTo",
3500
- inputs: [
3501
- { name: "_from", type: "address", internalType: "address" },
3502
- { name: "_to", type: "address", internalType: "address" },
3503
- { name: "_amount", type: "uint256", internalType: "uint256" }
3504
- ],
3505
- outputs: [],
3506
- stateMutability: "nonpayable"
3507
- },
3508
- {
3509
- type: "function",
3510
- name: "withdraw",
3511
- inputs: [{ name: "_l1Receiver", type: "address", internalType: "address" }],
3512
- outputs: [],
3513
- stateMutability: "payable"
3514
- },
3515
- {
3516
- type: "function",
3517
- name: "withdrawWithMessage",
3518
- inputs: [
3519
- { name: "_l1Receiver", type: "address", internalType: "address" },
3520
- { name: "_additionalData", type: "bytes", internalType: "bytes" }
3521
- ],
3522
- outputs: [],
3523
- stateMutability: "payable"
3524
- },
3525
- {
3526
- type: "event",
3527
- name: "Mint",
3528
- inputs: [
3529
- { name: "account", type: "address", indexed: true, internalType: "address" },
3530
- { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }
3531
- ],
3532
- anonymous: false
3533
- },
3534
- {
3535
- type: "event",
3536
- name: "Transfer",
3537
- inputs: [
3538
- { name: "from", type: "address", indexed: true, internalType: "address" },
3539
- { name: "to", type: "address", indexed: true, internalType: "address" },
3540
- { name: "value", type: "uint256", indexed: false, internalType: "uint256" }
3541
- ],
3542
- anonymous: false
3543
- },
3544
- {
3545
- type: "event",
3546
- name: "Withdrawal",
3547
- inputs: [
3548
- { name: "_l2Sender", type: "address", indexed: true, internalType: "address" },
3549
- { name: "_l1Receiver", type: "address", indexed: true, internalType: "address" },
3550
- { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }
3551
- ],
3552
- anonymous: false
3553
- },
3554
- {
3555
- type: "event",
3556
- name: "WithdrawalWithMessage",
3557
- inputs: [
3558
- { name: "_l2Sender", type: "address", indexed: true, internalType: "address" },
3559
- { name: "_l1Receiver", type: "address", indexed: true, internalType: "address" },
3560
- { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" },
3561
- { name: "_additionalData", type: "bytes", indexed: false, internalType: "bytes" }
3562
- ],
3563
- anonymous: false
3564
- }
3565
- ];
3566
- var IBaseToken_default = IBaseTokenABI;
3567
-
3568
- // src/core/internal/abis/IERC20.ts
3569
- var IERC20ABI = [
3570
- {
3571
- type: "constructor",
3572
- inputs: [
3573
- { name: "_name", type: "string", internalType: "string" },
3574
- { name: "_symbol", type: "string", internalType: "string" },
3575
- { name: "_decimals", type: "uint8", internalType: "uint8" }
3576
- ],
3577
- stateMutability: "nonpayable"
3578
- },
3579
- {
3580
- type: "function",
3581
- name: "allowance",
3582
- inputs: [
3583
- { name: "", type: "address", internalType: "address" },
3584
- { name: "", type: "address", internalType: "address" }
3585
- ],
3586
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3068
+ name: "allowance",
3069
+ inputs: [
3070
+ { name: "", type: "address", internalType: "address" },
3071
+ { name: "", type: "address", internalType: "address" }
3072
+ ],
3073
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
3587
3074
  stateMutability: "view"
3588
3075
  },
3589
3076
  {
@@ -4071,83 +3558,61 @@ var MailboxABI = [
4071
3558
  ];
4072
3559
  var Mailbox_default = MailboxABI;
4073
3560
 
4074
- // src/core/utils/gas.ts
4075
- function assertNoLegacyGas(overrides) {
4076
- if (!overrides) return;
4077
- if ("gasPrice" in overrides && overrides.gasPrice !== void 0) {
4078
- throw new Error("Legacy gasPrice is not supported; use EIP-1559 fields instead.");
4079
- }
4080
- }
4081
- function assertPriorityFeeBounds(fees) {
4082
- if (fees.maxPriorityFeePerGas > fees.maxFeePerGas) {
4083
- throw new Error("maxPriorityFeePerGas cannot exceed maxFeePerGas.");
4084
- }
3561
+ // src/adapters/ethers/resources/deposits/context.ts
3562
+ async function commonCtx(p, client, tokens, contracts) {
3563
+ const { bridgehub, l1AssetRouter } = await contracts.addresses();
3564
+ const { chainId } = await client.l2.getNetwork();
3565
+ const sender = await client.signer.getAddress();
3566
+ const gasPerPubdata = p.gasPerPubdata ?? 800n;
3567
+ const operatorTip = p.operatorTip ?? 0n;
3568
+ const refundRecipient = p.refundRecipient ?? sender;
3569
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l1" });
3570
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
3571
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
3572
+ const baseIsEth = resolvedToken.isChainEthBased;
3573
+ const route = (() => {
3574
+ if (resolvedToken.kind === "eth") {
3575
+ return baseIsEth ? "eth-base" : "eth-nonbase";
3576
+ }
3577
+ if (resolvedToken.kind === "base") {
3578
+ return baseIsEth ? "eth-base" : "erc20-base";
3579
+ }
3580
+ return "erc20-nonbase";
3581
+ })();
3582
+ return {
3583
+ client,
3584
+ tokens,
3585
+ contracts,
3586
+ resolvedToken,
3587
+ baseTokenAssetId,
3588
+ baseTokenL1,
3589
+ baseIsEth,
3590
+ l1AssetRouter,
3591
+ route,
3592
+ bridgehub,
3593
+ chainIdL2: BigInt(chainId),
3594
+ sender,
3595
+ gasOverrides: p.l1TxOverrides,
3596
+ l2GasLimit: p.l2GasLimit,
3597
+ gasPerPubdata,
3598
+ operatorTip,
3599
+ refundRecipient
3600
+ };
4085
3601
  }
4086
-
4087
- // src/adapters/ethers/resources/utils.ts
4088
- function supportsGetGasPrice(provider) {
4089
- return typeof provider === "object" && provider !== null && typeof provider.getGasPrice === "function";
3602
+ function encodeNativeTokenVaultTransferData(amount, receiver, token) {
3603
+ return new ethers.AbiCoder().encode(["uint256", "address", "address"], [amount, receiver, token]);
4090
3604
  }
4091
- function encodeNativeTokenVaultAssetId(chainId, address) {
4092
- const abi = new ethers.AbiCoder();
4093
- const hex = abi.encode(
4094
- ["uint256", "address", "address"],
4095
- [chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
3605
+ function encodeSecondBridgeArgs(token, amount, l2Receiver) {
3606
+ return ethers.AbiCoder.defaultAbiCoder().encode(
3607
+ ["address", "uint256", "address"],
3608
+ [token, amount, l2Receiver]
4096
3609
  );
4097
- return ethers.ethers.keccak256(hex);
4098
3610
  }
4099
- async function getFeeOverrides(client, overrides) {
4100
- assertNoLegacyGas(overrides);
4101
- const fd = await client.l1.getFeeData();
4102
- const maxFeeFromProvider = fd.maxFeePerGas ?? void 0;
4103
- const maxPriorityFromProvider = fd.maxPriorityFeePerGas ?? void 0;
4104
- const gasPriceFallback = fd.gasPrice ?? void 0;
4105
- const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
4106
- if (maxFeePerGas == null) throw new Error("provider returned no gas price data");
4107
- const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
4108
- assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
4109
- const gasPriceForBaseCost = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback ?? maxFeePerGas;
4110
- return {
4111
- gasLimit: overrides?.gasLimit,
4112
- maxFeePerGas,
4113
- maxPriorityFeePerGas,
4114
- gasPriceForBaseCost
4115
- };
3611
+ function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
3612
+ return encodeSecondBridgeArgs(token, amount, l2Receiver);
4116
3613
  }
4117
- async function getL2FeeOverrides(client, overrides) {
4118
- assertNoLegacyGas(overrides);
4119
- let maxFeeFromProvider;
4120
- let maxPriorityFromProvider;
4121
- let gasPriceFallback;
4122
- try {
4123
- const fd = await client.l2.getFeeData();
4124
- if (fd?.maxFeePerGas != null) maxFeeFromProvider = fd.maxFeePerGas;
4125
- if (fd?.maxPriorityFeePerGas != null) {
4126
- maxPriorityFromProvider = fd.maxPriorityFeePerGas;
4127
- }
4128
- if (fd?.gasPrice != null) gasPriceFallback = fd.gasPrice;
4129
- } catch {
4130
- }
4131
- if (gasPriceFallback == null) {
4132
- try {
4133
- if (supportsGetGasPrice(client.l2)) {
4134
- const gp = await client.l2.getGasPrice();
4135
- gasPriceFallback = typeof gp === "bigint" ? gp : BigInt(gp.toString());
4136
- }
4137
- } catch {
4138
- }
4139
- }
4140
- const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
4141
- if (maxFeePerGas == null) {
4142
- throw new Error("L2 provider returned no gas price data");
4143
- }
4144
- const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
4145
- assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
4146
- return {
4147
- gasLimit: overrides?.gasLimit,
4148
- maxFeePerGas,
4149
- maxPriorityFeePerGas
4150
- };
3614
+ function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
3615
+ return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
4151
3616
  }
4152
3617
  function buildDirectRequestStruct(args) {
4153
3618
  return {
@@ -4162,52 +3627,197 @@ function buildDirectRequestStruct(args) {
4162
3627
  refundRecipient: args.refundRecipient
4163
3628
  };
4164
3629
  }
4165
- function encodeSecondBridgeArgs(token, amount, l2Receiver) {
4166
- return ethers.AbiCoder.defaultAbiCoder().encode(
4167
- ["address", "uint256", "address"],
4168
- [token, amount, l2Receiver]
4169
- );
3630
+
3631
+ // src/core/resources/deposits/gas.ts
3632
+ function makeGasQuote(p) {
3633
+ const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
3634
+ return {
3635
+ gasLimit: p.gasLimit,
3636
+ maxFeePerGas: p.maxFeePerGas,
3637
+ maxPriorityFeePerGas,
3638
+ gasPerPubdata: p.gasPerPubdata,
3639
+ maxCost: p.gasLimit * p.maxFeePerGas
3640
+ };
4170
3641
  }
4171
- function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
4172
- return encodeSecondBridgeArgs(token, amount, l2Receiver);
3642
+ async function fetchFees(estimator) {
3643
+ try {
3644
+ const fees = await estimator.estimateFeesPerGas();
3645
+ if (fees.maxFeePerGas != null) {
3646
+ return {
3647
+ maxFeePerGas: fees.maxFeePerGas,
3648
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
3649
+ };
3650
+ }
3651
+ if (fees.gasPrice != null) {
3652
+ return {
3653
+ maxFeePerGas: fees.gasPrice,
3654
+ maxPriorityFeePerGas: 0n
3655
+ };
3656
+ }
3657
+ } catch {
3658
+ }
3659
+ try {
3660
+ const gp = await estimator.getGasPrice();
3661
+ return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
3662
+ } catch {
3663
+ return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
3664
+ }
4173
3665
  }
4174
- function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
4175
- return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
3666
+ async function quoteL1Gas(input) {
3667
+ const { estimator, tx, overrides, fallbackGasLimit } = input;
3668
+ let market;
3669
+ const getMarket = async () => {
3670
+ if (market) return market;
3671
+ market = await fetchFees(estimator);
3672
+ return market;
3673
+ };
3674
+ const maxFeePerGas = overrides?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : (await getMarket()).maxFeePerGas);
3675
+ const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : (await getMarket()).maxPriorityFeePerGas);
3676
+ const explicitGasLimit = overrides?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
3677
+ if (explicitGasLimit != null) {
3678
+ return makeGasQuote({ gasLimit: explicitGasLimit, maxFeePerGas, maxPriorityFeePerGas });
3679
+ }
3680
+ try {
3681
+ const est = await estimator.estimateGas(tx);
3682
+ const buffered = BigInt(est) * (100n + BUFFER) / 100n;
3683
+ return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
3684
+ } catch (err) {
3685
+ if (fallbackGasLimit != null) {
3686
+ return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
3687
+ }
3688
+ console.warn("L1 gas estimation failed", err);
3689
+ return void 0;
3690
+ }
4176
3691
  }
4177
-
4178
- // src/core/resources/deposits/route.ts
4179
- async function pickDepositRoute(client, chainIdL2, token) {
4180
- if (isETH(token)) {
4181
- const base2 = await client.baseToken(chainIdL2);
4182
- return isETH(base2) ? "eth-base" : "eth-nonbase";
3692
+ async function quoteL2Gas(input) {
3693
+ const { estimator, route, tx, gasPerPubdata, l2GasLimit, overrideGasLimit, stateOverrides } = input;
3694
+ const market = await fetchFees(estimator);
3695
+ const maxFeePerGas = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
3696
+ const txGasLimit = tx?.gasLimit != null ? BigInt(tx.gasLimit) : void 0;
3697
+ const explicit = overrideGasLimit ?? txGasLimit;
3698
+ if (explicit != null) {
3699
+ return makeGasQuote({
3700
+ gasLimit: explicit,
3701
+ maxFeePerGas,
3702
+ gasPerPubdata
3703
+ });
3704
+ }
3705
+ if (!tx) {
3706
+ return makeGasQuote({
3707
+ gasLimit: l2GasLimit ?? 0n,
3708
+ maxFeePerGas,
3709
+ gasPerPubdata
3710
+ });
3711
+ }
3712
+ try {
3713
+ const execEstimate = await estimator.estimateGas(tx, stateOverrides);
3714
+ const memoryBytes = route === "erc20-nonbase" ? 500n : DEFAULT_ABI_BYTES;
3715
+ const pubdataBytes = route === "erc20-nonbase" ? 200n : DEFAULT_PUBDATA_BYTES;
3716
+ const pp = gasPerPubdata ?? 800n;
3717
+ const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
3718
+ const pubdataOverhead = pubdataBytes * pp;
3719
+ let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
3720
+ total = total * (100n + BUFFER) / 100n;
3721
+ return makeGasQuote({
3722
+ gasLimit: total,
3723
+ maxFeePerGas,
3724
+ gasPerPubdata: pp
3725
+ });
3726
+ } catch (err) {
3727
+ console.warn("L2 gas estimation failed", err);
3728
+ return makeGasQuote({
3729
+ gasLimit: l2GasLimit ?? 0n,
3730
+ maxFeePerGas,
3731
+ gasPerPubdata
3732
+ });
3733
+ }
3734
+ }
3735
+ async function quoteL2BaseCost(input) {
3736
+ const { estimator, encode: encode2, bridgehub, chainIdL2, l2GasLimit, gasPerPubdata } = input;
3737
+ const market = await fetchFees(estimator);
3738
+ const l1GasPrice = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
3739
+ if (l1GasPrice === 0n) {
3740
+ throw new Error("Could not fetch L1 gas price for Bridgehub base cost calculation.");
4183
3741
  }
4184
- const base = await client.baseToken(chainIdL2);
4185
- return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
3742
+ const data = encode2(IBridgehub_default, "l2TransactionBaseCost", [
3743
+ chainIdL2,
3744
+ l1GasPrice,
3745
+ l2GasLimit,
3746
+ gasPerPubdata
3747
+ ]);
3748
+ const raw = await estimator.call({
3749
+ to: bridgehub,
3750
+ data
3751
+ });
3752
+ return BigInt(raw);
4186
3753
  }
4187
3754
 
4188
- // src/adapters/ethers/resources/deposits/context.ts
4189
- async function commonCtx(p, client) {
4190
- const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
4191
- const { chainId } = await client.l2.getNetwork();
4192
- const sender = await client.signer.getAddress();
4193
- const fee = await getFeeOverrides(client, p.l1TxOverrides);
4194
- const l2GasLimit = p.l2GasLimit ?? 300000n;
4195
- const gasPerPubdata = p.gasPerPubdata ?? 800n;
4196
- const operatorTip = p.operatorTip ?? 0n;
4197
- const refundRecipient = p.refundRecipient ?? sender;
4198
- const route = await pickDepositRoute(client, BigInt(chainId), p.token);
3755
+ // src/adapters/ethers/estimator.ts
3756
+ function toCoreTx(tx) {
4199
3757
  return {
4200
- client,
4201
- l1AssetRouter,
4202
- route,
4203
- bridgehub,
4204
- chainIdL2: BigInt(chainId),
4205
- sender,
4206
- fee,
4207
- l2GasLimit,
4208
- gasPerPubdata,
4209
- operatorTip,
4210
- refundRecipient
3758
+ to: tx.to,
3759
+ from: tx.from,
3760
+ data: tx.data,
3761
+ value: tx.value ? BigInt(tx.value) : void 0,
3762
+ gasLimit: tx.gasLimit ? BigInt(tx.gasLimit) : void 0,
3763
+ maxFeePerGas: tx.maxFeePerGas ? BigInt(tx.maxFeePerGas) : void 0,
3764
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas ? BigInt(tx.maxPriorityFeePerGas) : void 0
3765
+ };
3766
+ }
3767
+ function ethersToGasEstimator(provider) {
3768
+ return {
3769
+ async estimateGas(tx, stateOverrides) {
3770
+ const ethTx = {
3771
+ to: tx.to,
3772
+ from: tx.from,
3773
+ data: tx.data,
3774
+ value: tx.value,
3775
+ gasLimit: tx.gasLimit,
3776
+ maxFeePerGas: tx.maxFeePerGas,
3777
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas
3778
+ };
3779
+ if (stateOverrides && "send" in provider) {
3780
+ try {
3781
+ const jsonRpcProvider = provider;
3782
+ const result = await jsonRpcProvider.send("eth_estimateGas", [
3783
+ ethTx,
3784
+ "latest",
3785
+ stateOverrides
3786
+ ]);
3787
+ return BigInt(result);
3788
+ } catch (error) {
3789
+ console.warn(
3790
+ "Failed to estimate gas with state overrides, falling back to standard estimation:",
3791
+ error
3792
+ );
3793
+ }
3794
+ } else if (stateOverrides) {
3795
+ console.warn('Provider does not support "send", skipping state overrides estimation.');
3796
+ }
3797
+ return await provider.estimateGas(ethTx);
3798
+ },
3799
+ async estimateFeesPerGas() {
3800
+ const fd = await provider.getFeeData();
3801
+ return {
3802
+ maxFeePerGas: fd.maxFeePerGas != null ? BigInt(fd.maxFeePerGas) : void 0,
3803
+ maxPriorityFeePerGas: fd.maxPriorityFeePerGas != null ? BigInt(fd.maxPriorityFeePerGas) : void 0,
3804
+ gasPrice: fd.gasPrice != null ? BigInt(fd.gasPrice) : void 0
3805
+ };
3806
+ },
3807
+ async getGasPrice() {
3808
+ const fd = await provider.getFeeData();
3809
+ if (fd.gasPrice != null) return BigInt(fd.gasPrice);
3810
+ throw new Error("Could not fetch gas price");
3811
+ },
3812
+ async call(tx) {
3813
+ const ethTx = {
3814
+ to: tx.to,
3815
+ data: tx.data,
3816
+ value: tx.value,
3817
+ from: tx.from
3818
+ };
3819
+ return await provider.call(ethTx);
3820
+ }
4211
3821
  };
4212
3822
  }
4213
3823
 
@@ -4380,162 +3990,268 @@ function createErrorHandlers(resource) {
4380
3990
  return { wrap: wrap2, wrapAs: wrapAs9, toResult: toResult2 };
4381
3991
  }
4382
3992
 
4383
- // src/adapters/ethers/resources/deposits/routes/eth.ts
3993
+ // src/adapters/ethers/resources/deposits/services/fee.ts
4384
3994
  var { wrapAs } = createErrorHandlers("deposits");
3995
+ var encode = (abi2, fn, args) => {
3996
+ return new ethers.Interface(abi2).encodeFunctionData(fn, args);
3997
+ };
3998
+ async function quoteL2BaseCost2(input) {
3999
+ const { ctx, l2GasLimit } = input;
4000
+ const estimator = ethersToGasEstimator(ctx.client.l1);
4001
+ return wrapAs(
4002
+ "RPC",
4003
+ "deposits.fees.l2BaseCost",
4004
+ () => quoteL2BaseCost({
4005
+ estimator,
4006
+ encode,
4007
+ bridgehub: ctx.bridgehub,
4008
+ chainIdL2: ctx.chainIdL2,
4009
+ l2GasLimit,
4010
+ gasPerPubdata: ctx.gasPerPubdata
4011
+ }),
4012
+ { ctx: { chainIdL2: ctx.chainIdL2 } }
4013
+ );
4014
+ }
4015
+
4016
+ // src/adapters/ethers/resources/deposits/services/gas.ts
4017
+ async function quoteL1Gas2(input) {
4018
+ const { ctx, tx, overrides, fallbackGasLimit } = input;
4019
+ const estimator = ethersToGasEstimator(ctx.client.l1);
4020
+ return quoteL1Gas({
4021
+ estimator,
4022
+ tx: toCoreTx(tx),
4023
+ overrides,
4024
+ fallbackGasLimit
4025
+ });
4026
+ }
4027
+ async function quoteL2Gas2(input) {
4028
+ const { ctx, route, l2TxForModeling, overrideGasLimit } = input;
4029
+ const estimator = ethersToGasEstimator(ctx.client.l2);
4030
+ return quoteL2Gas({
4031
+ estimator,
4032
+ route,
4033
+ tx: l2TxForModeling ? toCoreTx(l2TxForModeling) : void 0,
4034
+ gasPerPubdata: ctx.gasPerPubdata,
4035
+ l2GasLimit: ctx.l2GasLimit,
4036
+ overrideGasLimit,
4037
+ stateOverrides: input.stateOverrides
4038
+ });
4039
+ }
4040
+ async function determineErc20L2Gas(input) {
4041
+ const { ctx, l1Token } = input;
4042
+ const DEFAULT_SAFE_L2_GAS_LIMIT = 3000000n;
4043
+ if (ctx.l2GasLimit != null) {
4044
+ return quoteL2Gas2({
4045
+ ctx,
4046
+ route: "erc20-nonbase",
4047
+ overrideGasLimit: ctx.l2GasLimit
4048
+ });
4049
+ }
4050
+ try {
4051
+ const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token);
4052
+ if (l2TokenAddress === "0x0000000000000000000000000000000000000000") {
4053
+ return quoteL2Gas2({
4054
+ ctx,
4055
+ route: "erc20-nonbase",
4056
+ overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
4057
+ });
4058
+ }
4059
+ const modelTx = {
4060
+ to: input.modelTx?.to ?? ctx.sender,
4061
+ from: input.modelTx?.from ?? ctx.sender,
4062
+ data: input.modelTx?.data ?? "0x",
4063
+ value: input.modelTx?.value ?? 0n
4064
+ };
4065
+ const gas = await quoteL2Gas2({
4066
+ ctx,
4067
+ route: "erc20-nonbase",
4068
+ l2TxForModeling: modelTx
4069
+ });
4070
+ if (!gas) {
4071
+ return quoteL2Gas2({
4072
+ ctx,
4073
+ route: "erc20-nonbase",
4074
+ overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
4075
+ });
4076
+ }
4077
+ return gas;
4078
+ } catch (err) {
4079
+ console.warn("Failed to determine ERC20 L2 gas; defaulting to safe gas limit.", err);
4080
+ return quoteL2Gas2({
4081
+ ctx,
4082
+ route: "erc20-nonbase",
4083
+ overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
4084
+ });
4085
+ }
4086
+ }
4087
+
4088
+ // src/core/resources/deposits/fee.ts
4089
+ function buildFeeBreakdown(p) {
4090
+ const l1MaxTotal = p.l1Gas?.maxCost ?? 0n;
4091
+ const l2Total = p.l2BaseCost + p.operatorTip;
4092
+ const l1 = {
4093
+ gasLimit: p.l1Gas?.gasLimit ?? 0n,
4094
+ maxFeePerGas: p.l1Gas?.maxFeePerGas ?? 0n,
4095
+ maxPriorityFeePerGas: p.l1Gas?.maxPriorityFeePerGas,
4096
+ maxTotal: l1MaxTotal
4097
+ };
4098
+ const l2 = {
4099
+ total: l2Total,
4100
+ baseCost: p.l2BaseCost,
4101
+ operatorTip: p.operatorTip,
4102
+ gasLimit: p.l2Gas?.gasLimit ?? 0n,
4103
+ maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
4104
+ maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas,
4105
+ gasPerPubdata: p.l2Gas?.gasPerPubdata ?? 0n
4106
+ };
4107
+ return {
4108
+ token: p.feeToken,
4109
+ maxTotal: l1MaxTotal + l2Total,
4110
+ mintValue: p.mintValue,
4111
+ l1,
4112
+ l2
4113
+ };
4114
+ }
4115
+
4116
+ // src/adapters/ethers/resources/deposits/routes/eth.ts
4385
4117
  function routeEthDirect() {
4386
4118
  return {
4387
4119
  async build(p, ctx) {
4388
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4389
- const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
4390
- const rawBaseCost = await wrapAs(
4391
- "CONTRACT",
4392
- OP_DEPOSITS.eth.baseCost,
4393
- () => bh.l2TransactionBaseCost(
4394
- ctx.chainIdL2,
4395
- gasPriceForBaseCost,
4396
- ctx.l2GasLimit,
4397
- ctx.gasPerPubdata
4398
- ),
4399
- {
4400
- ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
4401
- message: "Could not fetch L2 base cost from Bridgehub."
4120
+ const bh = await ctx.contracts.bridgehub();
4121
+ const l2TxModel = {
4122
+ to: p.to ?? ctx.sender,
4123
+ from: ctx.sender,
4124
+ data: "0x",
4125
+ value: 0n
4126
+ };
4127
+ const l2GasParams = await quoteL2Gas2({
4128
+ ctx,
4129
+ route: "eth-base",
4130
+ l2TxForModeling: l2TxModel,
4131
+ overrideGasLimit: ctx.l2GasLimit,
4132
+ stateOverrides: {
4133
+ [ctx.sender]: {
4134
+ balance: "0xffffffffffffffffffff"
4135
+ }
4402
4136
  }
4403
- );
4404
- const baseCost = BigInt(rawBaseCost);
4405
- const l2Contract = p.to ?? ctx.sender;
4406
- const l2Value = p.amount;
4407
- const mintValue = baseCost + ctx.operatorTip + l2Value;
4137
+ });
4138
+ if (!l2GasParams) {
4139
+ throw new Error("Failed to estimate L2 gas for deposit.");
4140
+ }
4141
+ const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
4142
+ const mintValue = baseCost + ctx.operatorTip + p.amount;
4408
4143
  const req = buildDirectRequestStruct({
4409
4144
  chainId: ctx.chainIdL2,
4410
4145
  mintValue,
4411
- l2GasLimit: ctx.l2GasLimit,
4146
+ l2GasLimit: l2GasParams.gasLimit,
4412
4147
  gasPerPubdata: ctx.gasPerPubdata,
4413
4148
  refundRecipient: ctx.refundRecipient,
4414
- l2Contract,
4415
- l2Value
4149
+ l2Contract: p.to ?? ctx.sender,
4150
+ l2Value: p.amount
4416
4151
  });
4417
4152
  const data = bh.interface.encodeFunctionData("requestL2TransactionDirect", [req]);
4418
- let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
4419
- const tx = {
4153
+ const l1TxCandidate = {
4420
4154
  to: ctx.bridgehub,
4421
4155
  data,
4422
4156
  value: mintValue,
4423
4157
  from: ctx.sender,
4424
- ...txFeeOverrides
4158
+ ...ctx.gasOverrides
4425
4159
  };
4426
- if (overrideGasLimit != null) {
4427
- tx.gasLimit = overrideGasLimit;
4428
- resolvedL1GasLimit = overrideGasLimit;
4429
- } else {
4430
- try {
4431
- const est = await wrapAs(
4432
- "RPC",
4433
- OP_DEPOSITS.eth.estGas,
4434
- () => ctx.client.l1.estimateGas(tx),
4435
- {
4436
- ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
4437
- message: "Failed to estimate gas for Bridgehub request."
4438
- }
4439
- );
4440
- const buffered = BigInt(est) * 115n / 100n;
4441
- tx.gasLimit = buffered;
4442
- resolvedL1GasLimit = buffered;
4443
- } catch {
4444
- }
4160
+ const l1GasParams = await quoteL1Gas2({
4161
+ ctx,
4162
+ tx: l1TxCandidate,
4163
+ overrides: ctx.gasOverrides
4164
+ });
4165
+ if (l1GasParams) {
4166
+ l1TxCandidate.gasLimit = l1GasParams.gasLimit;
4167
+ l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
4168
+ l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
4445
4169
  }
4446
4170
  const steps = [
4447
4171
  {
4448
4172
  key: "bridgehub:direct",
4449
4173
  kind: "bridgehub:direct",
4450
4174
  description: "Bridge ETH via Bridgehub.requestL2TransactionDirect",
4451
- tx
4175
+ tx: l1TxCandidate
4452
4176
  }
4453
4177
  ];
4178
+ const fees = buildFeeBreakdown({
4179
+ feeToken: ETH_ADDRESS,
4180
+ l1Gas: l1GasParams,
4181
+ l2Gas: l2GasParams,
4182
+ l2BaseCost: baseCost,
4183
+ operatorTip: ctx.operatorTip,
4184
+ mintValue
4185
+ });
4454
4186
  return {
4455
4187
  steps,
4456
4188
  approvals: [],
4457
- quoteExtras: { baseCost, mintValue, l1GasLimit: resolvedL1GasLimit }
4189
+ fees
4458
4190
  };
4459
4191
  }
4460
4192
  };
4461
4193
  }
4462
4194
  var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
4463
- var MIN_L2_GAS_FOR_ERC20 = 2500000n;
4464
4195
  function routeErc20NonBase() {
4465
4196
  return {
4466
- async preflight() {
4467
- },
4468
- async build(p, ctx) {
4469
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4470
- const assetRouter = ctx.l1AssetRouter;
4471
- const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
4472
- const txOverrides = overrideGasLimit != null ? { ...txFeeOverrides, gasLimit: overrideGasLimit } : txFeeOverrides;
4473
- let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
4474
- const baseToken = await wrapAs2(
4475
- "CONTRACT",
4476
- OP_DEPOSITS.nonbase.baseToken,
4477
- () => bh.baseToken(ctx.chainIdL2),
4478
- {
4479
- ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
4480
- message: "Failed to read base token."
4481
- }
4482
- );
4197
+ async preflight(p, ctx) {
4198
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
4199
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4483
4200
  await wrapAs2(
4484
4201
  "VALIDATION",
4485
4202
  OP_DEPOSITS.nonbase.assertNonBaseToken,
4486
4203
  () => {
4487
- if (normalizeAddrEq(baseToken, p.token)) {
4204
+ if (resolved?.kind === "base" || resolved?.kind === "eth") {
4488
4205
  throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
4489
4206
  }
4490
4207
  },
4491
4208
  { ctx: { depositToken: p.token, baseToken } }
4492
4209
  );
4493
- const l2GasLimitUsed = ctx.l2GasLimit && ctx.l2GasLimit > 0n ? ctx.l2GasLimit < MIN_L2_GAS_FOR_ERC20 ? MIN_L2_GAS_FOR_ERC20 : ctx.l2GasLimit : MIN_L2_GAS_FOR_ERC20;
4494
- const rawBaseCost = await wrapAs2(
4495
- "RPC",
4496
- OP_DEPOSITS.nonbase.baseCost,
4497
- () => bh.l2TransactionBaseCost(
4498
- ctx.chainIdL2,
4499
- gasPriceForBaseCost,
4500
- l2GasLimitUsed,
4501
- ctx.gasPerPubdata
4502
- ),
4503
- {
4504
- ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
4505
- message: "Could not fetch L2 base cost from Bridgehub."
4210
+ },
4211
+ async build(p, ctx) {
4212
+ const l1Signer = ctx.client.getL1Signer();
4213
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4214
+ const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
4215
+ const l2GasParams = await determineErc20L2Gas({
4216
+ ctx,
4217
+ l1Token: p.token,
4218
+ modelTx: {
4219
+ to: p.to ?? ctx.sender,
4220
+ from: ctx.sender,
4221
+ data: "0x",
4222
+ value: 0n
4506
4223
  }
4507
- );
4508
- const baseCost = BigInt(rawBaseCost);
4224
+ });
4225
+ if (!l2GasParams) throw new Error("Failed to establish L2 gas parameters.");
4226
+ const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
4509
4227
  const mintValue = baseCost + ctx.operatorTip;
4510
4228
  const approvals = [];
4511
4229
  const steps = [];
4512
- const l1Signer = ctx.client.getL1Signer();
4513
- {
4514
- const erc20Deposit = new ethers.Contract(p.token, IERC20_default, l1Signer);
4515
- const allowanceToken = await wrapAs2(
4516
- "RPC",
4517
- OP_DEPOSITS.nonbase.allowanceToken,
4518
- () => erc20Deposit.allowance(ctx.sender, assetRouter),
4519
- {
4520
- ctx: { where: "erc20.allowance", token: p.token, spender: assetRouter },
4521
- message: "Failed to read deposit-token allowance."
4522
- }
4523
- );
4524
- if (allowanceToken < p.amount) {
4525
- approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
4526
- const data = erc20Deposit.interface.encodeFunctionData("approve", [
4527
- assetRouter,
4528
- p.amount
4529
- ]);
4530
- steps.push({
4531
- key: `approve:${p.token}:${assetRouter}`,
4532
- kind: "approve",
4533
- description: `Approve ${p.amount} for router (deposit token)`,
4534
- tx: { to: p.token, data, from: ctx.sender, ...txOverrides }
4535
- });
4230
+ const assetRouter = ctx.l1AssetRouter;
4231
+ const erc20Deposit = new ethers.Contract(p.token, IERC20_default, l1Signer);
4232
+ const allowanceToken = await wrapAs2(
4233
+ "RPC",
4234
+ OP_DEPOSITS.nonbase.allowanceToken,
4235
+ () => erc20Deposit.allowance(ctx.sender, assetRouter),
4236
+ {
4237
+ ctx: { where: "erc20.allowance", token: p.token, spender: assetRouter },
4238
+ message: "Failed to read deposit-token allowance."
4536
4239
  }
4240
+ );
4241
+ if (allowanceToken < p.amount) {
4242
+ approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
4243
+ steps.push({
4244
+ key: `approve:${p.token}:${assetRouter}`,
4245
+ kind: "approve",
4246
+ description: `Approve ${p.amount} for router (deposit token)`,
4247
+ tx: {
4248
+ to: p.token,
4249
+ data: erc20Deposit.interface.encodeFunctionData("approve", [assetRouter, p.amount]),
4250
+ from: ctx.sender,
4251
+ ...ctx.gasOverrides
4252
+ }
4253
+ });
4537
4254
  }
4538
- const baseIsEth = isETH(baseToken);
4539
4255
  if (!baseIsEth) {
4540
4256
  const erc20Base = new ethers.Contract(baseToken, IERC20_default, l1Signer);
4541
4257
  const allowanceBase = await wrapAs2(
@@ -4549,12 +4265,16 @@ function routeErc20NonBase() {
4549
4265
  );
4550
4266
  if (allowanceBase < mintValue) {
4551
4267
  approvals.push({ token: baseToken, spender: assetRouter, amount: mintValue });
4552
- const data = erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]);
4553
4268
  steps.push({
4554
4269
  key: `approve:${baseToken}:${assetRouter}`,
4555
4270
  kind: "approve",
4556
4271
  description: `Approve base token for mintValue`,
4557
- tx: { to: baseToken, data, from: ctx.sender, ...txOverrides }
4272
+ tx: {
4273
+ to: baseToken,
4274
+ data: erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]),
4275
+ from: ctx.sender,
4276
+ ...ctx.gasOverrides
4277
+ }
4558
4278
  });
4559
4279
  }
4560
4280
  }
@@ -4567,96 +4287,86 @@ function routeErc20NonBase() {
4567
4287
  message: "Failed to encode bridging calldata."
4568
4288
  }
4569
4289
  );
4570
- const outer = {
4290
+ const requestStruct = {
4571
4291
  chainId: ctx.chainIdL2,
4572
4292
  mintValue,
4573
- // fees (in ETH if base=ETH, else pulled as base ERC-20)
4574
4293
  l2Value: 0n,
4575
- l2GasLimit: l2GasLimitUsed,
4294
+ l2GasLimit: l2GasParams.gasLimit,
4576
4295
  l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
4577
4296
  refundRecipient: ctx.refundRecipient,
4578
4297
  secondBridgeAddress: assetRouter,
4579
4298
  secondBridgeValue: 0n,
4580
4299
  secondBridgeCalldata
4581
4300
  };
4582
- const dataTwo = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [outer]);
4583
- const bridgeTx = {
4301
+ const bh = await ctx.contracts.bridgehub();
4302
+ const data = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
4303
+ requestStruct
4304
+ ]);
4305
+ const txValue = baseIsEth ? mintValue : 0n;
4306
+ const l1TxCandidate = {
4584
4307
  to: ctx.bridgehub,
4585
- data: dataTwo,
4586
- value: baseIsEth ? mintValue : 0n,
4308
+ data,
4309
+ value: txValue,
4587
4310
  from: ctx.sender,
4588
- ...txOverrides
4311
+ ...ctx.gasOverrides
4589
4312
  };
4590
- if (overrideGasLimit != null) {
4591
- bridgeTx.gasLimit = overrideGasLimit;
4592
- resolvedL1GasLimit = overrideGasLimit;
4593
- } else {
4594
- try {
4595
- const est = await wrapAs2(
4596
- "RPC",
4597
- OP_DEPOSITS.nonbase.estGas,
4598
- () => ctx.client.l1.estimateGas(bridgeTx),
4599
- {
4600
- ctx: { where: "l1.estimateGas", to: ctx.bridgehub, baseIsEth },
4601
- message: "Failed to estimate gas for Bridgehub request."
4602
- }
4603
- );
4604
- const buffered = BigInt(est) * 125n / 100n;
4605
- bridgeTx.gasLimit = buffered;
4606
- resolvedL1GasLimit = buffered;
4607
- } catch {
4608
- }
4313
+ const l1GasParams = await quoteL1Gas2({
4314
+ ctx,
4315
+ tx: l1TxCandidate,
4316
+ overrides: ctx.gasOverrides,
4317
+ fallbackGasLimit: SAFE_L1_BRIDGE_GAS
4318
+ });
4319
+ if (l1GasParams) {
4320
+ l1TxCandidate.gasLimit = l1GasParams.gasLimit;
4321
+ l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
4322
+ l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
4609
4323
  }
4610
4324
  steps.push({
4611
- key: "bridgehub:two-bridges:nonbase",
4325
+ key: "bridgehub:two-bridges",
4612
4326
  kind: "bridgehub:two-bridges",
4613
- description: baseIsEth ? "Bridge ERC-20 (fees in ETH) via Bridgehub.requestL2TransactionTwoBridges" : "Bridge ERC-20 (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
4614
- tx: bridgeTx
4327
+ description: baseIsEth ? "Bridge ERC-20 (Fees paid in ETH)" : "Bridge ERC-20 (Fees paid in Base Token)",
4328
+ tx: l1TxCandidate
4329
+ });
4330
+ const fees = buildFeeBreakdown({
4331
+ feeToken: baseToken,
4332
+ l1Gas: l1GasParams,
4333
+ l2Gas: l2GasParams,
4334
+ l2BaseCost: baseCost,
4335
+ operatorTip: ctx.operatorTip,
4336
+ mintValue
4615
4337
  });
4616
4338
  return {
4617
4339
  steps,
4618
4340
  approvals,
4619
- quoteExtras: { baseCost, mintValue, baseToken, baseIsEth, l1GasLimit: resolvedL1GasLimit }
4341
+ fees
4620
4342
  };
4621
4343
  }
4622
4344
  };
4623
4345
  }
4624
4346
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
4625
- var BASE_COST_BUFFER_BPS = 100n;
4626
- var BPS = 10000n;
4627
- var withBuffer = (x) => x * (BPS + BASE_COST_BUFFER_BPS) / BPS;
4628
4347
  function routeEthNonBase() {
4629
4348
  return {
4630
4349
  async preflight(p, ctx) {
4350
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
4631
4351
  await wrapAs3(
4632
4352
  "VALIDATION",
4633
4353
  OP_DEPOSITS.ethNonBase.assertEthAsset,
4634
4354
  () => {
4635
- if (!isETH(p.token)) {
4355
+ if (resolved?.kind !== "eth" && !isETH(p.token)) {
4636
4356
  throw new Error("eth-nonbase route requires ETH as the deposit asset.");
4637
4357
  }
4638
4358
  },
4639
4359
  { ctx: { token: p.token } }
4640
4360
  );
4641
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4642
- const baseToken = await wrapAs3(
4643
- "CONTRACT",
4644
- OP_DEPOSITS.ethNonBase.baseToken,
4645
- () => bh.baseToken(ctx.chainIdL2),
4646
- {
4647
- ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
4648
- message: "Failed to read base token."
4649
- }
4650
- );
4651
4361
  await wrapAs3(
4652
4362
  "VALIDATION",
4653
4363
  OP_DEPOSITS.ethNonBase.assertNonEthBase,
4654
4364
  () => {
4655
- if (isETH(baseToken)) {
4365
+ if (ctx.baseIsEth) {
4656
4366
  throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
4657
4367
  }
4658
4368
  },
4659
- { ctx: { baseToken, chainIdL2: ctx.chainIdL2 } }
4369
+ { ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
4660
4370
  );
4661
4371
  const ethBal = await wrapAs3(
4662
4372
  "RPC",
@@ -4680,61 +4390,48 @@ function routeEthNonBase() {
4680
4390
  return;
4681
4391
  },
4682
4392
  async build(p, ctx) {
4683
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4684
- const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
4685
- const txOverrides = overrideGasLimit != null ? { ...txFeeOverrides, gasLimit: overrideGasLimit } : txFeeOverrides;
4686
- const baseToken = await wrapAs3(
4687
- "CONTRACT",
4688
- OP_DEPOSITS.ethNonBase.baseToken,
4689
- () => bh.baseToken(ctx.chainIdL2),
4690
- {
4691
- ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
4692
- message: "Failed to read base token."
4693
- }
4694
- );
4695
- const rawBaseCost = await wrapAs3(
4393
+ const l1Signer = ctx.client.getL1Signer();
4394
+ const baseToken = ctx.baseTokenL1;
4395
+ const l2TxModel = {
4396
+ to: p.to ?? ctx.sender,
4397
+ from: ctx.sender,
4398
+ data: "0x",
4399
+ value: 0n
4400
+ };
4401
+ const l2GasParams = await quoteL2Gas2({
4402
+ ctx,
4403
+ route: "eth-nonbase",
4404
+ l2TxForModeling: l2TxModel,
4405
+ overrideGasLimit: ctx.l2GasLimit
4406
+ });
4407
+ if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
4408
+ const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
4409
+ const mintValue = baseCost + ctx.operatorTip;
4410
+ const approvals = [];
4411
+ const steps = [];
4412
+ const erc20Base = new ethers.Contract(baseToken, IERC20_default, l1Signer);
4413
+ const allowance = await wrapAs3(
4696
4414
  "RPC",
4697
- OP_DEPOSITS.ethNonBase.baseCost,
4698
- () => bh.l2TransactionBaseCost(
4699
- ctx.chainIdL2,
4700
- gasPriceForBaseCost,
4701
- ctx.l2GasLimit,
4702
- ctx.gasPerPubdata
4703
- ),
4415
+ OP_DEPOSITS.ethNonBase.allowanceBase,
4416
+ () => erc20Base.allowance(ctx.sender, ctx.l1AssetRouter),
4704
4417
  {
4705
- ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
4706
- message: "Could not fetch L2 base cost."
4418
+ ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
4419
+ message: "Failed to read base-token allowance."
4707
4420
  }
4708
4421
  );
4709
- const baseCost = BigInt(rawBaseCost);
4710
- const mintValueRaw = baseCost + ctx.operatorTip;
4711
- const mintValue = withBuffer(mintValueRaw);
4712
- const approvals = [];
4713
- const steps = [];
4714
- {
4715
- const erc20 = new ethers.Contract(baseToken, IERC20_default, ctx.client.getL1Signer());
4716
- const allowance = await wrapAs3(
4717
- "RPC",
4718
- OP_DEPOSITS.ethNonBase.allowanceBase,
4719
- () => erc20.allowance(ctx.sender, ctx.l1AssetRouter),
4720
- {
4721
- ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
4722
- message: "Failed to read base-token allowance."
4422
+ if (allowance < mintValue) {
4423
+ approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
4424
+ steps.push({
4425
+ key: `approve:${baseToken}`,
4426
+ kind: "approve",
4427
+ description: `Approve base token for fees (mintValue)`,
4428
+ tx: {
4429
+ to: baseToken,
4430
+ data: erc20Base.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
4431
+ from: ctx.sender,
4432
+ ...ctx.gasOverrides
4723
4433
  }
4724
- );
4725
- if (allowance < mintValue) {
4726
- approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
4727
- const data = erc20.interface.encodeFunctionData("approve", [
4728
- ctx.l1AssetRouter,
4729
- mintValue
4730
- ]);
4731
- steps.push({
4732
- key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
4733
- kind: "approve",
4734
- description: `Approve base token for mintValue`,
4735
- tx: { to: baseToken, data, from: ctx.sender, ...txOverrides }
4736
- });
4737
- }
4434
+ });
4738
4435
  }
4739
4436
  const secondBridgeCalldata = await wrapAs3(
4740
4437
  "INTERNAL",
@@ -4748,92 +4445,78 @@ function routeEthNonBase() {
4748
4445
  }
4749
4446
  }
4750
4447
  );
4751
- const outer = {
4448
+ const requestStruct = {
4752
4449
  chainId: ctx.chainIdL2,
4753
4450
  mintValue,
4754
- l2Value: 0n,
4755
- l2GasLimit: ctx.l2GasLimit,
4451
+ l2Value: p.amount,
4452
+ l2GasLimit: l2GasParams.gasLimit,
4756
4453
  l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
4757
4454
  refundRecipient: ctx.refundRecipient,
4758
4455
  secondBridgeAddress: ctx.l1AssetRouter,
4759
4456
  secondBridgeValue: p.amount,
4760
4457
  secondBridgeCalldata
4761
4458
  };
4762
- const dataTwo = new ethers.Contract(
4763
- ctx.bridgehub,
4764
- IBridgehub_default,
4765
- ctx.client.l1
4766
- ).interface.encodeFunctionData("requestL2TransactionTwoBridges", [outer]);
4767
- let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
4768
- const bridgeTx = {
4459
+ const bridgehub = await ctx.contracts.bridgehub();
4460
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
4461
+ requestStruct
4462
+ ]);
4463
+ const l1TxCandidate = {
4769
4464
  to: ctx.bridgehub,
4770
- data: dataTwo,
4771
- value: p.amount,
4772
- // base ≠ ETH ⇒ msg.value == secondBridgeValue
4773
- from: ctx.sender,
4774
- ...txOverrides
4775
- };
4776
- if (overrideGasLimit != null) {
4777
- bridgeTx.gasLimit = overrideGasLimit;
4778
- resolvedL1GasLimit = overrideGasLimit;
4779
- } else {
4780
- try {
4781
- const est = await wrapAs3(
4782
- "RPC",
4783
- OP_DEPOSITS.ethNonBase.estGas,
4784
- () => ctx.client.l1.estimateGas(bridgeTx),
4785
- {
4786
- ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
4787
- message: "Failed to estimate gas for Bridgehub request."
4788
- }
4789
- );
4790
- const buffered = BigInt(est) * 115n / 100n;
4791
- bridgeTx.gasLimit = buffered;
4792
- resolvedL1GasLimit = buffered;
4793
- } catch {
4794
- }
4465
+ data,
4466
+ value: p.amount,
4467
+ // base ≠ ETH ⇒ msg.value == secondBridgeValue
4468
+ from: ctx.sender,
4469
+ ...ctx.gasOverrides
4470
+ };
4471
+ const l1GasParams = await quoteL1Gas2({
4472
+ ctx,
4473
+ tx: l1TxCandidate,
4474
+ overrides: ctx.gasOverrides,
4475
+ fallbackGasLimit: SAFE_L1_BRIDGE_GAS
4476
+ });
4477
+ if (l1GasParams) {
4478
+ l1TxCandidate.gasLimit = l1GasParams.gasLimit;
4479
+ l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
4480
+ l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
4795
4481
  }
4796
4482
  steps.push({
4797
4483
  key: "bridgehub:two-bridges:eth-nonbase",
4798
4484
  kind: "bridgehub:two-bridges",
4799
4485
  description: "Bridge ETH (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
4800
- tx: bridgeTx
4486
+ tx: l1TxCandidate
4487
+ });
4488
+ const fees = buildFeeBreakdown({
4489
+ feeToken: baseToken,
4490
+ l1Gas: l1GasParams,
4491
+ l2Gas: l2GasParams,
4492
+ l2BaseCost: baseCost,
4493
+ operatorTip: ctx.operatorTip,
4494
+ mintValue
4801
4495
  });
4802
4496
  return {
4803
4497
  steps,
4804
4498
  approvals,
4805
- quoteExtras: { baseCost, mintValue, l1GasLimit: resolvedL1GasLimit }
4499
+ fees
4806
4500
  };
4807
4501
  }
4808
4502
  };
4809
4503
  }
4810
4504
  var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
4811
- var BASE_COST_BUFFER_BPS2 = 100n;
4812
- var BPS2 = 10000n;
4813
- var withBuffer2 = (x) => x * (BPS2 + BASE_COST_BUFFER_BPS2) / BPS2;
4814
4505
  function routeErc20Base() {
4815
4506
  return {
4816
4507
  async preflight(p, ctx) {
4508
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
4817
4509
  await wrapAs4(
4818
4510
  "VALIDATION",
4819
4511
  OP_DEPOSITS.base.assertErc20Asset,
4820
4512
  () => {
4821
- if (isETH(p.token)) {
4513
+ if (resolved?.kind === "eth" || isETH(p.token)) {
4822
4514
  throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
4823
4515
  }
4824
4516
  },
4825
4517
  { ctx: { token: p.token } }
4826
4518
  );
4827
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4828
- const baseToken = await wrapAs4(
4829
- "CONTRACT",
4830
- OP_DEPOSITS.base.baseToken,
4831
- () => bh.baseToken(ctx.chainIdL2),
4832
- {
4833
- ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
4834
- message: "Failed to read base token."
4835
- }
4836
- );
4519
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4837
4520
  await wrapAs4(
4838
4521
  "VALIDATION",
4839
4522
  OP_DEPOSITS.base.assertMatchesBase,
@@ -4847,41 +4530,27 @@ function routeErc20Base() {
4847
4530
  return;
4848
4531
  },
4849
4532
  async build(p, ctx) {
4850
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4851
- const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
4852
- const txOverrides = overrideGasLimit != null ? { ...txFeeOverrides, gasLimit: overrideGasLimit } : txFeeOverrides;
4853
- let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
4854
- const baseToken = await wrapAs4(
4855
- "CONTRACT",
4856
- OP_DEPOSITS.base.baseToken,
4857
- () => bh.baseToken(ctx.chainIdL2),
4858
- {
4859
- ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
4860
- message: "Failed to read base token."
4861
- }
4862
- );
4863
- const rawBaseCost = await wrapAs4(
4864
- "RPC",
4865
- OP_DEPOSITS.base.baseCost,
4866
- () => bh.l2TransactionBaseCost(
4867
- ctx.chainIdL2,
4868
- gasPriceForBaseCost,
4869
- ctx.l2GasLimit,
4870
- ctx.gasPerPubdata
4871
- ),
4872
- {
4873
- ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
4874
- message: "Could not fetch L2 base cost from Bridgehub."
4875
- }
4876
- );
4877
- const baseCost = BigInt(rawBaseCost);
4878
- const l2Value = p.amount;
4879
- const rawMintValue = baseCost + ctx.operatorTip + l2Value;
4880
- const mintValue = withBuffer2(rawMintValue);
4533
+ const l1Signer = ctx.client.getL1Signer();
4534
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4535
+ const l2TxModel = {
4536
+ to: p.to ?? ctx.sender,
4537
+ from: ctx.sender,
4538
+ data: "0x",
4539
+ value: 0n
4540
+ };
4541
+ const l2GasParams = await quoteL2Gas2({
4542
+ ctx,
4543
+ route: "erc20-base",
4544
+ l2TxForModeling: l2TxModel,
4545
+ overrideGasLimit: ctx.l2GasLimit
4546
+ });
4547
+ if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
4548
+ const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
4549
+ const mintValue = baseCost + ctx.operatorTip + p.amount;
4881
4550
  const approvals = [];
4882
4551
  const steps = [];
4883
4552
  {
4884
- const erc20 = new ethers.Contract(baseToken, IERC20_default, ctx.client.getL1Signer());
4553
+ const erc20 = new ethers.Contract(baseToken, IERC20_default, l1Signer);
4885
4554
  const allowance = await wrapAs4(
4886
4555
  "RPC",
4887
4556
  OP_DEPOSITS.base.allowance,
@@ -4893,75 +4562,350 @@ function routeErc20Base() {
4893
4562
  );
4894
4563
  if (allowance < mintValue) {
4895
4564
  approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
4896
- const data2 = erc20.interface.encodeFunctionData("approve", [
4897
- ctx.l1AssetRouter,
4898
- mintValue
4899
- ]);
4900
4565
  steps.push({
4901
4566
  key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
4902
4567
  kind: "approve",
4903
4568
  description: "Approve base token for mintValue",
4904
- tx: { to: baseToken, data: data2, from: ctx.sender, ...txOverrides }
4569
+ tx: {
4570
+ to: baseToken,
4571
+ data: erc20.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
4572
+ from: ctx.sender,
4573
+ ...ctx.gasOverrides
4574
+ }
4905
4575
  });
4906
4576
  }
4907
4577
  }
4908
- const req = buildDirectRequestStruct({
4578
+ const requestStruct = buildDirectRequestStruct({
4909
4579
  chainId: ctx.chainIdL2,
4910
4580
  mintValue,
4911
- l2GasLimit: ctx.l2GasLimit,
4581
+ l2GasLimit: l2GasParams.gasLimit,
4912
4582
  gasPerPubdata: ctx.gasPerPubdata,
4913
4583
  refundRecipient: ctx.refundRecipient,
4914
4584
  l2Contract: p.to ?? ctx.sender,
4915
- l2Value
4585
+ l2Value: p.amount
4916
4586
  });
4917
- const data = new ethers.Contract(
4918
- ctx.bridgehub,
4919
- IBridgehub_default,
4920
- ctx.client.l1
4921
- ).interface.encodeFunctionData("requestL2TransactionDirect", [req]);
4922
- const tx = {
4587
+ const bridgehub = await ctx.contracts.bridgehub();
4588
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
4589
+ requestStruct
4590
+ ]);
4591
+ const l1TxCandidate = {
4923
4592
  to: ctx.bridgehub,
4924
4593
  data,
4925
4594
  value: 0n,
4926
4595
  // base token is ERC-20 ⇒ msg.value MUST be 0
4927
4596
  from: ctx.sender,
4928
- ...txOverrides
4597
+ ...ctx.gasOverrides
4929
4598
  };
4930
- if (overrideGasLimit != null) {
4931
- tx.gasLimit = overrideGasLimit;
4932
- resolvedL1GasLimit = overrideGasLimit;
4933
- } else {
4934
- try {
4935
- const est = await wrapAs4(
4936
- "RPC",
4937
- OP_DEPOSITS.base.estGas,
4938
- () => ctx.client.l1.estimateGas(tx),
4939
- {
4940
- ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
4941
- message: "Failed to estimate gas for Bridgehub request."
4942
- }
4943
- );
4944
- const buffered = BigInt(est) * 115n / 100n;
4945
- tx.gasLimit = buffered;
4946
- resolvedL1GasLimit = buffered;
4947
- } catch {
4948
- }
4599
+ const l1GasParams = await quoteL1Gas2({
4600
+ ctx,
4601
+ tx: l1TxCandidate,
4602
+ overrides: ctx.gasOverrides,
4603
+ fallbackGasLimit: SAFE_L1_BRIDGE_GAS
4604
+ });
4605
+ if (l1GasParams) {
4606
+ l1TxCandidate.gasLimit = l1GasParams.gasLimit;
4607
+ l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
4608
+ l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
4949
4609
  }
4950
4610
  steps.push({
4951
4611
  key: "bridgehub:direct:erc20-base",
4952
4612
  kind: "bridgehub:direct",
4953
4613
  description: "Bridge base ERC-20 via Bridgehub.requestL2TransactionDirect",
4954
- tx
4614
+ tx: l1TxCandidate
4615
+ });
4616
+ const fees = buildFeeBreakdown({
4617
+ feeToken: baseToken,
4618
+ l1Gas: l1GasParams,
4619
+ l2Gas: l2GasParams,
4620
+ l2BaseCost: baseCost,
4621
+ operatorTip: ctx.operatorTip,
4622
+ mintValue
4955
4623
  });
4956
4624
  return {
4957
4625
  steps,
4958
4626
  approvals,
4959
- quoteExtras: { baseCost, mintValue, l1GasLimit: resolvedL1GasLimit }
4627
+ fees
4960
4628
  };
4961
4629
  }
4962
4630
  };
4963
4631
  }
4964
4632
 
4633
+ // src/core/codec/ntv.ts
4634
+ function createNTVCodec(deps) {
4635
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
4636
+ const encoded = deps.encode(
4637
+ ["uint256", "address", "address"],
4638
+ [originChainId, ntvAddress, tokenAddress]
4639
+ );
4640
+ return deps.keccak256(encoded);
4641
+ }
4642
+ return {
4643
+ encodeAssetId
4644
+ };
4645
+ }
4646
+
4647
+ // src/adapters/ethers/resources/tokens/tokens.ts
4648
+ var { wrapAs: wrapAs5 } = createErrorHandlers("tokens");
4649
+ var abi = ethers.AbiCoder.defaultAbiCoder();
4650
+ var ntvCodec = createNTVCodec({
4651
+ encode: (types, values) => abi.encode(types, values),
4652
+ keccak256: (data) => ethers.ethers.keccak256(data)
4653
+ });
4654
+ function createTokensResource(client) {
4655
+ let l2NtvL1ChainIdPromise = null;
4656
+ let baseTokenAssetIdPromise = null;
4657
+ let wethL1Promise = null;
4658
+ let wethL2Promise = null;
4659
+ async function getL1ChainId() {
4660
+ if (!l2NtvL1ChainIdPromise) {
4661
+ l2NtvL1ChainIdPromise = wrapAs5("INTERNAL", "getL1ChainId", async () => {
4662
+ const { l2NativeTokenVault } = await client.contracts();
4663
+ const chainId = await l2NativeTokenVault.L1_CHAIN_ID();
4664
+ return chainId;
4665
+ });
4666
+ }
4667
+ return l2NtvL1ChainIdPromise;
4668
+ }
4669
+ async function getBaseTokenAssetId() {
4670
+ if (!baseTokenAssetIdPromise) {
4671
+ baseTokenAssetIdPromise = wrapAs5("INTERNAL", "baseTokenAssetId", async () => {
4672
+ const { l2NativeTokenVault } = await client.contracts();
4673
+ const assetId = await l2NativeTokenVault.BASE_TOKEN_ASSET_ID();
4674
+ return assetId;
4675
+ });
4676
+ }
4677
+ return baseTokenAssetIdPromise;
4678
+ }
4679
+ async function getWethL1() {
4680
+ if (!wethL1Promise) {
4681
+ wethL1Promise = wrapAs5("INTERNAL", "wethL1", async () => {
4682
+ const { l1NativeTokenVault } = await client.contracts();
4683
+ const weth = await l1NativeTokenVault.WETH_TOKEN();
4684
+ return weth;
4685
+ });
4686
+ }
4687
+ return wethL1Promise;
4688
+ }
4689
+ async function getWethL2() {
4690
+ if (!wethL2Promise) {
4691
+ wethL2Promise = wrapAs5("INTERNAL", "wethL2", async () => {
4692
+ const { l2NativeTokenVault } = await client.contracts();
4693
+ const weth = await l2NativeTokenVault.WETH_TOKEN();
4694
+ return weth;
4695
+ });
4696
+ }
4697
+ return wethL2Promise;
4698
+ }
4699
+ async function toL2Address(l1Token) {
4700
+ return wrapAs5("CONTRACT", "tokens.toL2Address", async () => {
4701
+ const normalized = normalizeL1Token(l1Token);
4702
+ const { chainId } = await client.l2.getNetwork();
4703
+ const baseToken = await client.baseToken(BigInt(chainId));
4704
+ if (isAddressEq(normalized, baseToken)) {
4705
+ return L2_BASE_TOKEN_ADDRESS;
4706
+ }
4707
+ const { l2NativeTokenVault } = await client.contracts();
4708
+ const l2Token = await l2NativeTokenVault.l2TokenAddress(normalized);
4709
+ return l2Token;
4710
+ });
4711
+ }
4712
+ async function toL1Address(l2Token) {
4713
+ return wrapAs5("CONTRACT", "tokens.toL1Address", async () => {
4714
+ if (isAddressEq(l2Token, ETH_ADDRESS)) {
4715
+ return ETH_ADDRESS;
4716
+ }
4717
+ if (isAddressEq(l2Token, L2_BASE_TOKEN_ADDRESS)) {
4718
+ const { chainId } = await client.l2.getNetwork();
4719
+ return await client.baseToken(BigInt(chainId));
4720
+ }
4721
+ const { l2AssetRouter } = await client.contracts();
4722
+ const l1Token = await l2AssetRouter.l1TokenAddress(l2Token);
4723
+ return l1Token;
4724
+ });
4725
+ }
4726
+ async function assetIdOfL1(l1Token) {
4727
+ return wrapAs5("CONTRACT", "tokens.assetIdOfL1", async () => {
4728
+ const normalized = normalizeL1Token(l1Token);
4729
+ const { l1NativeTokenVault } = await client.contracts();
4730
+ const assetId = await l1NativeTokenVault.assetId(normalized);
4731
+ return assetId;
4732
+ });
4733
+ }
4734
+ async function assetIdOfL2(l2Token) {
4735
+ return wrapAs5("CONTRACT", "tokens.assetIdOfL2", async () => {
4736
+ const { l2NativeTokenVault } = await client.contracts();
4737
+ const assetId = await l2NativeTokenVault.assetId(l2Token);
4738
+ return assetId;
4739
+ });
4740
+ }
4741
+ async function l2TokenFromAssetId(assetId) {
4742
+ return wrapAs5("CONTRACT", "tokens.l2TokenFromAssetId", async () => {
4743
+ const { l2NativeTokenVault } = await client.contracts();
4744
+ const tokenAddr = await l2NativeTokenVault.tokenAddress(assetId);
4745
+ return tokenAddr;
4746
+ });
4747
+ }
4748
+ async function l1TokenFromAssetId(assetId) {
4749
+ return wrapAs5("CONTRACT", "tokens.l1TokenFromAssetId", async () => {
4750
+ const { l1NativeTokenVault } = await client.contracts();
4751
+ const tokenAddr = await l1NativeTokenVault.tokenAddress(assetId);
4752
+ return tokenAddr;
4753
+ });
4754
+ }
4755
+ async function originChainId(assetId) {
4756
+ return wrapAs5("CONTRACT", "tokens.originChainId", async () => {
4757
+ const { l2NativeTokenVault } = await client.contracts();
4758
+ const chainId = await l2NativeTokenVault.originChainId(assetId);
4759
+ return chainId;
4760
+ });
4761
+ }
4762
+ async function baseTokenAssetId() {
4763
+ return getBaseTokenAssetId();
4764
+ }
4765
+ async function isChainEthBased() {
4766
+ return wrapAs5("CONTRACT", "tokens.isChainEthBased", async () => {
4767
+ const baseAssetId = await getBaseTokenAssetId();
4768
+ const l1ChainId = await getL1ChainId();
4769
+ const ethAssetId = ntvCodec.encodeAssetId(
4770
+ l1ChainId,
4771
+ L2_NATIVE_TOKEN_VAULT_ADDRESS,
4772
+ ETH_ADDRESS
4773
+ );
4774
+ return hexEq(baseAssetId, ethAssetId);
4775
+ });
4776
+ }
4777
+ async function wethL1() {
4778
+ return getWethL1();
4779
+ }
4780
+ async function wethL2() {
4781
+ return getWethL2();
4782
+ }
4783
+ async function computeL2BridgedAddress(args) {
4784
+ return wrapAs5("CONTRACT", "tokens.computeL2BridgedAddress", async () => {
4785
+ const normalized = normalizeL1Token(args.l1Token);
4786
+ const { l2NativeTokenVault } = await client.contracts();
4787
+ const predicted = await l2NativeTokenVault.calculateCreate2TokenAddress(
4788
+ args.originChainId,
4789
+ normalized
4790
+ );
4791
+ return predicted;
4792
+ });
4793
+ }
4794
+ async function resolve(ref, opts) {
4795
+ return wrapAs5("CONTRACT", "tokens.resolve", async () => {
4796
+ let chain;
4797
+ let address;
4798
+ if (typeof ref === "string") {
4799
+ chain = opts?.chain ?? "l1";
4800
+ address = ref;
4801
+ } else {
4802
+ chain = ref.chain;
4803
+ address = ref.address;
4804
+ }
4805
+ let l1;
4806
+ let l2;
4807
+ if (chain === "l1") {
4808
+ l1 = normalizeL1Token(address);
4809
+ l2 = await toL2Address(address);
4810
+ } else {
4811
+ l2 = address;
4812
+ l1 = await toL1Address(address);
4813
+ }
4814
+ const assetId = await assetIdOfL1(l1);
4815
+ const originChainIdVal = await originChainId(assetId);
4816
+ const [baseAssetId, wethL1Addr, wethL2Addr, ethBased] = await Promise.all([
4817
+ baseTokenAssetId(),
4818
+ wethL1(),
4819
+ wethL2(),
4820
+ isChainEthBased()
4821
+ ]);
4822
+ let kind;
4823
+ if (isAddressEq(l1, ETH_ADDRESS)) {
4824
+ kind = "eth";
4825
+ } else if (hexEq(assetId, baseAssetId)) {
4826
+ kind = "base";
4827
+ } else {
4828
+ kind = "erc20";
4829
+ }
4830
+ return {
4831
+ kind,
4832
+ l1,
4833
+ l2,
4834
+ assetId,
4835
+ originChainId: originChainIdVal,
4836
+ isChainEthBased: ethBased,
4837
+ baseTokenAssetId: baseAssetId,
4838
+ wethL1: wethL1Addr,
4839
+ wethL2: wethL2Addr
4840
+ };
4841
+ });
4842
+ }
4843
+ return {
4844
+ resolve,
4845
+ toL2Address,
4846
+ toL1Address,
4847
+ assetIdOfL1,
4848
+ assetIdOfL2,
4849
+ l2TokenFromAssetId,
4850
+ l1TokenFromAssetId,
4851
+ originChainId,
4852
+ baseTokenAssetId,
4853
+ isChainEthBased,
4854
+ wethL1,
4855
+ wethL2,
4856
+ computeL2BridgedAddress
4857
+ };
4858
+ }
4859
+
4860
+ // src/adapters/ethers/resources/contracts/contracts.ts
4861
+ function createContractsResource(client) {
4862
+ async function addresses() {
4863
+ return client.ensureAddresses();
4864
+ }
4865
+ async function instances() {
4866
+ return client.contracts();
4867
+ }
4868
+ async function bridgehub() {
4869
+ const { bridgehub: bridgehub2 } = await instances();
4870
+ return bridgehub2;
4871
+ }
4872
+ async function l1AssetRouter() {
4873
+ const { l1AssetRouter: l1AssetRouter2 } = await instances();
4874
+ return l1AssetRouter2;
4875
+ }
4876
+ async function l1NativeTokenVault() {
4877
+ const { l1NativeTokenVault: l1NativeTokenVault2 } = await instances();
4878
+ return l1NativeTokenVault2;
4879
+ }
4880
+ async function l1Nullifier() {
4881
+ const { l1Nullifier: l1Nullifier2 } = await instances();
4882
+ return l1Nullifier2;
4883
+ }
4884
+ async function l2AssetRouter() {
4885
+ const { l2AssetRouter: l2AssetRouter2 } = await instances();
4886
+ return l2AssetRouter2;
4887
+ }
4888
+ async function l2NativeTokenVault() {
4889
+ const { l2NativeTokenVault: l2NativeTokenVault2 } = await instances();
4890
+ return l2NativeTokenVault2;
4891
+ }
4892
+ async function l2BaseTokenSystem() {
4893
+ const { l2BaseTokenSystem: l2BaseTokenSystem2 } = await instances();
4894
+ return l2BaseTokenSystem2;
4895
+ }
4896
+ return {
4897
+ addresses,
4898
+ instances,
4899
+ bridgehub,
4900
+ l1AssetRouter,
4901
+ l1NativeTokenVault,
4902
+ l1Nullifier,
4903
+ l2AssetRouter,
4904
+ l2NativeTokenVault,
4905
+ l2BaseTokenSystem
4906
+ };
4907
+ }
4908
+
4965
4909
  // src/adapters/ethers/resources/deposits/index.ts
4966
4910
  var { wrap, toResult } = createErrorHandlers("deposits");
4967
4911
  var ROUTES = {
@@ -4970,42 +4914,26 @@ var ROUTES = {
4970
4914
  "erc20-nonbase": routeErc20NonBase(),
4971
4915
  "erc20-base": routeErc20Base()
4972
4916
  };
4973
- function createDepositsResource(client) {
4917
+ function createDepositsResource(client, tokens, contracts) {
4918
+ const tokensResource = tokens ?? createTokensResource(client);
4919
+ const contractsResource = contracts ?? createContractsResource(client);
4974
4920
  async function buildPlan(p) {
4975
- const ctx = await commonCtx(p, client);
4921
+ const ctx = await commonCtx(p, client, tokensResource, contractsResource);
4976
4922
  const route = ctx.route;
4977
4923
  await ROUTES[route].preflight?.(p, ctx);
4978
- const { steps, approvals, quoteExtras } = await ROUTES[route].build(p, ctx);
4979
- const { baseCost, mintValue } = quoteExtras;
4980
- const fallbackGasLimit = quoteExtras.l1GasLimit;
4981
- const resolveGasLimit = () => {
4982
- if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
4983
- for (let i = steps.length - 1; i >= 0; i--) {
4984
- const candidate = steps[i].tx.gasLimit;
4985
- if (candidate == null) continue;
4986
- if (typeof candidate === "bigint") return candidate;
4987
- try {
4988
- return BigInt(candidate.toString());
4989
- } catch {
4990
- }
4991
- }
4992
- if (fallbackGasLimit != null) return fallbackGasLimit;
4993
- return ctx.l2GasLimit;
4994
- };
4995
- const gasLimit = resolveGasLimit();
4924
+ const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
4996
4925
  return {
4997
4926
  route: ctx.route,
4998
4927
  summary: {
4999
4928
  route: ctx.route,
5000
4929
  approvalsNeeded: approvals,
5001
- baseCost,
5002
- mintValue,
5003
- gasPerPubdata: ctx.gasPerPubdata,
5004
- fees: {
5005
- gasLimit,
5006
- maxFeePerGas: ctx.fee.maxFeePerGas,
5007
- maxPriorityFeePerGas: ctx.fee.maxPriorityFeePerGas
5008
- }
4930
+ amounts: {
4931
+ transfer: { token: p.token, amount: p.amount }
4932
+ },
4933
+ fees,
4934
+ // Legacy fields (maintained for backward compatibility)
4935
+ baseCost: fees.l2?.baseCost,
4936
+ mintValue: fees.mintValue
5009
4937
  },
5010
4938
  steps
5011
4939
  };
@@ -5074,7 +5002,7 @@ function createDepositsResource(client) {
5074
5002
  step.tx.maxPriorityFeePerGas = overrides.maxPriorityFeePerGas;
5075
5003
  }
5076
5004
  }
5077
- if (!step.tx.gasLimit) {
5005
+ if (!p.l1TxOverrides?.gasLimit) {
5078
5006
  try {
5079
5007
  const est = await client.l1.estimateGas(step.tx);
5080
5008
  step.tx.gasLimit = BigInt(est) * 115n / 100n;
@@ -5265,28 +5193,12 @@ function normalizeTokenForRouting(token) {
5265
5193
  function pickWithdrawRoute(args) {
5266
5194
  const tokenNorm = normalizeTokenForRouting(args.token);
5267
5195
  const isL2BaseAlias = tokenNorm.toLowerCase() === L2_BASE_TOKEN_ADDRESS.toLowerCase();
5268
- if (isL2BaseAlias) return args.baseIsEth ? "eth-base" : "eth-nonbase";
5196
+ if (isL2BaseAlias) return "base";
5269
5197
  return "erc20-nonbase";
5270
5198
  }
5271
- async function ntvBaseAssetId(l2, ntv) {
5272
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
5273
- return await c.BASE_TOKEN_ASSET_ID();
5274
- }
5275
- async function ntvL1ChainId(l2, ntv) {
5276
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
5277
- return await c.L1_CHAIN_ID();
5278
- }
5279
- async function isEthBasedChain(l2, ntv) {
5280
- const [baseAssetId, l1ChainId] = await Promise.all([
5281
- ntvBaseAssetId(l2, ntv),
5282
- ntvL1ChainId(l2, ntv)
5283
- ]);
5284
- const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
5285
- return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
5286
- }
5287
5199
 
5288
5200
  // src/adapters/ethers/resources/withdrawals/context.ts
5289
- async function commonCtx2(p, client) {
5201
+ async function commonCtx2(p, client, tokens, contracts) {
5290
5202
  const sender = await client.signer.getAddress();
5291
5203
  const {
5292
5204
  bridgehub,
@@ -5295,16 +5207,21 @@ async function commonCtx2(p, client) {
5295
5207
  l2AssetRouter,
5296
5208
  l2NativeTokenVault,
5297
5209
  l2BaseTokenSystem
5298
- } = await client.ensureAddresses();
5210
+ } = await contracts.addresses();
5299
5211
  const { chainId } = await client.l2.getNetwork();
5300
5212
  const chainIdL2 = BigInt(chainId);
5301
- const baseIsEth = await isEthBasedChain(client.l2, l2NativeTokenVault);
5302
- const fee = await getL2FeeOverrides(client, p.l2TxOverrides);
5303
- const route = pickWithdrawRoute({ token: p.token, baseIsEth });
5304
- const l2GasLimit = p.l2GasLimit ?? 300000n;
5305
- const gasBufferPct = 15;
5213
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l2" });
5214
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
5215
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
5216
+ const baseIsEth = resolvedToken.isChainEthBased;
5217
+ const route = pickWithdrawRoute({ token: p.token});
5306
5218
  return {
5307
5219
  client,
5220
+ tokens,
5221
+ contracts,
5222
+ resolvedToken,
5223
+ baseTokenAssetId,
5224
+ baseTokenL1,
5308
5225
  bridgehub,
5309
5226
  chainIdL2,
5310
5227
  sender,
@@ -5315,29 +5232,111 @@ async function commonCtx2(p, client) {
5315
5232
  l2NativeTokenVault,
5316
5233
  l2BaseTokenSystem,
5317
5234
  baseIsEth,
5318
- l2GasLimit,
5319
- gasBufferPct,
5320
- fee
5235
+ gasOverrides: p.l2TxOverrides
5236
+ };
5237
+ }
5238
+
5239
+ // src/core/resources/withdrawals/gas.ts
5240
+ function makeGasQuote2(p) {
5241
+ return {
5242
+ gasLimit: p.gasLimit,
5243
+ maxFeePerGas: p.maxFeePerGas,
5244
+ maxPriorityFeePerGas: p.maxPriorityFeePerGas,
5245
+ maxCost: p.gasLimit * p.maxFeePerGas
5246
+ };
5247
+ }
5248
+ async function fetchFees2(estimator) {
5249
+ try {
5250
+ const fees = await estimator.estimateFeesPerGas();
5251
+ if (fees.maxFeePerGas != null) {
5252
+ return {
5253
+ maxFeePerGas: fees.maxFeePerGas,
5254
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
5255
+ };
5256
+ }
5257
+ if (fees.gasPrice != null) {
5258
+ return {
5259
+ maxFeePerGas: fees.gasPrice,
5260
+ maxPriorityFeePerGas: 0n
5261
+ };
5262
+ }
5263
+ } catch {
5264
+ }
5265
+ try {
5266
+ const gp = await estimator.getGasPrice();
5267
+ return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
5268
+ } catch {
5269
+ return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
5270
+ }
5271
+ }
5272
+ async function quoteL2Gas3(input) {
5273
+ const { estimator, tx, overrides } = input;
5274
+ const market = await fetchFees2(estimator);
5275
+ const o = overrides;
5276
+ const maxFeePerGas = o?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : market.maxFeePerGas);
5277
+ const maxPriorityFeePerGas = o?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : market.maxPriorityFeePerGas);
5278
+ const explicitGasLimit = o?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
5279
+ if (explicitGasLimit != null) {
5280
+ return makeGasQuote2({
5281
+ gasLimit: explicitGasLimit,
5282
+ maxFeePerGas,
5283
+ maxPriorityFeePerGas
5284
+ });
5285
+ }
5286
+ try {
5287
+ const est = await estimator.estimateGas(tx);
5288
+ const buffered = BigInt(est) * (100n + BUFFER) / 100n;
5289
+ return makeGasQuote2({
5290
+ gasLimit: buffered,
5291
+ maxFeePerGas,
5292
+ maxPriorityFeePerGas
5293
+ });
5294
+ } catch (err) {
5295
+ console.warn("Failed to estimate L2 gas for withdrawal.", err);
5296
+ return void 0;
5297
+ }
5298
+ }
5299
+
5300
+ // src/adapters/ethers/resources/withdrawals/services/gas.ts
5301
+ async function quoteL2Gas4(input) {
5302
+ const { ctx, tx } = input;
5303
+ const estimator = ethersToGasEstimator(ctx.client.l2);
5304
+ return quoteL2Gas3({
5305
+ estimator,
5306
+ tx: toCoreTx(tx),
5307
+ overrides: ctx.gasOverrides
5308
+ });
5309
+ }
5310
+
5311
+ // src/adapters/ethers/resources/withdrawals/services/fees.ts
5312
+ function buildFeeBreakdown2(p) {
5313
+ const l2Total = p.l2Gas?.maxCost ?? 0n;
5314
+ const l2 = {
5315
+ total: l2Total,
5316
+ gasLimit: p.l2Gas?.gasLimit ?? 0n,
5317
+ maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
5318
+ maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas
5319
+ };
5320
+ return {
5321
+ token: p.feeToken,
5322
+ maxTotal: l2Total,
5323
+ l2
5321
5324
  };
5322
5325
  }
5323
- var { wrapAs: wrapAs5 } = createErrorHandlers("withdrawals");
5326
+
5327
+ // src/adapters/ethers/resources/withdrawals/routes/eth.ts
5328
+ var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
5324
5329
  function routeEthBase() {
5325
5330
  return {
5326
5331
  async build(p, ctx) {
5327
5332
  const steps = [];
5328
- const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
5329
- const base = new ethers.Contract(
5330
- L2_BASE_TOKEN_ADDRESS,
5331
- new ethers.Interface(IBaseToken_default),
5332
- ctx.client.l2
5333
- );
5334
- const toL1 = p.to ?? ctx.sender;
5335
- const data = await wrapAs5(
5333
+ const base = await ctx.contracts.l2BaseTokenSystem();
5334
+ const data = await wrapAs6(
5336
5335
  "INTERNAL",
5337
5336
  OP_WITHDRAWALS.eth.encodeWithdraw,
5338
- () => Promise.resolve(base.interface.encodeFunctionData("withdraw", [toL1])),
5337
+ () => Promise.resolve(base.interface.encodeFunctionData("withdraw", [p.to ?? ctx.sender])),
5339
5338
  {
5340
- ctx: { where: "L2BaseToken.withdraw", to: toL1 },
5339
+ ctx: { where: "L2BaseToken.withdraw", to: p.to ?? ctx.sender },
5341
5340
  message: "Failed to encode ETH withdraw calldata."
5342
5341
  }
5343
5342
  );
@@ -5345,38 +5344,29 @@ function routeEthBase() {
5345
5344
  to: L2_BASE_TOKEN_ADDRESS,
5346
5345
  data,
5347
5346
  from: ctx.sender,
5348
- value: p.amount,
5349
- maxFeePerGas,
5350
- maxPriorityFeePerGas
5347
+ value: p.amount
5351
5348
  };
5352
- if (overrideGasLimit != null) {
5353
- tx.gasLimit = overrideGasLimit;
5354
- } else {
5355
- try {
5356
- const est = await wrapAs5(
5357
- "RPC",
5358
- OP_WITHDRAWALS.eth.estGas,
5359
- () => ctx.client.l2.estimateGas(tx),
5360
- {
5361
- ctx: { where: "l2.estimateGas", to: L2_BASE_TOKEN_ADDRESS },
5362
- message: "Failed to estimate gas for L2 ETH withdraw."
5363
- }
5364
- );
5365
- tx.gasLimit = BigInt(est) * 115n / 100n;
5366
- } catch {
5367
- }
5368
- }
5349
+ const gas = await quoteL2Gas4({ ctx, tx });
5350
+ if (gas) {
5351
+ tx.gasLimit = gas.gasLimit;
5352
+ tx.maxFeePerGas = gas.maxFeePerGas;
5353
+ tx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
5354
+ }
5355
+ const fees = buildFeeBreakdown2({
5356
+ feeToken: L2_BASE_TOKEN_ADDRESS,
5357
+ l2Gas: gas
5358
+ });
5369
5359
  steps.push({
5370
5360
  key: "l2-base-token:withdraw",
5371
5361
  kind: "l2-base-token:withdraw",
5372
5362
  description: "Withdraw ETH via L2 Base Token System",
5373
5363
  tx
5374
5364
  });
5375
- return { steps, approvals: [], quoteExtras: {} };
5365
+ return { steps, approvals: [], fees };
5376
5366
  }
5377
5367
  };
5378
5368
  }
5379
- var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
5369
+ var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
5380
5370
  var SIG = {
5381
5371
  withdraw: "withdraw(bytes32,bytes)"
5382
5372
  };
@@ -5385,10 +5375,8 @@ function routeErc20NonBase2() {
5385
5375
  async build(p, ctx) {
5386
5376
  const steps = [];
5387
5377
  const approvals = [];
5388
- const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
5389
- const txOverrides = overrideGasLimit != null ? { maxFeePerGas, maxPriorityFeePerGas, gasLimit: overrideGasLimit } : { maxFeePerGas, maxPriorityFeePerGas };
5390
5378
  const erc20 = new ethers.Contract(p.token, IERC20_default, ctx.client.getL2Signer());
5391
- const current = await wrapAs6(
5379
+ const current = await wrapAs7(
5392
5380
  "CONTRACT",
5393
5381
  OP_WITHDRAWALS.erc20.allowance,
5394
5382
  () => erc20.allowance(ctx.sender, ctx.l2NativeTokenVault),
@@ -5408,39 +5396,51 @@ function routeErc20NonBase2() {
5408
5396
  ctx.l2NativeTokenVault,
5409
5397
  p.amount
5410
5398
  ]);
5399
+ const approveTx = {
5400
+ to: p.token,
5401
+ data,
5402
+ from: ctx.sender
5403
+ };
5404
+ const approveGas = await quoteL2Gas4({ ctx, tx: approveTx });
5405
+ if (approveGas) {
5406
+ approveTx.gasLimit = approveGas.gasLimit;
5407
+ approveTx.maxFeePerGas = approveGas.maxFeePerGas;
5408
+ approveTx.maxPriorityFeePerGas = approveGas.maxPriorityFeePerGas;
5409
+ }
5411
5410
  steps.push({
5412
5411
  key: `approve:l2:${p.token}:${ctx.l2NativeTokenVault}`,
5413
5412
  kind: "approve:l2",
5414
5413
  description: `Approve ${p.amount} to NativeTokenVault`,
5415
- tx: { to: p.token, data, from: ctx.sender, ...txOverrides }
5414
+ tx: approveTx
5416
5415
  });
5417
5416
  }
5418
- const ntv = new ethers.Contract(ctx.l2NativeTokenVault, L2NativeTokenVault_default, ctx.client.l2);
5419
- const assetId = await wrapAs6(
5417
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l2" }) : void 0);
5418
+ const assetId = resolved?.assetId ?? await wrapAs7(
5420
5419
  "CONTRACT",
5421
5420
  OP_WITHDRAWALS.erc20.ensureRegistered,
5422
- () => ntv.getFunction("ensureTokenIsRegistered").staticCall(p.token),
5421
+ async () => {
5422
+ const ntv = await ctx.contracts.l2NativeTokenVault();
5423
+ const ensured = await ntv.getFunction("ensureTokenIsRegistered").staticCall(p.token);
5424
+ return ensured;
5425
+ },
5423
5426
  {
5424
5427
  ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
5425
5428
  message: "Failed to ensure token is registered in L2NativeTokenVault."
5426
5429
  }
5427
5430
  );
5428
- const assetData = await wrapAs6(
5431
+ const assetData = await wrapAs7(
5429
5432
  "INTERNAL",
5430
5433
  OP_WITHDRAWALS.erc20.encodeAssetData,
5431
5434
  () => Promise.resolve(
5432
- ethers.AbiCoder.defaultAbiCoder().encode(
5433
- ["uint256", "address", "address"],
5434
- [p.amount, p.to ?? ctx.sender, p.token]
5435
- )
5435
+ encodeNativeTokenVaultTransferData(p.amount, p.to ?? ctx.sender, p.token)
5436
5436
  ),
5437
5437
  {
5438
5438
  ctx: { where: "AbiCoder.encode", token: p.token, to: p.to ?? ctx.sender },
5439
5439
  message: "Failed to encode burn/withdraw asset data."
5440
5440
  }
5441
5441
  );
5442
- const l2ar = new ethers.Contract(ctx.l2AssetRouter, IL2AssetRouter_default, ctx.client.l2);
5443
- const dataWithdraw = await wrapAs6(
5442
+ const l2ar = await ctx.contracts.l2AssetRouter();
5443
+ const dataWithdraw = await wrapAs7(
5444
5444
  "INTERNAL",
5445
5445
  OP_WITHDRAWALS.erc20.encodeWithdraw,
5446
5446
  () => Promise.resolve(l2ar.interface.encodeFunctionData(SIG.withdraw, [assetId, assetData])),
@@ -5452,81 +5452,25 @@ function routeErc20NonBase2() {
5452
5452
  const withdrawTx = {
5453
5453
  to: ctx.l2AssetRouter,
5454
5454
  data: dataWithdraw,
5455
- from: ctx.sender,
5456
- ...txOverrides
5455
+ from: ctx.sender
5457
5456
  };
5457
+ const withdrawGas = await quoteL2Gas4({ ctx, tx: withdrawTx });
5458
+ if (withdrawGas) {
5459
+ withdrawTx.gasLimit = withdrawGas.gasLimit;
5460
+ withdrawTx.maxFeePerGas = withdrawGas.maxFeePerGas;
5461
+ withdrawTx.maxPriorityFeePerGas = withdrawGas.maxPriorityFeePerGas;
5462
+ }
5458
5463
  steps.push({
5459
5464
  key: "l2-asset-router:withdraw",
5460
5465
  kind: "l2-asset-router:withdraw",
5461
5466
  description: "Burn on L2 & send L2\u2192L1 message",
5462
5467
  tx: withdrawTx
5463
5468
  });
5464
- return { steps, approvals, quoteExtras: {} };
5465
- }
5466
- };
5467
- }
5468
- var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
5469
- function routeEthNonBase2() {
5470
- return {
5471
- async preflight(p, ctx) {
5472
- await wrapAs7(
5473
- "VALIDATION",
5474
- OP_WITHDRAWALS.ethNonBase.assertNonEthBase,
5475
- () => {
5476
- if (p.token.toLowerCase() !== L2_BASE_TOKEN_ADDRESS.toLowerCase()) {
5477
- throw new Error("eth-nonbase route requires the L2 base-token alias (0x\u2026800A).");
5478
- }
5479
- if (ctx.baseIsEth) {
5480
- throw new Error("eth-nonbase route requires chain base \u2260 ETH.");
5481
- }
5482
- },
5483
- { ctx: { token: p.token, baseIsEth: ctx.baseIsEth } }
5484
- );
5485
- },
5486
- async build(p, ctx) {
5487
- const steps = [];
5488
- const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
5489
- const toL1 = p.to ?? ctx.sender;
5490
- const iface = new ethers.Interface(IBaseToken_default);
5491
- const data = await wrapAs7(
5492
- "INTERNAL",
5493
- OP_WITHDRAWALS.eth.encodeWithdraw,
5494
- // reuse label for base-token system call
5495
- () => Promise.resolve(iface.encodeFunctionData("withdraw", [toL1])),
5496
- { ctx: { where: "L2BaseToken.withdraw", to: toL1 } }
5497
- );
5498
- const tx = {
5499
- to: L2_BASE_TOKEN_ADDRESS,
5500
- data,
5501
- from: ctx.sender,
5502
- value: p.amount,
5503
- maxFeePerGas,
5504
- maxPriorityFeePerGas
5505
- };
5506
- if (overrideGasLimit != null) {
5507
- tx.gasLimit = overrideGasLimit;
5508
- } else {
5509
- try {
5510
- const est = await wrapAs7(
5511
- "RPC",
5512
- OP_WITHDRAWALS.eth.estGas,
5513
- () => ctx.client.l2.estimateGas(tx),
5514
- {
5515
- ctx: { where: "l2.estimateGas", to: L2_BASE_TOKEN_ADDRESS },
5516
- message: "Failed to estimate gas for L2 base-token withdraw."
5517
- }
5518
- );
5519
- tx.gasLimit = BigInt(est) * 115n / 100n;
5520
- } catch {
5521
- }
5522
- }
5523
- steps.push({
5524
- key: "l2-base-token:withdraw",
5525
- kind: "l2-base-token:withdraw",
5526
- description: "Withdraw base token via L2 Base Token System (base \u2260 ETH)",
5527
- tx
5469
+ const fees = buildFeeBreakdown2({
5470
+ feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
5471
+ l2Gas: withdrawGas
5528
5472
  });
5529
- return { steps, approvals: [], quoteExtras: {} };
5473
+ return { steps, approvals, fees };
5530
5474
  }
5531
5475
  };
5532
5476
  }
@@ -5838,45 +5782,32 @@ function createFinalizationServices(client) {
5838
5782
 
5839
5783
  // src/adapters/ethers/resources/withdrawals/index.ts
5840
5784
  var ROUTES2 = {
5841
- "eth-base": routeEthBase(),
5785
+ base: routeEthBase(),
5842
5786
  // BaseTokenSystem.withdraw, chain base = ETH
5843
- "eth-nonbase": routeEthNonBase2(),
5844
- // BaseTokenSystem.withdraw, chain base ≠ ETH
5845
5787
  "erc20-nonbase": routeErc20NonBase2()
5846
5788
  // AssetRouter.withdraw for non-base ERC-20s
5847
5789
  };
5848
- function createWithdrawalsResource(client) {
5790
+ function createWithdrawalsResource(client, tokens, contracts) {
5849
5791
  const svc = createFinalizationServices(client);
5850
5792
  const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
5793
+ const tokensResource = tokens ?? createTokensResource(client);
5794
+ const contractsResource = contracts ?? createContractsResource(client);
5851
5795
  async function buildPlan(p) {
5852
- const ctx = await commonCtx2(p, client);
5796
+ const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
5853
5797
  await ROUTES2[ctx.route].preflight?.(p, ctx);
5854
- const { steps, approvals } = await ROUTES2[ctx.route].build(p, ctx);
5855
- const resolveGasLimit = () => {
5856
- if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
5857
- for (let i = steps.length - 1; i >= 0; i--) {
5858
- const candidate = steps[i].tx.gasLimit;
5859
- if (candidate == null) continue;
5860
- if (typeof candidate === "bigint") return candidate;
5861
- try {
5862
- return BigInt(candidate.toString());
5863
- } catch {
5864
- }
5865
- }
5866
- return void 0;
5867
- };
5868
- const gasLimit = resolveGasLimit();
5869
- const summary = {
5798
+ const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
5799
+ return {
5870
5800
  route: ctx.route,
5871
- approvalsNeeded: approvals,
5872
- suggestedL2GasLimit: ctx.l2GasLimit,
5873
- fees: {
5874
- gasLimit,
5875
- maxFeePerGas: ctx.fee.maxFeePerGas,
5876
- maxPriorityFeePerGas: ctx.fee.maxPriorityFeePerGas
5877
- }
5801
+ summary: {
5802
+ route: ctx.route,
5803
+ approvalsNeeded: approvals,
5804
+ amounts: {
5805
+ transfer: { token: p.token, amount: p.amount }
5806
+ },
5807
+ fees
5808
+ },
5809
+ steps
5878
5810
  };
5879
- return { route: ctx.route, summary, steps };
5880
5811
  }
5881
5812
  const finalizeCache = /* @__PURE__ */ new Map();
5882
5813
  const quote = (p) => wrap2(
@@ -6186,57 +6117,13 @@ function createWithdrawalsResource(client) {
6186
6117
 
6187
6118
  // src/adapters/ethers/sdk.ts
6188
6119
  function createEthersSdk(client) {
6120
+ const tokens = createTokensResource(client);
6121
+ const contracts = createContractsResource(client);
6189
6122
  return {
6190
- deposits: createDepositsResource(client),
6191
- withdrawals: createWithdrawalsResource(client),
6192
- // TODO: might update to create dedicated resources for these
6193
- helpers: {
6194
- addresses: () => client.ensureAddresses(),
6195
- contracts: () => client.contracts(),
6196
- async l1AssetRouter() {
6197
- const { l1AssetRouter } = await client.contracts();
6198
- return l1AssetRouter;
6199
- },
6200
- async l1NativeTokenVault() {
6201
- const { l1NativeTokenVault } = await client.contracts();
6202
- return l1NativeTokenVault;
6203
- },
6204
- async l1Nullifier() {
6205
- const { l1Nullifier } = await client.contracts();
6206
- return l1Nullifier;
6207
- },
6208
- async baseToken(chainId) {
6209
- const id = chainId ?? BigInt((await client.l2.getNetwork()).chainId);
6210
- return client.baseToken(id);
6211
- },
6212
- async l2TokenAddress(l1Token) {
6213
- if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
6214
- return ETH_ADDRESS;
6215
- }
6216
- const { chainId } = await client.l2.getNetwork();
6217
- const base = await client.baseToken(BigInt(chainId));
6218
- if (isAddressEq(l1Token, base)) {
6219
- return L2_BASE_TOKEN_ADDRESS;
6220
- }
6221
- const { l2NativeTokenVault } = await client.contracts();
6222
- const addr = await l2NativeTokenVault.l2TokenAddress(l1Token);
6223
- return addr;
6224
- },
6225
- async l1TokenAddress(l2Token) {
6226
- if (isAddressEq(l2Token, ETH_ADDRESS)) {
6227
- return ETH_ADDRESS;
6228
- }
6229
- const { l2AssetRouter } = await client.contracts();
6230
- const addr = await l2AssetRouter.l1TokenAddress(l2Token);
6231
- return addr;
6232
- },
6233
- async assetId(l1Token) {
6234
- const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
6235
- const { l1NativeTokenVault } = await client.contracts();
6236
- const id = await l1NativeTokenVault.assetId(norm);
6237
- return id;
6238
- }
6239
- }
6123
+ deposits: createDepositsResource(client, tokens, contracts),
6124
+ withdrawals: createWithdrawalsResource(client, tokens, contracts),
6125
+ tokens,
6126
+ contracts
6240
6127
  };
6241
6128
  }
6242
6129