@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
@@ -40,6 +40,8 @@ function normalizeAddrEq(a, b) {
40
40
  };
41
41
  return normalize(a) === normalize(b);
42
42
  }
43
+ var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
44
+ var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
43
45
 
44
46
  // src/core/errors/formatter.ts
45
47
  function elideMiddle(s, max = 96) {
@@ -3556,27 +3558,35 @@ var MailboxABI = [
3556
3558
  ];
3557
3559
  var Mailbox_default = MailboxABI;
3558
3560
 
3559
- // src/core/resources/deposits/route.ts
3560
- async function pickDepositRoute(client, chainIdL2, token) {
3561
- if (isETH(token)) {
3562
- const base2 = await client.baseToken(chainIdL2);
3563
- return isETH(base2) ? "eth-base" : "eth-nonbase";
3564
- }
3565
- const base = await client.baseToken(chainIdL2);
3566
- return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
3567
- }
3568
-
3569
3561
  // src/adapters/ethers/resources/deposits/context.ts
3570
- async function commonCtx(p, client) {
3571
- const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
3562
+ async function commonCtx(p, client, tokens, contracts) {
3563
+ const { bridgehub, l1AssetRouter } = await contracts.addresses();
3572
3564
  const { chainId } = await client.l2.getNetwork();
3573
3565
  const sender = await client.signer.getAddress();
3574
3566
  const gasPerPubdata = p.gasPerPubdata ?? 800n;
3575
3567
  const operatorTip = p.operatorTip ?? 0n;
3576
3568
  const refundRecipient = p.refundRecipient ?? sender;
3577
- const route = await pickDepositRoute(client, BigInt(chainId), p.token);
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
+ })();
3578
3582
  return {
3579
3583
  client,
3584
+ tokens,
3585
+ contracts,
3586
+ resolvedToken,
3587
+ baseTokenAssetId,
3588
+ baseTokenL1,
3589
+ baseIsEth,
3580
3590
  l1AssetRouter,
3581
3591
  route,
3582
3592
  bridgehub,
@@ -3589,14 +3599,6 @@ async function commonCtx(p, client) {
3589
3599
  refundRecipient
3590
3600
  };
3591
3601
  }
3592
- function encodeNativeTokenVaultAssetId(chainId, address) {
3593
- const abi = new ethers.AbiCoder();
3594
- const hex = abi.encode(
3595
- ["uint256", "address", "address"],
3596
- [chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
3597
- );
3598
- return ethers.ethers.keccak256(hex);
3599
- }
3600
3602
  function encodeNativeTokenVaultTransferData(amount, receiver, token) {
3601
3603
  return new ethers.AbiCoder().encode(["uint256", "address", "address"], [amount, receiver, token]);
3602
3604
  }
@@ -3964,7 +3966,7 @@ function createErrorHandlers(resource) {
3964
3966
  function wrap2(operation, fn, opts) {
3965
3967
  return run("INTERNAL", operation, fn, opts);
3966
3968
  }
3967
- function wrapAs8(kind, operation, fn, opts) {
3969
+ function wrapAs9(kind, operation, fn, opts) {
3968
3970
  return run(kind, operation, fn, opts);
3969
3971
  }
3970
3972
  async function toResult2(operation, fn, opts) {
@@ -3985,13 +3987,13 @@ function createErrorHandlers(resource) {
3985
3987
  return { ok: false, error: shaped };
3986
3988
  }
3987
3989
  }
3988
- return { wrap: wrap2, wrapAs: wrapAs8, toResult: toResult2 };
3990
+ return { wrap: wrap2, wrapAs: wrapAs9, toResult: toResult2 };
3989
3991
  }
3990
3992
 
3991
3993
  // src/adapters/ethers/resources/deposits/services/fee.ts
3992
3994
  var { wrapAs } = createErrorHandlers("deposits");
3993
- var encode = (abi, fn, args) => {
3994
- return new ethers.Interface(abi).encodeFunctionData(fn, args);
3995
+ var encode = (abi2, fn, args) => {
3996
+ return new ethers.Interface(abi2).encodeFunctionData(fn, args);
3995
3997
  };
3996
3998
  async function quoteL2BaseCost2(input) {
3997
3999
  const { ctx, l2GasLimit } = input;
@@ -4046,8 +4048,7 @@ async function determineErc20L2Gas(input) {
4046
4048
  });
4047
4049
  }
4048
4050
  try {
4049
- const { l2NativeTokenVault } = await ctx.client.contracts();
4050
- const l2TokenAddress = await l2NativeTokenVault.l2TokenAddress(l1Token);
4051
+ const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token);
4051
4052
  if (l2TokenAddress === "0x0000000000000000000000000000000000000000") {
4052
4053
  return quoteL2Gas2({
4053
4054
  ctx,
@@ -4116,7 +4117,7 @@ function buildFeeBreakdown(p) {
4116
4117
  function routeEthDirect() {
4117
4118
  return {
4118
4119
  async build(p, ctx) {
4119
- const bh = new ethers.Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
4120
+ const bh = await ctx.contracts.bridgehub();
4120
4121
  const l2TxModel = {
4121
4122
  to: p.to ?? ctx.sender,
4122
4123
  from: ctx.sender,
@@ -4193,14 +4194,14 @@ function routeEthDirect() {
4193
4194
  var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
4194
4195
  function routeErc20NonBase() {
4195
4196
  return {
4196
- // TODO: do we even need these validations?
4197
4197
  async preflight(p, ctx) {
4198
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
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);
4199
4200
  await wrapAs2(
4200
4201
  "VALIDATION",
4201
4202
  OP_DEPOSITS.nonbase.assertNonBaseToken,
4202
4203
  () => {
4203
- if (normalizeAddrEq(baseToken, p.token)) {
4204
+ if (resolved?.kind === "base" || resolved?.kind === "eth") {
4204
4205
  throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
4205
4206
  }
4206
4207
  },
@@ -4209,8 +4210,8 @@ function routeErc20NonBase() {
4209
4210
  },
4210
4211
  async build(p, ctx) {
4211
4212
  const l1Signer = ctx.client.getL1Signer();
4212
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4213
- const baseIsEth = isETH(baseToken);
4213
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4214
+ const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
4214
4215
  const l2GasParams = await determineErc20L2Gas({
4215
4216
  ctx,
4216
4217
  l1Token: p.token,
@@ -4297,7 +4298,7 @@ function routeErc20NonBase() {
4297
4298
  secondBridgeValue: 0n,
4298
4299
  secondBridgeCalldata
4299
4300
  };
4300
- const bh = (await ctx.client.contracts()).bridgehub;
4301
+ const bh = await ctx.contracts.bridgehub();
4301
4302
  const data = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
4302
4303
  requestStruct
4303
4304
  ]);
@@ -4346,26 +4347,26 @@ var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
4346
4347
  function routeEthNonBase() {
4347
4348
  return {
4348
4349
  async preflight(p, ctx) {
4350
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
4349
4351
  await wrapAs3(
4350
4352
  "VALIDATION",
4351
4353
  OP_DEPOSITS.ethNonBase.assertEthAsset,
4352
4354
  () => {
4353
- if (!isETH(p.token)) {
4355
+ if (resolved?.kind !== "eth" && !isETH(p.token)) {
4354
4356
  throw new Error("eth-nonbase route requires ETH as the deposit asset.");
4355
4357
  }
4356
4358
  },
4357
4359
  { ctx: { token: p.token } }
4358
4360
  );
4359
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4360
4361
  await wrapAs3(
4361
4362
  "VALIDATION",
4362
4363
  OP_DEPOSITS.ethNonBase.assertNonEthBase,
4363
4364
  () => {
4364
- if (isETH(baseToken)) {
4365
+ if (ctx.baseIsEth) {
4365
4366
  throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
4366
4367
  }
4367
4368
  },
4368
- { ctx: { baseToken, chainIdL2: ctx.chainIdL2 } }
4369
+ { ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
4369
4370
  );
4370
4371
  const ethBal = await wrapAs3(
4371
4372
  "RPC",
@@ -4390,7 +4391,7 @@ function routeEthNonBase() {
4390
4391
  },
4391
4392
  async build(p, ctx) {
4392
4393
  const l1Signer = ctx.client.getL1Signer();
4393
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4394
+ const baseToken = ctx.baseTokenL1;
4394
4395
  const l2TxModel = {
4395
4396
  to: p.to ?? ctx.sender,
4396
4397
  from: ctx.sender,
@@ -4455,11 +4456,10 @@ function routeEthNonBase() {
4455
4456
  secondBridgeValue: p.amount,
4456
4457
  secondBridgeCalldata
4457
4458
  };
4458
- const data = new ethers.Contract(
4459
- ctx.bridgehub,
4460
- IBridgehub_default,
4461
- ctx.client.l1
4462
- ).interface.encodeFunctionData("requestL2TransactionTwoBridges", [requestStruct]);
4459
+ const bridgehub = await ctx.contracts.bridgehub();
4460
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
4461
+ requestStruct
4462
+ ]);
4463
4463
  const l1TxCandidate = {
4464
4464
  to: ctx.bridgehub,
4465
4465
  data,
@@ -4505,17 +4505,18 @@ var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
4505
4505
  function routeErc20Base() {
4506
4506
  return {
4507
4507
  async preflight(p, ctx) {
4508
+ const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
4508
4509
  await wrapAs4(
4509
4510
  "VALIDATION",
4510
4511
  OP_DEPOSITS.base.assertErc20Asset,
4511
4512
  () => {
4512
- if (isETH(p.token)) {
4513
+ if (resolved?.kind === "eth" || isETH(p.token)) {
4513
4514
  throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
4514
4515
  }
4515
4516
  },
4516
4517
  { ctx: { token: p.token } }
4517
4518
  );
4518
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4519
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4519
4520
  await wrapAs4(
4520
4521
  "VALIDATION",
4521
4522
  OP_DEPOSITS.base.assertMatchesBase,
@@ -4530,7 +4531,7 @@ function routeErc20Base() {
4530
4531
  },
4531
4532
  async build(p, ctx) {
4532
4533
  const l1Signer = ctx.client.getL1Signer();
4533
- const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
4534
+ const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4534
4535
  const l2TxModel = {
4535
4536
  to: p.to ?? ctx.sender,
4536
4537
  from: ctx.sender,
@@ -4583,11 +4584,10 @@ function routeErc20Base() {
4583
4584
  l2Contract: p.to ?? ctx.sender,
4584
4585
  l2Value: p.amount
4585
4586
  });
4586
- const data = new ethers.Contract(
4587
- ctx.bridgehub,
4588
- IBridgehub_default,
4589
- ctx.client.l1
4590
- ).interface.encodeFunctionData("requestL2TransactionDirect", [requestStruct]);
4587
+ const bridgehub = await ctx.contracts.bridgehub();
4588
+ const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
4589
+ requestStruct
4590
+ ]);
4591
4591
  const l1TxCandidate = {
4592
4592
  to: ctx.bridgehub,
4593
4593
  data,
@@ -4630,6 +4630,282 @@ function routeErc20Base() {
4630
4630
  };
4631
4631
  }
4632
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
+
4633
4909
  // src/adapters/ethers/resources/deposits/index.ts
4634
4910
  var { wrap, toResult } = createErrorHandlers("deposits");
4635
4911
  var ROUTES = {
@@ -4638,9 +4914,11 @@ var ROUTES = {
4638
4914
  "erc20-nonbase": routeErc20NonBase(),
4639
4915
  "erc20-base": routeErc20Base()
4640
4916
  };
4641
- function createDepositsResource(client) {
4917
+ function createDepositsResource(client, tokens, contracts) {
4918
+ const tokensResource = tokens ?? createTokensResource(client);
4919
+ const contractsResource = contracts ?? createContractsResource(client);
4642
4920
  async function buildPlan(p) {
4643
- const ctx = await commonCtx(p, client);
4921
+ const ctx = await commonCtx(p, client, tokensResource, contractsResource);
4644
4922
  const route = ctx.route;
4645
4923
  await ROUTES[route].preflight?.(p, ctx);
4646
4924
  const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
@@ -4918,25 +5196,9 @@ function pickWithdrawRoute(args) {
4918
5196
  if (isL2BaseAlias) return "base";
4919
5197
  return "erc20-nonbase";
4920
5198
  }
4921
- async function ntvBaseAssetId(l2, ntv) {
4922
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
4923
- return await c.BASE_TOKEN_ASSET_ID();
4924
- }
4925
- async function ntvL1ChainId(l2, ntv) {
4926
- const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
4927
- return await c.L1_CHAIN_ID();
4928
- }
4929
- async function isEthBasedChain(l2, ntv) {
4930
- const [baseAssetId, l1ChainId] = await Promise.all([
4931
- ntvBaseAssetId(l2, ntv),
4932
- ntvL1ChainId(l2, ntv)
4933
- ]);
4934
- const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
4935
- return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
4936
- }
4937
5199
 
4938
5200
  // src/adapters/ethers/resources/withdrawals/context.ts
4939
- async function commonCtx2(p, client) {
5201
+ async function commonCtx2(p, client, tokens, contracts) {
4940
5202
  const sender = await client.signer.getAddress();
4941
5203
  const {
4942
5204
  bridgehub,
@@ -4945,13 +5207,21 @@ async function commonCtx2(p, client) {
4945
5207
  l2AssetRouter,
4946
5208
  l2NativeTokenVault,
4947
5209
  l2BaseTokenSystem
4948
- } = await client.ensureAddresses();
5210
+ } = await contracts.addresses();
4949
5211
  const { chainId } = await client.l2.getNetwork();
4950
5212
  const chainIdL2 = BigInt(chainId);
4951
- const baseIsEth = await isEthBasedChain(client.l2, l2NativeTokenVault);
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;
4952
5217
  const route = pickWithdrawRoute({ token: p.token});
4953
5218
  return {
4954
5219
  client,
5220
+ tokens,
5221
+ contracts,
5222
+ resolvedToken,
5223
+ baseTokenAssetId,
5224
+ baseTokenL1,
4955
5225
  bridgehub,
4956
5226
  chainIdL2,
4957
5227
  sender,
@@ -5055,13 +5325,13 @@ function buildFeeBreakdown2(p) {
5055
5325
  }
5056
5326
 
5057
5327
  // src/adapters/ethers/resources/withdrawals/routes/eth.ts
5058
- var { wrapAs: wrapAs5 } = createErrorHandlers("withdrawals");
5328
+ var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
5059
5329
  function routeEthBase() {
5060
5330
  return {
5061
5331
  async build(p, ctx) {
5062
5332
  const steps = [];
5063
- const base = (await ctx.client.contracts()).l2BaseTokenSystem;
5064
- const data = await wrapAs5(
5333
+ const base = await ctx.contracts.l2BaseTokenSystem();
5334
+ const data = await wrapAs6(
5065
5335
  "INTERNAL",
5066
5336
  OP_WITHDRAWALS.eth.encodeWithdraw,
5067
5337
  () => Promise.resolve(base.interface.encodeFunctionData("withdraw", [p.to ?? ctx.sender])),
@@ -5096,7 +5366,7 @@ function routeEthBase() {
5096
5366
  }
5097
5367
  };
5098
5368
  }
5099
- var { wrapAs: wrapAs6 } = createErrorHandlers("withdrawals");
5369
+ var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
5100
5370
  var SIG = {
5101
5371
  withdraw: "withdraw(bytes32,bytes)"
5102
5372
  };
@@ -5106,7 +5376,7 @@ function routeErc20NonBase2() {
5106
5376
  const steps = [];
5107
5377
  const approvals = [];
5108
5378
  const erc20 = new ethers.Contract(p.token, IERC20_default, ctx.client.getL2Signer());
5109
- const current = await wrapAs6(
5379
+ const current = await wrapAs7(
5110
5380
  "CONTRACT",
5111
5381
  OP_WITHDRAWALS.erc20.allowance,
5112
5382
  () => erc20.allowance(ctx.sender, ctx.l2NativeTokenVault),
@@ -5144,17 +5414,21 @@ function routeErc20NonBase2() {
5144
5414
  tx: approveTx
5145
5415
  });
5146
5416
  }
5147
- const ntv = (await ctx.client.contracts()).l2NativeTokenVault;
5148
- 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(
5149
5419
  "CONTRACT",
5150
5420
  OP_WITHDRAWALS.erc20.ensureRegistered,
5151
- () => 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
+ },
5152
5426
  {
5153
5427
  ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
5154
5428
  message: "Failed to ensure token is registered in L2NativeTokenVault."
5155
5429
  }
5156
5430
  );
5157
- const assetData = await wrapAs6(
5431
+ const assetData = await wrapAs7(
5158
5432
  "INTERNAL",
5159
5433
  OP_WITHDRAWALS.erc20.encodeAssetData,
5160
5434
  () => Promise.resolve(
@@ -5165,8 +5439,8 @@ function routeErc20NonBase2() {
5165
5439
  message: "Failed to encode burn/withdraw asset data."
5166
5440
  }
5167
5441
  );
5168
- const l2ar = (await ctx.client.contracts()).l2AssetRouter;
5169
- const dataWithdraw = await wrapAs6(
5442
+ const l2ar = await ctx.contracts.l2AssetRouter();
5443
+ const dataWithdraw = await wrapAs7(
5170
5444
  "INTERNAL",
5171
5445
  OP_WITHDRAWALS.erc20.encodeWithdraw,
5172
5446
  () => Promise.resolve(l2ar.interface.encodeFunctionData(SIG.withdraw, [assetId, assetData])),
@@ -5193,7 +5467,7 @@ function routeErc20NonBase2() {
5193
5467
  tx: withdrawTx
5194
5468
  });
5195
5469
  const fees = buildFeeBreakdown2({
5196
- feeToken: await ctx.client.baseToken(ctx.chainIdL2),
5470
+ feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
5197
5471
  l2Gas: withdrawGas
5198
5472
  });
5199
5473
  return { steps, approvals, fees };
@@ -5234,7 +5508,7 @@ function messengerLogIndex(raw, opts) {
5234
5508
  }
5235
5509
 
5236
5510
  // src/adapters/ethers/resources/withdrawals/services/finalization.ts
5237
- var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
5511
+ var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
5238
5512
  var IL1NullifierMini = [
5239
5513
  "function isWithdrawalFinalized(uint256,uint256,uint256) view returns (bool)"
5240
5514
  ];
@@ -5242,7 +5516,7 @@ function createFinalizationServices(client) {
5242
5516
  const { l1, l2, signer } = client;
5243
5517
  return {
5244
5518
  async fetchFinalizeDepositParams(l2TxHash) {
5245
- const parsed = await wrapAs7(
5519
+ const parsed = await wrapAs8(
5246
5520
  "RPC",
5247
5521
  OP_WITHDRAWALS.finalize.fetchParams.receipt,
5248
5522
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -5259,7 +5533,7 @@ function createFinalizationServices(client) {
5259
5533
  context: { l2TxHash }
5260
5534
  });
5261
5535
  }
5262
- const ev = await wrapAs7(
5536
+ const ev = await wrapAs8(
5263
5537
  "INTERNAL",
5264
5538
  OP_WITHDRAWALS.finalize.fetchParams.findMessage,
5265
5539
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
@@ -5269,7 +5543,7 @@ function createFinalizationServices(client) {
5269
5543
  message: "Failed to locate L1MessageSent event in L2 receipt."
5270
5544
  }
5271
5545
  );
5272
- const message = await wrapAs7(
5546
+ const message = await wrapAs8(
5273
5547
  "INTERNAL",
5274
5548
  OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
5275
5549
  () => Promise.resolve(ethers.AbiCoder.defaultAbiCoder().decode(["bytes"], ev.data)[0]),
@@ -5278,7 +5552,7 @@ function createFinalizationServices(client) {
5278
5552
  message: "Failed to decode withdrawal message."
5279
5553
  }
5280
5554
  );
5281
- const raw = await wrapAs7(
5555
+ const raw = await wrapAs8(
5282
5556
  "RPC",
5283
5557
  OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
5284
5558
  () => client.zks.getReceiptWithL2ToL1(l2TxHash),
@@ -5295,7 +5569,7 @@ function createFinalizationServices(client) {
5295
5569
  context: { l2TxHash }
5296
5570
  });
5297
5571
  }
5298
- const idx = await wrapAs7(
5572
+ const idx = await wrapAs8(
5299
5573
  "INTERNAL",
5300
5574
  OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
5301
5575
  () => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
@@ -5304,7 +5578,7 @@ function createFinalizationServices(client) {
5304
5578
  message: "Failed to derive messenger log index."
5305
5579
  }
5306
5580
  );
5307
- const proof = await wrapAs7(
5581
+ const proof = await wrapAs8(
5308
5582
  "RPC",
5309
5583
  OP_WITHDRAWALS.finalize.fetchParams.proof,
5310
5584
  () => client.zks.getL2ToL1LogProof(l2TxHash, idx),
@@ -5313,7 +5587,7 @@ function createFinalizationServices(client) {
5313
5587
  message: "Failed to fetch L2\u2192L1 log proof."
5314
5588
  }
5315
5589
  );
5316
- const { chainId } = await wrapAs7(
5590
+ const { chainId } = await wrapAs8(
5317
5591
  "RPC",
5318
5592
  OP_WITHDRAWALS.finalize.fetchParams.network,
5319
5593
  () => l2.getNetwork(),
@@ -5332,7 +5606,7 @@ function createFinalizationServices(client) {
5332
5606
  message,
5333
5607
  merkleProof: proof.proof
5334
5608
  };
5335
- const { l1Nullifier } = await wrapAs7(
5609
+ const { l1Nullifier } = await wrapAs8(
5336
5610
  "INTERNAL",
5337
5611
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
5338
5612
  () => client.ensureAddresses(),
@@ -5344,7 +5618,7 @@ function createFinalizationServices(client) {
5344
5618
  return { params, nullifier: l1Nullifier };
5345
5619
  },
5346
5620
  async simulateFinalizeReadiness(params) {
5347
- const { l1Nullifier } = await wrapAs7(
5621
+ const { l1Nullifier } = await wrapAs8(
5348
5622
  "INTERNAL",
5349
5623
  OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
5350
5624
  () => client.ensureAddresses(),
@@ -5356,7 +5630,7 @@ function createFinalizationServices(client) {
5356
5630
  const done = await (async () => {
5357
5631
  try {
5358
5632
  const cMini = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
5359
- const isFinalized = await wrapAs7(
5633
+ const isFinalized = await wrapAs8(
5360
5634
  "RPC",
5361
5635
  OP_WITHDRAWALS.finalize.readiness.isFinalized,
5362
5636
  () => cMini.isWithdrawalFinalized(
@@ -5384,7 +5658,7 @@ function createFinalizationServices(client) {
5384
5658
  }
5385
5659
  },
5386
5660
  async isWithdrawalFinalized(key) {
5387
- const { l1Nullifier } = await wrapAs7(
5661
+ const { l1Nullifier } = await wrapAs8(
5388
5662
  "INTERNAL",
5389
5663
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
5390
5664
  () => client.ensureAddresses(),
@@ -5394,7 +5668,7 @@ function createFinalizationServices(client) {
5394
5668
  }
5395
5669
  );
5396
5670
  const c = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
5397
- return await wrapAs7(
5671
+ return await wrapAs8(
5398
5672
  "RPC",
5399
5673
  OP_WITHDRAWALS.finalize.isFinalized,
5400
5674
  () => c.isWithdrawalFinalized(key.chainIdL2, key.l2BatchNumber, key.l2MessageIndex),
@@ -5405,7 +5679,7 @@ function createFinalizationServices(client) {
5405
5679
  );
5406
5680
  },
5407
5681
  async estimateFinalization(params) {
5408
- const { l1Nullifier } = await wrapAs7(
5682
+ const { l1Nullifier } = await wrapAs8(
5409
5683
  "INTERNAL",
5410
5684
  OP_WITHDRAWALS.finalize.estimate,
5411
5685
  () => client.ensureAddresses(),
@@ -5416,7 +5690,7 @@ function createFinalizationServices(client) {
5416
5690
  );
5417
5691
  const signer2 = client.getL1Signer();
5418
5692
  const c = new ethers.Contract(l1Nullifier, IL1Nullifier_default, signer2);
5419
- const gasLimit = await wrapAs7(
5693
+ const gasLimit = await wrapAs8(
5420
5694
  "RPC",
5421
5695
  OP_WITHDRAWALS.finalize.estimate,
5422
5696
  () => c.finalizeDeposit.estimateGas(params),
@@ -5431,7 +5705,7 @@ function createFinalizationServices(client) {
5431
5705
  message: "Failed to estimate gas for finalizeDeposit."
5432
5706
  }
5433
5707
  );
5434
- const feeData = await wrapAs7("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
5708
+ const feeData = await wrapAs8("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
5435
5709
  ctx: { where: "l1.getFeeData" },
5436
5710
  message: "Failed to estimate fee data for finalizeDeposit."
5437
5711
  });
@@ -5452,7 +5726,7 @@ function createFinalizationServices(client) {
5452
5726
  };
5453
5727
  },
5454
5728
  async finalizeDeposit(params) {
5455
- const { l1Nullifier } = await wrapAs7(
5729
+ const { l1Nullifier } = await wrapAs8(
5456
5730
  "INTERNAL",
5457
5731
  OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
5458
5732
  () => client.ensureAddresses(),
@@ -5513,11 +5787,13 @@ var ROUTES2 = {
5513
5787
  "erc20-nonbase": routeErc20NonBase2()
5514
5788
  // AssetRouter.withdraw for non-base ERC-20s
5515
5789
  };
5516
- function createWithdrawalsResource(client) {
5790
+ function createWithdrawalsResource(client, tokens, contracts) {
5517
5791
  const svc = createFinalizationServices(client);
5518
5792
  const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
5793
+ const tokensResource = tokens ?? createTokensResource(client);
5794
+ const contractsResource = contracts ?? createContractsResource(client);
5519
5795
  async function buildPlan(p) {
5520
- const ctx = await commonCtx2(p, client);
5796
+ const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
5521
5797
  await ROUTES2[ctx.route].preflight?.(p, ctx);
5522
5798
  const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
5523
5799
  return {
@@ -5841,57 +6117,13 @@ function createWithdrawalsResource(client) {
5841
6117
 
5842
6118
  // src/adapters/ethers/sdk.ts
5843
6119
  function createEthersSdk(client) {
6120
+ const tokens = createTokensResource(client);
6121
+ const contracts = createContractsResource(client);
5844
6122
  return {
5845
- deposits: createDepositsResource(client),
5846
- withdrawals: createWithdrawalsResource(client),
5847
- // TODO: might update to create dedicated resources for these
5848
- helpers: {
5849
- addresses: () => client.ensureAddresses(),
5850
- contracts: () => client.contracts(),
5851
- async l1AssetRouter() {
5852
- const { l1AssetRouter } = await client.contracts();
5853
- return l1AssetRouter;
5854
- },
5855
- async l1NativeTokenVault() {
5856
- const { l1NativeTokenVault } = await client.contracts();
5857
- return l1NativeTokenVault;
5858
- },
5859
- async l1Nullifier() {
5860
- const { l1Nullifier } = await client.contracts();
5861
- return l1Nullifier;
5862
- },
5863
- async baseToken(chainId) {
5864
- const id = chainId ?? BigInt((await client.l2.getNetwork()).chainId);
5865
- return client.baseToken(id);
5866
- },
5867
- async l2TokenAddress(l1Token) {
5868
- if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
5869
- return ETH_ADDRESS;
5870
- }
5871
- const { chainId } = await client.l2.getNetwork();
5872
- const base = await client.baseToken(BigInt(chainId));
5873
- if (isAddressEq(l1Token, base)) {
5874
- return L2_BASE_TOKEN_ADDRESS;
5875
- }
5876
- const { l2NativeTokenVault } = await client.contracts();
5877
- const addr = await l2NativeTokenVault.l2TokenAddress(l1Token);
5878
- return addr;
5879
- },
5880
- async l1TokenAddress(l2Token) {
5881
- if (isAddressEq(l2Token, ETH_ADDRESS)) {
5882
- return ETH_ADDRESS;
5883
- }
5884
- const { l2AssetRouter } = await client.contracts();
5885
- const addr = await l2AssetRouter.l1TokenAddress(l2Token);
5886
- return addr;
5887
- },
5888
- async assetId(l1Token) {
5889
- const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
5890
- const { l1NativeTokenVault } = await client.contracts();
5891
- const id = await l1NativeTokenVault.assetId(norm);
5892
- return id;
5893
- }
5894
- }
6123
+ deposits: createDepositsResource(client, tokens, contracts),
6124
+ withdrawals: createWithdrawalsResource(client, tokens, contracts),
6125
+ tokens,
6126
+ contracts
5895
6127
  };
5896
6128
  }
5897
6129