@matterlabs/zksync-js 0.0.16 → 0.0.18

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.
@@ -1,5 +1,5 @@
1
- export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createInteropFinalizationServices, createInteropResource, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-3KH5PCD6.js';
2
- import '../../chunk-NLUCYVMX.js';
1
+ export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createInteropFinalizationServices, createInteropResource, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-GBS7KQFU.js';
2
+ import '../../chunk-6LYAENO6.js';
3
3
  import '../../chunk-3HHUZXSV.js';
4
4
  export { createViemClient as createClient, createViemClient } from '../../chunk-CK5UFAZK.js';
5
5
  export { classifyReadinessFromRevert, createErrorHandlers, decodeRevert, registerErrorAbi, toZKsyncError } from '../../chunk-SBGBYZJM.js';
@@ -0,0 +1,11 @@
1
+ import type { Address } from '../../../../../core/types/primitives';
2
+ import type { BuildCtx } from '../context';
3
+ import type { ViemPlanWriteRequest } from './types';
4
+ type BuildApprovalRequestInput = {
5
+ ctx: BuildCtx;
6
+ token: Address;
7
+ spender: Address;
8
+ amount: bigint;
9
+ };
10
+ export declare function buildApprovalRequest({ ctx, token, spender, amount, }: BuildApprovalRequestInput): Promise<ViemPlanWriteRequest>;
11
+ export {};
@@ -8,6 +8,7 @@ import type { InteropRouteStrategy, ViemTransactionRequest } from './routes/type
8
8
  import { createInteropFinalizationServices, type InteropFinalizationServices } from './services/finalization';
9
9
  import { type LogsQueryOptions } from './services/finalization/data-fetchers';
10
10
  import type { ChainRef, InteropConfig } from './types';
11
+ import type { TxGasOverrides } from '../../../../core/types/fees';
11
12
  export declare const ROUTES: Record<InteropRoute, InteropRouteStrategy>;
12
13
  export interface InteropResource {
13
14
  quote(dstChain: ChainRef, params: InteropParams): Promise<InteropQuote>;
@@ -49,8 +50,8 @@ export interface InteropResource {
49
50
  ok: false;
50
51
  error: unknown;
51
52
  }>;
52
- finalize(dstChain: ChainRef, h: InteropWaitable | InteropFinalizationInfo, opts?: LogsQueryOptions): Promise<InteropFinalizationResult>;
53
- tryFinalize(dstChain: ChainRef, h: InteropWaitable | InteropFinalizationInfo, opts?: LogsQueryOptions): Promise<{
53
+ finalize(dstChain: ChainRef, h: InteropWaitable | InteropFinalizationInfo, opts?: LogsQueryOptions, txOverrides?: TxGasOverrides): Promise<InteropFinalizationResult>;
54
+ tryFinalize(dstChain: ChainRef, h: InteropWaitable | InteropFinalizationInfo, opts?: LogsQueryOptions, txOverrides?: TxGasOverrides): Promise<{
54
55
  ok: true;
55
56
  value: InteropFinalizationResult;
56
57
  } | {
@@ -1,6 +1,7 @@
1
1
  import { type PublicClient, type TransactionReceipt } from 'viem';
2
2
  import type { Hex } from '../../../../../../core/types/primitives';
3
3
  import type { InteropFinalizationInfo } from '../../../../../../core/types/flows/interop';
4
+ import type { TxGasOverrides } from '../../../../../../core/types/fees';
4
5
  import type { ViemClient } from '../../../../client';
5
6
  import type { InteropPhase } from '../../../../../../core/types/flows/interop';
6
7
  import type { InteropTopics } from '../../../../../../core/resources/interop/events';
@@ -9,7 +10,7 @@ export declare function getBundleStatus(client: ViemClient, dstProvider: PublicC
9
10
  phase: InteropPhase;
10
11
  dstExecTxHash?: Hex;
11
12
  }>;
12
- export declare function executeBundle(client: ViemClient, dstProvider: PublicClient, info: InteropFinalizationInfo, opts?: LogsQueryOptions): Promise<{
13
+ export declare function executeBundle(client: ViemClient, dstProvider: PublicClient, info: InteropFinalizationInfo, opts?: LogsQueryOptions, txOverrides?: TxGasOverrides): Promise<{
13
14
  hash: Hex;
14
15
  wait: () => Promise<TransactionReceipt>;
15
16
  }>;
@@ -2,12 +2,13 @@ import type { PublicClient } from 'viem';
2
2
  import type { InteropStatus, InteropWaitable, InteropFinalizationInfo, InteropFinalizationResult } from '../../../../../../core/types/flows/interop';
3
3
  import type { ViemClient } from '../../../../client';
4
4
  import type { LogsQueryOptions } from './data-fetchers';
5
+ import type { TxGasOverrides } from '../../../../../../core/types/fees';
5
6
  export interface InteropFinalizationServices {
6
7
  status(dstProvider: PublicClient, input: InteropWaitable, opts?: LogsQueryOptions): Promise<InteropStatus>;
7
8
  wait(dstProvider: PublicClient, gwProvider: PublicClient, input: InteropWaitable, opts?: {
8
9
  pollMs?: number;
9
10
  timeoutMs?: number;
10
11
  }): Promise<InteropFinalizationInfo>;
11
- finalize(dstProvider: PublicClient, info: InteropFinalizationInfo, opts?: LogsQueryOptions): Promise<InteropFinalizationResult>;
12
+ finalize(dstProvider: PublicClient, info: InteropFinalizationInfo, opts?: LogsQueryOptions, txOverrides?: TxGasOverrides): Promise<InteropFinalizationResult>;
12
13
  }
13
14
  export declare function createInteropFinalizationServices(client: ViemClient): InteropFinalizationServices;
@@ -6533,8 +6533,8 @@ function buildFeeBreakdown(p) {
6533
6533
 
6534
6534
  // src/core/resources/deposits/priority.ts
6535
6535
  var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
6536
- var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
6537
- var ERAVM_PRIORITY_L2_GAS_BUFFER = 30n;
6536
+ var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 7n;
6537
+ var PRIORITY_L2_GAS_BUFFER = 40n;
6538
6538
  var maxBigInt2 = (a, b) => a > b ? a : b;
6539
6539
  var ceilDiv = (a, b) => (a + b - 1n) / b;
6540
6540
  function derivePriorityTxGasBreakdown(input) {
@@ -6562,10 +6562,7 @@ function derivePriorityBodyGasEstimateCap(input) {
6562
6562
  return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
6563
6563
  }
6564
6564
  function applyPriorityL2GasLimitBuffer(input) {
6565
- if (!isEraVmChain(input.chainIdL2)) {
6566
- return input.gasLimit;
6567
- }
6568
- return input.gasLimit * (100n + ERAVM_PRIORITY_L2_GAS_BUFFER) / 100n;
6565
+ return input.gasLimit * (100n + PRIORITY_L2_GAS_BUFFER) / 100n;
6569
6566
  }
6570
6567
  var EMPTY_BYTES = "0x";
6571
6568
  var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
@@ -6732,8 +6729,73 @@ function routeEthDirect() {
6732
6729
  }
6733
6730
  };
6734
6731
  }
6732
+
6733
+ // src/adapters/viem/resources/deposits/routes/approval.ts
6734
+ function errorText(error) {
6735
+ const parts = [];
6736
+ let current = error;
6737
+ for (let depth = 0; current && depth < 8; depth++) {
6738
+ const record = current;
6739
+ for (const key of ["name", "shortMessage", "message", "details"]) {
6740
+ const value = record[key];
6741
+ if (typeof value === "string") parts.push(value);
6742
+ }
6743
+ current = record.cause;
6744
+ }
6745
+ return parts.join("\n");
6746
+ }
6747
+ function isNoReturnApproveSimulationError(error) {
6748
+ const text = errorText(error);
6749
+ return /approve/i.test(text) && (/returned no data/i.test(text) || /return(?:ed)? data[^\n]*0x/i.test(text) || /0x[^\n]*no data/i.test(text));
6750
+ }
6751
+ async function buildApprovalRequest({
6752
+ ctx,
6753
+ token,
6754
+ spender,
6755
+ amount
6756
+ }) {
6757
+ try {
6758
+ const sim = await ctx.client.l1.simulateContract({
6759
+ address: token,
6760
+ abi: IERC20_default,
6761
+ functionName: "approve",
6762
+ args: [spender, amount],
6763
+ account: ctx.client.account
6764
+ });
6765
+ return { ...sim.request };
6766
+ } catch (error) {
6767
+ if (!isNoReturnApproveSimulationError(error)) {
6768
+ throw error;
6769
+ }
6770
+ return {
6771
+ address: token,
6772
+ abi: IERC20_default,
6773
+ functionName: "approve",
6774
+ args: [spender, amount],
6775
+ account: ctx.client.account
6776
+ };
6777
+ }
6778
+ }
6779
+
6780
+ // src/adapters/viem/resources/deposits/routes/erc20-nonbase.ts
6735
6781
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
6736
6782
  var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
6783
+ async function encodeSecondBridgeErc20DepositCalldata(input) {
6784
+ if (!input.ctx.resolvedToken) {
6785
+ return encodeSecondBridgeErc20Args(input.token, input.amount, input.receiver);
6786
+ }
6787
+ const l1ChainId = BigInt(await input.ctx.client.l1.getChainId());
6788
+ const isL1Origin = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID || input.ctx.resolvedToken.originChainId === 0n || input.ctx.resolvedToken.originChainId === l1ChainId;
6789
+ if (isL1Origin) {
6790
+ return encodeSecondBridgeErc20Args(input.token, input.amount, input.receiver);
6791
+ }
6792
+ const transferData = encodeNativeTokenVaultTransferData(
6793
+ input.amount,
6794
+ input.receiver,
6795
+ input.token
6796
+ );
6797
+ return encodeSecondBridgeDataV1(input.ctx.resolvedToken.assetId, transferData);
6798
+ }
6737
6799
  async function getPriorityGasModel(input) {
6738
6800
  try {
6739
6801
  const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
@@ -6823,10 +6885,15 @@ function routeErc20NonBase() {
6823
6885
  const secondBridgeCalldata = await wrapAs3(
6824
6886
  "INTERNAL",
6825
6887
  OP_DEPOSITS.nonbase.encodeCalldata,
6826
- () => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, receiver)),
6888
+ () => encodeSecondBridgeErc20DepositCalldata({
6889
+ ctx,
6890
+ token: p.token,
6891
+ amount: p.amount,
6892
+ receiver
6893
+ }),
6827
6894
  {
6828
6895
  ctx: {
6829
- where: "encodeSecondBridgeErc20Args",
6896
+ where: "encodeSecondBridgeErc20DepositCalldata",
6830
6897
  token: p.token,
6831
6898
  amount: p.amount.toString()
6832
6899
  },
@@ -6871,15 +6938,14 @@ function routeErc20NonBase() {
6871
6938
  }
6872
6939
  );
6873
6940
  if (depositAllowance < p.amount) {
6874
- const approveSim = await wrapAs3(
6941
+ const approveTx = await wrapAs3(
6875
6942
  "CONTRACT",
6876
6943
  OP_DEPOSITS.nonbase.estGas,
6877
- () => ctx.client.l1.simulateContract({
6878
- address: p.token,
6879
- abi: IERC20_default,
6880
- functionName: "approve",
6881
- args: [assetRouter, p.amount],
6882
- account: ctx.client.account
6944
+ () => buildApprovalRequest({
6945
+ ctx,
6946
+ token: p.token,
6947
+ spender: assetRouter,
6948
+ amount: p.amount
6883
6949
  }),
6884
6950
  {
6885
6951
  ctx: { where: "l1.simulateContract", to: p.token },
@@ -6891,7 +6957,7 @@ function routeErc20NonBase() {
6891
6957
  key: `approve:${p.token}:${assetRouter}`,
6892
6958
  kind: "approve",
6893
6959
  description: `Approve deposit token for amount`,
6894
- tx: { ...approveSim.request }
6960
+ tx: approveTx
6895
6961
  });
6896
6962
  }
6897
6963
  if (!baseIsEth) {
@@ -6910,15 +6976,14 @@ function routeErc20NonBase() {
6910
6976
  }
6911
6977
  );
6912
6978
  if (baseAllowance < mintValue) {
6913
- const approveBaseSim = await wrapAs3(
6979
+ const approveBaseTx = await wrapAs3(
6914
6980
  "CONTRACT",
6915
6981
  OP_DEPOSITS.nonbase.estGas,
6916
- () => ctx.client.l1.simulateContract({
6917
- address: baseToken,
6918
- abi: IERC20_default,
6919
- functionName: "approve",
6920
- args: [assetRouter, mintValue],
6921
- account: ctx.client.account
6982
+ () => buildApprovalRequest({
6983
+ ctx,
6984
+ token: baseToken,
6985
+ spender: assetRouter,
6986
+ amount: mintValue
6922
6987
  }),
6923
6988
  {
6924
6989
  ctx: { where: "l1.simulateContract", to: baseToken },
@@ -6930,7 +6995,7 @@ function routeErc20NonBase() {
6930
6995
  key: `approve:${baseToken}:${assetRouter}`,
6931
6996
  kind: "approve",
6932
6997
  description: `Approve base token for mintValue`,
6933
- tx: { ...approveBaseSim.request }
6998
+ tx: approveBaseTx
6934
6999
  });
6935
7000
  }
6936
7001
  }
@@ -7182,15 +7247,14 @@ function routeEthNonBase() {
7182
7247
  );
7183
7248
  const needsApprove = allowance < mintValue;
7184
7249
  if (needsApprove) {
7185
- const approveSim = await wrapAs4(
7250
+ const approveTx = await wrapAs4(
7186
7251
  "CONTRACT",
7187
7252
  OP_DEPOSITS.ethNonBase.estGas,
7188
- () => ctx.client.l1.simulateContract({
7189
- address: baseToken,
7190
- abi: IERC20_default,
7191
- functionName: "approve",
7192
- args: [ctx.l1AssetRouter, mintValue],
7193
- account: ctx.client.account
7253
+ () => buildApprovalRequest({
7254
+ ctx,
7255
+ token: baseToken,
7256
+ spender: ctx.l1AssetRouter,
7257
+ amount: mintValue
7194
7258
  }),
7195
7259
  {
7196
7260
  ctx: { where: "l1.simulateContract", to: baseToken },
@@ -7202,7 +7266,7 @@ function routeEthNonBase() {
7202
7266
  key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
7203
7267
  kind: "approve",
7204
7268
  description: `Approve base token for fees (mintValue)`,
7205
- tx: { ...approveSim.request }
7269
+ tx: approveTx
7206
7270
  });
7207
7271
  }
7208
7272
  const secondBridgeCalldata = await wrapAs4(
@@ -7382,15 +7446,14 @@ function routeErc20Base() {
7382
7446
  );
7383
7447
  const needsApprove = allowance < mintValue;
7384
7448
  if (needsApprove) {
7385
- const approveSim = await wrapAs5(
7449
+ const approveTx = await wrapAs5(
7386
7450
  "CONTRACT",
7387
7451
  OP_DEPOSITS.base.estGas,
7388
- () => ctx.client.l1.simulateContract({
7389
- address: baseToken,
7390
- abi: IERC20_default,
7391
- functionName: "approve",
7392
- args: [ctx.l1AssetRouter, mintValue],
7393
- account: ctx.client.account
7452
+ () => buildApprovalRequest({
7453
+ ctx,
7454
+ token: baseToken,
7455
+ spender: ctx.l1AssetRouter,
7456
+ amount: mintValue
7394
7457
  }),
7395
7458
  {
7396
7459
  ctx: { where: "l1.simulateContract", to: baseToken },
@@ -7402,7 +7465,7 @@ function routeErc20Base() {
7402
7465
  key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
7403
7466
  kind: "approve",
7404
7467
  description: "Approve base token for mintValue",
7405
- tx: { ...approveSim.request }
7468
+ tx: approveTx
7406
7469
  });
7407
7470
  }
7408
7471
  const req = buildDirectRequestStruct({
@@ -9709,13 +9772,23 @@ function routeIndirect() {
9709
9772
  }
9710
9773
  function routeDirect() {
9711
9774
  return {
9712
- // eslint-disable-next-line @typescript-eslint/require-await
9713
9775
  async preflight(params, ctx) {
9714
9776
  preflightDirect(params, {
9715
9777
  dstChainId: ctx.dstChainId,
9716
9778
  baseTokens: ctx.baseTokens,
9717
9779
  l2AssetRouter: ctx.l2AssetRouter,
9718
9780
  l2NativeTokenVault: ctx.l2NativeTokenVault});
9781
+ for (const action of params.actions) {
9782
+ const bytecode = await ctx.dstPublicClient.getCode({ address: action.to });
9783
+ if (!bytecode || bytecode === "0x") {
9784
+ throw createError("VALIDATION", {
9785
+ resource: "interop",
9786
+ operation: OP_INTEROP.routes.direct.preflight,
9787
+ message: `Destination address ${action.to} is not a contract on the destination chain. The receiver must be a contract that implements the IERC7786Recipient interface (receiveMessage).`,
9788
+ context: { to: action.to, action: action.type }
9789
+ });
9790
+ }
9791
+ }
9719
9792
  },
9720
9793
  async build(params, ctx) {
9721
9794
  const steps = [];
@@ -9975,7 +10048,7 @@ async function getBundleStatus(client, dstProvider, topics, bundleHash, opts) {
9975
10048
  }
9976
10049
  return { phase: "SENT" };
9977
10050
  }
9978
- async function executeBundle(client, dstProvider, info, opts) {
10051
+ async function executeBundle(client, dstProvider, info, opts, txOverrides) {
9979
10052
  const { topics } = getTopics();
9980
10053
  const { bundleHash, encodedData, proof } = info;
9981
10054
  const dstStatus = await getBundleStatus(client, dstProvider, topics, bundleHash, opts);
@@ -10004,7 +10077,10 @@ async function executeBundle(client, dstProvider, info, opts) {
10004
10077
  functionName: "executeBundle",
10005
10078
  args: [encodedData, proof],
10006
10079
  account: client.account,
10007
- chain: dstProvider.chain ?? null
10080
+ chain: dstProvider.chain ?? null,
10081
+ gas: txOverrides?.gasLimit,
10082
+ maxFeePerGas: txOverrides?.maxFeePerGas,
10083
+ maxPriorityFeePerGas: txOverrides?.maxPriorityFeePerGas
10008
10084
  });
10009
10085
  return {
10010
10086
  hash,
@@ -10461,8 +10537,8 @@ function createInteropFinalizationServices(client) {
10461
10537
  wait(dstProvider, gwProvider, input, opts) {
10462
10538
  return waitForFinalization(client, dstProvider, gwProvider, input, opts);
10463
10539
  },
10464
- async finalize(dstProvider, info, opts) {
10465
- const execResult = await executeBundle(client, dstProvider, info, opts);
10540
+ async finalize(dstProvider, info, opts, txOverrides) {
10541
+ const execResult = await executeBundle(client, dstProvider, info, opts, txOverrides);
10466
10542
  await execResult.wait();
10467
10543
  return {
10468
10544
  bundleHash: info.bundleHash,
@@ -10690,22 +10766,25 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
10690
10766
  ctx: { where: "interop.wait" }
10691
10767
  });
10692
10768
  const tryWait = (dstChain, h, opts) => toResult2(OP_INTEROP.tryWait, () => wait(dstChain, h, opts));
10693
- const finalize = (dstChain, h, opts) => wrap6(
10769
+ const finalize = (dstChain, h, opts, txOverrides) => wrap6(
10694
10770
  OP_INTEROP.finalize,
10695
10771
  async () => {
10696
10772
  const dstProvider = resolveChainRef(dstChain);
10697
10773
  if (isInteropFinalizationInfo(h)) {
10698
- return svc.finalize(dstProvider, h, opts);
10774
+ return svc.finalize(dstProvider, h, opts, txOverrides);
10699
10775
  }
10700
10776
  const info = await svc.wait(dstProvider, getGwProvider(), h);
10701
- return svc.finalize(dstProvider, info, opts);
10777
+ return svc.finalize(dstProvider, info, opts, txOverrides);
10702
10778
  },
10703
10779
  {
10704
10780
  message: "Failed to finalize/execute interop bundle on destination.",
10705
10781
  ctx: { where: "interop.finalize" }
10706
10782
  }
10707
10783
  );
10708
- const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
10784
+ const tryFinalize = (dstChain, h, opts, txOverrides) => toResult2(
10785
+ OP_INTEROP.tryFinalize,
10786
+ () => finalize(dstChain, h, opts, txOverrides)
10787
+ );
10709
10788
  const interopGetRoot = (dstChain, rootChainId, batchNumber) => wrap6(
10710
10789
  OP_INTEROP.svc.status.getRoot,
10711
10790
  () => getInteropRoot(resolveChainRef(dstChain), rootChainId, batchNumber),