@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
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var viem = require('viem');
3
4
  var sha3 = require('@noble/hashes/sha3');
4
5
  var utils = require('@noble/hashes/utils');
5
- var viem = require('viem');
6
6
 
7
7
  // src/core/internal/abis/IBridgehub.ts
8
8
  var IBridgehubABI = [
@@ -3645,63 +3645,36 @@ var MailboxABI = [
3645
3645
  { type: "error", name: "ZeroGasPriceL1TxZKSyncOS", inputs: [] }
3646
3646
  ];
3647
3647
  var Mailbox_default = MailboxABI;
3648
- var k256hex = (s) => `0x${utils.bytesToHex(sha3.keccak_256(utils.utf8ToBytes(s)))}`.toLowerCase();
3649
- var FORMAL_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
3650
- var ETH_ADDRESS = "0x0000000000000000000000000000000000000001";
3651
- var L2_ASSET_ROUTER_ADDRESS = "0x0000000000000000000000000000000000010003";
3652
- var L2_NATIVE_TOKEN_VAULT_ADDRESS = "0x0000000000000000000000000000000000010004";
3653
- var L1_MESSENGER_ADDRESS = "0x0000000000000000000000000000000000008008";
3654
- var L2_BASE_TOKEN_ADDRESS = "0x000000000000000000000000000000000000800A";
3655
- var TOPIC_L1_MESSAGE_SENT_NEW = k256hex("L1MessageSent(uint256,bytes32,bytes)");
3656
- var TOPIC_L1_MESSAGE_SENT_LEG = k256hex("L1MessageSent(address,bytes32,bytes)");
3657
- var TOPIC_CANONICAL_ASSIGNED = "0x779f441679936c5441b671969f37400b8c3ed0071cb47444431bf985754560df";
3658
- var TOPIC_CANONICAL_SUCCESS = "0xe4def01b981193a97a9e81230d7b9f31812ceaf23f864a828a82c687911cb2df";
3659
- var BUFFER = 20n;
3660
- var TX_OVERHEAD_GAS = 10000n;
3661
- var TX_MEMORY_OVERHEAD_GAS = 10n;
3662
- var DEFAULT_PUBDATA_BYTES = 155n;
3663
- var DEFAULT_ABI_BYTES = 400n;
3664
- var SAFE_L1_BRIDGE_GAS = 600000n;
3665
-
3666
- // src/core/utils/addr.ts
3667
- var isHash66 = (x) => !!x && x.startsWith("0x") && x.length === 66;
3668
- function isAddressEq(a, b) {
3669
- return a.toLowerCase() === b.toLowerCase();
3670
- }
3671
- function isETH(token) {
3672
- return isAddressEq(token, FORMAL_ETH_ADDRESS) || isAddressEq(token, L2_BASE_TOKEN_ADDRESS) || isAddressEq(token, ETH_ADDRESS);
3673
- }
3674
- function normalizeAddrEq(a, b) {
3675
- if (!a || !b) return false;
3676
- const normalize = (s) => {
3677
- const hasPrefix = s.slice(0, 2).toLowerCase() === "0x";
3678
- const body = hasPrefix ? s.slice(2) : s;
3679
- return `0x${body.toLowerCase()}`;
3680
- };
3681
- return normalize(a) === normalize(b);
3682
- }
3683
-
3684
- // src/core/resources/deposits/route.ts
3685
- async function pickDepositRoute(client, chainIdL2, token) {
3686
- if (isETH(token)) {
3687
- const base2 = await client.baseToken(chainIdL2);
3688
- return isETH(base2) ? "eth-base" : "eth-nonbase";
3689
- }
3690
- const base = await client.baseToken(chainIdL2);
3691
- return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
3692
- }
3693
3648
 
3694
3649
  // src/adapters/viem/resources/deposits/context.ts
3695
- async function commonCtx(p, client) {
3696
- const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
3650
+ async function commonCtx(p, client, tokens, contracts) {
3651
+ const { bridgehub, l1AssetRouter } = await contracts.addresses();
3697
3652
  const chainId = await client.l2.getChainId();
3698
3653
  const sender = client.account.address;
3699
3654
  const gasPerPubdata = p.gasPerPubdata ?? 800n;
3700
3655
  const operatorTip = p.operatorTip ?? 0n;
3701
3656
  const refundRecipient = p.refundRecipient ?? sender;
3702
- const route = await pickDepositRoute(client, BigInt(chainId), p.token);
3657
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l1" });
3658
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
3659
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
3660
+ const baseIsEth = resolvedToken.isChainEthBased;
3661
+ const route = (() => {
3662
+ if (resolvedToken.kind === "eth") {
3663
+ return baseIsEth ? "eth-base" : "eth-nonbase";
3664
+ }
3665
+ if (resolvedToken.kind === "base") {
3666
+ return baseIsEth ? "eth-base" : "erc20-base";
3667
+ }
3668
+ return "erc20-nonbase";
3669
+ })();
3703
3670
  return {
3704
3671
  client,
3672
+ tokens,
3673
+ contracts,
3674
+ resolvedToken,
3675
+ baseTokenAssetId,
3676
+ baseTokenL1,
3677
+ baseIsEth,
3705
3678
  l1AssetRouter,
3706
3679
  route,
3707
3680
  bridgehub,
@@ -3714,17 +3687,25 @@ async function commonCtx(p, client) {
3714
3687
  refundRecipient
3715
3688
  };
3716
3689
  }
3717
- function encodeNativeTokenVaultAssetId(chainId, address) {
3718
- const encoded = viem.encodeAbiParameters(
3719
- [
3720
- { type: "uint256", name: "originChainId" },
3721
- { type: "address", name: "ntv" },
3722
- { type: "address", name: "token" }
3723
- ],
3724
- [chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
3725
- );
3726
- return viem.keccak256(encoded);
3727
- }
3690
+ var k256hex = (s) => `0x${utils.bytesToHex(sha3.keccak_256(utils.utf8ToBytes(s)))}`.toLowerCase();
3691
+ var FORMAL_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
3692
+ var ETH_ADDRESS = "0x0000000000000000000000000000000000000001";
3693
+ var L2_ASSET_ROUTER_ADDRESS = "0x0000000000000000000000000000000000010003";
3694
+ var L2_NATIVE_TOKEN_VAULT_ADDRESS = "0x0000000000000000000000000000000000010004";
3695
+ var L1_MESSENGER_ADDRESS = "0x0000000000000000000000000000000000008008";
3696
+ var L2_BASE_TOKEN_ADDRESS = "0x000000000000000000000000000000000000800A";
3697
+ var TOPIC_L1_MESSAGE_SENT_NEW = k256hex("L1MessageSent(uint256,bytes32,bytes)");
3698
+ var TOPIC_L1_MESSAGE_SENT_LEG = k256hex("L1MessageSent(address,bytes32,bytes)");
3699
+ var TOPIC_CANONICAL_ASSIGNED = "0x779f441679936c5441b671969f37400b8c3ed0071cb47444431bf985754560df";
3700
+ var TOPIC_CANONICAL_SUCCESS = "0xe4def01b981193a97a9e81230d7b9f31812ceaf23f864a828a82c687911cb2df";
3701
+ var BUFFER = 20n;
3702
+ var TX_OVERHEAD_GAS = 10000n;
3703
+ var TX_MEMORY_OVERHEAD_GAS = 10n;
3704
+ var DEFAULT_PUBDATA_BYTES = 155n;
3705
+ var DEFAULT_ABI_BYTES = 400n;
3706
+ var SAFE_L1_BRIDGE_GAS = 600000n;
3707
+
3708
+ // src/adapters/viem/resources/utils.ts
3728
3709
  function encodeSecondBridgeArgs(token, amount, l2Receiver) {
3729
3710
  return viem.encodeAbiParameters(
3730
3711
  [
@@ -4218,7 +4199,7 @@ function createErrorHandlers(resource) {
4218
4199
  function wrap2(operation, fn, opts) {
4219
4200
  return run("INTERNAL", operation, fn, opts);
4220
4201
  }
4221
- function wrapAs9(kind, operation, fn, opts) {
4202
+ function wrapAs10(kind, operation, fn, opts) {
4222
4203
  return run(kind, operation, fn, opts);
4223
4204
  }
4224
4205
  async function toResult2(operation, fn, opts) {
@@ -4239,7 +4220,7 @@ function createErrorHandlers(resource) {
4239
4220
  return { ok: false, error: shaped };
4240
4221
  }
4241
4222
  }
4242
- return { wrap: wrap2, wrapAs: wrapAs9, toResult: toResult2 };
4223
+ return { wrap: wrap2, wrapAs: wrapAs10, toResult: toResult2 };
4243
4224
  }
4244
4225
 
4245
4226
  // src/core/resources/deposits/gas.ts
@@ -4465,13 +4446,7 @@ async function determineErc20L2Gas(input) {
4465
4446
  });
4466
4447
  }
4467
4448
  try {
4468
- const l2NativeTokenVault = (await ctx.client.contracts()).l2NativeTokenVault;
4469
- const l2TokenAddress = await ctx.client.l2.readContract({
4470
- address: l2NativeTokenVault.address,
4471
- abi: l2NativeTokenVault.abi,
4472
- functionName: "l2TokenAddress",
4473
- args: [l1Token]
4474
- });
4449
+ const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).read.l2TokenAddress([l1Token]);
4475
4450
  if (l2TokenAddress === viem.zeroAddress) {
4476
4451
  return quoteL2Gas2({
4477
4452
  ctx,
@@ -4653,6 +4628,28 @@ function routeEthDirect() {
4653
4628
  }
4654
4629
  };
4655
4630
  }
4631
+
4632
+ // src/core/utils/addr.ts
4633
+ var isHash66 = (x) => !!x && x.startsWith("0x") && x.length === 66;
4634
+ function isAddressEq(a, b) {
4635
+ return a.toLowerCase() === b.toLowerCase();
4636
+ }
4637
+ function isETH(token) {
4638
+ return isAddressEq(token, FORMAL_ETH_ADDRESS) || isAddressEq(token, L2_BASE_TOKEN_ADDRESS) || isAddressEq(token, ETH_ADDRESS);
4639
+ }
4640
+ function normalizeAddrEq(a, b) {
4641
+ if (!a || !b) return false;
4642
+ const normalize = (s) => {
4643
+ const hasPrefix = s.slice(0, 2).toLowerCase() === "0x";
4644
+ const body = hasPrefix ? s.slice(2) : s;
4645
+ return `0x${body.toLowerCase()}`;
4646
+ };
4647
+ return normalize(a) === normalize(b);
4648
+ }
4649
+ var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
4650
+ var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
4651
+
4652
+ // src/adapters/viem/resources/deposits/routes/erc20-nonbase.ts
4656
4653
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
4657
4654
  function routeErc20NonBase() {
4658
4655
  return {
@@ -4662,18 +4659,18 @@ function routeErc20NonBase() {
4662
4659
  "VALIDATION",
4663
4660
  OP_DEPOSITS.nonbase.assertNotEthAsset,
4664
4661
  () => {
4665
- if (isETH(p.token)) {
4662
+ if (ctx.resolvedToken?.kind === "eth" || isETH(p.token)) {
4666
4663
  throw new Error("erc20-nonbase route requires an ERC-20 token (not ETH).");
4667
4664
  }
4668
4665
  },
4669
4666
  { ctx: { token: p.token } }
4670
4667
  );
4671
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4668
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4672
4669
  await wrapAs3(
4673
4670
  "VALIDATION",
4674
4671
  OP_DEPOSITS.nonbase.assertNonBaseToken,
4675
4672
  () => {
4676
- if (normalizeAddrEq(baseToken, p.token)) {
4673
+ if (ctx.resolvedToken?.kind === "base" || normalizeAddrEq(baseToken, p.token)) {
4677
4674
  throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
4678
4675
  }
4679
4676
  },
@@ -4681,8 +4678,8 @@ function routeErc20NonBase() {
4681
4678
  );
4682
4679
  },
4683
4680
  async build(p, ctx) {
4684
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4685
- const baseIsEth = isETH(baseToken);
4681
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4682
+ const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
4686
4683
  const assetRouter = ctx.l1AssetRouter;
4687
4684
  const l2Gas = await determineErc20L2Gas({
4688
4685
  ctx,
@@ -4889,22 +4886,21 @@ function routeEthNonBase() {
4889
4886
  "VALIDATION",
4890
4887
  OP_DEPOSITS.ethNonBase.assertEthAsset,
4891
4888
  () => {
4892
- if (!isETH(p.token)) {
4889
+ if (ctx.resolvedToken?.kind !== "eth" && !isETH(p.token)) {
4893
4890
  throw new Error("eth-nonbase route requires ETH as the deposit asset.");
4894
4891
  }
4895
4892
  },
4896
4893
  { ctx: { token: p.token } }
4897
4894
  );
4898
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4899
4895
  await wrapAs4(
4900
4896
  "VALIDATION",
4901
4897
  OP_DEPOSITS.ethNonBase.assertNonEthBase,
4902
4898
  () => {
4903
- if (isETH(baseToken)) {
4899
+ if (ctx.baseIsEth) {
4904
4900
  throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
4905
4901
  }
4906
4902
  },
4907
- { ctx: { baseToken, chainIdL2: ctx.chainIdL2 } }
4903
+ { ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
4908
4904
  );
4909
4905
  const ethBal = await wrapAs4(
4910
4906
  "RPC",
@@ -4927,7 +4923,7 @@ function routeEthNonBase() {
4927
4923
  );
4928
4924
  },
4929
4925
  async build(p, ctx) {
4930
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4926
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4931
4927
  const l2TxModel = {
4932
4928
  to: p.to ?? ctx.sender,
4933
4929
  from: ctx.sender,
@@ -5100,13 +5096,13 @@ function routeErc20Base() {
5100
5096
  "VALIDATION",
5101
5097
  OP_DEPOSITS.base.assertErc20Asset,
5102
5098
  () => {
5103
- if (isETH(p.token)) {
5099
+ if (ctx.resolvedToken?.kind === "eth" || isETH(p.token)) {
5104
5100
  throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
5105
5101
  }
5106
5102
  },
5107
5103
  { ctx: { token: p.token } }
5108
5104
  );
5109
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
5105
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5110
5106
  await wrapAs5(
5111
5107
  "VALIDATION",
5112
5108
  OP_DEPOSITS.base.assertMatchesBase,
@@ -5119,7 +5115,7 @@ function routeErc20Base() {
5119
5115
  );
5120
5116
  },
5121
5117
  async build(p, ctx) {
5122
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
5118
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5123
5119
  const l2TxModel = {
5124
5120
  to: p.to ?? ctx.sender,
5125
5121
  from: ctx.sender,
@@ -5345,6 +5341,276 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
5345
5341
  return { l2Receipt, l2TxHash };
5346
5342
  }
5347
5343
 
5344
+ // src/core/codec/ntv.ts
5345
+ function createNTVCodec(deps) {
5346
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
5347
+ const encoded = deps.encode(
5348
+ ["uint256", "address", "address"],
5349
+ [originChainId, ntvAddress, tokenAddress]
5350
+ );
5351
+ return deps.keccak256(encoded);
5352
+ }
5353
+ return {
5354
+ encodeAssetId
5355
+ };
5356
+ }
5357
+
5358
+ // src/adapters/viem/resources/tokens/tokens.ts
5359
+ var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
5360
+ var ntvCodec = createNTVCodec({
5361
+ encode: (types, values) => viem.encodeAbiParameters(
5362
+ types.map((t, i) => ({ type: t, name: `arg${i}` })),
5363
+ values
5364
+ ),
5365
+ keccak256: (data) => viem.keccak256(data)
5366
+ });
5367
+ function createTokensResource(client) {
5368
+ let l2NtvL1ChainIdPromise = null;
5369
+ let baseTokenAssetIdPromise = null;
5370
+ let wethL1Promise = null;
5371
+ let wethL2Promise = null;
5372
+ async function getL1ChainId() {
5373
+ if (!l2NtvL1ChainIdPromise) {
5374
+ l2NtvL1ChainIdPromise = wrapAs6("INTERNAL", "getL1ChainId", async () => {
5375
+ const { l2NativeTokenVault } = await client.contracts();
5376
+ return await l2NativeTokenVault.read.L1_CHAIN_ID();
5377
+ });
5378
+ }
5379
+ return l2NtvL1ChainIdPromise;
5380
+ }
5381
+ async function getBaseTokenAssetId() {
5382
+ if (!baseTokenAssetIdPromise) {
5383
+ baseTokenAssetIdPromise = wrapAs6("INTERNAL", "baseTokenAssetId", async () => {
5384
+ const { l2NativeTokenVault } = await client.contracts();
5385
+ const assetId = await l2NativeTokenVault.read.BASE_TOKEN_ASSET_ID();
5386
+ return assetId;
5387
+ });
5388
+ }
5389
+ return baseTokenAssetIdPromise;
5390
+ }
5391
+ async function getWethL1() {
5392
+ if (!wethL1Promise) {
5393
+ wethL1Promise = wrapAs6("INTERNAL", "wethL1", async () => {
5394
+ const { l1NativeTokenVault } = await client.contracts();
5395
+ const weth = await l1NativeTokenVault.read.WETH_TOKEN();
5396
+ return weth;
5397
+ });
5398
+ }
5399
+ return wethL1Promise;
5400
+ }
5401
+ async function getWethL2() {
5402
+ if (!wethL2Promise) {
5403
+ wethL2Promise = wrapAs6("INTERNAL", "wethL2", async () => {
5404
+ const { l2NativeTokenVault } = await client.contracts();
5405
+ const weth = await l2NativeTokenVault.read.WETH_TOKEN();
5406
+ return weth;
5407
+ });
5408
+ }
5409
+ return wethL2Promise;
5410
+ }
5411
+ async function toL2Address(l1Token) {
5412
+ return wrapAs6("CONTRACT", "tokens.toL2Address", async () => {
5413
+ const normalized = normalizeL1Token(l1Token);
5414
+ const chainId = BigInt(await client.l2.getChainId());
5415
+ const baseToken = await client.baseToken(chainId);
5416
+ if (isAddressEq(normalized, baseToken)) {
5417
+ return L2_BASE_TOKEN_ADDRESS;
5418
+ }
5419
+ const { l2NativeTokenVault } = await client.contracts();
5420
+ const l2Token = await l2NativeTokenVault.read.l2TokenAddress([normalized]);
5421
+ return l2Token;
5422
+ });
5423
+ }
5424
+ async function toL1Address(l2Token) {
5425
+ return wrapAs6("CONTRACT", "tokens.toL1Address", async () => {
5426
+ if (isAddressEq(l2Token, ETH_ADDRESS)) return ETH_ADDRESS;
5427
+ if (isAddressEq(l2Token, L2_BASE_TOKEN_ADDRESS)) {
5428
+ const chainId = BigInt(await client.l2.getChainId());
5429
+ return await client.baseToken(chainId);
5430
+ }
5431
+ const { l2AssetRouter } = await client.contracts();
5432
+ const l1Token = await l2AssetRouter.read.l1TokenAddress([l2Token]);
5433
+ return l1Token;
5434
+ });
5435
+ }
5436
+ async function assetIdOfL1(l1Token) {
5437
+ return wrapAs6("CONTRACT", "tokens.assetIdOfL1", async () => {
5438
+ const normalized = normalizeL1Token(l1Token);
5439
+ const { l1NativeTokenVault } = await client.contracts();
5440
+ return await l1NativeTokenVault.read.assetId([normalized]);
5441
+ });
5442
+ }
5443
+ async function assetIdOfL2(l2Token) {
5444
+ return wrapAs6("CONTRACT", "tokens.assetIdOfL2", async () => {
5445
+ const { l2NativeTokenVault } = await client.contracts();
5446
+ return await l2NativeTokenVault.read.assetId([l2Token]);
5447
+ });
5448
+ }
5449
+ async function l2TokenFromAssetId(assetId) {
5450
+ return wrapAs6("CONTRACT", "tokens.l2TokenFromAssetId", async () => {
5451
+ const { l2NativeTokenVault } = await client.contracts();
5452
+ return await l2NativeTokenVault.read.tokenAddress([assetId]);
5453
+ });
5454
+ }
5455
+ async function l1TokenFromAssetId(assetId) {
5456
+ return wrapAs6("CONTRACT", "tokens.l1TokenFromAssetId", async () => {
5457
+ const { l1NativeTokenVault } = await client.contracts();
5458
+ return await l1NativeTokenVault.read.tokenAddress([assetId]);
5459
+ });
5460
+ }
5461
+ async function originChainId(assetId) {
5462
+ return wrapAs6("CONTRACT", "tokens.originChainId", async () => {
5463
+ const { l2NativeTokenVault } = await client.contracts();
5464
+ return await l2NativeTokenVault.read.originChainId([assetId]);
5465
+ });
5466
+ }
5467
+ async function baseTokenAssetId() {
5468
+ return getBaseTokenAssetId();
5469
+ }
5470
+ async function isChainEthBased() {
5471
+ return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
5472
+ const baseAssetId = await getBaseTokenAssetId();
5473
+ const l1ChainId = await getL1ChainId();
5474
+ const ethAssetId = ntvCodec.encodeAssetId(
5475
+ l1ChainId,
5476
+ L2_NATIVE_TOKEN_VAULT_ADDRESS,
5477
+ ETH_ADDRESS
5478
+ );
5479
+ return hexEq(baseAssetId, ethAssetId);
5480
+ });
5481
+ }
5482
+ async function wethL1() {
5483
+ return getWethL1();
5484
+ }
5485
+ async function wethL2() {
5486
+ return getWethL2();
5487
+ }
5488
+ async function computeL2BridgedAddress(args) {
5489
+ return wrapAs6("CONTRACT", "tokens.computeL2BridgedAddress", async () => {
5490
+ const normalized = normalizeL1Token(args.l1Token);
5491
+ const { l2NativeTokenVault } = await client.contracts();
5492
+ const predicted = await l2NativeTokenVault.read.calculateCreate2TokenAddress([
5493
+ args.originChainId,
5494
+ normalized
5495
+ ]);
5496
+ return predicted;
5497
+ });
5498
+ }
5499
+ async function resolve(ref, opts) {
5500
+ return wrapAs6("CONTRACT", "tokens.resolve", async () => {
5501
+ let chain;
5502
+ let address;
5503
+ if (typeof ref === "string") {
5504
+ chain = opts?.chain ?? "l1";
5505
+ address = ref;
5506
+ } else {
5507
+ chain = ref.chain;
5508
+ address = ref.address;
5509
+ }
5510
+ let l1;
5511
+ let l2;
5512
+ if (chain === "l1") {
5513
+ l1 = normalizeL1Token(address);
5514
+ l2 = await toL2Address(address);
5515
+ } else {
5516
+ l2 = address;
5517
+ l1 = await toL1Address(address);
5518
+ }
5519
+ const assetId = await assetIdOfL1(l1);
5520
+ const originChainIdVal = await originChainId(assetId);
5521
+ const [baseAssetId, wethL1Addr, wethL2Addr, ethBased] = await Promise.all([
5522
+ baseTokenAssetId(),
5523
+ wethL1(),
5524
+ wethL2(),
5525
+ isChainEthBased()
5526
+ ]);
5527
+ let kind;
5528
+ if (isAddressEq(l1, ETH_ADDRESS)) {
5529
+ kind = "eth";
5530
+ } else if (hexEq(assetId, baseAssetId)) {
5531
+ kind = "base";
5532
+ } else {
5533
+ kind = "erc20";
5534
+ }
5535
+ return {
5536
+ kind,
5537
+ l1,
5538
+ l2,
5539
+ assetId,
5540
+ originChainId: originChainIdVal,
5541
+ isChainEthBased: ethBased,
5542
+ baseTokenAssetId: baseAssetId,
5543
+ wethL1: wethL1Addr,
5544
+ wethL2: wethL2Addr
5545
+ };
5546
+ });
5547
+ }
5548
+ return {
5549
+ resolve,
5550
+ toL2Address,
5551
+ toL1Address,
5552
+ assetIdOfL1,
5553
+ assetIdOfL2,
5554
+ l2TokenFromAssetId,
5555
+ l1TokenFromAssetId,
5556
+ originChainId,
5557
+ baseTokenAssetId,
5558
+ isChainEthBased,
5559
+ wethL1,
5560
+ wethL2,
5561
+ computeL2BridgedAddress
5562
+ };
5563
+ }
5564
+
5565
+ // src/adapters/viem/resources/contracts/contracts.ts
5566
+ function createContractsResource(client) {
5567
+ async function addresses() {
5568
+ return client.ensureAddresses();
5569
+ }
5570
+ async function instances() {
5571
+ return client.contracts();
5572
+ }
5573
+ async function bridgehub() {
5574
+ const { bridgehub: bridgehub2 } = await instances();
5575
+ return bridgehub2;
5576
+ }
5577
+ async function l1AssetRouter() {
5578
+ const { l1AssetRouter: l1AssetRouter2 } = await instances();
5579
+ return l1AssetRouter2;
5580
+ }
5581
+ async function l1NativeTokenVault() {
5582
+ const { l1NativeTokenVault: l1NativeTokenVault2 } = await instances();
5583
+ return l1NativeTokenVault2;
5584
+ }
5585
+ async function l1Nullifier() {
5586
+ const { l1Nullifier: l1Nullifier2 } = await instances();
5587
+ return l1Nullifier2;
5588
+ }
5589
+ async function l2AssetRouter() {
5590
+ const { l2AssetRouter: l2AssetRouter2 } = await instances();
5591
+ return l2AssetRouter2;
5592
+ }
5593
+ async function l2NativeTokenVault() {
5594
+ const { l2NativeTokenVault: l2NativeTokenVault2 } = await instances();
5595
+ return l2NativeTokenVault2;
5596
+ }
5597
+ async function l2BaseTokenSystem() {
5598
+ const { l2BaseTokenSystem: l2BaseTokenSystem2 } = await instances();
5599
+ return l2BaseTokenSystem2;
5600
+ }
5601
+ return {
5602
+ addresses,
5603
+ instances,
5604
+ bridgehub,
5605
+ l1AssetRouter,
5606
+ l1NativeTokenVault,
5607
+ l1Nullifier,
5608
+ l2AssetRouter,
5609
+ l2NativeTokenVault,
5610
+ l2BaseTokenSystem
5611
+ };
5612
+ }
5613
+
5348
5614
  // src/adapters/viem/resources/deposits/index.ts
5349
5615
  var { wrap, toResult } = createErrorHandlers("deposits");
5350
5616
  var ROUTES = {
@@ -5353,9 +5619,11 @@ var ROUTES = {
5353
5619
  "erc20-nonbase": routeErc20NonBase(),
5354
5620
  "erc20-base": routeErc20Base()
5355
5621
  };
5356
- function createDepositsResource(client) {
5622
+ function createDepositsResource(client, tokens, contracts) {
5623
+ const tokensResource = tokens ?? createTokensResource(client);
5624
+ const contractsResource = contracts ?? createContractsResource(client);
5357
5625
  async function buildPlan(p) {
5358
- const ctx = await commonCtx(p, client);
5626
+ const ctx = await commonCtx(p, client, tokensResource, contractsResource);
5359
5627
  const route = ctx.route;
5360
5628
  await ROUTES[route].preflight?.(p, ctx);
5361
5629
  const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
@@ -5672,32 +5940,8 @@ function pickWithdrawRoute(args) {
5672
5940
  return "erc20-nonbase";
5673
5941
  }
5674
5942
 
5675
- // src/adapters/viem/resources/token-info.ts
5676
- async function ntvBaseAssetId(l2, ntv) {
5677
- return l2.readContract({
5678
- address: ntv,
5679
- abi: L2NativeTokenVault_default,
5680
- functionName: "BASE_TOKEN_ASSET_ID"
5681
- });
5682
- }
5683
- async function ntvL1ChainId(l2, ntv) {
5684
- return l2.readContract({
5685
- address: ntv,
5686
- abi: L2NativeTokenVault_default,
5687
- functionName: "L1_CHAIN_ID"
5688
- });
5689
- }
5690
- async function isEthBasedChain(l2, ntv) {
5691
- const [baseAssetId, l1ChainId] = await Promise.all([
5692
- ntvBaseAssetId(l2, ntv),
5693
- ntvL1ChainId(l2, ntv)
5694
- ]);
5695
- const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
5696
- return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
5697
- }
5698
-
5699
5943
  // src/adapters/viem/resources/withdrawals/context.ts
5700
- async function commonCtx2(p, client) {
5944
+ async function commonCtx2(p, client, tokens, contracts) {
5701
5945
  const sender = client.account.address;
5702
5946
  const {
5703
5947
  bridgehub,
@@ -5706,12 +5950,20 @@ async function commonCtx2(p, client) {
5706
5950
  l2AssetRouter,
5707
5951
  l2NativeTokenVault,
5708
5952
  l2BaseTokenSystem
5709
- } = await client.ensureAddresses();
5953
+ } = await contracts.addresses();
5710
5954
  const chainIdL2 = BigInt(await client.l2.getChainId());
5711
- const baseIsEth = await isEthBasedChain(client.l2, l2NativeTokenVault);
5955
+ const resolvedToken = await tokens.resolve(p.token, { chain: "l2" });
5956
+ const baseTokenAssetId = resolvedToken.baseTokenAssetId;
5957
+ const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
5958
+ const baseIsEth = resolvedToken.isChainEthBased;
5712
5959
  const route = pickWithdrawRoute({ token: p.token});
5713
5960
  return {
5714
5961
  client,
5962
+ tokens,
5963
+ contracts,
5964
+ resolvedToken,
5965
+ baseTokenAssetId,
5966
+ baseTokenL1,
5715
5967
  bridgehub,
5716
5968
  chainIdL2,
5717
5969
  sender,
@@ -5815,12 +6067,12 @@ function buildFeeBreakdown2(p) {
5815
6067
  }
5816
6068
 
5817
6069
  // src/adapters/viem/resources/withdrawals/routes/eth.ts
5818
- var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
6070
+ var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
5819
6071
  function routeEthBase() {
5820
6072
  return {
5821
6073
  async build(p, ctx) {
5822
6074
  const steps = [];
5823
- const data = await wrapAs6(
6075
+ const data = await wrapAs7(
5824
6076
  "INTERNAL",
5825
6077
  OP_WITHDRAWALS.eth.encodeWithdraw,
5826
6078
  () => Promise.resolve(
@@ -5870,14 +6122,14 @@ function routeEthBase() {
5870
6122
  }
5871
6123
  };
5872
6124
  }
5873
- var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
6125
+ var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
5874
6126
  function routeErc20NonBase2() {
5875
6127
  return {
5876
6128
  // TODO: add preflight validations here
5877
6129
  async build(p, ctx) {
5878
6130
  const steps = [];
5879
6131
  const approvals = [];
5880
- const current = await wrapAs7(
6132
+ const current = await wrapAs8(
5881
6133
  "CONTRACT",
5882
6134
  OP_WITHDRAWALS.erc20.allowance,
5883
6135
  () => ctx.client.l2.readContract({
@@ -5916,7 +6168,7 @@ function routeErc20NonBase2() {
5916
6168
  approveTxCandidate.maxFeePerGas = approveGas.maxFeePerGas;
5917
6169
  approveTxCandidate.maxPriorityFeePerGas = approveGas.maxPriorityFeePerGas;
5918
6170
  }
5919
- const approveSim = await wrapAs7(
6171
+ const approveSim = await wrapAs8(
5920
6172
  "CONTRACT",
5921
6173
  OP_WITHDRAWALS.erc20.estGas,
5922
6174
  () => ctx.client.l2.simulateContract({
@@ -5943,7 +6195,8 @@ function routeErc20NonBase2() {
5943
6195
  tx: approveTx
5944
6196
  });
5945
6197
  }
5946
- const ensure = await wrapAs7(
6198
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l2" }) : void 0);
6199
+ const assetId = resolved?.assetId ?? (await wrapAs8(
5947
6200
  "CONTRACT",
5948
6201
  OP_WITHDRAWALS.erc20.ensureRegistered,
5949
6202
  () => ctx.client.l2.simulateContract({
@@ -5957,8 +6210,7 @@ function routeErc20NonBase2() {
5957
6210
  ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
5958
6211
  message: "Failed to ensure token is registered in L2NativeTokenVault."
5959
6212
  }
5960
- );
5961
- const assetId = ensure.result;
6213
+ )).result;
5962
6214
  const assetData = viem.encodeAbiParameters(
5963
6215
  [
5964
6216
  { type: "uint256", name: "amount" },
@@ -5995,7 +6247,7 @@ function routeErc20NonBase2() {
5995
6247
  ...withdrawGas
5996
6248
  };
5997
6249
  } else {
5998
- const sim = await wrapAs7(
6250
+ const sim = await wrapAs8(
5999
6251
  "CONTRACT",
6000
6252
  OP_WITHDRAWALS.erc20.estGas,
6001
6253
  () => ctx.client.l2.simulateContract({
@@ -6024,7 +6276,7 @@ function routeErc20NonBase2() {
6024
6276
  tx: withdrawTx
6025
6277
  });
6026
6278
  const fees = buildFeeBreakdown2({
6027
- feeToken: await ctx.client.baseToken(ctx.chainIdL2),
6279
+ feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
6028
6280
  l2Gas: withdrawGas
6029
6281
  });
6030
6282
  return { steps, approvals, fees };
@@ -6063,7 +6315,7 @@ function messengerLogIndex(raw, opts) {
6063
6315
  }
6064
6316
  return (hits[index] ?? hits[0]).i;
6065
6317
  }
6066
- var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
6318
+ var { wrapAs: wrapAs9 } = createErrorHandlers("withdrawals");
6067
6319
  var IL1NullifierMini = [
6068
6320
  {
6069
6321
  type: "function",
@@ -6080,7 +6332,7 @@ var IL1NullifierMini = [
6080
6332
  function createFinalizationServices(client) {
6081
6333
  return {
6082
6334
  async fetchFinalizeDepositParams(l2TxHash) {
6083
- const parsed = await wrapAs8(
6335
+ const parsed = await wrapAs9(
6084
6336
  "RPC",
6085
6337
  OP_WITHDRAWALS.finalize.fetchParams.receipt,
6086
6338
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -6097,7 +6349,7 @@ function createFinalizationServices(client) {
6097
6349
  context: { l2TxHash }
6098
6350
  });
6099
6351
  }
6100
- const ev = await wrapAs8(
6352
+ const ev = await wrapAs9(
6101
6353
  "INTERNAL",
6102
6354
  OP_WITHDRAWALS.finalize.fetchParams.findMessage,
6103
6355
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
@@ -6107,7 +6359,7 @@ function createFinalizationServices(client) {
6107
6359
  message: "Failed to locate L1MessageSent event in L2 receipt."
6108
6360
  }
6109
6361
  );
6110
- const message = await wrapAs8(
6362
+ const message = await wrapAs9(
6111
6363
  "INTERNAL",
6112
6364
  OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
6113
6365
  () => {
@@ -6119,7 +6371,7 @@ function createFinalizationServices(client) {
6119
6371
  message: "Failed to decode withdrawal message."
6120
6372
  }
6121
6373
  );
6122
- const raw = await wrapAs8(
6374
+ const raw = await wrapAs9(
6123
6375
  "RPC",
6124
6376
  OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
6125
6377
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -6136,7 +6388,7 @@ function createFinalizationServices(client) {
6136
6388
  context: { l2TxHash }
6137
6389
  });
6138
6390
  }
6139
- const idx = await wrapAs8(
6391
+ const idx = await wrapAs9(
6140
6392
  "INTERNAL",
6141
6393
  OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
6142
6394
  () => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
@@ -6145,7 +6397,7 @@ function createFinalizationServices(client) {
6145
6397
  message: "Failed to derive messenger log index."
6146
6398
  }
6147
6399
  );
6148
- const proof = await wrapAs8(
6400
+ const proof = await wrapAs9(
6149
6401
  "RPC",
6150
6402
  OP_WITHDRAWALS.finalize.fetchParams.proof,
6151
6403
  () => client.zks.getL2ToL1LogProof(l2TxHash, idx),
@@ -6154,7 +6406,7 @@ function createFinalizationServices(client) {
6154
6406
  message: "Failed to fetch L2\u2192L1 log proof."
6155
6407
  }
6156
6408
  );
6157
- const chainId = await wrapAs8(
6409
+ const chainId = await wrapAs9(
6158
6410
  "RPC",
6159
6411
  OP_WITHDRAWALS.finalize.fetchParams.network,
6160
6412
  () => client.l2.getChainId(),
@@ -6170,7 +6422,7 @@ function createFinalizationServices(client) {
6170
6422
  message,
6171
6423
  merkleProof: proof.proof
6172
6424
  };
6173
- const { l1Nullifier } = await wrapAs8(
6425
+ const { l1Nullifier } = await wrapAs9(
6174
6426
  "INTERNAL",
6175
6427
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
6176
6428
  () => client.ensureAddresses(),
@@ -6182,7 +6434,7 @@ function createFinalizationServices(client) {
6182
6434
  return { params, nullifier: l1Nullifier };
6183
6435
  },
6184
6436
  async simulateFinalizeReadiness(params) {
6185
- const { l1Nullifier } = await wrapAs8(
6437
+ const { l1Nullifier } = await wrapAs9(
6186
6438
  "INTERNAL",
6187
6439
  OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
6188
6440
  () => client.ensureAddresses(),
@@ -6193,7 +6445,7 @@ function createFinalizationServices(client) {
6193
6445
  );
6194
6446
  const done = await (async () => {
6195
6447
  try {
6196
- const result = await wrapAs8(
6448
+ const result = await wrapAs9(
6197
6449
  "RPC",
6198
6450
  OP_WITHDRAWALS.finalize.readiness.isFinalized,
6199
6451
  () => client.l1.readContract({
@@ -6227,7 +6479,7 @@ function createFinalizationServices(client) {
6227
6479
  }
6228
6480
  },
6229
6481
  async isWithdrawalFinalized(key) {
6230
- const { l1Nullifier } = await wrapAs8(
6482
+ const { l1Nullifier } = await wrapAs9(
6231
6483
  "INTERNAL",
6232
6484
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
6233
6485
  () => client.ensureAddresses(),
@@ -6236,7 +6488,7 @@ function createFinalizationServices(client) {
6236
6488
  message: "Failed to ensure L1 Nullifier address."
6237
6489
  }
6238
6490
  );
6239
- return await wrapAs8(
6491
+ return await wrapAs9(
6240
6492
  "RPC",
6241
6493
  OP_WITHDRAWALS.finalize.isFinalized,
6242
6494
  () => client.l1.readContract({
@@ -6252,7 +6504,7 @@ function createFinalizationServices(client) {
6252
6504
  );
6253
6505
  },
6254
6506
  async estimateFinalization(params) {
6255
- const { l1Nullifier } = await wrapAs8(
6507
+ const { l1Nullifier } = await wrapAs9(
6256
6508
  "INTERNAL",
6257
6509
  OP_WITHDRAWALS.finalize.estimate,
6258
6510
  () => client.ensureAddresses(),
@@ -6261,7 +6513,7 @@ function createFinalizationServices(client) {
6261
6513
  message: "Failed to ensure L1 Nullifier address."
6262
6514
  }
6263
6515
  );
6264
- const gasLimit = await wrapAs8(
6516
+ const gasLimit = await wrapAs9(
6265
6517
  "RPC",
6266
6518
  OP_WITHDRAWALS.finalize.estimate,
6267
6519
  () => client.l1.estimateContractGas({
@@ -6285,7 +6537,7 @@ function createFinalizationServices(client) {
6285
6537
  let maxFeePerGas;
6286
6538
  let maxPriorityFeePerGas;
6287
6539
  try {
6288
- const fee = await wrapAs8(
6540
+ const fee = await wrapAs9(
6289
6541
  "RPC",
6290
6542
  OP_WITHDRAWALS.finalize.estimate,
6291
6543
  () => client.l1.estimateFeesPerGas(),
@@ -6304,7 +6556,7 @@ function createFinalizationServices(client) {
6304
6556
  })();
6305
6557
  maxPriorityFeePerGas = fee.maxPriorityFeePerGas ?? 0n;
6306
6558
  } catch {
6307
- const gasPrice = await wrapAs8(
6559
+ const gasPrice = await wrapAs9(
6308
6560
  "RPC",
6309
6561
  OP_WITHDRAWALS.finalize.estimate,
6310
6562
  () => client.l1.getGasPrice(),
@@ -6323,7 +6575,7 @@ function createFinalizationServices(client) {
6323
6575
  };
6324
6576
  },
6325
6577
  async finalizeDeposit(params) {
6326
- const { l1Nullifier } = await wrapAs8(
6578
+ const { l1Nullifier } = await wrapAs9(
6327
6579
  "INTERNAL",
6328
6580
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
6329
6581
  () => client.ensureAddresses(),
@@ -6387,11 +6639,13 @@ var ROUTES2 = {
6387
6639
  "erc20-nonbase": routeErc20NonBase2()
6388
6640
  // AssetRouter.withdraw for non-base ERC-20s
6389
6641
  };
6390
- function createWithdrawalsResource(client) {
6642
+ function createWithdrawalsResource(client, tokens, contracts) {
6391
6643
  const svc = createFinalizationServices(client);
6392
6644
  const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
6645
+ const tokensResource = tokens ?? createTokensResource(client);
6646
+ const contractsResource = contracts ?? createContractsResource(client);
6393
6647
  async function buildPlan(p) {
6394
- const ctx = await commonCtx2(p, client);
6648
+ const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
6395
6649
  await ROUTES2[ctx.route].preflight?.(p, ctx);
6396
6650
  const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
6397
6651
  return {
@@ -6738,55 +6992,13 @@ function createWithdrawalsResource(client) {
6738
6992
 
6739
6993
  // src/adapters/viem/sdk.ts
6740
6994
  function createViemSdk(client) {
6995
+ const tokens = createTokensResource(client);
6996
+ const contracts = createContractsResource(client);
6741
6997
  return {
6742
- deposits: createDepositsResource(client),
6743
- withdrawals: createWithdrawalsResource(client),
6744
- helpers: {
6745
- addresses: () => client.ensureAddresses(),
6746
- contracts: () => client.contracts(),
6747
- async l1AssetRouter() {
6748
- const { l1AssetRouter } = await client.contracts();
6749
- return l1AssetRouter;
6750
- },
6751
- async l1NativeTokenVault() {
6752
- const { l1NativeTokenVault } = await client.contracts();
6753
- return l1NativeTokenVault;
6754
- },
6755
- async l1Nullifier() {
6756
- const { l1Nullifier } = await client.contracts();
6757
- return l1Nullifier;
6758
- },
6759
- async baseToken(chainId) {
6760
- const id = chainId ?? BigInt(await client.l2.getChainId());
6761
- return client.baseToken(id);
6762
- },
6763
- async l2TokenAddress(l1Token) {
6764
- if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
6765
- return ETH_ADDRESS;
6766
- }
6767
- const base = await client.baseToken(BigInt(await client.l2.getChainId()));
6768
- if (isAddressEq(l1Token, base)) {
6769
- return L2_BASE_TOKEN_ADDRESS;
6770
- }
6771
- const { l2NativeTokenVault } = await client.contracts();
6772
- const addr = await l2NativeTokenVault.read.l2TokenAddress([l1Token]);
6773
- return addr;
6774
- },
6775
- async l1TokenAddress(l2Token) {
6776
- if (isAddressEq(l2Token, FORMAL_ETH_ADDRESS)) {
6777
- return FORMAL_ETH_ADDRESS;
6778
- }
6779
- const { l2AssetRouter } = await client.contracts();
6780
- const addr = await l2AssetRouter.read.l1TokenAddress([l2Token]);
6781
- return addr;
6782
- },
6783
- async assetId(l1Token) {
6784
- const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
6785
- const { l1NativeTokenVault } = await client.contracts();
6786
- const id = await l1NativeTokenVault.read.assetId([norm]);
6787
- return id;
6788
- }
6789
- }
6998
+ deposits: createDepositsResource(client, tokens, contracts),
6999
+ withdrawals: createWithdrawalsResource(client, tokens, contracts),
7000
+ tokens,
7001
+ contracts
6790
7002
  };
6791
7003
  }
6792
7004