@matterlabs/zksync-js 0.0.2 → 0.0.5

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 (61) hide show
  1. package/README.md +1 -3
  2. package/dist/adapters/ethers/client.cjs.map +1 -1
  3. package/dist/adapters/ethers/index.cjs +391 -170
  4. package/dist/adapters/ethers/index.cjs.map +1 -1
  5. package/dist/adapters/ethers/index.d.ts +1 -0
  6. package/dist/adapters/ethers/index.js +3 -3
  7. package/dist/adapters/ethers/resources/contracts/contracts.d.ts +9 -0
  8. package/dist/adapters/ethers/resources/contracts/index.d.ts +2 -0
  9. package/dist/adapters/ethers/resources/contracts/types.d.ts +60 -0
  10. package/dist/adapters/ethers/resources/deposits/context.d.ts +16 -2
  11. package/dist/adapters/ethers/resources/deposits/index.d.ts +3 -1
  12. package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +3 -2
  13. package/dist/adapters/ethers/resources/tokens/index.d.ts +1 -0
  14. package/dist/adapters/ethers/resources/tokens/tokens.d.ts +10 -0
  15. package/dist/adapters/ethers/resources/utils.d.ts +0 -3
  16. package/dist/adapters/ethers/resources/withdrawals/context.d.ts +11 -3
  17. package/dist/adapters/ethers/resources/withdrawals/index.d.ts +3 -1
  18. package/dist/adapters/ethers/sdk.cjs +386 -154
  19. package/dist/adapters/ethers/sdk.cjs.map +1 -1
  20. package/dist/adapters/ethers/sdk.d.ts +5 -22
  21. package/dist/adapters/ethers/sdk.js +3 -3
  22. package/dist/adapters/viem/client.cjs.map +1 -1
  23. package/dist/adapters/viem/index.cjs +383 -176
  24. package/dist/adapters/viem/index.cjs.map +1 -1
  25. package/dist/adapters/viem/index.d.ts +3 -0
  26. package/dist/adapters/viem/index.js +3 -3
  27. package/dist/adapters/viem/resources/contracts/contracts.d.ts +9 -0
  28. package/dist/adapters/viem/resources/contracts/index.d.ts +2 -0
  29. package/dist/adapters/viem/resources/contracts/types.d.ts +61 -0
  30. package/dist/adapters/viem/resources/deposits/context.d.ts +16 -2
  31. package/dist/adapters/viem/resources/deposits/index.d.ts +3 -1
  32. package/dist/adapters/viem/resources/deposits/services/gas.d.ts +2 -1
  33. package/dist/adapters/viem/resources/tokens/index.d.ts +1 -0
  34. package/dist/adapters/viem/resources/tokens/tokens.d.ts +3 -0
  35. package/dist/adapters/viem/resources/utils.d.ts +0 -3
  36. package/dist/adapters/viem/resources/withdrawals/context.d.ts +11 -3
  37. package/dist/adapters/viem/resources/withdrawals/index.d.ts +3 -1
  38. package/dist/adapters/viem/sdk.cjs +401 -189
  39. package/dist/adapters/viem/sdk.cjs.map +1 -1
  40. package/dist/adapters/viem/sdk.d.ts +5 -25
  41. package/dist/adapters/viem/sdk.js +3 -3
  42. package/dist/{chunk-OC6ZVLSP.js → chunk-JXUFGIJG.js} +348 -150
  43. package/dist/{chunk-QJS6ETEE.js → chunk-LL3WKCFJ.js} +15 -1
  44. package/dist/{chunk-BCCKWWOX.js → chunk-NBJEQAOE.js} +373 -158
  45. package/dist/{chunk-HLUANWGN.js → chunk-NEC2ZKHI.js} +4 -12
  46. package/dist/chunk-NTEIA5KA.js +13 -0
  47. package/dist/core/codec/ntv.d.ts +48 -0
  48. package/dist/core/index.cjs +4 -0
  49. package/dist/core/index.cjs.map +1 -1
  50. package/dist/core/index.d.ts +1 -0
  51. package/dist/core/index.js +2 -1
  52. package/dist/core/types/errors.d.ts +1 -1
  53. package/dist/core/types/flows/token.d.ts +192 -0
  54. package/dist/core/utils/addr.d.ts +2 -0
  55. package/dist/index.cjs +4 -0
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.js +2 -1
  59. package/package.json +1 -1
  60. package/dist/adapters/ethers/resources/token-info.d.ts +0 -31
  61. package/dist/adapters/viem/resources/token-info.d.ts +0 -34
@@ -5137,9 +5137,9 @@ var IFACE_PANIC = new ethers.Interface(["error Panic(uint256)"]);
5137
5137
  } catch {
5138
5138
  }
5139
5139
  })();
5140
- function registerErrorAbi(name, abi) {
5140
+ function registerErrorAbi(name, abi2) {
5141
5141
  const existing = ERROR_IFACES.findIndex((x) => x.name === name);
5142
- const entry = { name, iface: new ethers.Interface(abi) };
5142
+ const entry = { name, iface: new ethers.Interface(abi2) };
5143
5143
  if (existing >= 0) ERROR_IFACES[existing] = entry;
5144
5144
  else ERROR_IFACES.push(entry);
5145
5145
  }
@@ -5231,7 +5231,7 @@ function createErrorHandlers(resource) {
5231
5231
  function wrap2(operation, fn, opts) {
5232
5232
  return run("INTERNAL", operation, fn, opts);
5233
5233
  }
5234
- function wrapAs9(kind, operation, fn, opts) {
5234
+ function wrapAs10(kind, operation, fn, opts) {
5235
5235
  return run(kind, operation, fn, opts);
5236
5236
  }
5237
5237
  async function toResult2(operation, fn, opts) {
@@ -5252,7 +5252,7 @@ function createErrorHandlers(resource) {
5252
5252
  return { ok: false, error: shaped };
5253
5253
  }
5254
5254
  }
5255
- return { wrap: wrap2, wrapAs: wrapAs9, toResult: toResult2 };
5255
+ return { wrap: wrap2, wrapAs: wrapAs10, toResult: toResult2 };
5256
5256
  }
5257
5257
 
5258
5258
  // src/adapters/ethers/client.ts
@@ -5396,6 +5396,8 @@ function normalizeAddrEq(a, b) {
5396
5396
  };
5397
5397
  return normalize(a) === normalize(b);
5398
5398
  }
5399
+ var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
5400
+ var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
5399
5401
 
5400
5402
  // src/adapters/ethers/resources/deposits/services/verification.ts
5401
5403
  var I_BRIDGEHUB = new ethers.Interface([
@@ -5462,27 +5464,35 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
5462
5464
  return { l2Receipt, l2TxHash };
5463
5465
  }
5464
5466
 
5465
- // src/core/resources/deposits/route.ts
5466
- async function pickDepositRoute(client, chainIdL2, token) {
5467
- if (isETH(token)) {
5468
- const base2 = await client.baseToken(chainIdL2);
5469
- return isETH(base2) ? "eth-base" : "eth-nonbase";
5470
- }
5471
- const base = await client.baseToken(chainIdL2);
5472
- return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
5473
- }
5474
-
5475
5467
  // src/adapters/ethers/resources/deposits/context.ts
5476
- async function commonCtx(p, client) {
5477
- const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
5468
+ async function commonCtx(p, client, tokens, contracts) {
5469
+ const { bridgehub, l1AssetRouter } = await contracts.addresses();
5478
5470
  const { chainId } = await client.l2.getNetwork();
5479
5471
  const sender = await client.signer.getAddress();
5480
5472
  const gasPerPubdata = p.gasPerPubdata ?? 800n;
5481
5473
  const operatorTip = p.operatorTip ?? 0n;
5482
5474
  const refundRecipient = p.refundRecipient ?? sender;
5483
- const route = await pickDepositRoute(client, BigInt(chainId), p.token);
5475
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l1" });
5476
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
5477
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
5478
+ const baseIsEth = resolvedToken.isChainEthBased;
5479
+ const route = (() => {
5480
+ if (resolvedToken.kind === "eth") {
5481
+ return baseIsEth ? "eth-base" : "eth-nonbase";
5482
+ }
5483
+ if (resolvedToken.kind === "base") {
5484
+ return baseIsEth ? "eth-base" : "erc20-base";
5485
+ }
5486
+ return "erc20-nonbase";
5487
+ })();
5484
5488
  return {
5485
5489
  client,
5490
+ tokens,
5491
+ contracts,
5492
+ resolvedToken,
5493
+ baseTokenAssetId,
5494
+ baseTokenL1,
5495
+ baseIsEth,
5486
5496
  l1AssetRouter,
5487
5497
  route,
5488
5498
  bridgehub,
@@ -5495,31 +5505,14 @@ async function commonCtx(p, client) {
5495
5505
  refundRecipient
5496
5506
  };
5497
5507
  }
5498
- function encodeNativeTokenVaultAssetId(chainId, address) {
5499
- const abi = new ethers.AbiCoder();
5500
- const hex = abi.encode(
5501
- ["uint256", "address", "address"],
5502
- [chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
5503
- );
5504
- return ethers.ethers.keccak256(hex);
5505
- }
5506
5508
  function encodeNativeTokenVaultTransferData(amount, receiver, token) {
5507
5509
  return new ethers.AbiCoder().encode(["uint256", "address", "address"], [amount, receiver, token]);
5508
5510
  }
5509
5511
  function encodeSecondBridgeDataV1(assetId, transferData) {
5510
- const abi = new ethers.AbiCoder();
5511
- const data = abi.encode(["bytes32", "bytes"], [assetId, transferData]);
5512
+ const abi2 = new ethers.AbiCoder();
5513
+ const data = abi2.encode(["bytes32", "bytes"], [assetId, transferData]);
5512
5514
  return ethers.ethers.concat(["0x01", data]);
5513
5515
  }
5514
- function encodeNTVAssetId(chainId, address) {
5515
- const abi = new ethers.AbiCoder();
5516
- const hex = abi.encode(
5517
- ["uint256", "address", "address"],
5518
- [chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
5519
- );
5520
- return ethers.ethers.keccak256(hex);
5521
- }
5522
- var encodeNTVTransferData = encodeNativeTokenVaultTransferData;
5523
5516
  function encodeSecondBridgeArgs(token, amount, l2Receiver) {
5524
5517
  return ethers.AbiCoder.defaultAbiCoder().encode(
5525
5518
  ["address", "uint256", "address"],
@@ -5741,8 +5734,8 @@ function ethersToGasEstimator(provider) {
5741
5734
 
5742
5735
  // src/adapters/ethers/resources/deposits/services/fee.ts
5743
5736
  var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
5744
- var encode = (abi, fn, args) => {
5745
- return new ethers.Interface(abi).encodeFunctionData(fn, args);
5737
+ var encode = (abi2, fn, args) => {
5738
+ return new ethers.Interface(abi2).encodeFunctionData(fn, args);
5746
5739
  };
5747
5740
  async function quoteL2BaseCost2(input) {
5748
5741
  const { ctx, l2GasLimit } = input;
@@ -5797,8 +5790,7 @@ async function determineErc20L2Gas(input) {
5797
5790
  });
5798
5791
  }
5799
5792
  try {
5800
- const { l2NativeTokenVault } = await ctx.client.contracts();
5801
- const l2TokenAddress = await l2NativeTokenVault.l2TokenAddress(l1Token);
5793
+ const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token);
5802
5794
  if (l2TokenAddress === "0x0000000000000000000000000000000000000000") {
5803
5795
  return quoteL2Gas2({
5804
5796
  ctx,
@@ -5867,7 +5859,7 @@ function buildFeeBreakdown(p) {
5867
5859
  function routeEthDirect() {
5868
5860
  return {
5869
5861
  async build(p, ctx) {
5870
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
5862
+ const bh = await ctx.contracts.bridgehub();
5871
5863
  const l2TxModel = {
5872
5864
  to: p.to ?? ctx.sender,
5873
5865
  from: ctx.sender,
@@ -5944,14 +5936,14 @@ function routeEthDirect() {
5944
5936
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
5945
5937
  function routeErc20NonBase() {
5946
5938
  return {
5947
- // TODO: do we even need these validations?
5948
5939
  async preflight(p, ctx) {
5949
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
5940
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
5941
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5950
5942
  await wrapAs3(
5951
5943
  "VALIDATION",
5952
5944
  OP_DEPOSITS.nonbase.assertNonBaseToken,
5953
5945
  () => {
5954
- if (normalizeAddrEq(baseToken, p.token)) {
5946
+ if (resolved?.kind === "base" || resolved?.kind === "eth") {
5955
5947
  throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
5956
5948
  }
5957
5949
  },
@@ -5960,8 +5952,8 @@ function routeErc20NonBase() {
5960
5952
  },
5961
5953
  async build(p, ctx) {
5962
5954
  const l1Signer = ctx.client.getL1Signer();
5963
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
5964
- const baseIsEth = isETH(baseToken);
5955
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5956
+ const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
5965
5957
  const l2GasParams = await determineErc20L2Gas({
5966
5958
  ctx,
5967
5959
  l1Token: p.token,
@@ -6048,7 +6040,7 @@ function routeErc20NonBase() {
6048
6040
  secondBridgeValue: 0n,
6049
6041
  secondBridgeCalldata
6050
6042
  };
6051
- const bh = (await ctx.client.contracts()).bridgehub;
6043
+ const bh = await ctx.contracts.bridgehub();
6052
6044
  const data = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
6053
6045
  requestStruct
6054
6046
  ]);
@@ -6097,26 +6089,26 @@ var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
6097
6089
  function routeEthNonBase() {
6098
6090
  return {
6099
6091
  async preflight(p, ctx) {
6092
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
6100
6093
  await wrapAs4(
6101
6094
  "VALIDATION",
6102
6095
  OP_DEPOSITS.ethNonBase.assertEthAsset,
6103
6096
  () => {
6104
- if (!isETH(p.token)) {
6097
+ if (resolved?.kind !== "eth" && !isETH(p.token)) {
6105
6098
  throw new Error("eth-nonbase route requires ETH as the deposit asset.");
6106
6099
  }
6107
6100
  },
6108
6101
  { ctx: { token: p.token } }
6109
6102
  );
6110
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
6111
6103
  await wrapAs4(
6112
6104
  "VALIDATION",
6113
6105
  OP_DEPOSITS.ethNonBase.assertNonEthBase,
6114
6106
  () => {
6115
- if (isETH(baseToken)) {
6107
+ if (ctx.baseIsEth) {
6116
6108
  throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
6117
6109
  }
6118
6110
  },
6119
- { ctx: { baseToken, chainIdL2: ctx.chainIdL2 } }
6111
+ { ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
6120
6112
  );
6121
6113
  const ethBal = await wrapAs4(
6122
6114
  "RPC",
@@ -6141,7 +6133,7 @@ function routeEthNonBase() {
6141
6133
  },
6142
6134
  async build(p, ctx) {
6143
6135
  const l1Signer = ctx.client.getL1Signer();
6144
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
6136
+ const baseToken = ctx.baseTokenL1;
6145
6137
  const l2TxModel = {
6146
6138
  to: p.to ?? ctx.sender,
6147
6139
  from: ctx.sender,
@@ -6206,11 +6198,10 @@ function routeEthNonBase() {
6206
6198
  secondBridgeValue: p.amount,
6207
6199
  secondBridgeCalldata
6208
6200
  };
6209
- const data = new ethers.Contract(
6210
- ctx.bridgehub,
6211
- IBridgehub_default,
6212
- ctx.client.l1
6213
- ).interface.encodeFunctionData("requestL2TransactionTwoBridges", [requestStruct]);
6201
+ const bridgehub = await ctx.contracts.bridgehub();
6202
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
6203
+ requestStruct
6204
+ ]);
6214
6205
  const l1TxCandidate = {
6215
6206
  to: ctx.bridgehub,
6216
6207
  data,
@@ -6256,17 +6247,18 @@ var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
6256
6247
  function routeErc20Base() {
6257
6248
  return {
6258
6249
  async preflight(p, ctx) {
6250
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
6259
6251
  await wrapAs5(
6260
6252
  "VALIDATION",
6261
6253
  OP_DEPOSITS.base.assertErc20Asset,
6262
6254
  () => {
6263
- if (isETH(p.token)) {
6255
+ if (resolved?.kind === "eth" || isETH(p.token)) {
6264
6256
  throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
6265
6257
  }
6266
6258
  },
6267
6259
  { ctx: { token: p.token } }
6268
6260
  );
6269
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
6261
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
6270
6262
  await wrapAs5(
6271
6263
  "VALIDATION",
6272
6264
  OP_DEPOSITS.base.assertMatchesBase,
@@ -6281,7 +6273,7 @@ function routeErc20Base() {
6281
6273
  },
6282
6274
  async build(p, ctx) {
6283
6275
  const l1Signer = ctx.client.getL1Signer();
6284
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
6276
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
6285
6277
  const l2TxModel = {
6286
6278
  to: p.to ?? ctx.sender,
6287
6279
  from: ctx.sender,
@@ -6334,11 +6326,10 @@ function routeErc20Base() {
6334
6326
  l2Contract: p.to ?? ctx.sender,
6335
6327
  l2Value: p.amount
6336
6328
  });
6337
- const data = new ethers.Contract(
6338
- ctx.bridgehub,
6339
- IBridgehub_default,
6340
- ctx.client.l1
6341
- ).interface.encodeFunctionData("requestL2TransactionDirect", [requestStruct]);
6329
+ const bridgehub = await ctx.contracts.bridgehub();
6330
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
6331
+ requestStruct
6332
+ ]);
6342
6333
  const l1TxCandidate = {
6343
6334
  to: ctx.bridgehub,
6344
6335
  data,
@@ -6381,6 +6372,282 @@ function routeErc20Base() {
6381
6372
  };
6382
6373
  }
6383
6374
 
6375
+ // src/core/codec/ntv.ts
6376
+ function createNTVCodec(deps) {
6377
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
6378
+ const encoded = deps.encode(
6379
+ ["uint256", "address", "address"],
6380
+ [originChainId, ntvAddress, tokenAddress]
6381
+ );
6382
+ return deps.keccak256(encoded);
6383
+ }
6384
+ return {
6385
+ encodeAssetId
6386
+ };
6387
+ }
6388
+
6389
+ // src/adapters/ethers/resources/tokens/tokens.ts
6390
+ var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
6391
+ var abi = ethers.AbiCoder.defaultAbiCoder();
6392
+ var ntvCodec = createNTVCodec({
6393
+ encode: (types, values) => abi.encode(types, values),
6394
+ keccak256: (data) => ethers.ethers.keccak256(data)
6395
+ });
6396
+ function createTokensResource(client) {
6397
+ let l2NtvL1ChainIdPromise = null;
6398
+ let baseTokenAssetIdPromise = null;
6399
+ let wethL1Promise = null;
6400
+ let wethL2Promise = null;
6401
+ async function getL1ChainId() {
6402
+ if (!l2NtvL1ChainIdPromise) {
6403
+ l2NtvL1ChainIdPromise = wrapAs6("INTERNAL", "getL1ChainId", async () => {
6404
+ const { l2NativeTokenVault } = await client.contracts();
6405
+ const chainId = await l2NativeTokenVault.L1_CHAIN_ID();
6406
+ return chainId;
6407
+ });
6408
+ }
6409
+ return l2NtvL1ChainIdPromise;
6410
+ }
6411
+ async function getBaseTokenAssetId() {
6412
+ if (!baseTokenAssetIdPromise) {
6413
+ baseTokenAssetIdPromise = wrapAs6("INTERNAL", "baseTokenAssetId", async () => {
6414
+ const { l2NativeTokenVault } = await client.contracts();
6415
+ const assetId = await l2NativeTokenVault.BASE_TOKEN_ASSET_ID();
6416
+ return assetId;
6417
+ });
6418
+ }
6419
+ return baseTokenAssetIdPromise;
6420
+ }
6421
+ async function getWethL1() {
6422
+ if (!wethL1Promise) {
6423
+ wethL1Promise = wrapAs6("INTERNAL", "wethL1", async () => {
6424
+ const { l1NativeTokenVault } = await client.contracts();
6425
+ const weth = await l1NativeTokenVault.WETH_TOKEN();
6426
+ return weth;
6427
+ });
6428
+ }
6429
+ return wethL1Promise;
6430
+ }
6431
+ async function getWethL2() {
6432
+ if (!wethL2Promise) {
6433
+ wethL2Promise = wrapAs6("INTERNAL", "wethL2", async () => {
6434
+ const { l2NativeTokenVault } = await client.contracts();
6435
+ const weth = await l2NativeTokenVault.WETH_TOKEN();
6436
+ return weth;
6437
+ });
6438
+ }
6439
+ return wethL2Promise;
6440
+ }
6441
+ async function toL2Address(l1Token) {
6442
+ return wrapAs6("CONTRACT", "tokens.toL2Address", async () => {
6443
+ const normalized = normalizeL1Token(l1Token);
6444
+ const { chainId } = await client.l2.getNetwork();
6445
+ const baseToken = await client.baseToken(BigInt(chainId));
6446
+ if (isAddressEq(normalized, baseToken)) {
6447
+ return L2_BASE_TOKEN_ADDRESS;
6448
+ }
6449
+ const { l2NativeTokenVault } = await client.contracts();
6450
+ const l2Token = await l2NativeTokenVault.l2TokenAddress(normalized);
6451
+ return l2Token;
6452
+ });
6453
+ }
6454
+ async function toL1Address(l2Token) {
6455
+ return wrapAs6("CONTRACT", "tokens.toL1Address", async () => {
6456
+ if (isAddressEq(l2Token, ETH_ADDRESS)) {
6457
+ return ETH_ADDRESS;
6458
+ }
6459
+ if (isAddressEq(l2Token, L2_BASE_TOKEN_ADDRESS)) {
6460
+ const { chainId } = await client.l2.getNetwork();
6461
+ return await client.baseToken(BigInt(chainId));
6462
+ }
6463
+ const { l2AssetRouter } = await client.contracts();
6464
+ const l1Token = await l2AssetRouter.l1TokenAddress(l2Token);
6465
+ return l1Token;
6466
+ });
6467
+ }
6468
+ async function assetIdOfL1(l1Token) {
6469
+ return wrapAs6("CONTRACT", "tokens.assetIdOfL1", async () => {
6470
+ const normalized = normalizeL1Token(l1Token);
6471
+ const { l1NativeTokenVault } = await client.contracts();
6472
+ const assetId = await l1NativeTokenVault.assetId(normalized);
6473
+ return assetId;
6474
+ });
6475
+ }
6476
+ async function assetIdOfL2(l2Token) {
6477
+ return wrapAs6("CONTRACT", "tokens.assetIdOfL2", async () => {
6478
+ const { l2NativeTokenVault } = await client.contracts();
6479
+ const assetId = await l2NativeTokenVault.assetId(l2Token);
6480
+ return assetId;
6481
+ });
6482
+ }
6483
+ async function l2TokenFromAssetId(assetId) {
6484
+ return wrapAs6("CONTRACT", "tokens.l2TokenFromAssetId", async () => {
6485
+ const { l2NativeTokenVault } = await client.contracts();
6486
+ const tokenAddr = await l2NativeTokenVault.tokenAddress(assetId);
6487
+ return tokenAddr;
6488
+ });
6489
+ }
6490
+ async function l1TokenFromAssetId(assetId) {
6491
+ return wrapAs6("CONTRACT", "tokens.l1TokenFromAssetId", async () => {
6492
+ const { l1NativeTokenVault } = await client.contracts();
6493
+ const tokenAddr = await l1NativeTokenVault.tokenAddress(assetId);
6494
+ return tokenAddr;
6495
+ });
6496
+ }
6497
+ async function originChainId(assetId) {
6498
+ return wrapAs6("CONTRACT", "tokens.originChainId", async () => {
6499
+ const { l2NativeTokenVault } = await client.contracts();
6500
+ const chainId = await l2NativeTokenVault.originChainId(assetId);
6501
+ return chainId;
6502
+ });
6503
+ }
6504
+ async function baseTokenAssetId() {
6505
+ return getBaseTokenAssetId();
6506
+ }
6507
+ async function isChainEthBased() {
6508
+ return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
6509
+ const baseAssetId = await getBaseTokenAssetId();
6510
+ const l1ChainId = await getL1ChainId();
6511
+ const ethAssetId = ntvCodec.encodeAssetId(
6512
+ l1ChainId,
6513
+ L2_NATIVE_TOKEN_VAULT_ADDRESS,
6514
+ ETH_ADDRESS
6515
+ );
6516
+ return hexEq(baseAssetId, ethAssetId);
6517
+ });
6518
+ }
6519
+ async function wethL1() {
6520
+ return getWethL1();
6521
+ }
6522
+ async function wethL2() {
6523
+ return getWethL2();
6524
+ }
6525
+ async function computeL2BridgedAddress(args) {
6526
+ return wrapAs6("CONTRACT", "tokens.computeL2BridgedAddress", async () => {
6527
+ const normalized = normalizeL1Token(args.l1Token);
6528
+ const { l2NativeTokenVault } = await client.contracts();
6529
+ const predicted = await l2NativeTokenVault.calculateCreate2TokenAddress(
6530
+ args.originChainId,
6531
+ normalized
6532
+ );
6533
+ return predicted;
6534
+ });
6535
+ }
6536
+ async function resolve(ref, opts) {
6537
+ return wrapAs6("CONTRACT", "tokens.resolve", async () => {
6538
+ let chain;
6539
+ let address;
6540
+ if (typeof ref === "string") {
6541
+ chain = opts?.chain ?? "l1";
6542
+ address = ref;
6543
+ } else {
6544
+ chain = ref.chain;
6545
+ address = ref.address;
6546
+ }
6547
+ let l1;
6548
+ let l2;
6549
+ if (chain === "l1") {
6550
+ l1 = normalizeL1Token(address);
6551
+ l2 = await toL2Address(address);
6552
+ } else {
6553
+ l2 = address;
6554
+ l1 = await toL1Address(address);
6555
+ }
6556
+ const assetId = await assetIdOfL1(l1);
6557
+ const originChainIdVal = await originChainId(assetId);
6558
+ const [baseAssetId, wethL1Addr, wethL2Addr, ethBased] = await Promise.all([
6559
+ baseTokenAssetId(),
6560
+ wethL1(),
6561
+ wethL2(),
6562
+ isChainEthBased()
6563
+ ]);
6564
+ let kind;
6565
+ if (isAddressEq(l1, ETH_ADDRESS)) {
6566
+ kind = "eth";
6567
+ } else if (hexEq(assetId, baseAssetId)) {
6568
+ kind = "base";
6569
+ } else {
6570
+ kind = "erc20";
6571
+ }
6572
+ return {
6573
+ kind,
6574
+ l1,
6575
+ l2,
6576
+ assetId,
6577
+ originChainId: originChainIdVal,
6578
+ isChainEthBased: ethBased,
6579
+ baseTokenAssetId: baseAssetId,
6580
+ wethL1: wethL1Addr,
6581
+ wethL2: wethL2Addr
6582
+ };
6583
+ });
6584
+ }
6585
+ return {
6586
+ resolve,
6587
+ toL2Address,
6588
+ toL1Address,
6589
+ assetIdOfL1,
6590
+ assetIdOfL2,
6591
+ l2TokenFromAssetId,
6592
+ l1TokenFromAssetId,
6593
+ originChainId,
6594
+ baseTokenAssetId,
6595
+ isChainEthBased,
6596
+ wethL1,
6597
+ wethL2,
6598
+ computeL2BridgedAddress
6599
+ };
6600
+ }
6601
+
6602
+ // src/adapters/ethers/resources/contracts/contracts.ts
6603
+ function createContractsResource(client) {
6604
+ async function addresses() {
6605
+ return client.ensureAddresses();
6606
+ }
6607
+ async function instances() {
6608
+ return client.contracts();
6609
+ }
6610
+ async function bridgehub() {
6611
+ const { bridgehub: bridgehub2 } = await instances();
6612
+ return bridgehub2;
6613
+ }
6614
+ async function l1AssetRouter() {
6615
+ const { l1AssetRouter: l1AssetRouter2 } = await instances();
6616
+ return l1AssetRouter2;
6617
+ }
6618
+ async function l1NativeTokenVault() {
6619
+ const { l1NativeTokenVault: l1NativeTokenVault2 } = await instances();
6620
+ return l1NativeTokenVault2;
6621
+ }
6622
+ async function l1Nullifier() {
6623
+ const { l1Nullifier: l1Nullifier2 } = await instances();
6624
+ return l1Nullifier2;
6625
+ }
6626
+ async function l2AssetRouter() {
6627
+ const { l2AssetRouter: l2AssetRouter2 } = await instances();
6628
+ return l2AssetRouter2;
6629
+ }
6630
+ async function l2NativeTokenVault() {
6631
+ const { l2NativeTokenVault: l2NativeTokenVault2 } = await instances();
6632
+ return l2NativeTokenVault2;
6633
+ }
6634
+ async function l2BaseTokenSystem() {
6635
+ const { l2BaseTokenSystem: l2BaseTokenSystem2 } = await instances();
6636
+ return l2BaseTokenSystem2;
6637
+ }
6638
+ return {
6639
+ addresses,
6640
+ instances,
6641
+ bridgehub,
6642
+ l1AssetRouter,
6643
+ l1NativeTokenVault,
6644
+ l1Nullifier,
6645
+ l2AssetRouter,
6646
+ l2NativeTokenVault,
6647
+ l2BaseTokenSystem
6648
+ };
6649
+ }
6650
+
6384
6651
  // src/adapters/ethers/resources/deposits/index.ts
6385
6652
  var { wrap, toResult } = createErrorHandlers("deposits");
6386
6653
  var ROUTES = {
@@ -6389,9 +6656,11 @@ var ROUTES = {
6389
6656
  "erc20-nonbase": routeErc20NonBase(),
6390
6657
  "erc20-base": routeErc20Base()
6391
6658
  };
6392
- function createDepositsResource(client) {
6659
+ function createDepositsResource(client, tokens, contracts) {
6660
+ const tokensResource = tokens ?? createTokensResource(client);
6661
+ const contractsResource = contracts ?? createContractsResource(client);
6393
6662
  async function buildPlan(p) {
6394
- const ctx = await commonCtx(p, client);
6663
+ const ctx = await commonCtx(p, client, tokensResource, contractsResource);
6395
6664
  const route = ctx.route;
6396
6665
  await ROUTES[route].preflight?.(p, ctx);
6397
6666
  const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
@@ -6669,25 +6938,9 @@ function pickWithdrawRoute(args) {
6669
6938
  if (isL2BaseAlias) return "base";
6670
6939
  return "erc20-nonbase";
6671
6940
  }
6672
- async function ntvBaseAssetId(l2, ntv) {
6673
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
6674
- return await c.BASE_TOKEN_ASSET_ID();
6675
- }
6676
- async function ntvL1ChainId(l2, ntv) {
6677
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
6678
- return await c.L1_CHAIN_ID();
6679
- }
6680
- async function isEthBasedChain(l2, ntv) {
6681
- const [baseAssetId, l1ChainId] = await Promise.all([
6682
- ntvBaseAssetId(l2, ntv),
6683
- ntvL1ChainId(l2, ntv)
6684
- ]);
6685
- const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
6686
- return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
6687
- }
6688
6941
 
6689
6942
  // src/adapters/ethers/resources/withdrawals/context.ts
6690
- async function commonCtx2(p, client) {
6943
+ async function commonCtx2(p, client, tokens, contracts) {
6691
6944
  const sender = await client.signer.getAddress();
6692
6945
  const {
6693
6946
  bridgehub,
@@ -6696,13 +6949,21 @@ async function commonCtx2(p, client) {
6696
6949
  l2AssetRouter,
6697
6950
  l2NativeTokenVault,
6698
6951
  l2BaseTokenSystem
6699
- } = await client.ensureAddresses();
6952
+ } = await contracts.addresses();
6700
6953
  const { chainId } = await client.l2.getNetwork();
6701
6954
  const chainIdL2 = BigInt(chainId);
6702
- const baseIsEth = await isEthBasedChain(client.l2, l2NativeTokenVault);
6955
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l2" });
6956
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
6957
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
6958
+ const baseIsEth = resolvedToken.isChainEthBased;
6703
6959
  const route = pickWithdrawRoute({ token: p.token});
6704
6960
  return {
6705
6961
  client,
6962
+ tokens,
6963
+ contracts,
6964
+ resolvedToken,
6965
+ baseTokenAssetId,
6966
+ baseTokenL1,
6706
6967
  bridgehub,
6707
6968
  chainIdL2,
6708
6969
  sender,
@@ -6806,13 +7067,13 @@ function buildFeeBreakdown2(p) {
6806
7067
  }
6807
7068
 
6808
7069
  // src/adapters/ethers/resources/withdrawals/routes/eth.ts
6809
- var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
7070
+ var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
6810
7071
  function routeEthBase() {
6811
7072
  return {
6812
7073
  async build(p, ctx) {
6813
7074
  const steps = [];
6814
- const base = (await ctx.client.contracts()).l2BaseTokenSystem;
6815
- const data = await wrapAs6(
7075
+ const base = await ctx.contracts.l2BaseTokenSystem();
7076
+ const data = await wrapAs7(
6816
7077
  "INTERNAL",
6817
7078
  OP_WITHDRAWALS.eth.encodeWithdraw,
6818
7079
  () => Promise.resolve(base.interface.encodeFunctionData("withdraw", [p.to ?? ctx.sender])),
@@ -6847,7 +7108,7 @@ function routeEthBase() {
6847
7108
  }
6848
7109
  };
6849
7110
  }
6850
- var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
7111
+ var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
6851
7112
  var SIG = {
6852
7113
  withdraw: "withdraw(bytes32,bytes)"
6853
7114
  };
@@ -6857,7 +7118,7 @@ function routeErc20NonBase2() {
6857
7118
  const steps = [];
6858
7119
  const approvals = [];
6859
7120
  const erc20 = new ethers.Contract(p.token, IERC20_default, ctx.client.getL2Signer());
6860
- const current = await wrapAs7(
7121
+ const current = await wrapAs8(
6861
7122
  "CONTRACT",
6862
7123
  OP_WITHDRAWALS.erc20.allowance,
6863
7124
  () => erc20.allowance(ctx.sender, ctx.l2NativeTokenVault),
@@ -6895,17 +7156,21 @@ function routeErc20NonBase2() {
6895
7156
  tx: approveTx
6896
7157
  });
6897
7158
  }
6898
- const ntv = (await ctx.client.contracts()).l2NativeTokenVault;
6899
- const assetId = await wrapAs7(
7159
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l2" }) : void 0);
7160
+ const assetId = resolved?.assetId ?? await wrapAs8(
6900
7161
  "CONTRACT",
6901
7162
  OP_WITHDRAWALS.erc20.ensureRegistered,
6902
- () => ntv.getFunction("ensureTokenIsRegistered").staticCall(p.token),
7163
+ async () => {
7164
+ const ntv = await ctx.contracts.l2NativeTokenVault();
7165
+ const ensured = await ntv.getFunction("ensureTokenIsRegistered").staticCall(p.token);
7166
+ return ensured;
7167
+ },
6903
7168
  {
6904
7169
  ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
6905
7170
  message: "Failed to ensure token is registered in L2NativeTokenVault."
6906
7171
  }
6907
7172
  );
6908
- const assetData = await wrapAs7(
7173
+ const assetData = await wrapAs8(
6909
7174
  "INTERNAL",
6910
7175
  OP_WITHDRAWALS.erc20.encodeAssetData,
6911
7176
  () => Promise.resolve(
@@ -6916,8 +7181,8 @@ function routeErc20NonBase2() {
6916
7181
  message: "Failed to encode burn/withdraw asset data."
6917
7182
  }
6918
7183
  );
6919
- const l2ar = (await ctx.client.contracts()).l2AssetRouter;
6920
- const dataWithdraw = await wrapAs7(
7184
+ const l2ar = await ctx.contracts.l2AssetRouter();
7185
+ const dataWithdraw = await wrapAs8(
6921
7186
  "INTERNAL",
6922
7187
  OP_WITHDRAWALS.erc20.encodeWithdraw,
6923
7188
  () => Promise.resolve(l2ar.interface.encodeFunctionData(SIG.withdraw, [assetId, assetData])),
@@ -6944,7 +7209,7 @@ function routeErc20NonBase2() {
6944
7209
  tx: withdrawTx
6945
7210
  });
6946
7211
  const fees = buildFeeBreakdown2({
6947
- feeToken: await ctx.client.baseToken(ctx.chainIdL2),
7212
+ feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
6948
7213
  l2Gas: withdrawGas
6949
7214
  });
6950
7215
  return { steps, approvals, fees };
@@ -6985,7 +7250,7 @@ function messengerLogIndex(raw, opts) {
6985
7250
  }
6986
7251
 
6987
7252
  // src/adapters/ethers/resources/withdrawals/services/finalization.ts
6988
- var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
7253
+ var { wrapAs: wrapAs9 } = createErrorHandlers("withdrawals");
6989
7254
  var IL1NullifierMini = [
6990
7255
  "function isWithdrawalFinalized(uint256,uint256,uint256) view returns (bool)"
6991
7256
  ];
@@ -6993,7 +7258,7 @@ function createFinalizationServices(client) {
6993
7258
  const { l1, l2, signer } = client;
6994
7259
  return {
6995
7260
  async fetchFinalizeDepositParams(l2TxHash) {
6996
- const parsed = await wrapAs8(
7261
+ const parsed = await wrapAs9(
6997
7262
  "RPC",
6998
7263
  OP_WITHDRAWALS.finalize.fetchParams.receipt,
6999
7264
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -7010,7 +7275,7 @@ function createFinalizationServices(client) {
7010
7275
  context: { l2TxHash }
7011
7276
  });
7012
7277
  }
7013
- const ev = await wrapAs8(
7278
+ const ev = await wrapAs9(
7014
7279
  "INTERNAL",
7015
7280
  OP_WITHDRAWALS.finalize.fetchParams.findMessage,
7016
7281
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
@@ -7020,7 +7285,7 @@ function createFinalizationServices(client) {
7020
7285
  message: "Failed to locate L1MessageSent event in L2 receipt."
7021
7286
  }
7022
7287
  );
7023
- const message = await wrapAs8(
7288
+ const message = await wrapAs9(
7024
7289
  "INTERNAL",
7025
7290
  OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
7026
7291
  () => Promise.resolve(ethers.AbiCoder.defaultAbiCoder().decode(["bytes"], ev.data)[0]),
@@ -7029,7 +7294,7 @@ function createFinalizationServices(client) {
7029
7294
  message: "Failed to decode withdrawal message."
7030
7295
  }
7031
7296
  );
7032
- const raw = await wrapAs8(
7297
+ const raw = await wrapAs9(
7033
7298
  "RPC",
7034
7299
  OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
7035
7300
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -7046,7 +7311,7 @@ function createFinalizationServices(client) {
7046
7311
  context: { l2TxHash }
7047
7312
  });
7048
7313
  }
7049
- const idx = await wrapAs8(
7314
+ const idx = await wrapAs9(
7050
7315
  "INTERNAL",
7051
7316
  OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
7052
7317
  () => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
@@ -7055,7 +7320,7 @@ function createFinalizationServices(client) {
7055
7320
  message: "Failed to derive messenger log index."
7056
7321
  }
7057
7322
  );
7058
- const proof = await wrapAs8(
7323
+ const proof = await wrapAs9(
7059
7324
  "RPC",
7060
7325
  OP_WITHDRAWALS.finalize.fetchParams.proof,
7061
7326
  () => client.zks.getL2ToL1LogProof(l2TxHash, idx),
@@ -7064,7 +7329,7 @@ function createFinalizationServices(client) {
7064
7329
  message: "Failed to fetch L2\u2192L1 log proof."
7065
7330
  }
7066
7331
  );
7067
- const { chainId } = await wrapAs8(
7332
+ const { chainId } = await wrapAs9(
7068
7333
  "RPC",
7069
7334
  OP_WITHDRAWALS.finalize.fetchParams.network,
7070
7335
  () => l2.getNetwork(),
@@ -7083,7 +7348,7 @@ function createFinalizationServices(client) {
7083
7348
  message,
7084
7349
  merkleProof: proof.proof
7085
7350
  };
7086
- const { l1Nullifier } = await wrapAs8(
7351
+ const { l1Nullifier } = await wrapAs9(
7087
7352
  "INTERNAL",
7088
7353
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
7089
7354
  () => client.ensureAddresses(),
@@ -7095,7 +7360,7 @@ function createFinalizationServices(client) {
7095
7360
  return { params, nullifier: l1Nullifier };
7096
7361
  },
7097
7362
  async simulateFinalizeReadiness(params) {
7098
- const { l1Nullifier } = await wrapAs8(
7363
+ const { l1Nullifier } = await wrapAs9(
7099
7364
  "INTERNAL",
7100
7365
  OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
7101
7366
  () => client.ensureAddresses(),
@@ -7107,7 +7372,7 @@ function createFinalizationServices(client) {
7107
7372
  const done = await (async () => {
7108
7373
  try {
7109
7374
  const cMini = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
7110
- const isFinalized = await wrapAs8(
7375
+ const isFinalized = await wrapAs9(
7111
7376
  "RPC",
7112
7377
  OP_WITHDRAWALS.finalize.readiness.isFinalized,
7113
7378
  () => cMini.isWithdrawalFinalized(
@@ -7135,7 +7400,7 @@ function createFinalizationServices(client) {
7135
7400
  }
7136
7401
  },
7137
7402
  async isWithdrawalFinalized(key) {
7138
- const { l1Nullifier } = await wrapAs8(
7403
+ const { l1Nullifier } = await wrapAs9(
7139
7404
  "INTERNAL",
7140
7405
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
7141
7406
  () => client.ensureAddresses(),
@@ -7145,7 +7410,7 @@ function createFinalizationServices(client) {
7145
7410
  }
7146
7411
  );
7147
7412
  const c = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
7148
- return await wrapAs8(
7413
+ return await wrapAs9(
7149
7414
  "RPC",
7150
7415
  OP_WITHDRAWALS.finalize.isFinalized,
7151
7416
  () => c.isWithdrawalFinalized(key.chainIdL2, key.l2BatchNumber, key.l2MessageIndex),
@@ -7156,7 +7421,7 @@ function createFinalizationServices(client) {
7156
7421
  );
7157
7422
  },
7158
7423
  async estimateFinalization(params) {
7159
- const { l1Nullifier } = await wrapAs8(
7424
+ const { l1Nullifier } = await wrapAs9(
7160
7425
  "INTERNAL",
7161
7426
  OP_WITHDRAWALS.finalize.estimate,
7162
7427
  () => client.ensureAddresses(),
@@ -7167,7 +7432,7 @@ function createFinalizationServices(client) {
7167
7432
  );
7168
7433
  const signer2 = client.getL1Signer();
7169
7434
  const c = new ethers.Contract(l1Nullifier, IL1Nullifier_default, signer2);
7170
- const gasLimit = await wrapAs8(
7435
+ const gasLimit = await wrapAs9(
7171
7436
  "RPC",
7172
7437
  OP_WITHDRAWALS.finalize.estimate,
7173
7438
  () => c.finalizeDeposit.estimateGas(params),
@@ -7182,7 +7447,7 @@ function createFinalizationServices(client) {
7182
7447
  message: "Failed to estimate gas for finalizeDeposit."
7183
7448
  }
7184
7449
  );
7185
- const feeData = await wrapAs8("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
7450
+ const feeData = await wrapAs9("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
7186
7451
  ctx: { where: "l1.getFeeData" },
7187
7452
  message: "Failed to estimate fee data for finalizeDeposit."
7188
7453
  });
@@ -7203,7 +7468,7 @@ function createFinalizationServices(client) {
7203
7468
  };
7204
7469
  },
7205
7470
  async finalizeDeposit(params) {
7206
- const { l1Nullifier } = await wrapAs8(
7471
+ const { l1Nullifier } = await wrapAs9(
7207
7472
  "INTERNAL",
7208
7473
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
7209
7474
  () => client.ensureAddresses(),
@@ -7264,11 +7529,13 @@ var ROUTES2 = {
7264
7529
  "erc20-nonbase": routeErc20NonBase2()
7265
7530
  // AssetRouter.withdraw for non-base ERC-20s
7266
7531
  };
7267
- function createWithdrawalsResource(client) {
7532
+ function createWithdrawalsResource(client, tokens, contracts) {
7268
7533
  const svc = createFinalizationServices(client);
7269
7534
  const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
7535
+ const tokensResource = tokens ?? createTokensResource(client);
7536
+ const contractsResource = contracts ?? createContractsResource(client);
7270
7537
  async function buildPlan(p) {
7271
- const ctx = await commonCtx2(p, client);
7538
+ const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
7272
7539
  await ROUTES2[ctx.route].preflight?.(p, ctx);
7273
7540
  const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
7274
7541
  return {
@@ -7592,57 +7859,13 @@ function createWithdrawalsResource(client) {
7592
7859
 
7593
7860
  // src/adapters/ethers/sdk.ts
7594
7861
  function createEthersSdk(client) {
7862
+ const tokens = createTokensResource(client);
7863
+ const contracts = createContractsResource(client);
7595
7864
  return {
7596
- deposits: createDepositsResource(client),
7597
- withdrawals: createWithdrawalsResource(client),
7598
- // TODO: might update to create dedicated resources for these
7599
- helpers: {
7600
- addresses: () => client.ensureAddresses(),
7601
- contracts: () => client.contracts(),
7602
- async l1AssetRouter() {
7603
- const { l1AssetRouter } = await client.contracts();
7604
- return l1AssetRouter;
7605
- },
7606
- async l1NativeTokenVault() {
7607
- const { l1NativeTokenVault } = await client.contracts();
7608
- return l1NativeTokenVault;
7609
- },
7610
- async l1Nullifier() {
7611
- const { l1Nullifier } = await client.contracts();
7612
- return l1Nullifier;
7613
- },
7614
- async baseToken(chainId) {
7615
- const id = chainId ?? BigInt((await client.l2.getNetwork()).chainId);
7616
- return client.baseToken(id);
7617
- },
7618
- async l2TokenAddress(l1Token) {
7619
- if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
7620
- return ETH_ADDRESS;
7621
- }
7622
- const { chainId } = await client.l2.getNetwork();
7623
- const base = await client.baseToken(BigInt(chainId));
7624
- if (isAddressEq(l1Token, base)) {
7625
- return L2_BASE_TOKEN_ADDRESS;
7626
- }
7627
- const { l2NativeTokenVault } = await client.contracts();
7628
- const addr = await l2NativeTokenVault.l2TokenAddress(l1Token);
7629
- return addr;
7630
- },
7631
- async l1TokenAddress(l2Token) {
7632
- if (isAddressEq(l2Token, ETH_ADDRESS)) {
7633
- return ETH_ADDRESS;
7634
- }
7635
- const { l2AssetRouter } = await client.contracts();
7636
- const addr = await l2AssetRouter.l1TokenAddress(l2Token);
7637
- return addr;
7638
- },
7639
- async assetId(l1Token) {
7640
- const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
7641
- const { l1NativeTokenVault } = await client.contracts();
7642
- const id = await l1NativeTokenVault.assetId(norm);
7643
- return id;
7644
- }
7645
- }
7865
+ deposits: createDepositsResource(client, tokens, contracts),
7866
+ withdrawals: createWithdrawalsResource(client, tokens, contracts),
7867
+ tokens,
7868
+ contracts
7646
7869
  };
7647
7870
  }
7648
7871
 
@@ -7654,11 +7877,9 @@ exports.createErrorHandlers = createErrorHandlers;
7654
7877
  exports.createEthersClient = createEthersClient;
7655
7878
  exports.createEthersSdk = createEthersSdk;
7656
7879
  exports.createFinalizationServices = createFinalizationServices;
7880
+ exports.createTokensResource = createTokensResource;
7657
7881
  exports.createWithdrawalsResource = createWithdrawalsResource;
7658
7882
  exports.decodeRevert = decodeRevert;
7659
- exports.encodeNTVAssetId = encodeNTVAssetId;
7660
- exports.encodeNTVTransferData = encodeNTVTransferData;
7661
- exports.encodeNativeTokenVaultAssetId = encodeNativeTokenVaultAssetId;
7662
7883
  exports.encodeNativeTokenVaultTransferData = encodeNativeTokenVaultTransferData;
7663
7884
  exports.encodeSecondBridgeArgs = encodeSecondBridgeArgs;
7664
7885
  exports.encodeSecondBridgeDataV1 = encodeSecondBridgeDataV1;