@matterlabs/zksync-js 0.0.13 → 0.0.14
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 +13 -4
- package/dist/adapters/ethers/client.cjs.map +1 -1
- package/dist/adapters/ethers/client.js +7 -6
- package/dist/adapters/ethers/index.cjs +501 -242
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.js +10 -9
- package/dist/adapters/ethers/resources/deposits/routes/priority.d.ts +12 -0
- package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +4 -0
- package/dist/adapters/ethers/resources/interop/index.d.ts +14 -14
- package/dist/adapters/ethers/resources/interop/resolvers.d.ts +3 -8
- package/dist/adapters/ethers/resources/interop/routes/types.d.ts +2 -1
- package/dist/adapters/ethers/resources/interop/services/erc20.d.ts +10 -0
- package/dist/adapters/ethers/resources/interop/services/fee.d.ts +12 -0
- package/dist/adapters/ethers/resources/interop/services/finalization/index.d.ts +1 -1
- package/dist/adapters/ethers/resources/interop/services/finalization/polling.d.ts +1 -1
- package/dist/adapters/ethers/resources/interop/types.d.ts +6 -14
- package/dist/adapters/ethers/sdk.cjs +912 -252
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.d.ts +6 -1
- package/dist/adapters/ethers/sdk.js +8 -7
- package/dist/adapters/viem/client.cjs +8 -4
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.js +7 -6
- package/dist/adapters/viem/index.cjs +315 -73
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.js +10 -9
- package/dist/adapters/viem/resources/deposits/routes/priority.d.ts +13 -0
- package/dist/adapters/viem/resources/deposits/services/gas.d.ts +4 -0
- package/dist/adapters/viem/sdk.cjs +307 -69
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.js +7 -7
- package/dist/{chunk-E3KP7XCG.js → chunk-3HHUZXSV.js} +1 -1
- package/dist/{chunk-UDBRUBEK.js → chunk-5RRJDPAJ.js} +2 -2
- package/dist/{chunk-EDWBCPO3.js → chunk-75IOOODG.js} +253 -53
- package/dist/{chunk-R5WRFPK2.js → chunk-7CAVFIMW.js} +5 -4
- package/dist/chunk-BWKWWLY4.js +9 -0
- package/dist/{chunk-4S4XDA4N.js → chunk-DYJKK5FW.js} +17 -15
- package/dist/{chunk-5L6EYUJB.js → chunk-EOBXYHTZ.js} +35 -7
- package/dist/{chunk-53MC5BR2.js → chunk-HP3EWKJL.js} +1 -1
- package/dist/{chunk-HI64OOAR.js → chunk-J47RI3G7.js} +1 -1
- package/dist/{chunk-RI73VJSH.js → chunk-JY62QO3W.js} +44 -21
- package/dist/{chunk-QQ2OR434.js → chunk-MT4X5FEO.js} +18 -2
- package/dist/{chunk-2RIARDXZ.js → chunk-OTXPSNNC.js} +5 -4
- package/dist/{chunk-5R7L5NM5.js → chunk-XDRCN4FC.js} +2 -2
- package/dist/{chunk-JHO2UQ5F.js → chunk-XKRNLFET.js} +394 -200
- package/dist/core/constants.cjs +17 -1
- package/dist/core/constants.cjs.map +1 -1
- package/dist/core/constants.d.ts +9 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/index.cjs +52 -24
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/internal/abis/IERC7786Attributes.d.ts +21 -11
- package/dist/core/internal/abis/IInteropCenter.d.ts +4 -0
- package/dist/core/resources/deposits/priority.d.ts +37 -0
- package/dist/core/resources/interop/attributes/bundle.d.ts +1 -0
- package/dist/core/resources/interop/attributes/resource.d.ts +1 -0
- package/dist/core/resources/interop/plan.d.ts +11 -3
- package/dist/core/rpc/types.d.ts +1 -0
- package/dist/core/rpc/zks.d.ts +5 -1
- package/dist/core/types/errors.d.ts +5 -0
- package/dist/core/types/flows/interop.d.ts +11 -18
- package/dist/index.cjs +69 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -5
- package/package.json +1 -1
|
@@ -48,7 +48,15 @@ var TX_OVERHEAD_GAS = 10000n;
|
|
|
48
48
|
var TX_MEMORY_OVERHEAD_GAS = 10n;
|
|
49
49
|
var DEFAULT_PUBDATA_BYTES = 155n;
|
|
50
50
|
var DEFAULT_ABI_BYTES = 400n;
|
|
51
|
-
var SAFE_L1_BRIDGE_GAS =
|
|
51
|
+
var SAFE_L1_BRIDGE_GAS = 3000000n;
|
|
52
|
+
var L1_TX_INTRINSIC_L2_GAS = 167157n;
|
|
53
|
+
var L1_TX_INTRINSIC_PUBDATA = 88n;
|
|
54
|
+
var L1_TX_MIN_L2_GAS_BASE = 173484n;
|
|
55
|
+
var L1_TX_DELTA_544_ENCODING_BYTES = 1656n;
|
|
56
|
+
var L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473n;
|
|
57
|
+
var L1_TX_DELTA_FACTORY_DEPS_PUBDATA = 64n;
|
|
58
|
+
var TX_SLOT_OVERHEAD_L2_GAS = 10000n;
|
|
59
|
+
var PRIORITY_TX_MAX_GAS_LIMIT = 72000000n;
|
|
52
60
|
|
|
53
61
|
// src/core/utils/addr.ts
|
|
54
62
|
function isAddress(x) {
|
|
@@ -413,6 +421,11 @@ var OP_INTEROP = {
|
|
|
413
421
|
wait: {
|
|
414
422
|
poll: "interop.svc.wait:poll",
|
|
415
423
|
timeout: "interop.svc.wait:timeout"
|
|
424
|
+
},
|
|
425
|
+
fees: {
|
|
426
|
+
zkInteropFee: "interop.svc.fees:zkInteropFee",
|
|
427
|
+
zkToken: "interop.svc.fees:zkToken",
|
|
428
|
+
protocolFee: "interop.svc.fees:protocolFee"
|
|
416
429
|
}
|
|
417
430
|
}
|
|
418
431
|
};
|
|
@@ -481,6 +494,7 @@ function normalizeProof(p) {
|
|
|
481
494
|
const raw = p ?? {};
|
|
482
495
|
const idRaw = raw?.id ?? raw?.index;
|
|
483
496
|
const bnRaw = raw?.batch_number ?? raw?.batchNumber;
|
|
497
|
+
const gwBlockNumberRaw = raw?.gatewayBlockNumber;
|
|
484
498
|
if (idRaw == null || bnRaw == null) {
|
|
485
499
|
throw createError("RPC", {
|
|
486
500
|
resource: "zksrpc",
|
|
@@ -501,7 +515,8 @@ function normalizeProof(p) {
|
|
|
501
515
|
id: toBig(idRaw),
|
|
502
516
|
batchNumber: toBig(bnRaw),
|
|
503
517
|
proof: toHexArray(raw?.proof),
|
|
504
|
-
root: raw.root
|
|
518
|
+
root: raw.root,
|
|
519
|
+
gatewayBlockNumber: gwBlockNumberRaw != null ? toBig(gwBlockNumberRaw) : void 0
|
|
505
520
|
};
|
|
506
521
|
} catch (e) {
|
|
507
522
|
if (isZKsyncError(e)) throw e;
|
|
@@ -778,13 +793,15 @@ function createZksRpc(transport) {
|
|
|
778
793
|
);
|
|
779
794
|
},
|
|
780
795
|
// Fetches a proof for an L2→L1 log emitted in the given transaction.
|
|
781
|
-
async getL2ToL1LogProof(txHash, index) {
|
|
796
|
+
async getL2ToL1LogProof(txHash, index, proofTarget) {
|
|
782
797
|
return withRpcOp(
|
|
783
798
|
"zksrpc.getL2ToL1LogProof",
|
|
784
799
|
"Failed to fetch L2\u2192L1 log proof.",
|
|
785
|
-
{ txHash, index },
|
|
800
|
+
{ txHash, index, proofTarget },
|
|
786
801
|
async () => {
|
|
787
|
-
const
|
|
802
|
+
const params = [txHash, index];
|
|
803
|
+
if (proofTarget != void 0) params.push(proofTarget);
|
|
804
|
+
const proof = await transport(METHODS.getL2ToL1LogProof, params);
|
|
788
805
|
if (!proof) {
|
|
789
806
|
throw createError("STATE", {
|
|
790
807
|
resource: "zksrpc",
|
|
@@ -4967,56 +4984,69 @@ var IERC20_default = IERC20ABI;
|
|
|
4967
4984
|
// src/core/internal/abis/IERC7786Attributes.ts
|
|
4968
4985
|
var IERC7786AttributesABI = [
|
|
4969
4986
|
{
|
|
4987
|
+
type: "function",
|
|
4988
|
+
name: "executionAddress",
|
|
4970
4989
|
inputs: [
|
|
4971
4990
|
{
|
|
4972
|
-
internalType: "bytes",
|
|
4973
4991
|
name: "_executionAddress",
|
|
4974
|
-
type: "bytes"
|
|
4992
|
+
type: "bytes",
|
|
4993
|
+
internalType: "bytes"
|
|
4975
4994
|
}
|
|
4976
4995
|
],
|
|
4977
|
-
name: "executionAddress",
|
|
4978
4996
|
outputs: [],
|
|
4979
|
-
stateMutability: "pure"
|
|
4980
|
-
type: "function"
|
|
4997
|
+
stateMutability: "pure"
|
|
4981
4998
|
},
|
|
4982
4999
|
{
|
|
5000
|
+
type: "function",
|
|
5001
|
+
name: "indirectCall",
|
|
4983
5002
|
inputs: [
|
|
4984
5003
|
{
|
|
4985
|
-
internalType: "uint256",
|
|
4986
5004
|
name: "_indirectCallMessageValue",
|
|
4987
|
-
type: "uint256"
|
|
5005
|
+
type: "uint256",
|
|
5006
|
+
internalType: "uint256"
|
|
4988
5007
|
}
|
|
4989
5008
|
],
|
|
4990
|
-
name: "indirectCall",
|
|
4991
5009
|
outputs: [],
|
|
4992
|
-
stateMutability: "pure"
|
|
4993
|
-
type: "function"
|
|
5010
|
+
stateMutability: "pure"
|
|
4994
5011
|
},
|
|
4995
5012
|
{
|
|
5013
|
+
type: "function",
|
|
5014
|
+
name: "interopCallValue",
|
|
4996
5015
|
inputs: [
|
|
4997
5016
|
{
|
|
4998
|
-
internalType: "uint256",
|
|
4999
5017
|
name: "_interopCallValue",
|
|
5000
|
-
type: "uint256"
|
|
5018
|
+
type: "uint256",
|
|
5019
|
+
internalType: "uint256"
|
|
5001
5020
|
}
|
|
5002
5021
|
],
|
|
5003
|
-
name: "interopCallValue",
|
|
5004
5022
|
outputs: [],
|
|
5005
|
-
stateMutability: "pure"
|
|
5006
|
-
type: "function"
|
|
5023
|
+
stateMutability: "pure"
|
|
5007
5024
|
},
|
|
5008
5025
|
{
|
|
5026
|
+
type: "function",
|
|
5027
|
+
name: "unbundlerAddress",
|
|
5009
5028
|
inputs: [
|
|
5010
5029
|
{
|
|
5011
|
-
internalType: "bytes",
|
|
5012
5030
|
name: "_unbundlerAddress",
|
|
5013
|
-
type: "bytes"
|
|
5031
|
+
type: "bytes",
|
|
5032
|
+
internalType: "bytes"
|
|
5014
5033
|
}
|
|
5015
5034
|
],
|
|
5016
|
-
name: "unbundlerAddress",
|
|
5017
5035
|
outputs: [],
|
|
5018
|
-
stateMutability: "pure"
|
|
5019
|
-
|
|
5036
|
+
stateMutability: "pure"
|
|
5037
|
+
},
|
|
5038
|
+
{
|
|
5039
|
+
type: "function",
|
|
5040
|
+
name: "useFixedFee",
|
|
5041
|
+
inputs: [
|
|
5042
|
+
{
|
|
5043
|
+
name: "_useFixed",
|
|
5044
|
+
type: "bool",
|
|
5045
|
+
internalType: "bool"
|
|
5046
|
+
}
|
|
5047
|
+
],
|
|
5048
|
+
outputs: [],
|
|
5049
|
+
stateMutability: "pure"
|
|
5020
5050
|
}
|
|
5021
5051
|
];
|
|
5022
5052
|
var IERC7786Attributes_default = IERC7786AttributesABI;
|
|
@@ -5864,6 +5894,11 @@ var IInteropCenterABI = [
|
|
|
5864
5894
|
type: "uint256",
|
|
5865
5895
|
internalType: "uint256"
|
|
5866
5896
|
},
|
|
5897
|
+
{
|
|
5898
|
+
name: "destinationBaseTokenAssetId",
|
|
5899
|
+
type: "bytes32",
|
|
5900
|
+
internalType: "bytes32"
|
|
5901
|
+
},
|
|
5867
5902
|
{
|
|
5868
5903
|
name: "interopBundleSalt",
|
|
5869
5904
|
type: "bytes32",
|
|
@@ -7498,7 +7533,7 @@ function createErrorOps(decodeRevert2) {
|
|
|
7498
7533
|
throw toZKsyncError2(kind, { resource, operation, context: opts?.ctx ?? {}, message }, e);
|
|
7499
7534
|
}
|
|
7500
7535
|
}
|
|
7501
|
-
function
|
|
7536
|
+
function wrap8(operation, fn, opts) {
|
|
7502
7537
|
return run("INTERNAL", operation, fn, opts);
|
|
7503
7538
|
}
|
|
7504
7539
|
function wrapAs10(kind, operation, fn, opts) {
|
|
@@ -7506,7 +7541,7 @@ function createErrorOps(decodeRevert2) {
|
|
|
7506
7541
|
}
|
|
7507
7542
|
async function toResult3(operation, fn, opts) {
|
|
7508
7543
|
try {
|
|
7509
|
-
const value = await
|
|
7544
|
+
const value = await wrap8(operation, fn, opts);
|
|
7510
7545
|
return { ok: true, value };
|
|
7511
7546
|
} catch (e) {
|
|
7512
7547
|
const shaped = isZKsyncError(e) ? e : toZKsyncError2(
|
|
@@ -7522,7 +7557,7 @@ function createErrorOps(decodeRevert2) {
|
|
|
7522
7557
|
return { ok: false, error: shaped };
|
|
7523
7558
|
}
|
|
7524
7559
|
}
|
|
7525
|
-
return { wrap:
|
|
7560
|
+
return { wrap: wrap8, wrapAs: wrapAs10, toResult: toResult3 };
|
|
7526
7561
|
}
|
|
7527
7562
|
return { toZKsyncError: toZKsyncError2, createErrorHandlers: createErrorHandlers2 };
|
|
7528
7563
|
}
|
|
@@ -8054,11 +8089,10 @@ async function quoteL1Gas(input) {
|
|
|
8054
8089
|
const est = await estimator.estimateGas(tx);
|
|
8055
8090
|
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
8056
8091
|
return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
|
|
8057
|
-
} catch
|
|
8092
|
+
} catch {
|
|
8058
8093
|
if (fallbackGasLimit != null) {
|
|
8059
8094
|
return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
8060
8095
|
}
|
|
8061
|
-
console.warn("L1 gas estimation failed", err);
|
|
8062
8096
|
return void 0;
|
|
8063
8097
|
}
|
|
8064
8098
|
}
|
|
@@ -8096,8 +8130,7 @@ async function quoteL2Gas(input) {
|
|
|
8096
8130
|
maxFeePerGas,
|
|
8097
8131
|
gasPerPubdata: pp
|
|
8098
8132
|
});
|
|
8099
|
-
} catch
|
|
8100
|
-
console.warn("L2 gas estimation failed", err);
|
|
8133
|
+
} catch {
|
|
8101
8134
|
return makeGasQuote({
|
|
8102
8135
|
gasLimit: l2GasLimit ?? 0n,
|
|
8103
8136
|
maxFeePerGas,
|
|
@@ -8260,8 +8293,22 @@ async function determineNonBaseL2Gas(input) {
|
|
|
8260
8293
|
try {
|
|
8261
8294
|
const l2TokenAddress = input.knownL2Token ?? (ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token));
|
|
8262
8295
|
if (l2TokenAddress === ZERO_L2_TOKEN_ADDRESS) {
|
|
8296
|
+
if (input.undeployedGasLimit != null) {
|
|
8297
|
+
return quoteL2Gas2({
|
|
8298
|
+
ctx,
|
|
8299
|
+
route,
|
|
8300
|
+
overrideGasLimit: input.undeployedGasLimit
|
|
8301
|
+
});
|
|
8302
|
+
}
|
|
8263
8303
|
return fallbackQuote();
|
|
8264
8304
|
}
|
|
8305
|
+
if (input.priorityFloorGasLimit != null) {
|
|
8306
|
+
return quoteL2Gas2({
|
|
8307
|
+
ctx,
|
|
8308
|
+
route,
|
|
8309
|
+
overrideGasLimit: input.priorityFloorGasLimit
|
|
8310
|
+
});
|
|
8311
|
+
}
|
|
8265
8312
|
const modelTx = {
|
|
8266
8313
|
to: input.modelTx?.to ?? ctx.sender,
|
|
8267
8314
|
from: input.modelTx?.from ?? ctx.sender,
|
|
@@ -8277,8 +8324,7 @@ async function determineNonBaseL2Gas(input) {
|
|
|
8277
8324
|
return fallbackQuote();
|
|
8278
8325
|
}
|
|
8279
8326
|
return gas;
|
|
8280
|
-
} catch
|
|
8281
|
-
console.warn("Failed to determine non-base deposit L2 gas; defaulting to safe gas limit.", err);
|
|
8327
|
+
} catch {
|
|
8282
8328
|
return fallbackQuote();
|
|
8283
8329
|
}
|
|
8284
8330
|
}
|
|
@@ -8295,7 +8341,9 @@ async function determineEthNonBaseL2Gas(input) {
|
|
|
8295
8341
|
route: "eth-nonbase",
|
|
8296
8342
|
l1Token: input.ctx.resolvedToken?.l1 ?? FORMAL_ETH_ADDRESS,
|
|
8297
8343
|
knownL2Token: input.ctx.resolvedToken?.l2,
|
|
8298
|
-
modelTx: input.modelTx
|
|
8344
|
+
modelTx: input.modelTx,
|
|
8345
|
+
priorityFloorGasLimit: input.priorityFloorGasLimit,
|
|
8346
|
+
undeployedGasLimit: input.undeployedGasLimit
|
|
8299
8347
|
});
|
|
8300
8348
|
}
|
|
8301
8349
|
|
|
@@ -8327,41 +8375,112 @@ function buildFeeBreakdown(p) {
|
|
|
8327
8375
|
};
|
|
8328
8376
|
}
|
|
8329
8377
|
|
|
8378
|
+
// src/core/resources/deposits/priority.ts
|
|
8379
|
+
var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
|
|
8380
|
+
var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
|
|
8381
|
+
var maxBigInt = (a, b) => a > b ? a : b;
|
|
8382
|
+
var ceilDiv = (a, b) => (a + b - 1n) / b;
|
|
8383
|
+
function derivePriorityTxGasBreakdown(input) {
|
|
8384
|
+
const factoryDepsCount = input.factoryDepsCount ?? 0n;
|
|
8385
|
+
const minBodyGas = maxBigInt(
|
|
8386
|
+
L1_TX_INTRINSIC_L2_GAS + ceilDiv(
|
|
8387
|
+
input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
|
|
8388
|
+
PRIORITY_TX_ENCODING_STEP_BYTES
|
|
8389
|
+
) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
|
|
8390
|
+
L1_TX_MIN_L2_GAS_BASE
|
|
8391
|
+
) + 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);
|
|
8393
|
+
const derivedBodyGas = minBodyGas;
|
|
8394
|
+
return {
|
|
8395
|
+
encodedLength: input.encodedLength,
|
|
8396
|
+
minBodyGas,
|
|
8397
|
+
overhead,
|
|
8398
|
+
derivedBodyGas,
|
|
8399
|
+
derivedL2GasLimit: derivedBodyGas + overhead,
|
|
8400
|
+
priorityTxMaxGasLimit: PRIORITY_TX_MAX_GAS_LIMIT,
|
|
8401
|
+
priorityTxMaxGasLimitExceeded: derivedBodyGas > PRIORITY_TX_MAX_GAS_LIMIT
|
|
8402
|
+
};
|
|
8403
|
+
}
|
|
8404
|
+
function derivePriorityBodyGasEstimateCap(input) {
|
|
8405
|
+
return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
|
|
8406
|
+
}
|
|
8407
|
+
|
|
8408
|
+
// src/adapters/ethers/resources/deposits/routes/priority.ts
|
|
8409
|
+
var EMPTY_BYTES = "0x";
|
|
8410
|
+
var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
|
|
8411
|
+
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)";
|
|
8412
|
+
function hexByteLength(hex) {
|
|
8413
|
+
return BigInt(Math.max(hex.length - 2, 0) / 2);
|
|
8414
|
+
}
|
|
8415
|
+
function getPriorityTxEncodedLength(input) {
|
|
8416
|
+
const encoded = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8417
|
+
[L2_CANONICAL_TRANSACTION_TUPLE],
|
|
8418
|
+
[
|
|
8419
|
+
[
|
|
8420
|
+
0n,
|
|
8421
|
+
BigInt(input.sender),
|
|
8422
|
+
BigInt(input.l2Contract),
|
|
8423
|
+
0n,
|
|
8424
|
+
input.gasPerPubdata,
|
|
8425
|
+
0n,
|
|
8426
|
+
0n,
|
|
8427
|
+
0n,
|
|
8428
|
+
0n,
|
|
8429
|
+
input.l2Value,
|
|
8430
|
+
ZERO_RESERVED_WORDS,
|
|
8431
|
+
input.l2Calldata,
|
|
8432
|
+
EMPTY_BYTES,
|
|
8433
|
+
input.factoryDepsHashes ?? [],
|
|
8434
|
+
EMPTY_BYTES,
|
|
8435
|
+
EMPTY_BYTES
|
|
8436
|
+
]
|
|
8437
|
+
]
|
|
8438
|
+
);
|
|
8439
|
+
return hexByteLength(encoded);
|
|
8440
|
+
}
|
|
8441
|
+
function getPriorityTxGasBreakdown(input) {
|
|
8442
|
+
return derivePriorityTxGasBreakdown({
|
|
8443
|
+
encodedLength: getPriorityTxEncodedLength(input),
|
|
8444
|
+
gasPerPubdata: input.gasPerPubdata,
|
|
8445
|
+
factoryDepsCount: BigInt(input.factoryDepsHashes?.length ?? 0)
|
|
8446
|
+
});
|
|
8447
|
+
}
|
|
8448
|
+
|
|
8330
8449
|
// src/adapters/ethers/resources/deposits/routes/eth.ts
|
|
8450
|
+
var EMPTY_BYTES2 = "0x";
|
|
8331
8451
|
function routeEthDirect() {
|
|
8332
8452
|
return {
|
|
8333
8453
|
async build(p, ctx) {
|
|
8334
8454
|
const bh = await ctx.contracts.bridgehub();
|
|
8335
|
-
const
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8455
|
+
const l2Contract = p.to ?? ctx.sender;
|
|
8456
|
+
const l2Value = p.amount;
|
|
8457
|
+
const l2Calldata = EMPTY_BYTES2;
|
|
8458
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8459
|
+
sender: ctx.sender,
|
|
8460
|
+
l2Contract,
|
|
8461
|
+
l2Value,
|
|
8462
|
+
l2Calldata,
|
|
8463
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
8464
|
+
});
|
|
8465
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
|
|
8341
8466
|
const l2GasParams = await quoteL2Gas2({
|
|
8342
8467
|
ctx,
|
|
8343
8468
|
route: "eth-base",
|
|
8344
|
-
|
|
8345
|
-
overrideGasLimit: ctx.l2GasLimit,
|
|
8346
|
-
stateOverrides: {
|
|
8347
|
-
[ctx.sender]: {
|
|
8348
|
-
balance: "0xffffffffffffffffffff"
|
|
8349
|
-
}
|
|
8350
|
-
}
|
|
8469
|
+
overrideGasLimit: quotedL2GasLimit
|
|
8351
8470
|
});
|
|
8352
8471
|
if (!l2GasParams) {
|
|
8353
8472
|
throw new Error("Failed to estimate L2 gas for deposit.");
|
|
8354
8473
|
}
|
|
8355
8474
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
8356
|
-
const mintValue = baseCost + ctx.operatorTip +
|
|
8475
|
+
const mintValue = baseCost + ctx.operatorTip + l2Value;
|
|
8357
8476
|
const req = buildDirectRequestStruct({
|
|
8358
8477
|
chainId: ctx.chainIdL2,
|
|
8359
8478
|
mintValue,
|
|
8360
8479
|
l2GasLimit: l2GasParams.gasLimit,
|
|
8361
8480
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
8362
8481
|
refundRecipient: ctx.refundRecipient,
|
|
8363
|
-
l2Contract
|
|
8364
|
-
l2Value
|
|
8482
|
+
l2Contract,
|
|
8483
|
+
l2Value
|
|
8365
8484
|
});
|
|
8366
8485
|
const data = bh.interface.encodeFunctionData("requestL2TransactionDirect", [req]);
|
|
8367
8486
|
const l1TxCandidate = {
|
|
@@ -8406,6 +8525,53 @@ function routeEthDirect() {
|
|
|
8406
8525
|
};
|
|
8407
8526
|
}
|
|
8408
8527
|
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
8528
|
+
var ZERO_L2_TOKEN_ADDRESS2 = "0x0000000000000000000000000000000000000000";
|
|
8529
|
+
var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8530
|
+
async function getPriorityGasModel(input) {
|
|
8531
|
+
try {
|
|
8532
|
+
const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
|
|
8533
|
+
const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
|
|
8534
|
+
const { chainId: l1ChainId } = await input.ctx.client.l1.getNetwork();
|
|
8535
|
+
const isFirstBridge = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID || input.ctx.resolvedToken.originChainId === 0n;
|
|
8536
|
+
const erc20MetadataOriginChainId = isFirstBridge ? BigInt(l1ChainId) : input.ctx.resolvedToken.originChainId;
|
|
8537
|
+
const erc20Metadata = await l1NativeTokenVault.getERC20Getters(
|
|
8538
|
+
input.token,
|
|
8539
|
+
erc20MetadataOriginChainId
|
|
8540
|
+
);
|
|
8541
|
+
const bridgeMintCalldata = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8542
|
+
["address", "address", "address", "uint256", "bytes"],
|
|
8543
|
+
[input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
|
|
8544
|
+
);
|
|
8545
|
+
const l2Calldata = isFirstBridge ? new ethers.Interface(IL2AssetRouter_default).encodeFunctionData(
|
|
8546
|
+
"finalizeDeposit(address,address,address,uint256,bytes)",
|
|
8547
|
+
[input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
|
|
8548
|
+
) : await (() => {
|
|
8549
|
+
return l1AssetRouter.getDepositCalldata(
|
|
8550
|
+
input.ctx.sender,
|
|
8551
|
+
input.ctx.resolvedToken.assetId,
|
|
8552
|
+
bridgeMintCalldata
|
|
8553
|
+
);
|
|
8554
|
+
})();
|
|
8555
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8556
|
+
sender: input.ctx.l1AssetRouter,
|
|
8557
|
+
l2Contract: L2_ASSET_ROUTER_ADDRESS,
|
|
8558
|
+
l2Value: 0n,
|
|
8559
|
+
l2Calldata,
|
|
8560
|
+
gasPerPubdata: input.ctx.gasPerPubdata
|
|
8561
|
+
});
|
|
8562
|
+
const model = {
|
|
8563
|
+
priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
8564
|
+
};
|
|
8565
|
+
if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS2) {
|
|
8566
|
+
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
8567
|
+
minBodyGas: priorityFloorBreakdown.minBodyGas
|
|
8568
|
+
}) + priorityFloorBreakdown.overhead;
|
|
8569
|
+
}
|
|
8570
|
+
return model;
|
|
8571
|
+
} catch {
|
|
8572
|
+
return {};
|
|
8573
|
+
}
|
|
8574
|
+
}
|
|
8409
8575
|
function routeErc20NonBase() {
|
|
8410
8576
|
return {
|
|
8411
8577
|
async preflight(p, ctx) {
|
|
@@ -8426,11 +8592,29 @@ function routeErc20NonBase() {
|
|
|
8426
8592
|
const l1Signer = ctx.client.getL1Signer();
|
|
8427
8593
|
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
8428
8594
|
const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
|
|
8595
|
+
const receiver = p.to ?? ctx.sender;
|
|
8596
|
+
const secondBridgeCalldata = await wrapAs3(
|
|
8597
|
+
"INTERNAL",
|
|
8598
|
+
OP_DEPOSITS.nonbase.encodeCalldata,
|
|
8599
|
+
() => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, receiver)),
|
|
8600
|
+
{
|
|
8601
|
+
ctx: { where: "encodeSecondBridgeErc20Args" },
|
|
8602
|
+
message: "Failed to encode bridging calldata."
|
|
8603
|
+
}
|
|
8604
|
+
);
|
|
8605
|
+
const priorityGasModel = await getPriorityGasModel({
|
|
8606
|
+
ctx,
|
|
8607
|
+
token: p.token,
|
|
8608
|
+
amount: p.amount,
|
|
8609
|
+
receiver
|
|
8610
|
+
});
|
|
8429
8611
|
const l2GasParams = await determineErc20L2Gas({
|
|
8430
8612
|
ctx,
|
|
8431
8613
|
l1Token: p.token,
|
|
8614
|
+
priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
|
|
8615
|
+
undeployedGasLimit: priorityGasModel.undeployedGasLimit,
|
|
8432
8616
|
modelTx: {
|
|
8433
|
-
to:
|
|
8617
|
+
to: receiver,
|
|
8434
8618
|
from: ctx.sender,
|
|
8435
8619
|
data: "0x",
|
|
8436
8620
|
value: 0n
|
|
@@ -8492,15 +8676,6 @@ function routeErc20NonBase() {
|
|
|
8492
8676
|
});
|
|
8493
8677
|
}
|
|
8494
8678
|
}
|
|
8495
|
-
const secondBridgeCalldata = await wrapAs3(
|
|
8496
|
-
"INTERNAL",
|
|
8497
|
-
OP_DEPOSITS.nonbase.encodeCalldata,
|
|
8498
|
-
() => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, p.to ?? ctx.sender)),
|
|
8499
|
-
{
|
|
8500
|
-
ctx: { where: "encodeSecondBridgeErc20Args" },
|
|
8501
|
-
message: "Failed to encode bridging calldata."
|
|
8502
|
-
}
|
|
8503
|
-
);
|
|
8504
8679
|
const requestStruct = {
|
|
8505
8680
|
chainId: ctx.chainIdL2,
|
|
8506
8681
|
mintValue,
|
|
@@ -8557,7 +8732,68 @@ function routeErc20NonBase() {
|
|
|
8557
8732
|
}
|
|
8558
8733
|
};
|
|
8559
8734
|
}
|
|
8735
|
+
|
|
8736
|
+
// src/core/codec/ntv.ts
|
|
8737
|
+
function createNTVCodec(deps) {
|
|
8738
|
+
function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
|
|
8739
|
+
const encoded = deps.encode(
|
|
8740
|
+
["uint256", "address", "address"],
|
|
8741
|
+
[originChainId, ntvAddress, tokenAddress]
|
|
8742
|
+
);
|
|
8743
|
+
return deps.keccak256(encoded);
|
|
8744
|
+
}
|
|
8745
|
+
return {
|
|
8746
|
+
encodeAssetId
|
|
8747
|
+
};
|
|
8748
|
+
}
|
|
8749
|
+
|
|
8750
|
+
// src/adapters/ethers/resources/deposits/routes/eth-nonbase.ts
|
|
8560
8751
|
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
8752
|
+
var ZERO_L2_TOKEN_ADDRESS3 = "0x0000000000000000000000000000000000000000";
|
|
8753
|
+
var ZERO_ASSET_ID2 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8754
|
+
var ntvCodec = createNTVCodec({
|
|
8755
|
+
encode: (types, values) => ethers.AbiCoder.defaultAbiCoder().encode(types, values),
|
|
8756
|
+
keccak256: (data) => ethers.keccak256(data)
|
|
8757
|
+
});
|
|
8758
|
+
async function getPriorityGasModel2(input) {
|
|
8759
|
+
try {
|
|
8760
|
+
const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
|
|
8761
|
+
const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
|
|
8762
|
+
const originChainId = input.ctx.resolvedToken.originChainId !== 0n ? input.ctx.resolvedToken.originChainId : BigInt((await input.ctx.client.l1.getNetwork()).chainId);
|
|
8763
|
+
const resolvedAssetId = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID2 ? ntvCodec.encodeAssetId(originChainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, ETH_ADDRESS) : input.ctx.resolvedToken.assetId;
|
|
8764
|
+
const erc20Metadata = await l1NativeTokenVault.getERC20Getters(
|
|
8765
|
+
ETH_ADDRESS,
|
|
8766
|
+
originChainId
|
|
8767
|
+
);
|
|
8768
|
+
const bridgeMintCalldata = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8769
|
+
["address", "address", "address", "uint256", "bytes"],
|
|
8770
|
+
[input.ctx.sender, input.receiver, ETH_ADDRESS, input.amount, erc20Metadata]
|
|
8771
|
+
);
|
|
8772
|
+
const l2Calldata = await l1AssetRouter.getDepositCalldata(
|
|
8773
|
+
input.ctx.sender,
|
|
8774
|
+
resolvedAssetId,
|
|
8775
|
+
bridgeMintCalldata
|
|
8776
|
+
);
|
|
8777
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8778
|
+
sender: input.ctx.l1AssetRouter,
|
|
8779
|
+
l2Contract: L2_ASSET_ROUTER_ADDRESS,
|
|
8780
|
+
l2Value: 0n,
|
|
8781
|
+
l2Calldata,
|
|
8782
|
+
gasPerPubdata: input.ctx.gasPerPubdata
|
|
8783
|
+
});
|
|
8784
|
+
const model = {
|
|
8785
|
+
priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
8786
|
+
};
|
|
8787
|
+
if (input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS3) {
|
|
8788
|
+
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
8789
|
+
minBodyGas: priorityFloorBreakdown.minBodyGas
|
|
8790
|
+
}) + priorityFloorBreakdown.overhead;
|
|
8791
|
+
}
|
|
8792
|
+
return model;
|
|
8793
|
+
} catch {
|
|
8794
|
+
return {};
|
|
8795
|
+
}
|
|
8796
|
+
}
|
|
8561
8797
|
function routeEthNonBase() {
|
|
8562
8798
|
return {
|
|
8563
8799
|
async preflight(p, ctx) {
|
|
@@ -8606,15 +8842,23 @@ function routeEthNonBase() {
|
|
|
8606
8842
|
async build(p, ctx) {
|
|
8607
8843
|
const l1Signer = ctx.client.getL1Signer();
|
|
8608
8844
|
const baseToken = ctx.baseTokenL1;
|
|
8845
|
+
const receiver = p.to ?? ctx.sender;
|
|
8846
|
+
const priorityGasModel = await getPriorityGasModel2({
|
|
8847
|
+
ctx,
|
|
8848
|
+
amount: p.amount,
|
|
8849
|
+
receiver
|
|
8850
|
+
});
|
|
8609
8851
|
const l2TxModel = {
|
|
8610
|
-
to:
|
|
8852
|
+
to: receiver,
|
|
8611
8853
|
from: ctx.sender,
|
|
8612
8854
|
data: "0x",
|
|
8613
8855
|
value: 0n
|
|
8614
8856
|
};
|
|
8615
8857
|
const l2GasParams = await determineEthNonBaseL2Gas({
|
|
8616
8858
|
ctx,
|
|
8617
|
-
modelTx: l2TxModel
|
|
8859
|
+
modelTx: l2TxModel,
|
|
8860
|
+
priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
|
|
8861
|
+
undeployedGasLimit: priorityGasModel.undeployedGasLimit
|
|
8618
8862
|
});
|
|
8619
8863
|
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
8620
8864
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
@@ -8648,12 +8892,12 @@ function routeEthNonBase() {
|
|
|
8648
8892
|
const secondBridgeCalldata = await wrapAs4(
|
|
8649
8893
|
"INTERNAL",
|
|
8650
8894
|
OP_DEPOSITS.ethNonBase.encodeCalldata,
|
|
8651
|
-
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount,
|
|
8895
|
+
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, receiver)),
|
|
8652
8896
|
{
|
|
8653
8897
|
ctx: {
|
|
8654
8898
|
where: "encodeSecondBridgeEthArgs",
|
|
8655
8899
|
amount: p.amount.toString(),
|
|
8656
|
-
to:
|
|
8900
|
+
to: receiver
|
|
8657
8901
|
}
|
|
8658
8902
|
}
|
|
8659
8903
|
);
|
|
@@ -8714,6 +8958,7 @@ function routeEthNonBase() {
|
|
|
8714
8958
|
};
|
|
8715
8959
|
}
|
|
8716
8960
|
var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
|
|
8961
|
+
var EMPTY_BYTES3 = "0x";
|
|
8717
8962
|
function routeErc20Base() {
|
|
8718
8963
|
return {
|
|
8719
8964
|
async preflight(p, ctx) {
|
|
@@ -8744,17 +8989,21 @@ function routeErc20Base() {
|
|
|
8744
8989
|
async build(p, ctx) {
|
|
8745
8990
|
const l1Signer = ctx.client.getL1Signer();
|
|
8746
8991
|
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
8747
|
-
const
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8992
|
+
const l2Contract = p.to ?? ctx.sender;
|
|
8993
|
+
const l2Value = p.amount;
|
|
8994
|
+
const l2Calldata = EMPTY_BYTES3;
|
|
8995
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8996
|
+
sender: ctx.sender,
|
|
8997
|
+
l2Contract,
|
|
8998
|
+
l2Value,
|
|
8999
|
+
l2Calldata,
|
|
9000
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
9001
|
+
});
|
|
9002
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
|
|
8753
9003
|
const l2GasParams = await quoteL2Gas2({
|
|
8754
9004
|
ctx,
|
|
8755
9005
|
route: "erc20-base",
|
|
8756
|
-
|
|
8757
|
-
overrideGasLimit: ctx.l2GasLimit
|
|
9006
|
+
overrideGasLimit: quotedL2GasLimit
|
|
8758
9007
|
});
|
|
8759
9008
|
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
8760
9009
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
@@ -8793,8 +9042,8 @@ function routeErc20Base() {
|
|
|
8793
9042
|
l2GasLimit: l2GasParams.gasLimit,
|
|
8794
9043
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
8795
9044
|
refundRecipient: ctx.refundRecipient,
|
|
8796
|
-
l2Contract
|
|
8797
|
-
l2Value
|
|
9045
|
+
l2Contract,
|
|
9046
|
+
l2Value
|
|
8798
9047
|
});
|
|
8799
9048
|
const bridgehub = await ctx.contracts.bridgehub();
|
|
8800
9049
|
const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
|
|
@@ -8841,25 +9090,9 @@ function routeErc20Base() {
|
|
|
8841
9090
|
}
|
|
8842
9091
|
};
|
|
8843
9092
|
}
|
|
8844
|
-
|
|
8845
|
-
// src/core/codec/ntv.ts
|
|
8846
|
-
function createNTVCodec(deps) {
|
|
8847
|
-
function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
|
|
8848
|
-
const encoded = deps.encode(
|
|
8849
|
-
["uint256", "address", "address"],
|
|
8850
|
-
[originChainId, ntvAddress, tokenAddress]
|
|
8851
|
-
);
|
|
8852
|
-
return deps.keccak256(encoded);
|
|
8853
|
-
}
|
|
8854
|
-
return {
|
|
8855
|
-
encodeAssetId
|
|
8856
|
-
};
|
|
8857
|
-
}
|
|
8858
|
-
|
|
8859
|
-
// src/adapters/ethers/resources/tokens/tokens.ts
|
|
8860
9093
|
var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
|
|
8861
9094
|
var abi = ethers.AbiCoder.defaultAbiCoder();
|
|
8862
|
-
var
|
|
9095
|
+
var ntvCodec2 = createNTVCodec({
|
|
8863
9096
|
encode: (types, values) => abi.encode(types, values),
|
|
8864
9097
|
keccak256: (data) => ethers.ethers.keccak256(data)
|
|
8865
9098
|
});
|
|
@@ -8978,7 +9211,7 @@ function createTokensResource(client) {
|
|
|
8978
9211
|
return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
|
|
8979
9212
|
const baseAssetId = await getBaseTokenAssetId();
|
|
8980
9213
|
const l1ChainId = await getL1ChainId();
|
|
8981
|
-
const ethAssetId =
|
|
9214
|
+
const ethAssetId = ntvCodec2.encodeAssetId(
|
|
8982
9215
|
l1ChainId,
|
|
8983
9216
|
L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
8984
9217
|
ETH_ADDRESS
|
|
@@ -9989,7 +10222,7 @@ var ROUTES2 = {
|
|
|
9989
10222
|
};
|
|
9990
10223
|
function createWithdrawalsResource(client, tokens, contracts) {
|
|
9991
10224
|
const svc = createFinalizationServices(client);
|
|
9992
|
-
const { wrap:
|
|
10225
|
+
const { wrap: wrap8, toResult: toResult3 } = createErrorHandlers("withdrawals");
|
|
9993
10226
|
const tokensResource = tokens ?? createTokensResource(client);
|
|
9994
10227
|
const contractsResource = contracts ?? createContractsResource(client);
|
|
9995
10228
|
async function buildPlan(p) {
|
|
@@ -10010,7 +10243,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10010
10243
|
};
|
|
10011
10244
|
}
|
|
10012
10245
|
const finalizeCache = /* @__PURE__ */ new Map();
|
|
10013
|
-
const quote = (p) =>
|
|
10246
|
+
const quote = (p) => wrap8(
|
|
10014
10247
|
OP_WITHDRAWALS.quote,
|
|
10015
10248
|
async () => {
|
|
10016
10249
|
const plan = await buildPlan(p);
|
|
@@ -10032,7 +10265,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10032
10265
|
ctx: { token: p.token, where: "withdrawals.tryQuote" }
|
|
10033
10266
|
}
|
|
10034
10267
|
);
|
|
10035
|
-
const prepare = (p) =>
|
|
10268
|
+
const prepare = (p) => wrap8(OP_WITHDRAWALS.prepare, () => buildPlan(p), {
|
|
10036
10269
|
message: "Internal error while preparing a withdrawal plan.",
|
|
10037
10270
|
ctx: { token: p.token, where: "withdrawals.prepare" }
|
|
10038
10271
|
});
|
|
@@ -10040,7 +10273,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10040
10273
|
message: "Internal error while preparing a withdrawal plan.",
|
|
10041
10274
|
ctx: { token: p.token, where: "withdrawals.tryPrepare" }
|
|
10042
10275
|
});
|
|
10043
|
-
const create = (p) =>
|
|
10276
|
+
const create = (p) => wrap8(
|
|
10044
10277
|
OP_WITHDRAWALS.create,
|
|
10045
10278
|
async () => {
|
|
10046
10279
|
const plan = await prepare(p);
|
|
@@ -10111,7 +10344,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10111
10344
|
message: "Internal error while creating withdrawal transactions.",
|
|
10112
10345
|
ctx: { token: p.token, amount: p.amount, to: p.to, where: "withdrawals.tryCreate" }
|
|
10113
10346
|
});
|
|
10114
|
-
const status = (h) =>
|
|
10347
|
+
const status = (h) => wrap8(
|
|
10115
10348
|
OP_WITHDRAWALS.status,
|
|
10116
10349
|
async () => {
|
|
10117
10350
|
const l2TxHash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
|
|
@@ -10166,7 +10399,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10166
10399
|
const wait = (h, opts = {
|
|
10167
10400
|
for: "l2",
|
|
10168
10401
|
pollMs: 5500
|
|
10169
|
-
}) =>
|
|
10402
|
+
}) => wrap8(
|
|
10170
10403
|
OP_WITHDRAWALS.wait,
|
|
10171
10404
|
async () => {
|
|
10172
10405
|
const l2Hash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
|
|
@@ -10231,7 +10464,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10231
10464
|
}
|
|
10232
10465
|
}
|
|
10233
10466
|
);
|
|
10234
|
-
const finalize = (l2TxHash) =>
|
|
10467
|
+
const finalize = (l2TxHash) => wrap8(
|
|
10235
10468
|
OP_WITHDRAWALS.finalize.send,
|
|
10236
10469
|
async () => {
|
|
10237
10470
|
const pack = await (async () => {
|
|
@@ -10357,9 +10590,11 @@ function createCallAttributes(codec) {
|
|
|
10357
10590
|
function createBundleAttributes(codec) {
|
|
10358
10591
|
const executionAddress = (executor) => codec.encode("executionAddress", [executor]);
|
|
10359
10592
|
const unbundlerAddress = (addr) => codec.encode("unbundlerAddress", [addr]);
|
|
10593
|
+
const useFixedFee = (enabled) => codec.encode("useFixedFee", [enabled]);
|
|
10360
10594
|
return {
|
|
10361
10595
|
executionAddress,
|
|
10362
|
-
unbundlerAddress
|
|
10596
|
+
unbundlerAddress,
|
|
10597
|
+
useFixedFee
|
|
10363
10598
|
};
|
|
10364
10599
|
}
|
|
10365
10600
|
|
|
@@ -10380,6 +10615,7 @@ function getInteropAttributes(params, ctx) {
|
|
|
10380
10615
|
if (params.unbundling?.by) {
|
|
10381
10616
|
bundleAttributes.push(ctx.attributes.bundle.unbundlerAddress(params.unbundling.by));
|
|
10382
10617
|
}
|
|
10618
|
+
bundleAttributes.push(ctx.attributes.bundle.useFixedFee(params.fee?.useFixed ?? false));
|
|
10383
10619
|
const callAttributes = params.actions.map((action) => {
|
|
10384
10620
|
switch (action.type) {
|
|
10385
10621
|
case "sendNative": {
|
|
@@ -10409,11 +10645,6 @@ function createEthersAttributesResource(opts = {}) {
|
|
|
10409
10645
|
}
|
|
10410
10646
|
|
|
10411
10647
|
// src/core/types/flows/interop.ts
|
|
10412
|
-
function isInteropExpectedRoot(obj) {
|
|
10413
|
-
if (typeof obj !== "object" || obj === null) return false;
|
|
10414
|
-
const root = obj;
|
|
10415
|
-
return isBigint(root.rootChainId) && isBigint(root.batchNumber) && isHash(root.expectedRoot);
|
|
10416
|
-
}
|
|
10417
10648
|
function isInteropMessageProof(obj) {
|
|
10418
10649
|
if (typeof obj !== "object" || obj === null) return false;
|
|
10419
10650
|
const proof = obj;
|
|
@@ -10422,7 +10653,7 @@ function isInteropMessageProof(obj) {
|
|
|
10422
10653
|
function isInteropFinalizationInfo(obj) {
|
|
10423
10654
|
if (typeof obj !== "object" || obj === null) return false;
|
|
10424
10655
|
const info = obj;
|
|
10425
|
-
return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) &&
|
|
10656
|
+
return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) && isInteropMessageProof(info.proof);
|
|
10426
10657
|
}
|
|
10427
10658
|
|
|
10428
10659
|
// src/core/resources/interop/route.ts
|
|
@@ -10475,7 +10706,7 @@ function preflightDirect(params, ctx) {
|
|
|
10475
10706
|
}
|
|
10476
10707
|
}
|
|
10477
10708
|
}
|
|
10478
|
-
function buildDirectBundle(params, ctx, attrs) {
|
|
10709
|
+
function buildDirectBundle(params, ctx, attrs, interopFeeInfo) {
|
|
10479
10710
|
const totalActionValue = sumActionMsgValue(params.actions);
|
|
10480
10711
|
const starters = params.actions.map((action, index) => {
|
|
10481
10712
|
const to = ctx.codec.formatAddress(action.to);
|
|
@@ -10493,7 +10724,8 @@ function buildDirectBundle(params, ctx, attrs) {
|
|
|
10493
10724
|
dstChain: ctx.codec.formatChain(ctx.dstChainId),
|
|
10494
10725
|
starters,
|
|
10495
10726
|
bundleAttributes: attrs.bundleAttributes,
|
|
10496
|
-
approvals: [],
|
|
10727
|
+
approvals: interopFeeInfo.approval ? [interopFeeInfo.approval] : [],
|
|
10728
|
+
interopFee: interopFeeInfo.fee,
|
|
10497
10729
|
quoteExtras: {
|
|
10498
10730
|
totalActionValue,
|
|
10499
10731
|
bridgedTokenTotal: 0n
|
|
@@ -10538,7 +10770,7 @@ function preflightIndirect(params, ctx) {
|
|
|
10538
10770
|
}
|
|
10539
10771
|
}
|
|
10540
10772
|
}
|
|
10541
|
-
function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
10773
|
+
function buildIndirectBundle(params, ctx, attrs, starterData, interopFeeInfo) {
|
|
10542
10774
|
const totalActionValue = sumActionMsgValue(params.actions);
|
|
10543
10775
|
const bridgedTokenTotal = sumErc20Amounts(params.actions);
|
|
10544
10776
|
const approvalMap = /* @__PURE__ */ new Map();
|
|
@@ -10557,6 +10789,7 @@ function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
|
10557
10789
|
}
|
|
10558
10790
|
}
|
|
10559
10791
|
const approvals = Array.from(approvalMap.values());
|
|
10792
|
+
if (interopFeeInfo.approval) approvals.push(interopFeeInfo.approval);
|
|
10560
10793
|
const starters = params.actions.map((action, index) => {
|
|
10561
10794
|
const callAttributes = attrs.callAttributes[index] ?? [];
|
|
10562
10795
|
if (starterData[index]?.assetRouterPayload) {
|
|
@@ -10580,6 +10813,7 @@ function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
|
10580
10813
|
starters,
|
|
10581
10814
|
bundleAttributes: attrs.bundleAttributes,
|
|
10582
10815
|
approvals,
|
|
10816
|
+
interopFee: interopFeeInfo.fee,
|
|
10583
10817
|
quoteExtras: {
|
|
10584
10818
|
totalActionValue,
|
|
10585
10819
|
bridgedTokenTotal
|
|
@@ -10626,6 +10860,29 @@ function buildEnsureTokenSteps(erc20Tokens, ctx) {
|
|
|
10626
10860
|
}
|
|
10627
10861
|
}));
|
|
10628
10862
|
}
|
|
10863
|
+
async function buildApproveSteps(approvals, ctx) {
|
|
10864
|
+
const steps = [];
|
|
10865
|
+
for (const approval of approvals) {
|
|
10866
|
+
const erc20 = new ethers.Contract(approval.token, IERC20_default, ctx.client.l2);
|
|
10867
|
+
const currentAllowance = await erc20.allowance(ctx.sender, approval.spender);
|
|
10868
|
+
if (currentAllowance < approval.amount) {
|
|
10869
|
+
steps.push({
|
|
10870
|
+
key: `approve:${approval.token}:${approval.spender}`,
|
|
10871
|
+
kind: "approve",
|
|
10872
|
+
description: `Approve ${approval.spender} to spend ${approval.amount} of ${approval.token}`,
|
|
10873
|
+
tx: {
|
|
10874
|
+
to: approval.token,
|
|
10875
|
+
data: erc20.interface.encodeFunctionData("approve", [
|
|
10876
|
+
approval.spender,
|
|
10877
|
+
approval.amount
|
|
10878
|
+
]),
|
|
10879
|
+
...ctx.gasOverrides
|
|
10880
|
+
}
|
|
10881
|
+
});
|
|
10882
|
+
}
|
|
10883
|
+
}
|
|
10884
|
+
return steps;
|
|
10885
|
+
}
|
|
10629
10886
|
async function resolveErc20AssetIds(erc20Tokens, ctx) {
|
|
10630
10887
|
const assetIds = /* @__PURE__ */ new Map();
|
|
10631
10888
|
if (erc20Tokens.length === 0) return assetIds;
|
|
@@ -10679,6 +10936,44 @@ async function getStarterData(params, ctx, erc20AssetIds) {
|
|
|
10679
10936
|
}
|
|
10680
10937
|
return starterData;
|
|
10681
10938
|
}
|
|
10939
|
+
var { wrap: wrap3 } = createErrorHandlers("interop");
|
|
10940
|
+
async function buildFeeInfo(params, ctx, numStarters) {
|
|
10941
|
+
const useFixed = params.fee?.useFixed ?? false;
|
|
10942
|
+
const interopCenter = new ethers.Contract(ctx.interopCenter, IInteropCenter_default, ctx.client.l2);
|
|
10943
|
+
if (useFixed) {
|
|
10944
|
+
const zkFeePerCall = await wrap3(
|
|
10945
|
+
OP_INTEROP.svc.fees.zkInteropFee,
|
|
10946
|
+
() => interopCenter.ZK_INTEROP_FEE(),
|
|
10947
|
+
{ message: "Failed to fetch ZK interop fee from InteropCenter." }
|
|
10948
|
+
);
|
|
10949
|
+
const zkFeeTotal = zkFeePerCall * BigInt(numStarters);
|
|
10950
|
+
const zkTokenAddress = await wrap3(
|
|
10951
|
+
OP_INTEROP.svc.fees.zkToken,
|
|
10952
|
+
() => interopCenter.zkToken(),
|
|
10953
|
+
{ message: "Failed to fetch ZK token address from InteropCenter." }
|
|
10954
|
+
);
|
|
10955
|
+
const approval = {
|
|
10956
|
+
token: zkTokenAddress,
|
|
10957
|
+
spender: ctx.interopCenter,
|
|
10958
|
+
amount: zkFeeTotal
|
|
10959
|
+
};
|
|
10960
|
+
return {
|
|
10961
|
+
approval,
|
|
10962
|
+
fee: { token: zkTokenAddress, amount: zkFeeTotal }
|
|
10963
|
+
};
|
|
10964
|
+
} else {
|
|
10965
|
+
const protocolFeePerCall = await wrap3(
|
|
10966
|
+
OP_INTEROP.svc.fees.protocolFee,
|
|
10967
|
+
() => interopCenter.interopProtocolFee(),
|
|
10968
|
+
{ message: "Failed to fetch interop protocol fee from InteropCenter." }
|
|
10969
|
+
);
|
|
10970
|
+
const totalFee = protocolFeePerCall * BigInt(numStarters);
|
|
10971
|
+
return {
|
|
10972
|
+
approval: null,
|
|
10973
|
+
fee: { token: ctx.baseTokens.src, amount: totalFee }
|
|
10974
|
+
};
|
|
10975
|
+
}
|
|
10976
|
+
}
|
|
10682
10977
|
|
|
10683
10978
|
// src/adapters/ethers/resources/interop/routes/indirect.ts
|
|
10684
10979
|
function routeIndirect() {
|
|
@@ -10694,7 +10989,10 @@ function routeIndirect() {
|
|
|
10694
10989
|
async build(params, ctx) {
|
|
10695
10990
|
const steps = [];
|
|
10696
10991
|
const erc20Tokens = getErc20Tokens(params);
|
|
10697
|
-
const erc20AssetIds = await
|
|
10992
|
+
const [erc20AssetIds, feeInfo] = await Promise.all([
|
|
10993
|
+
resolveErc20AssetIds(erc20Tokens, ctx),
|
|
10994
|
+
buildFeeInfo(params, ctx, params.actions.length)
|
|
10995
|
+
]);
|
|
10698
10996
|
const attributes = getInteropAttributes(params, ctx);
|
|
10699
10997
|
const starterData = await getStarterData(params, ctx, erc20AssetIds);
|
|
10700
10998
|
const bundle = buildIndirectBundle(
|
|
@@ -10707,32 +11005,11 @@ function routeIndirect() {
|
|
|
10707
11005
|
codec: interopCodec
|
|
10708
11006
|
},
|
|
10709
11007
|
attributes,
|
|
10710
|
-
starterData
|
|
11008
|
+
starterData,
|
|
11009
|
+
feeInfo
|
|
10711
11010
|
);
|
|
10712
11011
|
steps.push(...buildEnsureTokenSteps(erc20Tokens, ctx));
|
|
10713
|
-
|
|
10714
|
-
const erc20 = new ethers.Contract(approval.token, IERC20_default, ctx.client.l2);
|
|
10715
|
-
const currentAllowance = await erc20.allowance(
|
|
10716
|
-
ctx.sender,
|
|
10717
|
-
ctx.l2NativeTokenVault
|
|
10718
|
-
);
|
|
10719
|
-
if (currentAllowance < approval.amount) {
|
|
10720
|
-
const approveData = erc20.interface.encodeFunctionData("approve", [
|
|
10721
|
-
ctx.l2NativeTokenVault,
|
|
10722
|
-
approval.amount
|
|
10723
|
-
]);
|
|
10724
|
-
steps.push({
|
|
10725
|
-
key: `approve:${approval.token}:${ctx.l2NativeTokenVault}`,
|
|
10726
|
-
kind: "approve",
|
|
10727
|
-
description: `Approve ${ctx.l2NativeTokenVault} to spend ${approval.amount} of ${approval.token}`,
|
|
10728
|
-
tx: {
|
|
10729
|
-
to: approval.token,
|
|
10730
|
-
data: approveData,
|
|
10731
|
-
...ctx.gasOverrides
|
|
10732
|
-
}
|
|
10733
|
-
});
|
|
10734
|
-
}
|
|
10735
|
-
}
|
|
11012
|
+
steps.push(...await buildApproveSteps(bundle.approvals, ctx));
|
|
10736
11013
|
const data = ctx.ifaces.interopCenter.encodeFunctionData("sendBundle", [
|
|
10737
11014
|
bundle.dstChain,
|
|
10738
11015
|
bundle.starters,
|
|
@@ -10745,14 +11022,15 @@ function routeIndirect() {
|
|
|
10745
11022
|
tx: {
|
|
10746
11023
|
to: ctx.interopCenter,
|
|
10747
11024
|
data,
|
|
10748
|
-
value: bundle.quoteExtras.totalActionValue,
|
|
11025
|
+
value: bundle.quoteExtras.totalActionValue + feeInfo.fee.amount,
|
|
10749
11026
|
...ctx.gasOverrides
|
|
10750
11027
|
}
|
|
10751
11028
|
});
|
|
10752
11029
|
return {
|
|
10753
11030
|
steps,
|
|
10754
11031
|
approvals: bundle.approvals,
|
|
10755
|
-
quoteExtras: bundle.quoteExtras
|
|
11032
|
+
quoteExtras: bundle.quoteExtras,
|
|
11033
|
+
interopFee: feeInfo.fee
|
|
10756
11034
|
};
|
|
10757
11035
|
}
|
|
10758
11036
|
};
|
|
@@ -10769,10 +11047,10 @@ function routeDirect() {
|
|
|
10769
11047
|
l2AssetRouter: ctx.l2AssetRouter,
|
|
10770
11048
|
l2NativeTokenVault: ctx.l2NativeTokenVault});
|
|
10771
11049
|
},
|
|
10772
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
10773
11050
|
async build(params, ctx) {
|
|
10774
11051
|
const steps = [];
|
|
10775
11052
|
const attrs = getInteropAttributes(params, ctx);
|
|
11053
|
+
const feeInfo = await buildFeeInfo(params, ctx, params.actions.length);
|
|
10776
11054
|
const built = buildDirectBundle(
|
|
10777
11055
|
params,
|
|
10778
11056
|
{
|
|
@@ -10782,8 +11060,10 @@ function routeDirect() {
|
|
|
10782
11060
|
l2NativeTokenVault: ctx.l2NativeTokenVault,
|
|
10783
11061
|
codec: interopCodec
|
|
10784
11062
|
},
|
|
10785
|
-
attrs
|
|
11063
|
+
attrs,
|
|
11064
|
+
feeInfo
|
|
10786
11065
|
);
|
|
11066
|
+
steps.push(...await buildApproveSteps(built.approvals, ctx));
|
|
10787
11067
|
const data = ctx.ifaces.interopCenter.encodeFunctionData("sendBundle", [
|
|
10788
11068
|
built.dstChain,
|
|
10789
11069
|
built.starters,
|
|
@@ -10793,19 +11073,19 @@ function routeDirect() {
|
|
|
10793
11073
|
key: "sendBundle",
|
|
10794
11074
|
kind: "interop.center",
|
|
10795
11075
|
description: `Send interop bundle (direct route; ${params.actions.length} actions)`,
|
|
10796
|
-
//
|
|
10797
|
-
// all calls (sendNative.amount + call.value).
|
|
11076
|
+
// msg.value = forwarded action value + protocol fee.
|
|
10798
11077
|
tx: {
|
|
10799
11078
|
to: ctx.interopCenter,
|
|
10800
11079
|
data,
|
|
10801
|
-
value: built.quoteExtras.totalActionValue,
|
|
11080
|
+
value: built.quoteExtras.totalActionValue + feeInfo.fee.amount,
|
|
10802
11081
|
...ctx.gasOverrides
|
|
10803
11082
|
}
|
|
10804
11083
|
});
|
|
10805
11084
|
return {
|
|
10806
11085
|
steps,
|
|
10807
11086
|
approvals: built.approvals,
|
|
10808
|
-
quoteExtras: built.quoteExtras
|
|
11087
|
+
quoteExtras: built.quoteExtras,
|
|
11088
|
+
interopFee: feeInfo.fee
|
|
10809
11089
|
};
|
|
10810
11090
|
}
|
|
10811
11091
|
};
|
|
@@ -10885,7 +11165,7 @@ function getTopics() {
|
|
|
10885
11165
|
};
|
|
10886
11166
|
return { topics, centerIface };
|
|
10887
11167
|
}
|
|
10888
|
-
var { wrap:
|
|
11168
|
+
var { wrap: wrap4 } = createErrorHandlers("interop");
|
|
10889
11169
|
var DEFAULT_BLOCKS_RANGE_SIZE = 1e4;
|
|
10890
11170
|
var DEFAULT_MAX_BLOCKS_BACK = 2e4;
|
|
10891
11171
|
var SAFE_BLOCKS_RANGE_SIZE = 1e3;
|
|
@@ -10898,7 +11178,7 @@ function parseMaxBlockRangeLimit(error) {
|
|
|
10898
11178
|
return Number.isInteger(limit) && limit > 0 ? limit : null;
|
|
10899
11179
|
}
|
|
10900
11180
|
async function getTxReceipt(provider, txHash) {
|
|
10901
|
-
const receipt = await
|
|
11181
|
+
const receipt = await wrap4(
|
|
10902
11182
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
10903
11183
|
() => provider.getTransactionReceipt(txHash),
|
|
10904
11184
|
{
|
|
@@ -10919,7 +11199,7 @@ async function getTxReceipt(provider, txHash) {
|
|
|
10919
11199
|
async function getLogs(provider, address, topics, opts) {
|
|
10920
11200
|
const maxBlocksBack = opts?.maxBlocksBack ?? DEFAULT_MAX_BLOCKS_BACK;
|
|
10921
11201
|
const initialChunkSize = opts?.logChunkSize ?? DEFAULT_BLOCKS_RANGE_SIZE;
|
|
10922
|
-
return await
|
|
11202
|
+
return await wrap4(
|
|
10923
11203
|
OP_INTEROP.svc.status.dstLogs,
|
|
10924
11204
|
async () => {
|
|
10925
11205
|
const currentBlock = await provider.getBlockNumber();
|
|
@@ -10966,7 +11246,7 @@ async function getLogs(provider, address, topics, opts) {
|
|
|
10966
11246
|
);
|
|
10967
11247
|
}
|
|
10968
11248
|
async function getInteropRoot(provider, rootChainId, batchNumber) {
|
|
10969
|
-
return await
|
|
11249
|
+
return await wrap4(
|
|
10970
11250
|
OP_INTEROP.svc.status.getRoot,
|
|
10971
11251
|
async () => {
|
|
10972
11252
|
const rootStorage = new ethers.Contract(
|
|
@@ -10984,7 +11264,7 @@ async function getInteropRoot(provider, rootChainId, batchNumber) {
|
|
|
10984
11264
|
}
|
|
10985
11265
|
|
|
10986
11266
|
// src/adapters/ethers/resources/interop/services/finalization/bundle.ts
|
|
10987
|
-
var { wrap:
|
|
11267
|
+
var { wrap: wrap5 } = createErrorHandlers("interop");
|
|
10988
11268
|
async function getBundleStatus(client, dstProvider, topics, bundleHash, opts) {
|
|
10989
11269
|
const { interopHandler } = await client.ensureAddresses();
|
|
10990
11270
|
const bundleLogs = await getLogs(dstProvider, interopHandler, [null, bundleHash], opts);
|
|
@@ -11016,7 +11296,7 @@ async function executeBundle(client, dstProvider, info, opts) {
|
|
|
11016
11296
|
context: { bundleHash }
|
|
11017
11297
|
});
|
|
11018
11298
|
}
|
|
11019
|
-
const signer = await
|
|
11299
|
+
const signer = await wrap5(OP_INTEROP.exec.sendStep, () => client.signerFor(dstProvider), {
|
|
11020
11300
|
message: "Failed to resolve destination signer."
|
|
11021
11301
|
});
|
|
11022
11302
|
const { interopHandler } = await client.ensureAddresses();
|
|
@@ -11178,11 +11458,6 @@ function getBundleEncodedData(messageData) {
|
|
|
11178
11458
|
return `0x${messageData.slice(4)}`;
|
|
11179
11459
|
}
|
|
11180
11460
|
function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
|
|
11181
|
-
const expectedRoot = {
|
|
11182
|
-
rootChainId: bundleInfo.sourceChainId,
|
|
11183
|
-
batchNumber: proof.batchNumber,
|
|
11184
|
-
expectedRoot: proof.root
|
|
11185
|
-
};
|
|
11186
11461
|
const messageProof = {
|
|
11187
11462
|
chainId: bundleInfo.sourceChainId,
|
|
11188
11463
|
l1BatchNumber: proof.batchNumber,
|
|
@@ -11198,7 +11473,6 @@ function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
|
|
|
11198
11473
|
l2SrcTxHash: ids.l2SrcTxHash,
|
|
11199
11474
|
bundleHash: bundleInfo.bundleHash,
|
|
11200
11475
|
dstChainId: bundleInfo.dstChainId,
|
|
11201
|
-
expectedRoot,
|
|
11202
11476
|
proof: messageProof,
|
|
11203
11477
|
encodedData: getBundleEncodedData(messageData)
|
|
11204
11478
|
};
|
|
@@ -11221,7 +11495,7 @@ function decodeL1MessageData(log) {
|
|
|
11221
11495
|
}
|
|
11222
11496
|
|
|
11223
11497
|
// src/adapters/ethers/resources/interop/services/finalization/polling.ts
|
|
11224
|
-
var { wrap:
|
|
11498
|
+
var { wrap: wrap6 } = createErrorHandlers("interop");
|
|
11225
11499
|
function isProofNotReadyError(error) {
|
|
11226
11500
|
return isZKsyncError(error, {
|
|
11227
11501
|
operation: "zksrpc.getL2ToL1LogProof",
|
|
@@ -11258,30 +11532,26 @@ async function waitForProof(client, l2SrcTxHash, logIndex, blockNumber, pollMs,
|
|
|
11258
11532
|
});
|
|
11259
11533
|
}
|
|
11260
11534
|
try {
|
|
11261
|
-
return await client.zks.getL2ToL1LogProof(l2SrcTxHash, logIndex);
|
|
11535
|
+
return await client.zks.getL2ToL1LogProof(l2SrcTxHash, logIndex, "messageRoot" /* MessageRoot */);
|
|
11262
11536
|
} catch (error) {
|
|
11263
11537
|
if (!isProofNotReadyError(error)) throw error;
|
|
11264
11538
|
}
|
|
11265
11539
|
await sleep(pollMs);
|
|
11266
11540
|
}
|
|
11267
11541
|
}
|
|
11268
|
-
async function waitForRoot(provider,
|
|
11542
|
+
async function waitForRoot(provider, chainId, batchNumber, pollMs, deadline) {
|
|
11269
11543
|
while (true) {
|
|
11270
11544
|
if (Date.now() > deadline) {
|
|
11271
11545
|
throw createError("TIMEOUT", {
|
|
11272
11546
|
resource: "interop",
|
|
11273
11547
|
operation: OP_INTEROP.svc.wait.timeout,
|
|
11274
11548
|
message: "Timed out waiting for interop root to become available.",
|
|
11275
|
-
context: {
|
|
11549
|
+
context: { chainId, batchNumber }
|
|
11276
11550
|
});
|
|
11277
11551
|
}
|
|
11278
11552
|
let interopRoot = null;
|
|
11279
11553
|
try {
|
|
11280
|
-
const root = await getInteropRoot(
|
|
11281
|
-
provider,
|
|
11282
|
-
expectedRoot.rootChainId,
|
|
11283
|
-
expectedRoot.batchNumber
|
|
11284
|
-
);
|
|
11554
|
+
const root = await getInteropRoot(provider, chainId, batchNumber);
|
|
11285
11555
|
if (root !== ZERO_HASH) {
|
|
11286
11556
|
interopRoot = root;
|
|
11287
11557
|
}
|
|
@@ -11290,18 +11560,7 @@ async function waitForRoot(provider, expectedRoot, pollMs, deadline) {
|
|
|
11290
11560
|
interopRoot = null;
|
|
11291
11561
|
}
|
|
11292
11562
|
if (interopRoot) {
|
|
11293
|
-
|
|
11294
|
-
return;
|
|
11295
|
-
}
|
|
11296
|
-
throw createError("STATE", {
|
|
11297
|
-
resource: "interop",
|
|
11298
|
-
operation: OP_INTEROP.wait,
|
|
11299
|
-
message: "Interop root mismatch.",
|
|
11300
|
-
context: {
|
|
11301
|
-
expected: expectedRoot.expectedRoot,
|
|
11302
|
-
got: interopRoot
|
|
11303
|
-
}
|
|
11304
|
-
});
|
|
11563
|
+
return interopRoot;
|
|
11305
11564
|
}
|
|
11306
11565
|
await sleep(pollMs);
|
|
11307
11566
|
}
|
|
@@ -11316,7 +11575,7 @@ async function waitForTxReceipt(client, txHash, pollMs, deadline) {
|
|
|
11316
11575
|
context: { txHash }
|
|
11317
11576
|
});
|
|
11318
11577
|
}
|
|
11319
|
-
const receipt = await
|
|
11578
|
+
const receipt = await wrap6(
|
|
11320
11579
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
11321
11580
|
() => client.zks.getReceiptWithL2ToL1(txHash),
|
|
11322
11581
|
{
|
|
@@ -11330,7 +11589,7 @@ async function waitForTxReceipt(client, txHash, pollMs, deadline) {
|
|
|
11330
11589
|
await sleep(pollMs);
|
|
11331
11590
|
}
|
|
11332
11591
|
}
|
|
11333
|
-
async function waitForFinalization(client, dstProvider, input, opts) {
|
|
11592
|
+
async function waitForFinalization(client, dstProvider, gwProvider, input, opts) {
|
|
11334
11593
|
const { topics, centerIface } = getTopics();
|
|
11335
11594
|
const pollMs = opts?.pollMs ?? DEFAULT_POLL_MS;
|
|
11336
11595
|
const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -11379,7 +11638,16 @@ async function waitForFinalization(client, dstProvider, input, opts) {
|
|
|
11379
11638
|
proof,
|
|
11380
11639
|
bundleInfo.l1MessageData
|
|
11381
11640
|
);
|
|
11382
|
-
|
|
11641
|
+
if (proof.gatewayBlockNumber == null) {
|
|
11642
|
+
throw createError("STATE", {
|
|
11643
|
+
resource: "interop",
|
|
11644
|
+
operation: OP_INTEROP.svc.wait.timeout,
|
|
11645
|
+
message: "Proof missing gatewayBlockNumber required for interop finalization.",
|
|
11646
|
+
context: { l2SrcTxHash: ids.l2SrcTxHash }
|
|
11647
|
+
});
|
|
11648
|
+
}
|
|
11649
|
+
const { chainId: gwChainId } = await gwProvider.getNetwork();
|
|
11650
|
+
await waitForRoot(dstProvider, gwChainId, proof.gatewayBlockNumber, pollMs, deadline);
|
|
11383
11651
|
return finalizationInfo;
|
|
11384
11652
|
}
|
|
11385
11653
|
|
|
@@ -11425,8 +11693,8 @@ function createInteropFinalizationServices(client) {
|
|
|
11425
11693
|
status(dstProvider, input, opts) {
|
|
11426
11694
|
return getStatus(client, dstProvider, input, opts);
|
|
11427
11695
|
},
|
|
11428
|
-
wait(dstProvider, input, opts) {
|
|
11429
|
-
return waitForFinalization(client, dstProvider, input, opts);
|
|
11696
|
+
wait(dstProvider, gwProvider, input, opts) {
|
|
11697
|
+
return waitForFinalization(client, dstProvider, gwProvider, input, opts);
|
|
11430
11698
|
},
|
|
11431
11699
|
async finalize(dstProvider, info, opts) {
|
|
11432
11700
|
const execResult = await executeBundle(client, dstProvider, info, opts);
|
|
@@ -11438,24 +11706,31 @@ function createInteropFinalizationServices(client) {
|
|
|
11438
11706
|
}
|
|
11439
11707
|
};
|
|
11440
11708
|
}
|
|
11441
|
-
function
|
|
11442
|
-
return typeof
|
|
11443
|
-
}
|
|
11444
|
-
function resolveWaitableInput(waitableInput) {
|
|
11445
|
-
const input = waitableInput;
|
|
11446
|
-
return {
|
|
11447
|
-
dstProvider: resolveDstProvider(waitableInput.dstChain),
|
|
11448
|
-
waitable: input.waitable ? input.waitable : waitableInput
|
|
11449
|
-
};
|
|
11709
|
+
function resolveChainRef(ref) {
|
|
11710
|
+
return typeof ref === "string" ? new ethers.JsonRpcProvider(ref) : ref;
|
|
11450
11711
|
}
|
|
11451
11712
|
|
|
11452
11713
|
// src/adapters/ethers/resources/interop/index.ts
|
|
11453
|
-
var { wrap:
|
|
11714
|
+
var { wrap: wrap7, toResult: toResult2 } = createErrorHandlers("interop");
|
|
11454
11715
|
var ROUTES3 = {
|
|
11455
11716
|
direct: routeDirect(),
|
|
11456
11717
|
indirect: routeIndirect()
|
|
11457
11718
|
};
|
|
11458
|
-
function createInteropResource(client, tokens, contracts, attributes) {
|
|
11719
|
+
function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
11720
|
+
let gwProviderCache;
|
|
11721
|
+
function requireConfig() {
|
|
11722
|
+
if (!config)
|
|
11723
|
+
throw createError("STATE", {
|
|
11724
|
+
resource: "interop",
|
|
11725
|
+
operation: "interop.init",
|
|
11726
|
+
message: "Interop is not configured. Pass gwChain in createEthersSdk options."
|
|
11727
|
+
});
|
|
11728
|
+
return config;
|
|
11729
|
+
}
|
|
11730
|
+
function getGwProvider() {
|
|
11731
|
+
if (!gwProviderCache) gwProviderCache = resolveChainRef(requireConfig().gwChain);
|
|
11732
|
+
return gwProviderCache;
|
|
11733
|
+
}
|
|
11459
11734
|
const svc = createInteropFinalizationServices(client);
|
|
11460
11735
|
const tokensResource = tokens ?? createTokensResource(client);
|
|
11461
11736
|
const contractsResource = contracts ?? createContractsResource(client);
|
|
@@ -11479,11 +11754,11 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11479
11754
|
baseTokenDst: ctx.baseTokens.dst
|
|
11480
11755
|
}
|
|
11481
11756
|
});
|
|
11482
|
-
await
|
|
11757
|
+
await wrap7(OP_INTEROP.routes[route].preflight, () => ROUTES3[route].preflight?.(params, ctx), {
|
|
11483
11758
|
message: "Interop preflight failed.",
|
|
11484
11759
|
ctx: { where: `routes.${route}.preflight` }
|
|
11485
11760
|
});
|
|
11486
|
-
const { steps, approvals, quoteExtras } = await
|
|
11761
|
+
const { steps, approvals, quoteExtras, interopFee } = await wrap7(
|
|
11487
11762
|
OP_INTEROP.routes[route].build,
|
|
11488
11763
|
() => ROUTES3[route].build(params, ctx),
|
|
11489
11764
|
{
|
|
@@ -11495,7 +11770,8 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11495
11770
|
route,
|
|
11496
11771
|
approvalsNeeded: approvals,
|
|
11497
11772
|
totalActionValue: quoteExtras.totalActionValue,
|
|
11498
|
-
bridgedTokenTotal: quoteExtras.bridgedTokenTotal
|
|
11773
|
+
bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
|
|
11774
|
+
interopFee
|
|
11499
11775
|
};
|
|
11500
11776
|
return { plan: { route, summary, steps }, ctx };
|
|
11501
11777
|
}
|
|
@@ -11503,20 +11779,23 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11503
11779
|
const { plan } = await buildPlanWithCtx(dstProvider, params);
|
|
11504
11780
|
return plan;
|
|
11505
11781
|
}
|
|
11506
|
-
const quote = (params) =>
|
|
11507
|
-
const plan = await buildPlan(
|
|
11782
|
+
const quote = (dstChain, params) => wrap7(OP_INTEROP.quote, async () => {
|
|
11783
|
+
const plan = await buildPlan(resolveChainRef(dstChain), params);
|
|
11508
11784
|
return plan.summary;
|
|
11509
11785
|
});
|
|
11510
|
-
const tryQuote = (params) => toResult2(OP_INTEROP.tryQuote, () => quote(params));
|
|
11511
|
-
const prepare = (params) =>
|
|
11786
|
+
const tryQuote = (dstChain, params) => toResult2(OP_INTEROP.tryQuote, () => quote(dstChain, params));
|
|
11787
|
+
const prepare = (dstChain, params) => wrap7(OP_INTEROP.prepare, () => buildPlan(resolveChainRef(dstChain), params), {
|
|
11512
11788
|
message: "Internal error while preparing an interop plan.",
|
|
11513
11789
|
ctx: { where: "interop.prepare" }
|
|
11514
11790
|
});
|
|
11515
|
-
const tryPrepare = (params) => toResult2(
|
|
11516
|
-
|
|
11791
|
+
const tryPrepare = (dstChain, params) => toResult2(
|
|
11792
|
+
OP_INTEROP.tryPrepare,
|
|
11793
|
+
() => prepare(dstChain, params)
|
|
11794
|
+
);
|
|
11795
|
+
const create = (dstChain, params) => wrap7(
|
|
11517
11796
|
OP_INTEROP.create,
|
|
11518
11797
|
async () => {
|
|
11519
|
-
const { plan, ctx } = await buildPlanWithCtx(
|
|
11798
|
+
const { plan, ctx } = await buildPlanWithCtx(resolveChainRef(dstChain), params);
|
|
11520
11799
|
const signer = ctx.client.signerFor(ctx.client.l2);
|
|
11521
11800
|
const srcProvider = ctx.client.l2;
|
|
11522
11801
|
const from = await signer.getAddress();
|
|
@@ -11578,7 +11857,6 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11578
11857
|
const last = Object.values(stepHashes).pop();
|
|
11579
11858
|
return {
|
|
11580
11859
|
kind: "interop",
|
|
11581
|
-
dstChain: params.dstChain,
|
|
11582
11860
|
stepHashes,
|
|
11583
11861
|
plan,
|
|
11584
11862
|
l2SrcTxHash: last ?? "0x"
|
|
@@ -11589,46 +11867,27 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11589
11867
|
ctx: { where: "interop.create" }
|
|
11590
11868
|
}
|
|
11591
11869
|
);
|
|
11592
|
-
const tryCreate = (params) => toResult2(
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
}
|
|
11599
|
-
};
|
|
11600
|
-
const wait = (h, opts) => {
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
return { ...info, dstChain: h.dstChain };
|
|
11607
|
-
},
|
|
11608
|
-
{
|
|
11609
|
-
message: "Internal error while waiting for interop finalization.",
|
|
11610
|
-
ctx: { where: "interop.wait" }
|
|
11611
|
-
}
|
|
11612
|
-
);
|
|
11613
|
-
};
|
|
11614
|
-
const tryWait = (h, opts) => toResult2(OP_INTEROP.tryWait, () => wait(h, opts));
|
|
11615
|
-
const finalize = (h, opts) => wrap6(
|
|
11870
|
+
const tryCreate = (dstChain, params) => toResult2(
|
|
11871
|
+
OP_INTEROP.tryCreate,
|
|
11872
|
+
() => create(dstChain, params)
|
|
11873
|
+
);
|
|
11874
|
+
const status = (dstChain, h, opts) => wrap7(OP_INTEROP.status, () => svc.status(resolveChainRef(dstChain), h, opts), {
|
|
11875
|
+
message: "Internal error while checking interop status.",
|
|
11876
|
+
ctx: { where: "interop.status" }
|
|
11877
|
+
});
|
|
11878
|
+
const wait = (dstChain, h, opts) => wrap7(OP_INTEROP.wait, () => svc.wait(resolveChainRef(dstChain), getGwProvider(), h, opts), {
|
|
11879
|
+
message: "Internal error while waiting for interop finalization.",
|
|
11880
|
+
ctx: { where: "interop.wait" }
|
|
11881
|
+
});
|
|
11882
|
+
const tryWait = (dstChain, h, opts) => toResult2(OP_INTEROP.tryWait, () => wait(dstChain, h, opts));
|
|
11883
|
+
const finalize = (dstChain, h, opts) => wrap7(
|
|
11616
11884
|
OP_INTEROP.finalize,
|
|
11617
11885
|
async () => {
|
|
11886
|
+
const dstProvider = resolveChainRef(dstChain);
|
|
11618
11887
|
if (isInteropFinalizationInfo(h)) {
|
|
11619
|
-
|
|
11620
|
-
throw createError("STATE", {
|
|
11621
|
-
resource: "interop",
|
|
11622
|
-
operation: OP_INTEROP.finalize,
|
|
11623
|
-
message: "Missing dstChain in interop finalization info.",
|
|
11624
|
-
context: { input: h }
|
|
11625
|
-
});
|
|
11626
|
-
}
|
|
11627
|
-
const dstProvider2 = resolveDstProvider(h.dstChain);
|
|
11628
|
-
return svc.finalize(dstProvider2, h, opts);
|
|
11888
|
+
return svc.finalize(dstProvider, h, opts);
|
|
11629
11889
|
}
|
|
11630
|
-
const
|
|
11631
|
-
const info = await svc.wait(dstProvider, waitable);
|
|
11890
|
+
const info = await svc.wait(dstProvider, getGwProvider(), h);
|
|
11632
11891
|
return svc.finalize(dstProvider, info, opts);
|
|
11633
11892
|
},
|
|
11634
11893
|
{
|
|
@@ -11636,7 +11895,7 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11636
11895
|
ctx: { where: "interop.finalize" }
|
|
11637
11896
|
}
|
|
11638
11897
|
);
|
|
11639
|
-
const tryFinalize = (h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(h, opts));
|
|
11898
|
+
const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
|
|
11640
11899
|
return {
|
|
11641
11900
|
quote,
|
|
11642
11901
|
tryQuote,
|
|
@@ -11653,10 +11912,10 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11653
11912
|
}
|
|
11654
11913
|
|
|
11655
11914
|
// src/adapters/ethers/sdk.ts
|
|
11656
|
-
function createEthersSdk(client) {
|
|
11915
|
+
function createEthersSdk(client, options) {
|
|
11657
11916
|
const tokens = createTokensResource(client);
|
|
11658
11917
|
const contracts = createContractsResource(client);
|
|
11659
|
-
const interop = createInteropResource(client);
|
|
11918
|
+
const interop = createInteropResource(client, options?.interop, tokens, contracts);
|
|
11660
11919
|
return {
|
|
11661
11920
|
deposits: createDepositsResource(client, tokens, contracts),
|
|
11662
11921
|
withdrawals: createWithdrawalsResource(client, tokens, contracts),
|