@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,8 +1,7 @@
1
1
  import type { AbstractProvider, Signer } from 'ethers';
2
2
  import { Contract } from 'ethers';
3
- import type { Address } from '../../core/types/primitives';
3
+ import type { Address, ProtocolVersion } from '../../core/types/primitives';
4
4
  import type { ZksRpc } from '../../core/rpc/zks';
5
- export type ProtocolVersion = readonly [number, number, number];
6
5
  export interface ResolvedAddresses {
7
6
  bridgehub: Address;
8
7
  l1AssetRouter: Address;
@@ -1,7 +1,6 @@
1
- export { createEthersClient } from '../../chunk-7CAVFIMW.js';
2
- import '../../chunk-5RRJDPAJ.js';
1
+ export { createEthersClient } from '../../chunk-24TE2NNJ.js';
2
+ import '../../chunk-NJK325XV.js';
3
3
  import '../../chunk-BWKWWLY4.js';
4
- import '../../chunk-HP3EWKJL.js';
5
- import '../../chunk-DYJKK5FW.js';
6
- import '../../chunk-JY62QO3W.js';
4
+ import '../../chunk-JSBMIT4S.js';
5
+ import '../../chunk-UEKFQAOS.js';
7
6
  import '../../chunk-MT4X5FEO.js';
@@ -389,6 +389,7 @@ var OP_INTEROP = {
389
389
  tryWait: "interop.tryWait",
390
390
  finalize: "interop.finalize",
391
391
  tryFinalize: "interop.tryFinalize",
392
+ verify: "interop.verify",
392
393
  context: {
393
394
  chainTypeManager: "interop.chainTypeManager",
394
395
  protocolVersion: "interop.protocolVersion"
@@ -8036,7 +8037,33 @@ function buildDirectRequestStruct(args) {
8036
8037
  };
8037
8038
  }
8038
8039
 
8040
+ // src/core/resources/deposits/chains.ts
8041
+ var ERAVM_CHAIN_IDS = /* @__PURE__ */ new Set([324n, 2741n, 11124n, 300n]);
8042
+ function isEraVmChain(chainIdL2) {
8043
+ return ERAVM_CHAIN_IDS.has(chainIdL2);
8044
+ }
8045
+
8039
8046
  // src/core/resources/deposits/gas.ts
8047
+ var CREATE_REESTIMATE_BUFFER = 15n;
8048
+ var maxBigInt = (a, b) => a > b ? a : b;
8049
+ function applyGasBuffer(gasLimit, bufferPct = BUFFER) {
8050
+ return gasLimit * (100n + bufferPct) / 100n;
8051
+ }
8052
+ function resolveCreateDepositL1GasLimit(input) {
8053
+ const { chainIdL2, stepKey, preparedGasLimit, estimatedGasLimit } = input;
8054
+ if (estimatedGasLimit == null) {
8055
+ return preparedGasLimit;
8056
+ }
8057
+ const isEraVmBridgeStep = isEraVmChain(chainIdL2) && stepKey.startsWith("bridgehub:");
8058
+ const reestimatedGasLimit = applyGasBuffer(
8059
+ estimatedGasLimit,
8060
+ isEraVmBridgeStep ? BUFFER : CREATE_REESTIMATE_BUFFER
8061
+ );
8062
+ if (isEraVmBridgeStep && preparedGasLimit != null) {
8063
+ return maxBigInt(preparedGasLimit, reestimatedGasLimit);
8064
+ }
8065
+ return reestimatedGasLimit;
8066
+ }
8040
8067
  function makeGasQuote(p) {
8041
8068
  const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
8042
8069
  return {
@@ -8087,7 +8114,7 @@ async function quoteL1Gas(input) {
8087
8114
  }
8088
8115
  try {
8089
8116
  const est = await estimator.estimateGas(tx);
8090
- const buffered = BigInt(est) * (100n + BUFFER) / 100n;
8117
+ const buffered = applyGasBuffer(BigInt(est));
8091
8118
  return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
8092
8119
  } catch {
8093
8120
  if (fallbackGasLimit != null) {
@@ -8124,7 +8151,7 @@ async function quoteL2Gas(input) {
8124
8151
  const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
8125
8152
  const pubdataOverhead = pubdataBytes * pp;
8126
8153
  let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
8127
- total = total * (100n + BUFFER) / 100n;
8154
+ total = applyGasBuffer(total);
8128
8155
  return makeGasQuote({
8129
8156
  gasLimit: total,
8130
8157
  maxFeePerGas,
@@ -8378,18 +8405,19 @@ function buildFeeBreakdown(p) {
8378
8405
  // src/core/resources/deposits/priority.ts
8379
8406
  var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
8380
8407
  var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
8381
- var maxBigInt = (a, b) => a > b ? a : b;
8408
+ var ERAVM_PRIORITY_L2_GAS_BUFFER = 30n;
8409
+ var maxBigInt2 = (a, b) => a > b ? a : b;
8382
8410
  var ceilDiv = (a, b) => (a + b - 1n) / b;
8383
8411
  function derivePriorityTxGasBreakdown(input) {
8384
8412
  const factoryDepsCount = input.factoryDepsCount ?? 0n;
8385
- const minBodyGas = maxBigInt(
8413
+ const minBodyGas = maxBigInt2(
8386
8414
  L1_TX_INTRINSIC_L2_GAS + ceilDiv(
8387
8415
  input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
8388
8416
  PRIORITY_TX_ENCODING_STEP_BYTES
8389
8417
  ) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
8390
8418
  L1_TX_MIN_L2_GAS_BASE
8391
8419
  ) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
8392
- const overhead = maxBigInt(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
8420
+ const overhead = maxBigInt2(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
8393
8421
  const derivedBodyGas = minBodyGas;
8394
8422
  return {
8395
8423
  encodedLength: input.encodedLength,
@@ -8404,8 +8432,12 @@ function derivePriorityTxGasBreakdown(input) {
8404
8432
  function derivePriorityBodyGasEstimateCap(input) {
8405
8433
  return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
8406
8434
  }
8407
-
8408
- // src/adapters/ethers/resources/deposits/routes/priority.ts
8435
+ function applyPriorityL2GasLimitBuffer(input) {
8436
+ if (!isEraVmChain(input.chainIdL2)) {
8437
+ return input.gasLimit;
8438
+ }
8439
+ return input.gasLimit * (100n + ERAVM_PRIORITY_L2_GAS_BUFFER) / 100n;
8440
+ }
8409
8441
  var EMPTY_BYTES = "0x";
8410
8442
  var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
8411
8443
  var L2_CANONICAL_TRANSACTION_TUPLE = "tuple(uint256 txType,uint256 from,uint256 to,uint256 gasLimit,uint256 gasPerPubdataByteLimit,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 paymaster,uint256 nonce,uint256 value,uint256[4] reserved,bytes data,bytes signature,uint256[] factoryDeps,bytes paymasterInput,bytes reservedDynamic)";
@@ -8462,7 +8494,10 @@ function routeEthDirect() {
8462
8494
  l2Calldata,
8463
8495
  gasPerPubdata: ctx.gasPerPubdata
8464
8496
  });
8465
- const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
8497
+ const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
8498
+ chainIdL2: ctx.chainIdL2,
8499
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
8500
+ });
8466
8501
  const l2GasParams = await quoteL2Gas2({
8467
8502
  ctx,
8468
8503
  route: "eth-base",
@@ -8560,7 +8595,10 @@ async function getPriorityGasModel(input) {
8560
8595
  gasPerPubdata: input.ctx.gasPerPubdata
8561
8596
  });
8562
8597
  const model = {
8563
- priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
8598
+ priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
8599
+ chainIdL2: input.ctx.chainIdL2,
8600
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
8601
+ })
8564
8602
  };
8565
8603
  if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS2) {
8566
8604
  model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
@@ -8782,7 +8820,10 @@ async function getPriorityGasModel2(input) {
8782
8820
  gasPerPubdata: input.ctx.gasPerPubdata
8783
8821
  });
8784
8822
  const model = {
8785
- priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
8823
+ priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
8824
+ chainIdL2: input.ctx.chainIdL2,
8825
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
8826
+ })
8786
8827
  };
8787
8828
  if (input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS3) {
8788
8829
  model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
@@ -8904,7 +8945,7 @@ function routeEthNonBase() {
8904
8945
  const requestStruct = {
8905
8946
  chainId: ctx.chainIdL2,
8906
8947
  mintValue,
8907
- l2Value: p.amount,
8948
+ l2Value: 0n,
8908
8949
  l2GasLimit: l2GasParams.gasLimit,
8909
8950
  l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
8910
8951
  refundRecipient: ctx.refundRecipient,
@@ -8912,6 +8953,7 @@ function routeEthNonBase() {
8912
8953
  secondBridgeValue: p.amount,
8913
8954
  secondBridgeCalldata
8914
8955
  };
8956
+ const bridgehubValue = p.amount;
8915
8957
  const bridgehub = await ctx.contracts.bridgehub();
8916
8958
  const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
8917
8959
  requestStruct
@@ -8919,8 +8961,7 @@ function routeEthNonBase() {
8919
8961
  const l1TxCandidate = {
8920
8962
  to: ctx.bridgehub,
8921
8963
  data,
8922
- value: p.amount,
8923
- // base ≠ ETH ⇒ msg.value == secondBridgeValue
8964
+ value: bridgehubValue,
8924
8965
  from: ctx.sender,
8925
8966
  ...ctx.gasOverrides
8926
8967
  };
@@ -8999,7 +9040,10 @@ function routeErc20Base() {
8999
9040
  l2Calldata,
9000
9041
  gasPerPubdata: ctx.gasPerPubdata
9001
9042
  });
9002
- const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
9043
+ const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
9044
+ chainIdL2: ctx.chainIdL2,
9045
+ gasLimit: priorityFloorBreakdown.derivedL2GasLimit
9046
+ });
9003
9047
  const l2GasParams = await quoteL2Gas2({
9004
9048
  ctx,
9005
9049
  route: "erc20-base",
@@ -9425,6 +9469,8 @@ function createDepositsResource(client, tokens, contracts) {
9425
9469
  async () => {
9426
9470
  const plan = await prepare(p);
9427
9471
  const stepHashes = {};
9472
+ const { chainId } = await client.l2.getNetwork();
9473
+ const chainIdL2 = BigInt(chainId);
9428
9474
  const managed = new ethers.NonceManager(client.signer);
9429
9475
  const from = await managed.getAddress();
9430
9476
  let next;
@@ -9470,8 +9516,14 @@ function createDepositsResource(client, tokens, contracts) {
9470
9516
  }
9471
9517
  if (!p.l1TxOverrides?.gasLimit) {
9472
9518
  try {
9519
+ const preparedGasLimit = step.tx.gasLimit != null ? BigInt(step.tx.gasLimit.toString()) : void 0;
9473
9520
  const est = await client.l1.estimateGas(step.tx);
9474
- step.tx.gasLimit = BigInt(est) * 115n / 100n;
9521
+ step.tx.gasLimit = resolveCreateDepositL1GasLimit({
9522
+ chainIdL2,
9523
+ stepKey: step.key,
9524
+ preparedGasLimit,
9525
+ estimatedGasLimit: BigInt(est)
9526
+ });
9475
9527
  } catch {
9476
9528
  }
9477
9529
  }
@@ -11090,26 +11142,30 @@ function routeDirect() {
11090
11142
  }
11091
11143
  };
11092
11144
  }
11145
+
11146
+ // src/core/resources/interop/protocol.ts
11093
11147
  var MIN_INTEROP_PROTOCOL = 31;
11148
+ function assertProtocolVersion(chainId, protocolVersion) {
11149
+ if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
11150
+ throw createError("VALIDATION", {
11151
+ resource: "interop",
11152
+ operation: OP_INTEROP.context.protocolVersion,
11153
+ message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
11154
+ context: {
11155
+ chainId,
11156
+ requiredMinor: MIN_INTEROP_PROTOCOL,
11157
+ semver: protocolVersion
11158
+ }
11159
+ });
11160
+ }
11161
+ }
11162
+
11163
+ // src/adapters/ethers/resources/interop/context.ts
11094
11164
  async function assertInteropProtocolVersion(client, srcChainId, dstChainId) {
11095
11165
  const [srcProtocolVersion, dstProtocolVersion] = await Promise.all([
11096
11166
  client.getProtocolVersion(srcChainId),
11097
11167
  client.getProtocolVersion(dstChainId)
11098
11168
  ]);
11099
- const assertProtocolVersion = (chainId, protocolVersion) => {
11100
- if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
11101
- throw createError("VALIDATION", {
11102
- resource: "interop",
11103
- operation: OP_INTEROP.context.protocolVersion,
11104
- message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
11105
- context: {
11106
- chainId,
11107
- requiredMinor: MIN_INTEROP_PROTOCOL,
11108
- semver: protocolVersion
11109
- }
11110
- });
11111
- }
11112
- };
11113
11169
  assertProtocolVersion(srcChainId, srcProtocolVersion);
11114
11170
  assertProtocolVersion(dstChainId, dstProtocolVersion);
11115
11171
  }
@@ -11180,7 +11236,14 @@ function parseMaxBlockRangeLimit(error) {
11180
11236
  async function getTxReceipt(provider, txHash) {
11181
11237
  const receipt = await wrap4(
11182
11238
  OP_INTEROP.svc.status.sourceReceipt,
11183
- () => provider.getTransactionReceipt(txHash),
11239
+ async () => {
11240
+ try {
11241
+ return await provider.getTransactionReceipt(txHash);
11242
+ } catch (error) {
11243
+ if (isReceiptNotFound(error)) return null;
11244
+ throw error;
11245
+ }
11246
+ },
11184
11247
  {
11185
11248
  ctx: { where: "l2.getTransactionReceipt", l2SrcTxHash: txHash },
11186
11249
  message: "Failed to fetch source L2 receipt for interop tx."
@@ -11345,6 +11408,60 @@ async function executeBundle(client, dstProvider, info, opts) {
11345
11408
  );
11346
11409
  }
11347
11410
  }
11411
+ async function verifyBundle(client, dstProvider, info) {
11412
+ const signer = await wrap5(OP_INTEROP.verify, () => client.signerFor(dstProvider), {
11413
+ message: "Failed to resolve destination signer for verifyBundle."
11414
+ });
11415
+ const { interopHandler } = await client.ensureAddresses();
11416
+ const handler = new ethers.Contract(interopHandler, IInteropHandler_default, signer);
11417
+ try {
11418
+ const txResponse = await handler.verifyBundle(
11419
+ info.encodedData,
11420
+ info.proof
11421
+ );
11422
+ const hash = txResponse.hash;
11423
+ return {
11424
+ hash,
11425
+ wait: async () => {
11426
+ try {
11427
+ const receipt = await txResponse.wait();
11428
+ if (!receipt || receipt.status !== 1) {
11429
+ throw createError("EXECUTION", {
11430
+ resource: "interop",
11431
+ operation: OP_INTEROP.verify,
11432
+ message: "Interop bundle verification reverted on destination.",
11433
+ context: { txHash: hash }
11434
+ });
11435
+ }
11436
+ return receipt;
11437
+ } catch (e) {
11438
+ if (isZKsyncError(e)) throw e;
11439
+ throw toZKsyncError(
11440
+ "EXECUTION",
11441
+ {
11442
+ resource: "interop",
11443
+ operation: OP_INTEROP.verify,
11444
+ message: "Failed while waiting for verifyBundle transaction on destination.",
11445
+ context: { txHash: hash }
11446
+ },
11447
+ e
11448
+ );
11449
+ }
11450
+ }
11451
+ };
11452
+ } catch (e) {
11453
+ if (isZKsyncError(e)) throw e;
11454
+ throw toZKsyncError(
11455
+ "EXECUTION",
11456
+ {
11457
+ resource: "interop",
11458
+ operation: OP_INTEROP.verify,
11459
+ message: "Failed to send verifyBundle transaction on destination chain."
11460
+ },
11461
+ e
11462
+ );
11463
+ }
11464
+ }
11348
11465
 
11349
11466
  // src/core/resources/interop/finalization.ts
11350
11467
  var DEFAULT_POLL_MS = 1e3;
@@ -11710,6 +11827,31 @@ function resolveChainRef(ref) {
11710
11827
  return typeof ref === "string" ? new ethers.JsonRpcProvider(ref) : ref;
11711
11828
  }
11712
11829
 
11830
+ // src/adapters/ethers/resources/interop/services/gas.ts
11831
+ async function quoteStepsL2Fee(steps, ctx) {
11832
+ if (steps.length === 0) return 0n;
11833
+ const estimator = ethersToGasEstimator(ctx.client.l2);
11834
+ let maxFeePerGas;
11835
+ try {
11836
+ const fees = await estimator.estimateFeesPerGas();
11837
+ maxFeePerGas = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
11838
+ } catch {
11839
+ return void 0;
11840
+ }
11841
+ let total = 0n;
11842
+ for (const step of steps) {
11843
+ try {
11844
+ const coreTx = toCoreTx({ ...step.tx, from: ctx.sender });
11845
+ const est = await estimator.estimateGas(coreTx);
11846
+ const buffered = BigInt(est) * (100n + BUFFER) / 100n;
11847
+ total += buffered * maxFeePerGas;
11848
+ } catch {
11849
+ return void 0;
11850
+ }
11851
+ }
11852
+ return total;
11853
+ }
11854
+
11713
11855
  // src/adapters/ethers/resources/interop/index.ts
11714
11856
  var { wrap: wrap7, toResult: toResult2 } = createErrorHandlers("interop");
11715
11857
  var ROUTES3 = {
@@ -11766,12 +11908,14 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
11766
11908
  ctx: { where: `routes.${route}.build` }
11767
11909
  }
11768
11910
  );
11911
+ const l2Fee = await quoteStepsL2Fee(steps, ctx).catch(() => void 0);
11769
11912
  const summary = {
11770
11913
  route,
11771
11914
  approvalsNeeded: approvals,
11772
11915
  totalActionValue: quoteExtras.totalActionValue,
11773
11916
  bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
11774
- interopFee
11917
+ interopFee,
11918
+ l2Fee
11775
11919
  };
11776
11920
  return { plan: { route, summary, steps }, ctx };
11777
11921
  }
@@ -11896,6 +12040,28 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
11896
12040
  }
11897
12041
  );
11898
12042
  const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
12043
+ const interopGetRoot = (dstChain, rootChainId, batchNumber) => wrap7(
12044
+ OP_INTEROP.svc.status.getRoot,
12045
+ () => getInteropRoot(resolveChainRef(dstChain), rootChainId, batchNumber),
12046
+ {
12047
+ message: "Failed to get interop root from the destination chain.",
12048
+ ctx: { where: "interop.getInteropRoot" }
12049
+ }
12050
+ );
12051
+ const verifyBundle2 = (dstChain, h) => wrap7(
12052
+ OP_INTEROP.verify,
12053
+ async () => {
12054
+ const dstProvider = resolveChainRef(dstChain);
12055
+ const info = isInteropFinalizationInfo(h) ? h : await svc.wait(dstProvider, getGwProvider(), h);
12056
+ const result = await verifyBundle(client, dstProvider, info);
12057
+ await result.wait();
12058
+ return { bundleHash: info.bundleHash, dstExecTxHash: result.hash };
12059
+ },
12060
+ {
12061
+ message: "Failed to verify interop bundle on destination.",
12062
+ ctx: { where: "interop.verifyBundle" }
12063
+ }
12064
+ );
11899
12065
  return {
11900
12066
  quote,
11901
12067
  tryQuote,
@@ -11907,7 +12073,9 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
11907
12073
  wait,
11908
12074
  tryWait,
11909
12075
  finalize,
11910
- tryFinalize
12076
+ tryFinalize,
12077
+ getInteropRoot: interopGetRoot,
12078
+ verifyBundle: verifyBundle2
11911
12079
  };
11912
12080
  }
11913
12081