@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.
- package/dist/adapters/ethers/client.cjs.map +1 -1
- package/dist/adapters/ethers/client.d.ts +1 -2
- package/dist/adapters/ethers/client.js +4 -5
- package/dist/adapters/ethers/index.cjs +200 -32
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.js +6 -7
- package/dist/adapters/ethers/resources/interop/index.d.ts +4 -1
- package/dist/adapters/ethers/resources/interop/services/finalization/bundle.d.ts +4 -0
- package/dist/adapters/ethers/resources/interop/services/gas.d.ts +12 -0
- package/dist/adapters/ethers/sdk.cjs +200 -32
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.js +5 -6
- package/dist/adapters/viem/client.cjs +787 -3
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.d.ts +6 -1
- package/dist/adapters/viem/client.js +4 -5
- package/dist/adapters/viem/index.cjs +6502 -2966
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.d.ts +5 -0
- package/dist/adapters/viem/index.js +6 -7
- package/dist/adapters/viem/resources/interop/address.d.ts +18 -0
- package/dist/adapters/viem/resources/interop/attributes/resource.d.ts +6 -0
- package/dist/adapters/viem/resources/interop/context.d.ts +31 -0
- package/dist/adapters/viem/resources/interop/index.d.ts +65 -0
- package/dist/adapters/viem/resources/interop/resolvers.d.ts +4 -0
- package/dist/adapters/viem/resources/interop/routes/direct.d.ts +2 -0
- package/dist/adapters/viem/resources/interop/routes/indirect.d.ts +2 -0
- package/dist/adapters/viem/resources/interop/routes/types.d.ts +23 -0
- package/dist/adapters/viem/resources/interop/services/erc20.d.ts +25 -0
- package/dist/adapters/viem/resources/interop/services/fee.d.ts +12 -0
- package/dist/adapters/viem/resources/interop/services/finalization/bundle.d.ts +19 -0
- package/dist/adapters/viem/resources/interop/services/finalization/data-fetchers.d.ts +17 -0
- package/dist/adapters/viem/resources/interop/services/finalization/decoders.d.ts +11 -0
- package/dist/adapters/viem/resources/interop/services/finalization/index.d.ts +13 -0
- package/dist/adapters/viem/resources/interop/services/finalization/polling.d.ts +7 -0
- package/dist/adapters/viem/resources/interop/services/finalization/status.d.ts +5 -0
- package/dist/adapters/viem/resources/interop/services/finalization/topics.d.ts +4 -0
- package/dist/adapters/viem/resources/interop/services/gas.d.ts +12 -0
- package/dist/adapters/viem/resources/interop/services/starter-data.d.ts +6 -0
- package/dist/adapters/viem/resources/interop/types.d.ts +8 -0
- package/dist/adapters/viem/sdk.cjs +6665 -3173
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +8 -1
- package/dist/adapters/viem/sdk.js +5 -5
- package/dist/{chunk-7CAVFIMW.js → chunk-24TE2NNJ.js} +2 -3
- package/dist/{chunk-75IOOODG.js → chunk-3KH5PCD6.js} +1233 -31
- package/dist/{chunk-XKRNLFET.js → chunk-5HG2DUYW.js} +150 -375
- package/dist/{chunk-OTXPSNNC.js → chunk-CK5UFAZK.js} +64 -7
- package/dist/{chunk-HP3EWKJL.js → chunk-JSBMIT4S.js} +1 -1
- package/dist/{chunk-5RRJDPAJ.js → chunk-NJK325XV.js} +2 -2
- package/dist/chunk-NLUCYVMX.js +658 -0
- package/dist/{chunk-XDRCN4FC.js → chunk-SBGBYZJM.js} +10 -2
- package/dist/{chunk-J47RI3G7.js → chunk-TYYUG5GA.js} +1 -1
- package/dist/{chunk-JY62QO3W.js → chunk-UEKFQAOS.js} +420 -6
- package/dist/core/index.js +2 -3
- package/dist/core/resources/deposits/chains.d.ts +1 -0
- package/dist/core/resources/deposits/gas.d.ts +7 -0
- package/dist/core/resources/deposits/priority.d.ts +4 -0
- package/dist/core/resources/interop/protocol.d.ts +3 -0
- package/dist/core/types/errors.d.ts +1 -0
- package/dist/core/types/flows/interop.d.ts +0 -2
- package/dist/core/types/primitives.d.ts +2 -0
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/dist/chunk-DYJKK5FW.js +0 -417
- package/dist/chunk-EOBXYHTZ.js +0 -265
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export { createEthersClient as createClient, createEthersClient } from '../../chunk-
|
|
2
|
-
export { buildDirectRequestStruct, createDepositsResource, createEthersSdk, createFinalizationServices, createInteropFinalizationServices, createInteropResource, createTokensResource, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-
|
|
3
|
-
export { classifyReadinessFromRevert, createErrorHandlers, decodeRevert, registerErrorAbi, toZKsyncError } from '../../chunk-
|
|
4
|
-
import '../../chunk-
|
|
1
|
+
export { createEthersClient as createClient, createEthersClient } from '../../chunk-24TE2NNJ.js';
|
|
2
|
+
export { buildDirectRequestStruct, createDepositsResource, createEthersSdk, createFinalizationServices, createInteropFinalizationServices, createInteropResource, createTokensResource, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-5HG2DUYW.js';
|
|
3
|
+
export { classifyReadinessFromRevert, createErrorHandlers, decodeRevert, registerErrorAbi, toZKsyncError } from '../../chunk-NJK325XV.js';
|
|
4
|
+
import '../../chunk-NLUCYVMX.js';
|
|
5
5
|
import '../../chunk-3HHUZXSV.js';
|
|
6
6
|
import '../../chunk-BWKWWLY4.js';
|
|
7
|
-
import '../../chunk-
|
|
8
|
-
import '../../chunk-
|
|
9
|
-
import '../../chunk-JY62QO3W.js';
|
|
7
|
+
import '../../chunk-JSBMIT4S.js';
|
|
8
|
+
import '../../chunk-UEKFQAOS.js';
|
|
10
9
|
import '../../chunk-MT4X5FEO.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EthersClient } from '../../client';
|
|
2
|
+
import type { Hex } from '../../../../core/types/primitives';
|
|
2
3
|
import type { AttributesResource } from '../../../../core/resources/interop/attributes/resource';
|
|
3
4
|
import type { InteropRoute, InteropPlan, InteropQuote, InteropStatus, InteropFinalizationResult, InteropParams, InteropHandle, InteropWaitable, InteropFinalizationInfo } from '../../../../core/types/flows/interop';
|
|
4
5
|
import type { ContractsResource } from '../contracts';
|
|
@@ -6,7 +7,7 @@ import type { TokensResource } from '../../../../core/types/flows/token';
|
|
|
6
7
|
import type { InteropRouteStrategy } from './routes/types';
|
|
7
8
|
import type { TransactionRequest } from 'ethers';
|
|
8
9
|
import { createInteropFinalizationServices, type InteropFinalizationServices } from './services/finalization';
|
|
9
|
-
import type
|
|
10
|
+
import { type LogsQueryOptions } from './services/finalization/data-fetchers';
|
|
10
11
|
import type { ChainRef, InteropConfig } from './types';
|
|
11
12
|
export declare const ROUTES: Record<InteropRoute, InteropRouteStrategy>;
|
|
12
13
|
export interface InteropResource {
|
|
@@ -57,6 +58,8 @@ export interface InteropResource {
|
|
|
57
58
|
ok: false;
|
|
58
59
|
error: unknown;
|
|
59
60
|
}>;
|
|
61
|
+
getInteropRoot(dstChain: ChainRef, rootChainId: bigint, batchNumber: bigint): Promise<Hex>;
|
|
62
|
+
verifyBundle(dstChain: ChainRef, h: InteropWaitable | InteropFinalizationInfo): Promise<InteropFinalizationResult>;
|
|
60
63
|
}
|
|
61
64
|
export declare function createInteropResource(client: EthersClient, config?: InteropConfig, tokens?: TokensResource, contracts?: ContractsResource, attributes?: AttributesResource): InteropResource;
|
|
62
65
|
export { createInteropFinalizationServices };
|
|
@@ -13,3 +13,7 @@ export declare function executeBundle(client: EthersClient, dstProvider: Abstrac
|
|
|
13
13
|
hash: Hex;
|
|
14
14
|
wait: () => Promise<TransactionReceipt>;
|
|
15
15
|
}>;
|
|
16
|
+
export declare function verifyBundle(client: EthersClient, dstProvider: AbstractProvider, info: InteropFinalizationInfo): Promise<{
|
|
17
|
+
hash: Hex;
|
|
18
|
+
wait: () => Promise<TransactionReceipt>;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TransactionRequest } from 'ethers';
|
|
2
|
+
import type { BuildCtx } from '../context';
|
|
3
|
+
/**
|
|
4
|
+
* Estimates the combined L2 gas cost for all steps in an interop plan.
|
|
5
|
+
*
|
|
6
|
+
* Fetches gas price once, then estimates gas for each step using ctx.sender as the
|
|
7
|
+
* from address. Applies the standard buffer and sums gasLimit × maxFeePerGas across
|
|
8
|
+
* all steps. Returns undefined if estimation fails for any step.
|
|
9
|
+
*/
|
|
10
|
+
export declare function quoteStepsL2Fee(steps: Array<{
|
|
11
|
+
tx: TransactionRequest;
|
|
12
|
+
}>, ctx: BuildCtx): Promise<bigint | undefined>;
|
|
@@ -377,6 +377,7 @@ var OP_INTEROP = {
|
|
|
377
377
|
tryWait: "interop.tryWait",
|
|
378
378
|
finalize: "interop.finalize",
|
|
379
379
|
tryFinalize: "interop.tryFinalize",
|
|
380
|
+
verify: "interop.verify",
|
|
380
381
|
context: {
|
|
381
382
|
chainTypeManager: "interop.chainTypeManager",
|
|
382
383
|
protocolVersion: "interop.protocolVersion"
|
|
@@ -5930,7 +5931,33 @@ function buildDirectRequestStruct(args) {
|
|
|
5930
5931
|
};
|
|
5931
5932
|
}
|
|
5932
5933
|
|
|
5934
|
+
// src/core/resources/deposits/chains.ts
|
|
5935
|
+
var ERAVM_CHAIN_IDS = /* @__PURE__ */ new Set([324n, 2741n, 11124n, 300n]);
|
|
5936
|
+
function isEraVmChain(chainIdL2) {
|
|
5937
|
+
return ERAVM_CHAIN_IDS.has(chainIdL2);
|
|
5938
|
+
}
|
|
5939
|
+
|
|
5933
5940
|
// src/core/resources/deposits/gas.ts
|
|
5941
|
+
var CREATE_REESTIMATE_BUFFER = 15n;
|
|
5942
|
+
var maxBigInt = (a, b) => a > b ? a : b;
|
|
5943
|
+
function applyGasBuffer(gasLimit, bufferPct = BUFFER) {
|
|
5944
|
+
return gasLimit * (100n + bufferPct) / 100n;
|
|
5945
|
+
}
|
|
5946
|
+
function resolveCreateDepositL1GasLimit(input) {
|
|
5947
|
+
const { chainIdL2, stepKey, preparedGasLimit, estimatedGasLimit } = input;
|
|
5948
|
+
if (estimatedGasLimit == null) {
|
|
5949
|
+
return preparedGasLimit;
|
|
5950
|
+
}
|
|
5951
|
+
const isEraVmBridgeStep = isEraVmChain(chainIdL2) && stepKey.startsWith("bridgehub:");
|
|
5952
|
+
const reestimatedGasLimit = applyGasBuffer(
|
|
5953
|
+
estimatedGasLimit,
|
|
5954
|
+
isEraVmBridgeStep ? BUFFER : CREATE_REESTIMATE_BUFFER
|
|
5955
|
+
);
|
|
5956
|
+
if (isEraVmBridgeStep && preparedGasLimit != null) {
|
|
5957
|
+
return maxBigInt(preparedGasLimit, reestimatedGasLimit);
|
|
5958
|
+
}
|
|
5959
|
+
return reestimatedGasLimit;
|
|
5960
|
+
}
|
|
5934
5961
|
function makeGasQuote(p) {
|
|
5935
5962
|
const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
|
|
5936
5963
|
return {
|
|
@@ -5981,7 +6008,7 @@ async function quoteL1Gas(input) {
|
|
|
5981
6008
|
}
|
|
5982
6009
|
try {
|
|
5983
6010
|
const est = await estimator.estimateGas(tx);
|
|
5984
|
-
const buffered = BigInt(est)
|
|
6011
|
+
const buffered = applyGasBuffer(BigInt(est));
|
|
5985
6012
|
return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
|
|
5986
6013
|
} catch {
|
|
5987
6014
|
if (fallbackGasLimit != null) {
|
|
@@ -6018,7 +6045,7 @@ async function quoteL2Gas(input) {
|
|
|
6018
6045
|
const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
|
|
6019
6046
|
const pubdataOverhead = pubdataBytes * pp;
|
|
6020
6047
|
let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
|
|
6021
|
-
total = total
|
|
6048
|
+
total = applyGasBuffer(total);
|
|
6022
6049
|
return makeGasQuote({
|
|
6023
6050
|
gasLimit: total,
|
|
6024
6051
|
maxFeePerGas,
|
|
@@ -6455,18 +6482,19 @@ function buildFeeBreakdown(p) {
|
|
|
6455
6482
|
// src/core/resources/deposits/priority.ts
|
|
6456
6483
|
var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
|
|
6457
6484
|
var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
|
|
6458
|
-
var
|
|
6485
|
+
var ERAVM_PRIORITY_L2_GAS_BUFFER = 30n;
|
|
6486
|
+
var maxBigInt2 = (a, b) => a > b ? a : b;
|
|
6459
6487
|
var ceilDiv = (a, b) => (a + b - 1n) / b;
|
|
6460
6488
|
function derivePriorityTxGasBreakdown(input) {
|
|
6461
6489
|
const factoryDepsCount = input.factoryDepsCount ?? 0n;
|
|
6462
|
-
const minBodyGas =
|
|
6490
|
+
const minBodyGas = maxBigInt2(
|
|
6463
6491
|
L1_TX_INTRINSIC_L2_GAS + ceilDiv(
|
|
6464
6492
|
input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
|
|
6465
6493
|
PRIORITY_TX_ENCODING_STEP_BYTES
|
|
6466
6494
|
) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
|
|
6467
6495
|
L1_TX_MIN_L2_GAS_BASE
|
|
6468
6496
|
) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
|
|
6469
|
-
const overhead =
|
|
6497
|
+
const overhead = maxBigInt2(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
|
|
6470
6498
|
const derivedBodyGas = minBodyGas;
|
|
6471
6499
|
return {
|
|
6472
6500
|
encodedLength: input.encodedLength,
|
|
@@ -6481,8 +6509,12 @@ function derivePriorityTxGasBreakdown(input) {
|
|
|
6481
6509
|
function derivePriorityBodyGasEstimateCap(input) {
|
|
6482
6510
|
return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
|
|
6483
6511
|
}
|
|
6484
|
-
|
|
6485
|
-
|
|
6512
|
+
function applyPriorityL2GasLimitBuffer(input) {
|
|
6513
|
+
if (!isEraVmChain(input.chainIdL2)) {
|
|
6514
|
+
return input.gasLimit;
|
|
6515
|
+
}
|
|
6516
|
+
return input.gasLimit * (100n + ERAVM_PRIORITY_L2_GAS_BUFFER) / 100n;
|
|
6517
|
+
}
|
|
6486
6518
|
var EMPTY_BYTES = "0x";
|
|
6487
6519
|
var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
|
|
6488
6520
|
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)";
|
|
@@ -6539,7 +6571,10 @@ function routeEthDirect() {
|
|
|
6539
6571
|
l2Calldata,
|
|
6540
6572
|
gasPerPubdata: ctx.gasPerPubdata
|
|
6541
6573
|
});
|
|
6542
|
-
const quotedL2GasLimit = ctx.l2GasLimit ??
|
|
6574
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
6575
|
+
chainIdL2: ctx.chainIdL2,
|
|
6576
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
6577
|
+
});
|
|
6543
6578
|
const l2GasParams = await quoteL2Gas2({
|
|
6544
6579
|
ctx,
|
|
6545
6580
|
route: "eth-base",
|
|
@@ -6642,7 +6677,10 @@ async function getPriorityGasModel(input) {
|
|
|
6642
6677
|
gasPerPubdata: input.ctx.gasPerPubdata
|
|
6643
6678
|
});
|
|
6644
6679
|
const model = {
|
|
6645
|
-
priorityFloorGasLimit:
|
|
6680
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
6681
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
6682
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
6683
|
+
})
|
|
6646
6684
|
};
|
|
6647
6685
|
if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS2) {
|
|
6648
6686
|
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
@@ -6864,7 +6902,10 @@ async function getPriorityGasModel2(input) {
|
|
|
6864
6902
|
gasPerPubdata: input.ctx.gasPerPubdata
|
|
6865
6903
|
});
|
|
6866
6904
|
const model = {
|
|
6867
|
-
priorityFloorGasLimit:
|
|
6905
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
6906
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
6907
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
6908
|
+
})
|
|
6868
6909
|
};
|
|
6869
6910
|
if (input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS3) {
|
|
6870
6911
|
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
@@ -6986,7 +7027,7 @@ function routeEthNonBase() {
|
|
|
6986
7027
|
const requestStruct = {
|
|
6987
7028
|
chainId: ctx.chainIdL2,
|
|
6988
7029
|
mintValue,
|
|
6989
|
-
l2Value:
|
|
7030
|
+
l2Value: 0n,
|
|
6990
7031
|
l2GasLimit: l2GasParams.gasLimit,
|
|
6991
7032
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
6992
7033
|
refundRecipient: ctx.refundRecipient,
|
|
@@ -6994,6 +7035,7 @@ function routeEthNonBase() {
|
|
|
6994
7035
|
secondBridgeValue: p.amount,
|
|
6995
7036
|
secondBridgeCalldata
|
|
6996
7037
|
};
|
|
7038
|
+
const bridgehubValue = p.amount;
|
|
6997
7039
|
const bridgehub = await ctx.contracts.bridgehub();
|
|
6998
7040
|
const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
|
|
6999
7041
|
requestStruct
|
|
@@ -7001,8 +7043,7 @@ function routeEthNonBase() {
|
|
|
7001
7043
|
const l1TxCandidate = {
|
|
7002
7044
|
to: ctx.bridgehub,
|
|
7003
7045
|
data,
|
|
7004
|
-
value:
|
|
7005
|
-
// base ≠ ETH ⇒ msg.value == secondBridgeValue
|
|
7046
|
+
value: bridgehubValue,
|
|
7006
7047
|
from: ctx.sender,
|
|
7007
7048
|
...ctx.gasOverrides
|
|
7008
7049
|
};
|
|
@@ -7081,7 +7122,10 @@ function routeErc20Base() {
|
|
|
7081
7122
|
l2Calldata,
|
|
7082
7123
|
gasPerPubdata: ctx.gasPerPubdata
|
|
7083
7124
|
});
|
|
7084
|
-
const quotedL2GasLimit = ctx.l2GasLimit ??
|
|
7125
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
7126
|
+
chainIdL2: ctx.chainIdL2,
|
|
7127
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
7128
|
+
});
|
|
7085
7129
|
const l2GasParams = await quoteL2Gas2({
|
|
7086
7130
|
ctx,
|
|
7087
7131
|
route: "erc20-base",
|
|
@@ -7507,6 +7551,8 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
7507
7551
|
async () => {
|
|
7508
7552
|
const plan = await prepare(p);
|
|
7509
7553
|
const stepHashes = {};
|
|
7554
|
+
const { chainId } = await client.l2.getNetwork();
|
|
7555
|
+
const chainIdL2 = BigInt(chainId);
|
|
7510
7556
|
const managed = new ethers.NonceManager(client.signer);
|
|
7511
7557
|
const from = await managed.getAddress();
|
|
7512
7558
|
let next;
|
|
@@ -7552,8 +7598,14 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
7552
7598
|
}
|
|
7553
7599
|
if (!p.l1TxOverrides?.gasLimit) {
|
|
7554
7600
|
try {
|
|
7601
|
+
const preparedGasLimit = step.tx.gasLimit != null ? BigInt(step.tx.gasLimit.toString()) : void 0;
|
|
7555
7602
|
const est = await client.l1.estimateGas(step.tx);
|
|
7556
|
-
step.tx.gasLimit =
|
|
7603
|
+
step.tx.gasLimit = resolveCreateDepositL1GasLimit({
|
|
7604
|
+
chainIdL2,
|
|
7605
|
+
stepKey: step.key,
|
|
7606
|
+
preparedGasLimit,
|
|
7607
|
+
estimatedGasLimit: BigInt(est)
|
|
7608
|
+
});
|
|
7557
7609
|
} catch {
|
|
7558
7610
|
}
|
|
7559
7611
|
}
|
|
@@ -9172,26 +9224,30 @@ function routeDirect() {
|
|
|
9172
9224
|
}
|
|
9173
9225
|
};
|
|
9174
9226
|
}
|
|
9227
|
+
|
|
9228
|
+
// src/core/resources/interop/protocol.ts
|
|
9175
9229
|
var MIN_INTEROP_PROTOCOL = 31;
|
|
9230
|
+
function assertProtocolVersion(chainId, protocolVersion) {
|
|
9231
|
+
if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
|
|
9232
|
+
throw createError("VALIDATION", {
|
|
9233
|
+
resource: "interop",
|
|
9234
|
+
operation: OP_INTEROP.context.protocolVersion,
|
|
9235
|
+
message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
|
|
9236
|
+
context: {
|
|
9237
|
+
chainId,
|
|
9238
|
+
requiredMinor: MIN_INTEROP_PROTOCOL,
|
|
9239
|
+
semver: protocolVersion
|
|
9240
|
+
}
|
|
9241
|
+
});
|
|
9242
|
+
}
|
|
9243
|
+
}
|
|
9244
|
+
|
|
9245
|
+
// src/adapters/ethers/resources/interop/context.ts
|
|
9176
9246
|
async function assertInteropProtocolVersion(client, srcChainId, dstChainId) {
|
|
9177
9247
|
const [srcProtocolVersion, dstProtocolVersion] = await Promise.all([
|
|
9178
9248
|
client.getProtocolVersion(srcChainId),
|
|
9179
9249
|
client.getProtocolVersion(dstChainId)
|
|
9180
9250
|
]);
|
|
9181
|
-
const assertProtocolVersion = (chainId, protocolVersion) => {
|
|
9182
|
-
if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
|
|
9183
|
-
throw createError("VALIDATION", {
|
|
9184
|
-
resource: "interop",
|
|
9185
|
-
operation: OP_INTEROP.context.protocolVersion,
|
|
9186
|
-
message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
|
|
9187
|
-
context: {
|
|
9188
|
-
chainId,
|
|
9189
|
-
requiredMinor: MIN_INTEROP_PROTOCOL,
|
|
9190
|
-
semver: protocolVersion
|
|
9191
|
-
}
|
|
9192
|
-
});
|
|
9193
|
-
}
|
|
9194
|
-
};
|
|
9195
9251
|
assertProtocolVersion(srcChainId, srcProtocolVersion);
|
|
9196
9252
|
assertProtocolVersion(dstChainId, dstProtocolVersion);
|
|
9197
9253
|
}
|
|
@@ -9262,7 +9318,14 @@ function parseMaxBlockRangeLimit(error) {
|
|
|
9262
9318
|
async function getTxReceipt(provider, txHash) {
|
|
9263
9319
|
const receipt = await wrap3(
|
|
9264
9320
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
9265
|
-
() =>
|
|
9321
|
+
async () => {
|
|
9322
|
+
try {
|
|
9323
|
+
return await provider.getTransactionReceipt(txHash);
|
|
9324
|
+
} catch (error) {
|
|
9325
|
+
if (isReceiptNotFound(error)) return null;
|
|
9326
|
+
throw error;
|
|
9327
|
+
}
|
|
9328
|
+
},
|
|
9266
9329
|
{
|
|
9267
9330
|
ctx: { where: "l2.getTransactionReceipt", l2SrcTxHash: txHash },
|
|
9268
9331
|
message: "Failed to fetch source L2 receipt for interop tx."
|
|
@@ -9427,6 +9490,60 @@ async function executeBundle(client, dstProvider, info, opts) {
|
|
|
9427
9490
|
);
|
|
9428
9491
|
}
|
|
9429
9492
|
}
|
|
9493
|
+
async function verifyBundle(client, dstProvider, info) {
|
|
9494
|
+
const signer = await wrap4(OP_INTEROP.verify, () => client.signerFor(dstProvider), {
|
|
9495
|
+
message: "Failed to resolve destination signer for verifyBundle."
|
|
9496
|
+
});
|
|
9497
|
+
const { interopHandler } = await client.ensureAddresses();
|
|
9498
|
+
const handler = new ethers.Contract(interopHandler, IInteropHandler_default, signer);
|
|
9499
|
+
try {
|
|
9500
|
+
const txResponse = await handler.verifyBundle(
|
|
9501
|
+
info.encodedData,
|
|
9502
|
+
info.proof
|
|
9503
|
+
);
|
|
9504
|
+
const hash = txResponse.hash;
|
|
9505
|
+
return {
|
|
9506
|
+
hash,
|
|
9507
|
+
wait: async () => {
|
|
9508
|
+
try {
|
|
9509
|
+
const receipt = await txResponse.wait();
|
|
9510
|
+
if (!receipt || receipt.status !== 1) {
|
|
9511
|
+
throw createError("EXECUTION", {
|
|
9512
|
+
resource: "interop",
|
|
9513
|
+
operation: OP_INTEROP.verify,
|
|
9514
|
+
message: "Interop bundle verification reverted on destination.",
|
|
9515
|
+
context: { txHash: hash }
|
|
9516
|
+
});
|
|
9517
|
+
}
|
|
9518
|
+
return receipt;
|
|
9519
|
+
} catch (e) {
|
|
9520
|
+
if (isZKsyncError(e)) throw e;
|
|
9521
|
+
throw toZKsyncError(
|
|
9522
|
+
"EXECUTION",
|
|
9523
|
+
{
|
|
9524
|
+
resource: "interop",
|
|
9525
|
+
operation: OP_INTEROP.verify,
|
|
9526
|
+
message: "Failed while waiting for verifyBundle transaction on destination.",
|
|
9527
|
+
context: { txHash: hash }
|
|
9528
|
+
},
|
|
9529
|
+
e
|
|
9530
|
+
);
|
|
9531
|
+
}
|
|
9532
|
+
}
|
|
9533
|
+
};
|
|
9534
|
+
} catch (e) {
|
|
9535
|
+
if (isZKsyncError(e)) throw e;
|
|
9536
|
+
throw toZKsyncError(
|
|
9537
|
+
"EXECUTION",
|
|
9538
|
+
{
|
|
9539
|
+
resource: "interop",
|
|
9540
|
+
operation: OP_INTEROP.verify,
|
|
9541
|
+
message: "Failed to send verifyBundle transaction on destination chain."
|
|
9542
|
+
},
|
|
9543
|
+
e
|
|
9544
|
+
);
|
|
9545
|
+
}
|
|
9546
|
+
}
|
|
9430
9547
|
|
|
9431
9548
|
// src/core/resources/interop/finalization.ts
|
|
9432
9549
|
var DEFAULT_POLL_MS = 1e3;
|
|
@@ -9792,6 +9909,31 @@ function resolveChainRef(ref) {
|
|
|
9792
9909
|
return typeof ref === "string" ? new ethers.JsonRpcProvider(ref) : ref;
|
|
9793
9910
|
}
|
|
9794
9911
|
|
|
9912
|
+
// src/adapters/ethers/resources/interop/services/gas.ts
|
|
9913
|
+
async function quoteStepsL2Fee(steps, ctx) {
|
|
9914
|
+
if (steps.length === 0) return 0n;
|
|
9915
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
9916
|
+
let maxFeePerGas;
|
|
9917
|
+
try {
|
|
9918
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
9919
|
+
maxFeePerGas = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
|
|
9920
|
+
} catch {
|
|
9921
|
+
return void 0;
|
|
9922
|
+
}
|
|
9923
|
+
let total = 0n;
|
|
9924
|
+
for (const step of steps) {
|
|
9925
|
+
try {
|
|
9926
|
+
const coreTx = toCoreTx({ ...step.tx, from: ctx.sender });
|
|
9927
|
+
const est = await estimator.estimateGas(coreTx);
|
|
9928
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
9929
|
+
total += buffered * maxFeePerGas;
|
|
9930
|
+
} catch {
|
|
9931
|
+
return void 0;
|
|
9932
|
+
}
|
|
9933
|
+
}
|
|
9934
|
+
return total;
|
|
9935
|
+
}
|
|
9936
|
+
|
|
9795
9937
|
// src/adapters/ethers/resources/interop/index.ts
|
|
9796
9938
|
var { wrap: wrap6, toResult: toResult2 } = createErrorHandlers("interop");
|
|
9797
9939
|
var ROUTES3 = {
|
|
@@ -9848,12 +9990,14 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
|
9848
9990
|
ctx: { where: `routes.${route}.build` }
|
|
9849
9991
|
}
|
|
9850
9992
|
);
|
|
9993
|
+
const l2Fee = await quoteStepsL2Fee(steps, ctx).catch(() => void 0);
|
|
9851
9994
|
const summary = {
|
|
9852
9995
|
route,
|
|
9853
9996
|
approvalsNeeded: approvals,
|
|
9854
9997
|
totalActionValue: quoteExtras.totalActionValue,
|
|
9855
9998
|
bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
|
|
9856
|
-
interopFee
|
|
9999
|
+
interopFee,
|
|
10000
|
+
l2Fee
|
|
9857
10001
|
};
|
|
9858
10002
|
return { plan: { route, summary, steps }, ctx };
|
|
9859
10003
|
}
|
|
@@ -9978,6 +10122,28 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
|
9978
10122
|
}
|
|
9979
10123
|
);
|
|
9980
10124
|
const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
|
|
10125
|
+
const interopGetRoot = (dstChain, rootChainId, batchNumber) => wrap6(
|
|
10126
|
+
OP_INTEROP.svc.status.getRoot,
|
|
10127
|
+
() => getInteropRoot(resolveChainRef(dstChain), rootChainId, batchNumber),
|
|
10128
|
+
{
|
|
10129
|
+
message: "Failed to get interop root from the destination chain.",
|
|
10130
|
+
ctx: { where: "interop.getInteropRoot" }
|
|
10131
|
+
}
|
|
10132
|
+
);
|
|
10133
|
+
const verifyBundle2 = (dstChain, h) => wrap6(
|
|
10134
|
+
OP_INTEROP.verify,
|
|
10135
|
+
async () => {
|
|
10136
|
+
const dstProvider = resolveChainRef(dstChain);
|
|
10137
|
+
const info = isInteropFinalizationInfo(h) ? h : await svc.wait(dstProvider, getGwProvider(), h);
|
|
10138
|
+
const result = await verifyBundle(client, dstProvider, info);
|
|
10139
|
+
await result.wait();
|
|
10140
|
+
return { bundleHash: info.bundleHash, dstExecTxHash: result.hash };
|
|
10141
|
+
},
|
|
10142
|
+
{
|
|
10143
|
+
message: "Failed to verify interop bundle on destination.",
|
|
10144
|
+
ctx: { where: "interop.verifyBundle" }
|
|
10145
|
+
}
|
|
10146
|
+
);
|
|
9981
10147
|
return {
|
|
9982
10148
|
quote,
|
|
9983
10149
|
tryQuote,
|
|
@@ -9989,7 +10155,9 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
|
9989
10155
|
wait,
|
|
9990
10156
|
tryWait,
|
|
9991
10157
|
finalize,
|
|
9992
|
-
tryFinalize
|
|
10158
|
+
tryFinalize,
|
|
10159
|
+
getInteropRoot: interopGetRoot,
|
|
10160
|
+
verifyBundle: verifyBundle2
|
|
9993
10161
|
};
|
|
9994
10162
|
}
|
|
9995
10163
|
|