@matterlabs/zksync-js 0.0.14 → 0.0.16

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 (66) hide show
  1. package/dist/adapters/ethers/client.cjs.map +1 -1
  2. package/dist/adapters/ethers/client.d.ts +1 -2
  3. package/dist/adapters/ethers/client.js +4 -5
  4. package/dist/adapters/ethers/index.cjs +200 -32
  5. package/dist/adapters/ethers/index.cjs.map +1 -1
  6. package/dist/adapters/ethers/index.js +6 -7
  7. package/dist/adapters/ethers/resources/interop/index.d.ts +4 -1
  8. package/dist/adapters/ethers/resources/interop/services/finalization/bundle.d.ts +4 -0
  9. package/dist/adapters/ethers/resources/interop/services/gas.d.ts +12 -0
  10. package/dist/adapters/ethers/sdk.cjs +200 -32
  11. package/dist/adapters/ethers/sdk.cjs.map +1 -1
  12. package/dist/adapters/ethers/sdk.js +5 -6
  13. package/dist/adapters/viem/client.cjs +787 -3
  14. package/dist/adapters/viem/client.cjs.map +1 -1
  15. package/dist/adapters/viem/client.d.ts +6 -1
  16. package/dist/adapters/viem/client.js +4 -5
  17. package/dist/adapters/viem/index.cjs +6502 -2966
  18. package/dist/adapters/viem/index.cjs.map +1 -1
  19. package/dist/adapters/viem/index.d.ts +5 -0
  20. package/dist/adapters/viem/index.js +6 -7
  21. package/dist/adapters/viem/resources/interop/address.d.ts +18 -0
  22. package/dist/adapters/viem/resources/interop/attributes/resource.d.ts +6 -0
  23. package/dist/adapters/viem/resources/interop/context.d.ts +31 -0
  24. package/dist/adapters/viem/resources/interop/index.d.ts +65 -0
  25. package/dist/adapters/viem/resources/interop/resolvers.d.ts +4 -0
  26. package/dist/adapters/viem/resources/interop/routes/direct.d.ts +2 -0
  27. package/dist/adapters/viem/resources/interop/routes/indirect.d.ts +2 -0
  28. package/dist/adapters/viem/resources/interop/routes/types.d.ts +23 -0
  29. package/dist/adapters/viem/resources/interop/services/erc20.d.ts +25 -0
  30. package/dist/adapters/viem/resources/interop/services/fee.d.ts +12 -0
  31. package/dist/adapters/viem/resources/interop/services/finalization/bundle.d.ts +19 -0
  32. package/dist/adapters/viem/resources/interop/services/finalization/data-fetchers.d.ts +17 -0
  33. package/dist/adapters/viem/resources/interop/services/finalization/decoders.d.ts +11 -0
  34. package/dist/adapters/viem/resources/interop/services/finalization/index.d.ts +13 -0
  35. package/dist/adapters/viem/resources/interop/services/finalization/polling.d.ts +7 -0
  36. package/dist/adapters/viem/resources/interop/services/finalization/status.d.ts +5 -0
  37. package/dist/adapters/viem/resources/interop/services/finalization/topics.d.ts +4 -0
  38. package/dist/adapters/viem/resources/interop/services/gas.d.ts +12 -0
  39. package/dist/adapters/viem/resources/interop/services/starter-data.d.ts +6 -0
  40. package/dist/adapters/viem/resources/interop/types.d.ts +8 -0
  41. package/dist/adapters/viem/sdk.cjs +6665 -3173
  42. package/dist/adapters/viem/sdk.cjs.map +1 -1
  43. package/dist/adapters/viem/sdk.d.ts +8 -1
  44. package/dist/adapters/viem/sdk.js +5 -5
  45. package/dist/{chunk-7CAVFIMW.js → chunk-24TE2NNJ.js} +2 -3
  46. package/dist/{chunk-75IOOODG.js → chunk-3KH5PCD6.js} +1233 -31
  47. package/dist/{chunk-XKRNLFET.js → chunk-5HG2DUYW.js} +150 -375
  48. package/dist/{chunk-OTXPSNNC.js → chunk-CK5UFAZK.js} +64 -7
  49. package/dist/{chunk-HP3EWKJL.js → chunk-JSBMIT4S.js} +1 -1
  50. package/dist/{chunk-5RRJDPAJ.js → chunk-NJK325XV.js} +2 -2
  51. package/dist/chunk-NLUCYVMX.js +658 -0
  52. package/dist/{chunk-XDRCN4FC.js → chunk-SBGBYZJM.js} +10 -2
  53. package/dist/{chunk-J47RI3G7.js → chunk-TYYUG5GA.js} +1 -1
  54. package/dist/{chunk-JY62QO3W.js → chunk-UEKFQAOS.js} +420 -6
  55. package/dist/core/index.js +2 -3
  56. package/dist/core/resources/deposits/chains.d.ts +1 -0
  57. package/dist/core/resources/deposits/gas.d.ts +7 -0
  58. package/dist/core/resources/deposits/priority.d.ts +4 -0
  59. package/dist/core/resources/interop/protocol.d.ts +3 -0
  60. package/dist/core/types/errors.d.ts +1 -0
  61. package/dist/core/types/flows/interop.d.ts +0 -2
  62. package/dist/core/types/primitives.d.ts +2 -0
  63. package/dist/index.js +2 -3
  64. package/package.json +1 -1
  65. package/dist/chunk-DYJKK5FW.js +0 -417
  66. package/dist/chunk-EOBXYHTZ.js +0 -265
@@ -1,9 +1,9 @@
1
- import { createNTVCodec, toGasOverrides, buildFeeBreakdown, derivePriorityTxGasBreakdown, quoteL2Gas, quoteL1Gas, derivePriorityBodyGasEstimateCap, quoteL2Gas2 } from './chunk-EOBXYHTZ.js';
1
+ import { createNTVCodec, resolveCreateDepositL1GasLimit, isInteropFinalizationInfo, DEFAULT_POLL_MS, DEFAULT_TIMEOUT_MS, resolveIdsFromWaitable, parseBundleReceiptInfo, buildFinalizationInfo, parseBundleSentFromReceipt, createAttributesResource, pickInteropRoute, ZERO_HASH, toGasOverrides, applyPriorityL2GasLimitBuffer, buildFeeBreakdown, buildIndirectBundle, preflightIndirect, buildDirectBundle, preflightDirect, derivePriorityTxGasBreakdown, quoteL2Gas, quoteL1Gas, derivePriorityBodyGasEstimateCap, quoteL2Gas2, assertProtocolVersion } from './chunk-NLUCYVMX.js';
2
2
  import { findL1MessageSentLog, messengerLogIndex, pickWithdrawRoute } from './chunk-3HHUZXSV.js';
3
- import { createErrorHandlers, toZKsyncError, classifyReadinessFromRevert } from './chunk-XDRCN4FC.js';
4
- import { isHash66, IL1Nullifier_default, OP_WITHDRAWALS, createError, normalizeL1Token, isAddressEq, hexEq, OP_DEPOSITS, IERC20_default, isZKsyncError, isReceiptNotFound, IBridgehub_default, isETH, normalizeAddrEq, L2NativeTokenVault_default, IL2AssetRouter_default, IBaseToken_default } from './chunk-JY62QO3W.js';
5
- import { ETH_ADDRESS, TOPIC_CANONICAL_ASSIGNED, TOPIC_CANONICAL_SUCCESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS, SAFE_L1_BRIDGE_GAS, L2_ASSET_ROUTER_ADDRESS, FORMAL_ETH_ADDRESS } from './chunk-MT4X5FEO.js';
6
- import { keccak256, encodeAbiParameters, concat, decodeEventLog, decodeAbiParameters, encodeFunctionData, zeroAddress } from 'viem';
3
+ import { createErrorHandlers, toZKsyncError, classifyReadinessFromRevert } from './chunk-SBGBYZJM.js';
4
+ import { isHash66, IL1Nullifier_default, OP_WITHDRAWALS, createError, normalizeL1Token, isAddressEq, hexEq, OP_DEPOSITS, IERC20_default, isZKsyncError, isReceiptNotFound, OP_INTEROP, IInteropHandler_default, IInteropRootStorage_default, IInteropCenter_default, sleep, IERC7786Attributes_default, IBridgehub_default, isETH, normalizeAddrEq, L2NativeTokenVault_default, IL2AssetRouter_default, IBaseToken_default, assertNever } from './chunk-UEKFQAOS.js';
5
+ import { ETH_ADDRESS, TOPIC_CANONICAL_ASSIGNED, TOPIC_CANONICAL_SUCCESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS, L2_INTEROP_ROOT_STORAGE_ADDRESS, BUFFER, SAFE_L1_BRIDGE_GAS, L2_ASSET_ROUTER_ADDRESS, FORMAL_ETH_ADDRESS } from './chunk-MT4X5FEO.js';
6
+ import { keccak256, encodeAbiParameters, toBytes, concat, decodeEventLog, decodeAbiParameters, createWalletClient, custom, encodeFunctionData, createPublicClient, http, encodeEventTopics, numberToHex, zeroAddress, getAddress, toHex } from 'viem';
7
7
 
8
8
  // src/adapters/viem/resources/deposits/context.ts
9
9
  async function commonCtx(p, client, tokens, contracts) {
@@ -372,7 +372,10 @@ function routeEthDirect() {
372
372
  l2Calldata,
373
373
  gasPerPubdata: ctx.gasPerPubdata
374
374
  });
375
- const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
375
+ const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
376
+ chainIdL2: ctx.chainIdL2,
377
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
378
+ });
376
379
  const l2GasParams = await quoteL2Gas3({
377
380
  ctx,
378
381
  route: "eth-base",
@@ -425,12 +428,21 @@ function routeEthDirect() {
425
428
  tx: l1TxCandidate,
426
429
  overrides: ctx.gasOverrides
427
430
  });
431
+ let bridgeTx = { ...sim.request };
432
+ if (l1Gas) {
433
+ bridgeTx = {
434
+ ...bridgeTx,
435
+ gas: l1Gas.gasLimit,
436
+ maxFeePerGas: l1Gas.maxFeePerGas,
437
+ maxPriorityFeePerGas: l1Gas.maxPriorityFeePerGas
438
+ };
439
+ }
428
440
  const steps = [
429
441
  {
430
442
  key: "bridgehub:direct",
431
443
  kind: "bridgehub:direct",
432
444
  description: "Bridge ETH via Bridgehub.requestL2TransactionDirect",
433
- tx: { ...sim.request, ...l1Gas }
445
+ tx: bridgeTx
434
446
  }
435
447
  ];
436
448
  const fees = buildFeeBreakdown({
@@ -491,7 +503,10 @@ async function getPriorityGasModel(input) {
491
503
  gasPerPubdata: input.ctx.gasPerPubdata
492
504
  });
493
505
  const model = {
494
- priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
506
+ priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
507
+ chainIdL2: input.ctx.chainIdL2,
508
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
509
+ })
495
510
  };
496
511
  if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === zeroAddress) {
497
512
  model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
@@ -780,7 +795,10 @@ async function getPriorityGasModel2(input) {
780
795
  gasPerPubdata: input.ctx.gasPerPubdata
781
796
  });
782
797
  const model = {
783
- priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
798
+ priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
799
+ chainIdL2: input.ctx.chainIdL2,
800
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
801
+ })
784
802
  };
785
803
  if (input.ctx.resolvedToken.l2.toLowerCase() === zeroAddress) {
786
804
  model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
@@ -916,7 +934,7 @@ function routeEthNonBase() {
916
934
  const requestStruct = {
917
935
  chainId: ctx.chainIdL2,
918
936
  mintValue,
919
- l2Value: p.amount,
937
+ l2Value: 0n,
920
938
  l2GasLimit: l2Gas.gasLimit,
921
939
  l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
922
940
  refundRecipient: ctx.refundRecipient,
@@ -924,6 +942,7 @@ function routeEthNonBase() {
924
942
  secondBridgeValue: p.amount,
925
943
  secondBridgeCalldata
926
944
  };
945
+ const bridgehubValue = p.amount;
927
946
  let bridgeTx;
928
947
  let calldata;
929
948
  if (needsApprove) {
@@ -932,8 +951,7 @@ function routeEthNonBase() {
932
951
  abi: IBridgehub_default,
933
952
  functionName: "requestL2TransactionTwoBridges",
934
953
  args: [requestStruct],
935
- value: p.amount,
936
- // base ≠ ETH ⇒ msg.value == secondBridgeValue
954
+ value: bridgehubValue,
937
955
  account: ctx.client.account
938
956
  };
939
957
  calldata = encodeFunctionData({
@@ -950,7 +968,7 @@ function routeEthNonBase() {
950
968
  abi: IBridgehub_default,
951
969
  functionName: "requestL2TransactionTwoBridges",
952
970
  args: [requestStruct],
953
- value: p.amount,
971
+ value: bridgehubValue,
954
972
  account: ctx.client.account
955
973
  }),
956
974
  {
@@ -968,7 +986,7 @@ function routeEthNonBase() {
968
986
  const l1TxCandidate = {
969
987
  to: ctx.bridgehub,
970
988
  data: calldata,
971
- value: p.amount,
989
+ value: bridgehubValue,
972
990
  from: ctx.sender,
973
991
  ...ctx.gasOverrides
974
992
  };
@@ -1047,7 +1065,10 @@ function routeErc20Base() {
1047
1065
  l2Calldata,
1048
1066
  gasPerPubdata: ctx.gasPerPubdata
1049
1067
  });
1050
- const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
1068
+ const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
1069
+ chainIdL2: ctx.chainIdL2,
1070
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
1071
+ });
1051
1072
  const l2Gas = await quoteL2Gas3({
1052
1073
  ctx,
1053
1074
  route: "erc20-base",
@@ -1579,6 +1600,7 @@ function createDepositsResource(client, tokens, contracts) {
1579
1600
  async () => {
1580
1601
  const plan = await prepare(p);
1581
1602
  const stepHashes = {};
1603
+ const chainIdL2 = BigInt(await client.l2.getChainId());
1582
1604
  const from = client.account.address;
1583
1605
  let next;
1584
1606
  if (typeof p.l1TxOverrides?.nonce === "number") {
@@ -1630,6 +1652,7 @@ function createDepositsResource(client, tokens, contracts) {
1630
1652
  }
1631
1653
  if (!p.l1TxOverrides?.gasLimit) {
1632
1654
  try {
1655
+ const preparedGasLimit = step.tx.gas;
1633
1656
  const feePart = step.tx.maxFeePerGas != null && step.tx.maxPriorityFeePerGas != null ? {
1634
1657
  maxFeePerGas: step.tx.maxFeePerGas,
1635
1658
  maxPriorityFeePerGas: step.tx.maxPriorityFeePerGas
@@ -1648,7 +1671,12 @@ function createDepositsResource(client, tokens, contracts) {
1648
1671
  const gas = await client.l1.estimateContractGas({
1649
1672
  ...params
1650
1673
  });
1651
- step.tx.gas = gas * 115n / 100n;
1674
+ step.tx.gas = resolveCreateDepositL1GasLimit({
1675
+ chainIdL2,
1676
+ stepKey: step.key,
1677
+ preparedGasLimit,
1678
+ estimatedGasLimit: gas
1679
+ });
1652
1680
  } catch {
1653
1681
  }
1654
1682
  }
@@ -2409,7 +2437,7 @@ var ROUTES2 = {
2409
2437
  };
2410
2438
  function createWithdrawalsResource(client, tokens, contracts) {
2411
2439
  const svc = createFinalizationServices(client);
2412
- const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
2440
+ const { wrap: wrap7, toResult: toResult3 } = createErrorHandlers("withdrawals");
2413
2441
  const tokensResource = tokens ?? createTokensResource(client);
2414
2442
  const contractsResource = contracts ?? createContractsResource(client);
2415
2443
  async function buildPlan(p) {
@@ -2430,23 +2458,23 @@ function createWithdrawalsResource(client, tokens, contracts) {
2430
2458
  };
2431
2459
  }
2432
2460
  const finalizeCache = /* @__PURE__ */ new Map();
2433
- const quote = (p) => wrap2(OP_WITHDRAWALS.quote, async () => (await buildPlan(p)).summary, {
2461
+ const quote = (p) => wrap7(OP_WITHDRAWALS.quote, async () => (await buildPlan(p)).summary, {
2434
2462
  message: "Internal error while preparing a withdrawal quote.",
2435
2463
  ctx: { token: p.token, where: "withdrawals.quote" }
2436
2464
  });
2437
- const tryQuote = (p) => toResult2(OP_WITHDRAWALS.tryQuote, () => quote(p), {
2465
+ const tryQuote = (p) => toResult3(OP_WITHDRAWALS.tryQuote, () => quote(p), {
2438
2466
  message: "Internal error while preparing a withdrawal quote.",
2439
2467
  ctx: { token: p.token, where: "withdrawals.tryQuote" }
2440
2468
  });
2441
- const prepare = (p) => wrap2(OP_WITHDRAWALS.prepare, () => buildPlan(p), {
2469
+ const prepare = (p) => wrap7(OP_WITHDRAWALS.prepare, () => buildPlan(p), {
2442
2470
  message: "Internal error while preparing a withdrawal plan.",
2443
2471
  ctx: { token: p.token, where: "withdrawals.prepare" }
2444
2472
  });
2445
- const tryPrepare = (p) => toResult2(OP_WITHDRAWALS.tryPrepare, () => prepare(p), {
2473
+ const tryPrepare = (p) => toResult3(OP_WITHDRAWALS.tryPrepare, () => prepare(p), {
2446
2474
  message: "Internal error while preparing a withdrawal plan.",
2447
2475
  ctx: { token: p.token, where: "withdrawals.tryPrepare" }
2448
2476
  });
2449
- const create = (p) => wrap2(
2477
+ const create = (p) => wrap7(
2450
2478
  OP_WITHDRAWALS.create,
2451
2479
  async () => {
2452
2480
  const plan = await prepare(p);
@@ -2550,11 +2578,11 @@ function createWithdrawalsResource(client, tokens, contracts) {
2550
2578
  ctx: { token: p.token, amount: p.amount, to: p.to, where: "withdrawals.create" }
2551
2579
  }
2552
2580
  );
2553
- const tryCreate = (p) => toResult2(OP_WITHDRAWALS.tryCreate, () => create(p), {
2581
+ const tryCreate = (p) => toResult3(OP_WITHDRAWALS.tryCreate, () => create(p), {
2554
2582
  message: "Internal error while creating withdrawal transactions.",
2555
2583
  ctx: { token: p.token, amount: p.amount, to: p.to, where: "withdrawals.tryCreate" }
2556
2584
  });
2557
- const status = (h) => wrap2(
2585
+ const status = (h) => wrap7(
2558
2586
  OP_WITHDRAWALS.status,
2559
2587
  async () => {
2560
2588
  const l2TxHash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
@@ -2609,7 +2637,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
2609
2637
  const wait = (h, opts = {
2610
2638
  for: "l2",
2611
2639
  pollMs: 5500
2612
- }) => wrap2(
2640
+ }) => wrap7(
2613
2641
  OP_WITHDRAWALS.wait,
2614
2642
  async () => {
2615
2643
  const l2Hash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
@@ -2678,7 +2706,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
2678
2706
  }
2679
2707
  }
2680
2708
  );
2681
- const finalize = (l2TxHash) => wrap2(
2709
+ const finalize = (l2TxHash) => wrap7(
2682
2710
  OP_WITHDRAWALS.finalize.send,
2683
2711
  async () => {
2684
2712
  const pack = await (async () => {
@@ -2750,11 +2778,11 @@ function createWithdrawalsResource(client, tokens, contracts) {
2750
2778
  ctx: { l2TxHash, where: "withdrawals.finalize" }
2751
2779
  }
2752
2780
  );
2753
- const tryFinalize = (l2TxHash) => toResult2("withdrawals.tryFinalize", () => finalize(l2TxHash), {
2781
+ const tryFinalize = (l2TxHash) => toResult3("withdrawals.tryFinalize", () => finalize(l2TxHash), {
2754
2782
  message: "Internal error while attempting to tryFinalize withdrawal.",
2755
2783
  ctx: { l2TxHash, where: "withdrawals.tryFinalize" }
2756
2784
  });
2757
- const tryWait = (h, opts) => toResult2(
2785
+ const tryWait = (h, opts) => toResult3(
2758
2786
  OP_WITHDRAWALS.tryWait,
2759
2787
  async () => {
2760
2788
  const v = await wait(h, opts);
@@ -2789,17 +2817,1191 @@ function createWithdrawalsResource(client, tokens, contracts) {
2789
2817
  tryWait
2790
2818
  };
2791
2819
  }
2820
+ function getInteropAttributes(params, ctx) {
2821
+ const bundleAttributes = [];
2822
+ if (params.execution?.only) {
2823
+ bundleAttributes.push(ctx.attributes.bundle.executionAddress(params.execution.only));
2824
+ }
2825
+ if (params.unbundling?.by) {
2826
+ bundleAttributes.push(ctx.attributes.bundle.unbundlerAddress(params.unbundling.by));
2827
+ }
2828
+ bundleAttributes.push(ctx.attributes.bundle.useFixedFee(params.fee?.useFixed ?? false));
2829
+ const callAttributes = params.actions.map((action) => {
2830
+ switch (action.type) {
2831
+ case "sendNative": {
2832
+ const baseMatches = ctx.baseTokens.src.toLowerCase() === ctx.baseTokens.dst.toLowerCase();
2833
+ if (baseMatches) {
2834
+ return [ctx.attributes.call.interopCallValue(action.amount)];
2835
+ }
2836
+ return [ctx.attributes.call.indirectCall(action.amount)];
2837
+ }
2838
+ case "call":
2839
+ if (action.value && action.value > 0n) {
2840
+ return [ctx.attributes.call.interopCallValue(action.value)];
2841
+ }
2842
+ return [];
2843
+ case "sendErc20":
2844
+ return [ctx.attributes.call.indirectCall(0n)];
2845
+ default:
2846
+ assertNever(action);
2847
+ }
2848
+ });
2849
+ return { bundleAttributes, callAttributes };
2850
+ }
2851
+ function createViemAttributesResource() {
2852
+ const encode = (fn, args) => encodeFunctionData({
2853
+ abi: IERC7786Attributes_default,
2854
+ functionName: fn,
2855
+ args
2856
+ });
2857
+ return createAttributesResource({ encode });
2858
+ }
2859
+ var PREFIX_EVM_CHAIN = toBytes("0x00010000");
2860
+ var PREFIX_EVM_ADDRESS = toBytes("0x000100000014");
2861
+ function formatInteropEvmChain(chainId) {
2862
+ const chainRef = toBytes(toHex(chainId));
2863
+ const chainRefLength = toBytes(toHex(chainRef.length, { size: 1 }));
2864
+ const payload = concat([PREFIX_EVM_CHAIN, chainRefLength, chainRef, new Uint8Array([0])]);
2865
+ return toHex(payload);
2866
+ }
2867
+ function formatInteropEvmAddress(address) {
2868
+ const normalized = getAddress(address);
2869
+ const addrBytes = toBytes(normalized);
2870
+ const payload = concat([PREFIX_EVM_ADDRESS, addrBytes]);
2871
+ return toHex(payload);
2872
+ }
2873
+ var interopCodec = {
2874
+ formatChain: formatInteropEvmChain,
2875
+ formatAddress: formatInteropEvmAddress
2876
+ };
2877
+ function getErc20Tokens(params) {
2878
+ const erc20Tokens = /* @__PURE__ */ new Map();
2879
+ for (const action of params.actions) {
2880
+ if (action.type !== "sendErc20") continue;
2881
+ erc20Tokens.set(action.token.toLowerCase(), action.token);
2882
+ }
2883
+ return Array.from(erc20Tokens.values());
2884
+ }
2885
+ function buildEnsureTokenSteps(erc20Tokens, ctx) {
2886
+ if (erc20Tokens.length === 0) return [];
2887
+ return erc20Tokens.map((token) => ({
2888
+ key: `ensure-token:${token.toLowerCase()}`,
2889
+ kind: "interop.ntv.ensure-token",
2890
+ description: `Ensure ${token} is registered in the native token vault`,
2891
+ tx: {
2892
+ to: ctx.l2NativeTokenVault,
2893
+ data: encodeFunctionData({
2894
+ abi: L2NativeTokenVault_default,
2895
+ functionName: "ensureTokenIsRegistered",
2896
+ args: [token]
2897
+ }),
2898
+ ...ctx.gasOverrides
2899
+ }
2900
+ }));
2901
+ }
2902
+ async function buildApproveSteps(approvals, ctx) {
2903
+ const steps = [];
2904
+ for (const approval of approvals) {
2905
+ const currentAllowance = await ctx.client.l2.readContract({
2906
+ address: approval.token,
2907
+ abi: IERC20_default,
2908
+ functionName: "allowance",
2909
+ args: [ctx.sender, approval.spender]
2910
+ });
2911
+ if (currentAllowance < approval.amount) {
2912
+ steps.push({
2913
+ key: `approve:${approval.token}:${approval.spender}`,
2914
+ kind: "approve",
2915
+ description: `Approve ${approval.spender} to spend ${approval.amount} of ${approval.token}`,
2916
+ tx: {
2917
+ to: approval.token,
2918
+ data: encodeFunctionData({
2919
+ abi: IERC20_default,
2920
+ functionName: "approve",
2921
+ args: [approval.spender, approval.amount]
2922
+ }),
2923
+ ...ctx.gasOverrides
2924
+ }
2925
+ });
2926
+ }
2927
+ }
2928
+ return steps;
2929
+ }
2930
+ async function resolveErc20AssetIds(erc20Tokens, ctx) {
2931
+ const assetIds = /* @__PURE__ */ new Map();
2932
+ if (erc20Tokens.length === 0) return assetIds;
2933
+ for (const token of erc20Tokens) {
2934
+ const { result: assetId } = await ctx.client.l2.simulateContract({
2935
+ address: ctx.l2NativeTokenVault,
2936
+ abi: L2NativeTokenVault_default,
2937
+ functionName: "ensureTokenIsRegistered",
2938
+ args: [token],
2939
+ account: ctx.sender
2940
+ });
2941
+ assetIds.set(token.toLowerCase(), assetId);
2942
+ }
2943
+ return assetIds;
2944
+ }
2945
+
2946
+ // src/adapters/viem/resources/interop/services/starter-data.ts
2947
+ async function getStarterData(params, ctx, erc20AssetIds) {
2948
+ const starterData = [];
2949
+ for (const action of params.actions) {
2950
+ switch (action.type) {
2951
+ case "sendErc20": {
2952
+ const assetId = erc20AssetIds.get(action.token.toLowerCase());
2953
+ if (!assetId) {
2954
+ throw new Error(`Missing precomputed assetId for token ${action.token}.`);
2955
+ }
2956
+ const transferData = encodeNativeTokenVaultTransferData(
2957
+ action.amount,
2958
+ action.to,
2959
+ action.token
2960
+ );
2961
+ const assetRouterPayload = encodeSecondBridgeDataV1(assetId, transferData);
2962
+ starterData.push({ assetRouterPayload });
2963
+ break;
2964
+ }
2965
+ case "sendNative":
2966
+ if (!ctx.baseTokens.matches) {
2967
+ const assetId = await ctx.tokens.baseTokenAssetId();
2968
+ const transferData = encodeNativeTokenVaultTransferData(
2969
+ action.amount,
2970
+ action.to,
2971
+ ctx.baseTokens.src
2972
+ );
2973
+ const assetRouterPayload = encodeSecondBridgeDataV1(assetId, transferData);
2974
+ starterData.push({ assetRouterPayload });
2975
+ } else {
2976
+ starterData.push({});
2977
+ }
2978
+ break;
2979
+ case "call":
2980
+ starterData.push({});
2981
+ break;
2982
+ default:
2983
+ assertNever(action);
2984
+ }
2985
+ }
2986
+ return starterData;
2987
+ }
2988
+
2989
+ // src/adapters/viem/resources/interop/services/fee.ts
2990
+ var { wrap: wrap2 } = createErrorHandlers("interop");
2991
+ async function buildFeeInfo(params, ctx, numStarters) {
2992
+ const useFixed = params.fee?.useFixed ?? false;
2993
+ if (useFixed) {
2994
+ const zkFeePerCall = await wrap2(
2995
+ OP_INTEROP.svc.fees.zkInteropFee,
2996
+ () => ctx.client.l2.readContract({
2997
+ address: ctx.interopCenter,
2998
+ abi: IInteropCenter_default,
2999
+ functionName: "ZK_INTEROP_FEE"
3000
+ }),
3001
+ { message: "Failed to fetch ZK interop fee from InteropCenter." }
3002
+ );
3003
+ const zkFeeTotal = zkFeePerCall * BigInt(numStarters);
3004
+ const zkTokenAddress = await wrap2(
3005
+ OP_INTEROP.svc.fees.zkToken,
3006
+ () => ctx.client.l2.readContract({
3007
+ address: ctx.interopCenter,
3008
+ abi: IInteropCenter_default,
3009
+ functionName: "zkToken"
3010
+ }),
3011
+ { message: "Failed to fetch ZK token address from InteropCenter." }
3012
+ );
3013
+ const approval = {
3014
+ token: zkTokenAddress,
3015
+ spender: ctx.interopCenter,
3016
+ amount: zkFeeTotal
3017
+ };
3018
+ return {
3019
+ approval,
3020
+ fee: { token: zkTokenAddress, amount: zkFeeTotal }
3021
+ };
3022
+ } else {
3023
+ const protocolFeePerCall = await wrap2(
3024
+ OP_INTEROP.svc.fees.protocolFee,
3025
+ () => ctx.client.l2.readContract({
3026
+ address: ctx.interopCenter,
3027
+ abi: IInteropCenter_default,
3028
+ functionName: "interopProtocolFee"
3029
+ }),
3030
+ { message: "Failed to fetch interop protocol fee from InteropCenter." }
3031
+ );
3032
+ const totalFee = protocolFeePerCall * BigInt(numStarters);
3033
+ return {
3034
+ approval: null,
3035
+ fee: { token: ctx.baseTokens.src, amount: totalFee }
3036
+ };
3037
+ }
3038
+ }
3039
+
3040
+ // src/adapters/viem/resources/interop/routes/indirect.ts
3041
+ function routeIndirect() {
3042
+ return {
3043
+ // eslint-disable-next-line @typescript-eslint/require-await
3044
+ async preflight(params, ctx) {
3045
+ preflightIndirect(params, {
3046
+ dstChainId: ctx.dstChainId,
3047
+ baseTokens: ctx.baseTokens,
3048
+ l2AssetRouter: ctx.l2AssetRouter,
3049
+ l2NativeTokenVault: ctx.l2NativeTokenVault,
3050
+ codec: interopCodec
3051
+ });
3052
+ },
3053
+ async build(params, ctx) {
3054
+ const steps = [];
3055
+ const erc20Tokens = getErc20Tokens(params);
3056
+ const [erc20AssetIds, feeInfo] = await Promise.all([
3057
+ resolveErc20AssetIds(erc20Tokens, ctx),
3058
+ buildFeeInfo(params, ctx, params.actions.length)
3059
+ ]);
3060
+ const attributes = getInteropAttributes(params, ctx);
3061
+ const starterData = await getStarterData(params, ctx, erc20AssetIds);
3062
+ const bundle = buildIndirectBundle(
3063
+ params,
3064
+ {
3065
+ dstChainId: ctx.dstChainId,
3066
+ baseTokens: ctx.baseTokens,
3067
+ l2AssetRouter: ctx.l2AssetRouter,
3068
+ l2NativeTokenVault: ctx.l2NativeTokenVault,
3069
+ codec: interopCodec
3070
+ },
3071
+ attributes,
3072
+ starterData,
3073
+ feeInfo
3074
+ );
3075
+ steps.push(...buildEnsureTokenSteps(erc20Tokens, ctx));
3076
+ steps.push(...await buildApproveSteps(bundle.approvals, ctx));
3077
+ const data = encodeFunctionData({
3078
+ abi: IInteropCenter_default,
3079
+ functionName: "sendBundle",
3080
+ args: [bundle.dstChain, bundle.starters, bundle.bundleAttributes]
3081
+ });
3082
+ steps.push({
3083
+ key: "sendBundle",
3084
+ kind: "interop.center",
3085
+ description: "Send interop bundle (indirect route)",
3086
+ tx: {
3087
+ to: ctx.interopCenter,
3088
+ data,
3089
+ value: bundle.quoteExtras.totalActionValue + feeInfo.fee.amount,
3090
+ ...ctx.gasOverrides
3091
+ }
3092
+ });
3093
+ return {
3094
+ steps,
3095
+ approvals: bundle.approvals,
3096
+ quoteExtras: bundle.quoteExtras,
3097
+ interopFee: feeInfo.fee
3098
+ };
3099
+ }
3100
+ };
3101
+ }
3102
+ function routeDirect() {
3103
+ return {
3104
+ // eslint-disable-next-line @typescript-eslint/require-await
3105
+ async preflight(params, ctx) {
3106
+ preflightDirect(params, {
3107
+ dstChainId: ctx.dstChainId,
3108
+ baseTokens: ctx.baseTokens,
3109
+ l2AssetRouter: ctx.l2AssetRouter,
3110
+ l2NativeTokenVault: ctx.l2NativeTokenVault,
3111
+ codec: interopCodec
3112
+ });
3113
+ },
3114
+ async build(params, ctx) {
3115
+ const steps = [];
3116
+ const attrs = getInteropAttributes(params, ctx);
3117
+ const feeInfo = await buildFeeInfo(params, ctx, params.actions.length);
3118
+ const built = buildDirectBundle(
3119
+ params,
3120
+ {
3121
+ dstChainId: ctx.dstChainId,
3122
+ baseTokens: ctx.baseTokens,
3123
+ l2AssetRouter: ctx.l2AssetRouter,
3124
+ l2NativeTokenVault: ctx.l2NativeTokenVault,
3125
+ codec: interopCodec
3126
+ },
3127
+ attrs,
3128
+ feeInfo
3129
+ );
3130
+ steps.push(...await buildApproveSteps(built.approvals, ctx));
3131
+ const data = encodeFunctionData({
3132
+ abi: IInteropCenter_default,
3133
+ functionName: "sendBundle",
3134
+ args: [built.dstChain, built.starters, built.bundleAttributes]
3135
+ });
3136
+ steps.push({
3137
+ key: "sendBundle",
3138
+ kind: "interop.center",
3139
+ description: `Send interop bundle (direct route; ${params.actions.length} actions)`,
3140
+ tx: {
3141
+ to: ctx.interopCenter,
3142
+ data,
3143
+ value: built.quoteExtras.totalActionValue + feeInfo.fee.amount,
3144
+ ...ctx.gasOverrides
3145
+ }
3146
+ });
3147
+ return {
3148
+ steps,
3149
+ approvals: built.approvals,
3150
+ quoteExtras: built.quoteExtras,
3151
+ interopFee: feeInfo.fee
3152
+ };
3153
+ }
3154
+ };
3155
+ }
3156
+
3157
+ // src/adapters/viem/resources/interop/context.ts
3158
+ async function assertInteropProtocolVersion(client, srcChainId, dstChainId) {
3159
+ const [srcProtocolVersion, dstProtocolVersion] = await Promise.all([
3160
+ client.getProtocolVersion(srcChainId),
3161
+ client.getProtocolVersion(dstChainId)
3162
+ ]);
3163
+ assertProtocolVersion(srcChainId, srcProtocolVersion);
3164
+ assertProtocolVersion(dstChainId, dstProtocolVersion);
3165
+ }
3166
+ async function commonCtx3(dstPublicClient, params, client, tokens, contracts, attributes) {
3167
+ const sender = client.account.address;
3168
+ const chainId = BigInt(await client.l2.getChainId());
3169
+ const dstChainId = BigInt(await dstPublicClient.getChainId());
3170
+ const {
3171
+ bridgehub,
3172
+ l2AssetRouter,
3173
+ l2NativeTokenVault,
3174
+ interopCenter,
3175
+ interopHandler,
3176
+ l2MessageVerification
3177
+ } = await contracts.addresses();
3178
+ await assertInteropProtocolVersion(client, chainId, dstChainId);
3179
+ const [srcBaseToken, dstBaseToken] = await Promise.all([
3180
+ client.baseToken(chainId),
3181
+ client.baseToken(dstChainId)
3182
+ ]);
3183
+ const baseMatches = srcBaseToken.toLowerCase() === dstBaseToken.toLowerCase();
3184
+ return {
3185
+ client,
3186
+ tokens,
3187
+ contracts,
3188
+ sender,
3189
+ chainIdL2: chainId,
3190
+ chainId,
3191
+ bridgehub,
3192
+ dstChainId,
3193
+ dstPublicClient,
3194
+ interopCenter,
3195
+ interopHandler,
3196
+ l2MessageVerification,
3197
+ l2AssetRouter,
3198
+ l2NativeTokenVault,
3199
+ baseTokens: { src: srcBaseToken, dst: dstBaseToken, matches: baseMatches },
3200
+ attributes,
3201
+ gasOverrides: params.txOverrides ? toGasOverrides(params.txOverrides) : void 0
3202
+ };
3203
+ }
3204
+ function getTopics() {
3205
+ const topics = {
3206
+ interopBundleSent: encodeEventTopics({
3207
+ abi: IInteropCenter_default,
3208
+ eventName: "InteropBundleSent"
3209
+ })[0],
3210
+ bundleVerified: encodeEventTopics({
3211
+ abi: IInteropHandler_default,
3212
+ eventName: "BundleVerified"
3213
+ })[0],
3214
+ bundleExecuted: encodeEventTopics({
3215
+ abi: IInteropHandler_default,
3216
+ eventName: "BundleExecuted"
3217
+ })[0],
3218
+ bundleUnbundled: encodeEventTopics({
3219
+ abi: IInteropHandler_default,
3220
+ eventName: "BundleUnbundled"
3221
+ })[0]
3222
+ };
3223
+ return { topics };
3224
+ }
3225
+ var { wrap: wrap3 } = createErrorHandlers("interop");
3226
+ var DEFAULT_BLOCKS_RANGE_SIZE = 1e4;
3227
+ var DEFAULT_MAX_BLOCKS_BACK = 2e4;
3228
+ var SAFE_BLOCKS_RANGE_SIZE = 1e3;
3229
+ function parseMaxBlockRangeLimit(error) {
3230
+ const msg = typeof error === "object" && error !== null && "message" in error ? String(error.message) : String(error);
3231
+ const match = /query exceeds max block range\s+(\d+)/i.exec(msg);
3232
+ if (!match) return null;
3233
+ const limit = Number.parseInt(match[1], 10);
3234
+ return Number.isInteger(limit) && limit > 0 ? limit : null;
3235
+ }
3236
+ async function getTxReceipt(provider, txHash) {
3237
+ const receipt = await wrap3(
3238
+ OP_INTEROP.svc.status.sourceReceipt,
3239
+ async () => {
3240
+ try {
3241
+ return await provider.getTransactionReceipt({ hash: txHash });
3242
+ } catch (error) {
3243
+ if (isReceiptNotFound(error)) return null;
3244
+ throw error;
3245
+ }
3246
+ },
3247
+ {
3248
+ ctx: { where: "l2.getTransactionReceipt", l2SrcTxHash: txHash },
3249
+ message: "Failed to fetch source L2 receipt for interop tx."
3250
+ }
3251
+ );
3252
+ if (!receipt) return null;
3253
+ return {
3254
+ logs: receipt.logs.map((log) => ({
3255
+ address: log.address,
3256
+ topics: log.topics,
3257
+ data: log.data,
3258
+ transactionHash: log.transactionHash
3259
+ }))
3260
+ };
3261
+ }
3262
+ async function getLogs(provider, address, topics, opts) {
3263
+ const maxBlocksBack = opts?.maxBlocksBack ?? DEFAULT_MAX_BLOCKS_BACK;
3264
+ const initialChunkSize = opts?.logChunkSize ?? DEFAULT_BLOCKS_RANGE_SIZE;
3265
+ return await wrap3(
3266
+ OP_INTEROP.svc.status.dstLogs,
3267
+ async () => {
3268
+ const currentBlock = await provider.getBlockNumber();
3269
+ const minBlock = BigInt(Math.max(0, Number(currentBlock) - maxBlocksBack));
3270
+ let toBlock = currentBlock;
3271
+ let chunkSize = initialChunkSize;
3272
+ while (toBlock >= minBlock) {
3273
+ const fromBlock = toBlock - BigInt(chunkSize) + 1n > minBlock ? toBlock - BigInt(chunkSize) + 1n : minBlock;
3274
+ try {
3275
+ const rawLogs = await provider.request({
3276
+ method: "eth_getLogs",
3277
+ params: [
3278
+ {
3279
+ address,
3280
+ topics,
3281
+ fromBlock: numberToHex(fromBlock),
3282
+ toBlock: numberToHex(toBlock)
3283
+ }
3284
+ ]
3285
+ });
3286
+ if (rawLogs.length > 0) {
3287
+ return rawLogs.map((log) => ({
3288
+ address: log.address,
3289
+ topics: log.topics,
3290
+ data: log.data,
3291
+ transactionHash: log.transactionHash
3292
+ }));
3293
+ }
3294
+ toBlock = fromBlock - 1n;
3295
+ } catch (error) {
3296
+ const serverLimit = parseMaxBlockRangeLimit(error);
3297
+ if (serverLimit == null) {
3298
+ if (chunkSize > SAFE_BLOCKS_RANGE_SIZE) {
3299
+ chunkSize = SAFE_BLOCKS_RANGE_SIZE;
3300
+ } else {
3301
+ throw error;
3302
+ }
3303
+ } else {
3304
+ chunkSize = Math.min(chunkSize, serverLimit);
3305
+ }
3306
+ }
3307
+ }
3308
+ return [];
3309
+ },
3310
+ {
3311
+ ctx: { address, maxBlocksBack, logChunkSize: initialChunkSize },
3312
+ message: "Failed to query destination bundle lifecycle logs."
3313
+ }
3314
+ );
3315
+ }
3316
+ async function getInteropRoot(provider, rootChainId, batchNumber) {
3317
+ return await wrap3(
3318
+ OP_INTEROP.svc.status.getRoot,
3319
+ async () => {
3320
+ return await provider.readContract({
3321
+ address: L2_INTEROP_ROOT_STORAGE_ADDRESS,
3322
+ abi: IInteropRootStorage_default,
3323
+ functionName: "interopRoots",
3324
+ args: [rootChainId, batchNumber]
3325
+ });
3326
+ },
3327
+ {
3328
+ ctx: { rootChainId, batchNumber },
3329
+ message: "Failed to get interop root from the destination chain."
3330
+ }
3331
+ );
3332
+ }
3333
+
3334
+ // src/adapters/viem/resources/interop/services/finalization/bundle.ts
3335
+ var { wrap: wrap4 } = createErrorHandlers("interop");
3336
+ async function getBundleStatus(client, dstProvider, topics, bundleHash, opts) {
3337
+ const { interopHandler } = await client.ensureAddresses();
3338
+ const bundleLogs = await getLogs(dstProvider, interopHandler, [null, bundleHash], opts);
3339
+ const findLastByTopic = (eventTopic) => bundleLogs.findLast((log) => log.topics[0].toLowerCase() === eventTopic.toLowerCase());
3340
+ const lifecycleChecks = [
3341
+ { phase: "UNBUNDLED", topic: topics.bundleUnbundled, includeTxHash: true },
3342
+ { phase: "EXECUTED", topic: topics.bundleExecuted, includeTxHash: true },
3343
+ { phase: "VERIFIED", topic: topics.bundleVerified }
3344
+ ];
3345
+ for (const check of lifecycleChecks) {
3346
+ const match = findLastByTopic(check.topic);
3347
+ if (!match) continue;
3348
+ if (check.includeTxHash) {
3349
+ return { phase: check.phase, dstExecTxHash: match.transactionHash };
3350
+ }
3351
+ return { phase: check.phase };
3352
+ }
3353
+ return { phase: "SENT" };
3354
+ }
3355
+ async function executeBundle(client, dstProvider, info, opts) {
3356
+ const { topics } = getTopics();
3357
+ const { bundleHash, encodedData, proof } = info;
3358
+ const dstStatus = await getBundleStatus(client, dstProvider, topics, bundleHash, opts);
3359
+ if (["EXECUTED", "UNBUNDLED"].includes(dstStatus.phase)) {
3360
+ throw createError("STATE", {
3361
+ resource: "interop",
3362
+ operation: OP_INTEROP.finalize,
3363
+ message: `Interop bundle has already been ${dstStatus.phase.toLowerCase()}.`,
3364
+ context: { bundleHash }
3365
+ });
3366
+ }
3367
+ const dstWallet = await wrap4(
3368
+ OP_INTEROP.exec.sendStep,
3369
+ () => createWalletClient({
3370
+ account: client.account,
3371
+ transport: custom(dstProvider.transport),
3372
+ chain: dstProvider.chain
3373
+ }),
3374
+ { message: "Failed to create destination wallet client." }
3375
+ );
3376
+ const { interopHandler } = await client.ensureAddresses();
3377
+ try {
3378
+ const hash = await dstWallet.writeContract({
3379
+ address: interopHandler,
3380
+ abi: IInteropHandler_default,
3381
+ functionName: "executeBundle",
3382
+ args: [encodedData, proof],
3383
+ account: client.account,
3384
+ chain: dstProvider.chain ?? null
3385
+ });
3386
+ return {
3387
+ hash,
3388
+ wait: async () => {
3389
+ try {
3390
+ const receipt = await dstProvider.waitForTransactionReceipt({ hash });
3391
+ if (receipt.status === "reverted") {
3392
+ throw createError("EXECUTION", {
3393
+ resource: "interop",
3394
+ operation: OP_INTEROP.exec.waitStep,
3395
+ message: "Interop bundle execution reverted on destination.",
3396
+ context: { txHash: hash }
3397
+ });
3398
+ }
3399
+ return receipt;
3400
+ } catch (e) {
3401
+ if (isZKsyncError(e)) throw e;
3402
+ throw toZKsyncError(
3403
+ "EXECUTION",
3404
+ {
3405
+ resource: "interop",
3406
+ operation: OP_INTEROP.exec.waitStep,
3407
+ message: "Failed while waiting for executeBundle transaction on destination.",
3408
+ context: { txHash: hash }
3409
+ },
3410
+ e
3411
+ );
3412
+ }
3413
+ }
3414
+ };
3415
+ } catch (e) {
3416
+ throw toZKsyncError(
3417
+ "EXECUTION",
3418
+ {
3419
+ resource: "interop",
3420
+ operation: OP_INTEROP.exec.sendStep,
3421
+ message: "Failed to send executeBundle transaction on destination chain."
3422
+ },
3423
+ e
3424
+ );
3425
+ }
3426
+ }
3427
+ async function verifyBundle(client, dstProvider, info) {
3428
+ const { interopHandler } = await client.ensureAddresses();
3429
+ const dstWallet = await wrap4(
3430
+ OP_INTEROP.verify,
3431
+ () => createWalletClient({
3432
+ account: client.account,
3433
+ transport: custom(dstProvider.transport),
3434
+ chain: dstProvider.chain
3435
+ }),
3436
+ { message: "Failed to create destination wallet client for verifyBundle." }
3437
+ );
3438
+ try {
3439
+ const hash = await dstWallet.writeContract({
3440
+ address: interopHandler,
3441
+ abi: IInteropHandler_default,
3442
+ functionName: "verifyBundle",
3443
+ args: [info.encodedData, info.proof],
3444
+ account: client.account,
3445
+ chain: dstProvider.chain ?? null
3446
+ });
3447
+ return {
3448
+ hash,
3449
+ wait: async () => {
3450
+ try {
3451
+ const receipt = await dstProvider.waitForTransactionReceipt({ hash });
3452
+ if (receipt.status === "reverted") {
3453
+ throw createError("EXECUTION", {
3454
+ resource: "interop",
3455
+ operation: OP_INTEROP.verify,
3456
+ message: "Interop bundle verification reverted on destination.",
3457
+ context: { txHash: hash }
3458
+ });
3459
+ }
3460
+ return receipt;
3461
+ } catch (e) {
3462
+ if (isZKsyncError(e)) throw e;
3463
+ throw toZKsyncError(
3464
+ "EXECUTION",
3465
+ {
3466
+ resource: "interop",
3467
+ operation: OP_INTEROP.verify,
3468
+ message: "Failed while waiting for verifyBundle transaction on destination.",
3469
+ context: { txHash: hash }
3470
+ },
3471
+ e
3472
+ );
3473
+ }
3474
+ }
3475
+ };
3476
+ } catch (e) {
3477
+ if (isZKsyncError(e)) throw e;
3478
+ throw toZKsyncError(
3479
+ "EXECUTION",
3480
+ {
3481
+ resource: "interop",
3482
+ operation: OP_INTEROP.verify,
3483
+ message: "Failed to send verifyBundle transaction on destination chain."
3484
+ },
3485
+ e
3486
+ );
3487
+ }
3488
+ }
3489
+ function decodeInteropBundleSent(log) {
3490
+ const { args } = decodeEventLog({
3491
+ abi: IInteropCenter_default,
3492
+ eventName: "InteropBundleSent",
3493
+ data: log.data,
3494
+ topics: log.topics
3495
+ });
3496
+ return {
3497
+ bundleHash: args.interopBundleHash,
3498
+ sourceChainId: args.interopBundle.sourceChainId,
3499
+ destinationChainId: args.interopBundle.destinationChainId
3500
+ };
3501
+ }
3502
+ function decodeL1MessageData(log) {
3503
+ const [decoded] = decodeAbiParameters([{ type: "bytes" }], log.data);
3504
+ return decoded;
3505
+ }
3506
+
3507
+ // src/adapters/viem/resources/interop/services/finalization/polling.ts
3508
+ var { wrap: wrap5 } = createErrorHandlers("interop");
3509
+ function isProofNotReadyError(error) {
3510
+ return isZKsyncError(error, {
3511
+ operation: "zksrpc.getL2ToL1LogProof",
3512
+ messageIncludes: "proof not yet available"
3513
+ });
3514
+ }
3515
+ function shouldRetryRootFetch(error) {
3516
+ if (!isZKsyncError(error)) return false;
3517
+ return error.envelope.operation === OP_INTEROP.svc.status.getRoot;
3518
+ }
3519
+ async function waitForProof(client, l2SrcTxHash, logIndex, blockNumber, pollMs, deadline) {
3520
+ while (true) {
3521
+ if (Date.now() > deadline) {
3522
+ throw createError("TIMEOUT", {
3523
+ resource: "interop",
3524
+ operation: OP_INTEROP.svc.wait.timeout,
3525
+ message: "Timed out waiting for block to be finalized.",
3526
+ context: { l2SrcTxHash, logIndex, blockNumber }
3527
+ });
3528
+ }
3529
+ const finalizedBlock = await client.l2.getBlock({ blockTag: "finalized" });
3530
+ if (finalizedBlock && finalizedBlock.number !== null && finalizedBlock.number >= blockNumber) {
3531
+ break;
3532
+ }
3533
+ await sleep(pollMs);
3534
+ }
3535
+ while (true) {
3536
+ if (Date.now() > deadline) {
3537
+ throw createError("TIMEOUT", {
3538
+ resource: "interop",
3539
+ operation: OP_INTEROP.svc.wait.timeout,
3540
+ message: "Timed out waiting for L2->L1 log proof to become available.",
3541
+ context: { l2SrcTxHash, logIndex }
3542
+ });
3543
+ }
3544
+ try {
3545
+ return await client.zks.getL2ToL1LogProof(l2SrcTxHash, logIndex, "messageRoot" /* MessageRoot */);
3546
+ } catch (error) {
3547
+ if (!isProofNotReadyError(error)) throw error;
3548
+ }
3549
+ await sleep(pollMs);
3550
+ }
3551
+ }
3552
+ async function waitForRoot(provider, chainId, batchNumber, pollMs, deadline) {
3553
+ while (true) {
3554
+ if (Date.now() > deadline) {
3555
+ throw createError("TIMEOUT", {
3556
+ resource: "interop",
3557
+ operation: OP_INTEROP.svc.wait.timeout,
3558
+ message: "Timed out waiting for interop root to become available.",
3559
+ context: { chainId, batchNumber }
3560
+ });
3561
+ }
3562
+ let interopRoot = null;
3563
+ try {
3564
+ const root = await getInteropRoot(provider, chainId, batchNumber);
3565
+ if (root !== ZERO_HASH) {
3566
+ interopRoot = root;
3567
+ }
3568
+ } catch (error) {
3569
+ if (!shouldRetryRootFetch(error)) throw error;
3570
+ interopRoot = null;
3571
+ }
3572
+ if (interopRoot) {
3573
+ return interopRoot;
3574
+ }
3575
+ await sleep(pollMs);
3576
+ }
3577
+ }
3578
+ async function waitForTxReceipt(client, txHash, pollMs, deadline) {
3579
+ while (true) {
3580
+ if (Date.now() > deadline) {
3581
+ throw createError("TIMEOUT", {
3582
+ resource: "interop",
3583
+ operation: OP_INTEROP.svc.wait.timeout,
3584
+ message: "Timed out waiting for source receipt to be available.",
3585
+ context: { txHash }
3586
+ });
3587
+ }
3588
+ const receipt = await wrap5(
3589
+ OP_INTEROP.svc.status.sourceReceipt,
3590
+ () => client.zks.getReceiptWithL2ToL1(txHash),
3591
+ {
3592
+ ctx: { where: "zks.getReceiptWithL2ToL1", txHash },
3593
+ message: "Failed to fetch source L2 receipt (with L2->L1 logs) for interop tx."
3594
+ }
3595
+ );
3596
+ if (receipt) {
3597
+ return receipt;
3598
+ }
3599
+ await sleep(pollMs);
3600
+ }
3601
+ }
3602
+ async function waitForFinalization(client, dstProvider, gwProvider, input, opts) {
3603
+ const { topics } = getTopics();
3604
+ const pollMs = opts?.pollMs ?? DEFAULT_POLL_MS;
3605
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
3606
+ const deadline = Date.now() + timeoutMs;
3607
+ const ids = resolveIdsFromWaitable(input);
3608
+ if (!ids.l2SrcTxHash) {
3609
+ throw createError("STATE", {
3610
+ resource: "interop",
3611
+ operation: OP_INTEROP.svc.status.sourceReceipt,
3612
+ message: "Cannot wait for interop finalization: missing l2SrcTxHash.",
3613
+ context: { input }
3614
+ });
3615
+ }
3616
+ const { interopCenter } = await client.ensureAddresses();
3617
+ let bundleInfo = null;
3618
+ while (!bundleInfo) {
3619
+ if (Date.now() > deadline) {
3620
+ throw createError("TIMEOUT", {
3621
+ resource: "interop",
3622
+ operation: OP_INTEROP.svc.wait.timeout,
3623
+ message: "Timed out waiting for source receipt to be available.",
3624
+ context: { l2SrcTxHash: ids.l2SrcTxHash }
3625
+ });
3626
+ }
3627
+ const txReceipt = await waitForTxReceipt(client, ids.l2SrcTxHash, pollMs, deadline);
3628
+ bundleInfo = parseBundleReceiptInfo({
3629
+ rawReceipt: txReceipt,
3630
+ interopCenter,
3631
+ interopBundleSentTopic: topics.interopBundleSent,
3632
+ decodeInteropBundleSent: (log) => decodeInteropBundleSent(log),
3633
+ decodeL1MessageData,
3634
+ l2SrcTxHash: ids.l2SrcTxHash
3635
+ });
3636
+ }
3637
+ const proof = await waitForProof(
3638
+ client,
3639
+ ids.l2SrcTxHash,
3640
+ bundleInfo.l2ToL1LogIndex,
3641
+ BigInt(bundleInfo.rawReceipt.blockNumber),
3642
+ pollMs,
3643
+ deadline
3644
+ );
3645
+ const finalizationInfo = buildFinalizationInfo(
3646
+ { l2SrcTxHash: ids.l2SrcTxHash, bundleHash: ids.bundleHash },
3647
+ bundleInfo,
3648
+ proof,
3649
+ bundleInfo.l1MessageData
3650
+ );
3651
+ if (proof.gatewayBlockNumber == null) {
3652
+ throw createError("STATE", {
3653
+ resource: "interop",
3654
+ operation: OP_INTEROP.svc.wait.timeout,
3655
+ message: "Proof missing gatewayBlockNumber required for interop finalization.",
3656
+ context: { l2SrcTxHash: ids.l2SrcTxHash }
3657
+ });
3658
+ }
3659
+ const gwChainId = BigInt(await gwProvider.getChainId());
3660
+ await waitForRoot(dstProvider, gwChainId, proof.gatewayBlockNumber, pollMs, deadline);
3661
+ return finalizationInfo;
3662
+ }
3663
+
3664
+ // src/adapters/viem/resources/interop/services/finalization/status.ts
3665
+ async function getStatus(client, dstProvider, input, opts) {
3666
+ const { topics } = getTopics();
3667
+ const baseIds = resolveIdsFromWaitable(input);
3668
+ const enrichedIds = await (async () => {
3669
+ if (baseIds.bundleHash) return baseIds;
3670
+ if (!baseIds.l2SrcTxHash) return baseIds;
3671
+ const { interopCenter } = await client.ensureAddresses();
3672
+ const receipt = await getTxReceipt(client.l2, baseIds.l2SrcTxHash);
3673
+ if (!receipt) return baseIds;
3674
+ const { bundleHash } = parseBundleSentFromReceipt({
3675
+ receipt: { logs: receipt.logs },
3676
+ interopCenter,
3677
+ interopBundleSentTopic: topics.interopBundleSent,
3678
+ decodeInteropBundleSent: (log) => decodeInteropBundleSent(log)
3679
+ });
3680
+ return { ...baseIds, bundleHash };
3681
+ })();
3682
+ if (!enrichedIds.bundleHash) {
3683
+ const phase = enrichedIds.l2SrcTxHash ? "SENT" : "UNKNOWN";
3684
+ return {
3685
+ phase,
3686
+ l2SrcTxHash: enrichedIds.l2SrcTxHash,
3687
+ bundleHash: enrichedIds.bundleHash,
3688
+ dstExecTxHash: enrichedIds.dstExecTxHash
3689
+ };
3690
+ }
3691
+ const dstInfo = await getBundleStatus(client, dstProvider, topics, enrichedIds.bundleHash, opts);
3692
+ return {
3693
+ phase: dstInfo.phase,
3694
+ l2SrcTxHash: enrichedIds.l2SrcTxHash,
3695
+ bundleHash: enrichedIds.bundleHash,
3696
+ dstExecTxHash: dstInfo.dstExecTxHash ?? enrichedIds.dstExecTxHash
3697
+ };
3698
+ }
3699
+
3700
+ // src/adapters/viem/resources/interop/services/finalization/index.ts
3701
+ function createInteropFinalizationServices(client) {
3702
+ return {
3703
+ status(dstProvider, input, opts) {
3704
+ return getStatus(client, dstProvider, input, opts);
3705
+ },
3706
+ wait(dstProvider, gwProvider, input, opts) {
3707
+ return waitForFinalization(client, dstProvider, gwProvider, input, opts);
3708
+ },
3709
+ async finalize(dstProvider, info, opts) {
3710
+ const execResult = await executeBundle(client, dstProvider, info, opts);
3711
+ await execResult.wait();
3712
+ return {
3713
+ bundleHash: info.bundleHash,
3714
+ dstExecTxHash: execResult.hash
3715
+ };
3716
+ }
3717
+ };
3718
+ }
3719
+ function resolveChainRef(ref) {
3720
+ if (typeof ref === "string") {
3721
+ return createPublicClient({ transport: http(ref) });
3722
+ }
3723
+ return ref;
3724
+ }
3725
+
3726
+ // src/adapters/viem/resources/interop/services/gas.ts
3727
+ async function quoteStepsL2Fee(steps, ctx) {
3728
+ if (steps.length === 0) return 0n;
3729
+ const estimator = viemToGasEstimator(ctx.client.l2);
3730
+ let maxFeePerGas;
3731
+ try {
3732
+ const fees = await estimator.estimateFeesPerGas();
3733
+ maxFeePerGas = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
3734
+ } catch {
3735
+ return void 0;
3736
+ }
3737
+ let total = 0n;
3738
+ for (const step of steps) {
3739
+ try {
3740
+ const coreTx = {
3741
+ to: step.tx.to,
3742
+ from: ctx.sender,
3743
+ data: step.tx.data,
3744
+ value: step.tx.value,
3745
+ gasLimit: step.tx.gas ?? step.tx.gasLimit,
3746
+ maxFeePerGas: step.tx.maxFeePerGas,
3747
+ maxPriorityFeePerGas: step.tx.maxPriorityFeePerGas
3748
+ };
3749
+ const est = await estimator.estimateGas(coreTx);
3750
+ const buffered = BigInt(est) * (100n + BUFFER) / 100n;
3751
+ total += buffered * maxFeePerGas;
3752
+ } catch {
3753
+ return void 0;
3754
+ }
3755
+ }
3756
+ return total;
3757
+ }
3758
+
3759
+ // src/adapters/viem/resources/interop/index.ts
3760
+ var { wrap: wrap6, toResult: toResult2 } = createErrorHandlers("interop");
3761
+ var ROUTES3 = {
3762
+ direct: routeDirect(),
3763
+ indirect: routeIndirect()
3764
+ };
3765
+ function createInteropResource(client, config, tokens, contracts, attributes) {
3766
+ let gwProviderCache;
3767
+ function requireConfig() {
3768
+ if (!config)
3769
+ throw createError("STATE", {
3770
+ resource: "interop",
3771
+ operation: "interop.init",
3772
+ message: "Interop is not configured. Pass gwChain in createViemSdk options."
3773
+ });
3774
+ return config;
3775
+ }
3776
+ function getGwProvider() {
3777
+ if (!gwProviderCache) gwProviderCache = resolveChainRef(requireConfig().gwChain);
3778
+ return gwProviderCache;
3779
+ }
3780
+ const svc = createInteropFinalizationServices(client);
3781
+ const tokensResource = tokens ?? createTokensResource(client);
3782
+ const contractsResource = contracts ?? createContractsResource(client);
3783
+ const attributesResource = attributes ?? createViemAttributesResource();
3784
+ async function buildPlanWithCtx(dstPublicClient, params) {
3785
+ const ctx = await commonCtx3(
3786
+ dstPublicClient,
3787
+ params,
3788
+ client,
3789
+ tokensResource,
3790
+ contractsResource,
3791
+ attributesResource
3792
+ );
3793
+ const route = pickInteropRoute({
3794
+ actions: params.actions,
3795
+ ctx: {
3796
+ sender: ctx.sender,
3797
+ srcChainId: ctx.chainId,
3798
+ dstChainId: ctx.dstChainId,
3799
+ baseTokenSrc: ctx.baseTokens.src,
3800
+ baseTokenDst: ctx.baseTokens.dst
3801
+ }
3802
+ });
3803
+ await wrap6(OP_INTEROP.routes[route].preflight, () => ROUTES3[route].preflight?.(params, ctx), {
3804
+ message: "Interop preflight failed.",
3805
+ ctx: { where: `routes.${route}.preflight` }
3806
+ });
3807
+ const { steps, approvals, quoteExtras, interopFee } = await wrap6(
3808
+ OP_INTEROP.routes[route].build,
3809
+ () => ROUTES3[route].build(params, ctx),
3810
+ {
3811
+ message: "Failed to build interop route plan.",
3812
+ ctx: { where: `routes.${route}.build` }
3813
+ }
3814
+ );
3815
+ const l2Fee = await quoteStepsL2Fee(steps, ctx).catch(() => void 0);
3816
+ const summary = {
3817
+ route,
3818
+ approvalsNeeded: approvals,
3819
+ totalActionValue: quoteExtras.totalActionValue,
3820
+ bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
3821
+ interopFee,
3822
+ l2Fee
3823
+ };
3824
+ return { plan: { route, summary, steps }, ctx };
3825
+ }
3826
+ async function buildPlan(dstPublicClient, params) {
3827
+ const { plan } = await buildPlanWithCtx(dstPublicClient, params);
3828
+ return plan;
3829
+ }
3830
+ const quote = (dstChain, params) => wrap6(OP_INTEROP.quote, async () => {
3831
+ const plan = await buildPlan(resolveChainRef(dstChain), params);
3832
+ return plan.summary;
3833
+ });
3834
+ const tryQuote = (dstChain, params) => toResult2(OP_INTEROP.tryQuote, () => quote(dstChain, params));
3835
+ const prepare = (dstChain, params) => wrap6(OP_INTEROP.prepare, () => buildPlan(resolveChainRef(dstChain), params), {
3836
+ message: "Internal error while preparing an interop plan.",
3837
+ ctx: { where: "interop.prepare" }
3838
+ });
3839
+ const tryPrepare = (dstChain, params) => toResult2(
3840
+ OP_INTEROP.tryPrepare,
3841
+ () => prepare(dstChain, params)
3842
+ );
3843
+ const create = (dstChain, params) => wrap6(
3844
+ OP_INTEROP.create,
3845
+ async () => {
3846
+ const { plan } = await buildPlanWithCtx(resolveChainRef(dstChain), params);
3847
+ const l2Wallet = client.getL2Wallet();
3848
+ const from = client.account.address;
3849
+ let next;
3850
+ if (typeof params.txOverrides?.nonce === "number") {
3851
+ next = params.txOverrides.nonce;
3852
+ } else {
3853
+ const blockTag = params.txOverrides?.nonce ?? "pending";
3854
+ next = await client.l2.getTransactionCount({ address: from, blockTag });
3855
+ }
3856
+ const stepHashes = {};
3857
+ for (const step of plan.steps) {
3858
+ let gasLimit = step.tx.gas ?? step.tx.gasLimit;
3859
+ if (!gasLimit) {
3860
+ try {
3861
+ const est = await client.l2.estimateGas({
3862
+ account: from,
3863
+ to: step.tx.to,
3864
+ data: step.tx.data,
3865
+ value: step.tx.value
3866
+ });
3867
+ gasLimit = est * 115n / 100n;
3868
+ } catch {
3869
+ }
3870
+ }
3871
+ let hash;
3872
+ try {
3873
+ hash = await l2Wallet.sendTransaction({
3874
+ to: step.tx.to,
3875
+ data: step.tx.data,
3876
+ value: step.tx.value,
3877
+ gas: gasLimit,
3878
+ maxFeePerGas: step.tx.maxFeePerGas,
3879
+ maxPriorityFeePerGas: step.tx.maxPriorityFeePerGas,
3880
+ nonce: next++,
3881
+ account: client.account,
3882
+ chain: null
3883
+ });
3884
+ stepHashes[step.key] = hash;
3885
+ const rcpt = await client.l2.waitForTransactionReceipt({ hash });
3886
+ if (rcpt.status === "reverted") {
3887
+ throw createError("EXECUTION", {
3888
+ resource: "interop",
3889
+ operation: "interop.create.sendTransaction",
3890
+ message: "Interop transaction reverted on source L2.",
3891
+ context: { step: step.key, txHash: hash }
3892
+ });
3893
+ }
3894
+ } catch (e) {
3895
+ if (isZKsyncError(e)) throw e;
3896
+ throw toZKsyncError(
3897
+ "EXECUTION",
3898
+ {
3899
+ resource: "interop",
3900
+ operation: "interop.create.sendTransaction",
3901
+ message: "Failed to send or confirm an interop transaction step.",
3902
+ context: {
3903
+ step: step.key,
3904
+ txHash: hash,
3905
+ nonce: next - 1
3906
+ }
3907
+ },
3908
+ e
3909
+ );
3910
+ }
3911
+ }
3912
+ const last = Object.values(stepHashes).pop();
3913
+ return {
3914
+ kind: "interop",
3915
+ stepHashes,
3916
+ plan,
3917
+ l2SrcTxHash: last ?? "0x"
3918
+ };
3919
+ },
3920
+ {
3921
+ message: "Internal error while creating interop bundle.",
3922
+ ctx: { where: "interop.create" }
3923
+ }
3924
+ );
3925
+ const tryCreate = (dstChain, params) => toResult2(
3926
+ OP_INTEROP.tryCreate,
3927
+ () => create(dstChain, params)
3928
+ );
3929
+ const status = (dstChain, h, opts) => wrap6(OP_INTEROP.status, () => svc.status(resolveChainRef(dstChain), h, opts), {
3930
+ message: "Internal error while checking interop status.",
3931
+ ctx: { where: "interop.status" }
3932
+ });
3933
+ const wait = (dstChain, h, opts) => wrap6(OP_INTEROP.wait, () => svc.wait(resolveChainRef(dstChain), getGwProvider(), h, opts), {
3934
+ message: "Internal error while waiting for interop finalization.",
3935
+ ctx: { where: "interop.wait" }
3936
+ });
3937
+ const tryWait = (dstChain, h, opts) => toResult2(OP_INTEROP.tryWait, () => wait(dstChain, h, opts));
3938
+ const finalize = (dstChain, h, opts) => wrap6(
3939
+ OP_INTEROP.finalize,
3940
+ async () => {
3941
+ const dstProvider = resolveChainRef(dstChain);
3942
+ if (isInteropFinalizationInfo(h)) {
3943
+ return svc.finalize(dstProvider, h, opts);
3944
+ }
3945
+ const info = await svc.wait(dstProvider, getGwProvider(), h);
3946
+ return svc.finalize(dstProvider, info, opts);
3947
+ },
3948
+ {
3949
+ message: "Failed to finalize/execute interop bundle on destination.",
3950
+ ctx: { where: "interop.finalize" }
3951
+ }
3952
+ );
3953
+ const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
3954
+ const interopGetRoot = (dstChain, rootChainId, batchNumber) => wrap6(
3955
+ OP_INTEROP.svc.status.getRoot,
3956
+ () => getInteropRoot(resolveChainRef(dstChain), rootChainId, batchNumber),
3957
+ {
3958
+ message: "Failed to get interop root from the destination chain.",
3959
+ ctx: { where: "interop.getInteropRoot" }
3960
+ }
3961
+ );
3962
+ const verifyBundle2 = (dstChain, h) => wrap6(
3963
+ OP_INTEROP.verify,
3964
+ async () => {
3965
+ const dstProvider = resolveChainRef(dstChain);
3966
+ const info = isInteropFinalizationInfo(h) ? h : await svc.wait(dstProvider, getGwProvider(), h);
3967
+ const result = await verifyBundle(client, dstProvider, info);
3968
+ await result.wait();
3969
+ return { bundleHash: info.bundleHash, dstExecTxHash: result.hash };
3970
+ },
3971
+ {
3972
+ message: "Failed to verify interop bundle on destination.",
3973
+ ctx: { where: "interop.verifyBundle" }
3974
+ }
3975
+ );
3976
+ return {
3977
+ quote,
3978
+ tryQuote,
3979
+ prepare,
3980
+ tryPrepare,
3981
+ create,
3982
+ tryCreate,
3983
+ status,
3984
+ wait,
3985
+ tryWait,
3986
+ finalize,
3987
+ tryFinalize,
3988
+ getInteropRoot: interopGetRoot,
3989
+ verifyBundle: verifyBundle2
3990
+ };
3991
+ }
2792
3992
 
2793
3993
  // src/adapters/viem/sdk.ts
2794
- function createViemSdk(client) {
3994
+ function createViemSdk(client, options) {
2795
3995
  const tokens = createTokensResource(client);
2796
3996
  const contracts = createContractsResource(client);
3997
+ const interop = createInteropResource(client, options?.interop, tokens, contracts);
2797
3998
  return {
2798
3999
  deposits: createDepositsResource(client, tokens, contracts),
2799
4000
  withdrawals: createWithdrawalsResource(client, tokens, contracts),
2800
4001
  tokens,
2801
- contracts
4002
+ contracts,
4003
+ interop
2802
4004
  };
2803
4005
  }
2804
4006
 
2805
- export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs };
4007
+ export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createInteropFinalizationServices, createInteropResource, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs };