@matterlabs/zksync-js 0.0.13 → 0.0.15
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.d.ts +1 -2
- package/dist/adapters/ethers/client.js +6 -6
- package/dist/adapters/ethers/index.cjs +607 -259
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.js +9 -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/services/gas.d.ts +12 -0
- package/dist/adapters/ethers/resources/interop/types.d.ts +6 -14
- package/dist/adapters/ethers/sdk.cjs +1008 -259
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.d.ts +6 -1
- package/dist/adapters/ethers/sdk.js +7 -7
- package/dist/adapters/viem/client.cjs +795 -7
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.d.ts +6 -1
- package/dist/adapters/viem/client.js +6 -6
- package/dist/adapters/viem/index.cjs +6490 -2799
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.d.ts +5 -0
- package/dist/adapters/viem/index.js +9 -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/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 +62 -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 +15 -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 +6401 -2758
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +8 -1
- package/dist/adapters/viem/sdk.js +7 -7
- package/dist/{chunk-E3KP7XCG.js → chunk-3HHUZXSV.js} +1 -1
- package/dist/{chunk-EDWBCPO3.js → chunk-4PZCNTQ3.js} +1387 -71
- package/dist/{chunk-UDBRUBEK.js → chunk-65HAYKVL.js} +2 -2
- package/dist/chunk-BWKWWLY4.js +9 -0
- package/dist/{chunk-JHO2UQ5F.js → chunk-HGB3DOV2.js} +445 -554
- package/dist/{chunk-HI64OOAR.js → chunk-HVHMLAYH.js} +1 -1
- package/dist/{chunk-2RIARDXZ.js → chunk-JHRYNLZG.js} +65 -7
- package/dist/{chunk-RI73VJSH.js → chunk-JXR5V5YK.js} +463 -27
- package/dist/chunk-K2UVKMLN.js +658 -0
- package/dist/{chunk-53MC5BR2.js → chunk-MDPX5LNW.js} +1 -1
- package/dist/{chunk-QQ2OR434.js → chunk-MT4X5FEO.js} +18 -2
- package/dist/{chunk-R5WRFPK2.js → chunk-MZBKM3GH.js} +4 -4
- package/dist/{chunk-5R7L5NM5.js → chunk-YIWXIP2M.js} +10 -2
- 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 +5 -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/chains.d.ts +1 -0
- package/dist/core/resources/deposits/gas.d.ts +7 -0
- package/dist/core/resources/deposits/priority.d.ts +41 -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/resources/interop/protocol.d.ts +3 -0
- 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 -20
- package/dist/core/types/primitives.d.ts +2 -0
- package/dist/index.cjs +69 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-4S4XDA4N.js +0 -415
- package/dist/chunk-5L6EYUJB.js +0 -237
|
@@ -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
|
}
|
|
@@ -8001,7 +8036,33 @@ function buildDirectRequestStruct(args) {
|
|
|
8001
8036
|
};
|
|
8002
8037
|
}
|
|
8003
8038
|
|
|
8039
|
+
// src/core/resources/deposits/chains.ts
|
|
8040
|
+
var ERAVM_CHAIN_IDS = /* @__PURE__ */ new Set([324n, 2741n, 11124n, 300n]);
|
|
8041
|
+
function isEraVmChain(chainIdL2) {
|
|
8042
|
+
return ERAVM_CHAIN_IDS.has(chainIdL2);
|
|
8043
|
+
}
|
|
8044
|
+
|
|
8004
8045
|
// src/core/resources/deposits/gas.ts
|
|
8046
|
+
var CREATE_REESTIMATE_BUFFER = 15n;
|
|
8047
|
+
var maxBigInt = (a, b) => a > b ? a : b;
|
|
8048
|
+
function applyGasBuffer(gasLimit, bufferPct = BUFFER) {
|
|
8049
|
+
return gasLimit * (100n + bufferPct) / 100n;
|
|
8050
|
+
}
|
|
8051
|
+
function resolveCreateDepositL1GasLimit(input) {
|
|
8052
|
+
const { chainIdL2, stepKey, preparedGasLimit, estimatedGasLimit } = input;
|
|
8053
|
+
if (estimatedGasLimit == null) {
|
|
8054
|
+
return preparedGasLimit;
|
|
8055
|
+
}
|
|
8056
|
+
const isEraVmBridgeStep = isEraVmChain(chainIdL2) && stepKey.startsWith("bridgehub:");
|
|
8057
|
+
const reestimatedGasLimit = applyGasBuffer(
|
|
8058
|
+
estimatedGasLimit,
|
|
8059
|
+
isEraVmBridgeStep ? BUFFER : CREATE_REESTIMATE_BUFFER
|
|
8060
|
+
);
|
|
8061
|
+
if (isEraVmBridgeStep && preparedGasLimit != null) {
|
|
8062
|
+
return maxBigInt(preparedGasLimit, reestimatedGasLimit);
|
|
8063
|
+
}
|
|
8064
|
+
return reestimatedGasLimit;
|
|
8065
|
+
}
|
|
8005
8066
|
function makeGasQuote(p) {
|
|
8006
8067
|
const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
|
|
8007
8068
|
return {
|
|
@@ -8052,13 +8113,12 @@ async function quoteL1Gas(input) {
|
|
|
8052
8113
|
}
|
|
8053
8114
|
try {
|
|
8054
8115
|
const est = await estimator.estimateGas(tx);
|
|
8055
|
-
const buffered = BigInt(est)
|
|
8116
|
+
const buffered = applyGasBuffer(BigInt(est));
|
|
8056
8117
|
return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
|
|
8057
|
-
} catch
|
|
8118
|
+
} catch {
|
|
8058
8119
|
if (fallbackGasLimit != null) {
|
|
8059
8120
|
return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
8060
8121
|
}
|
|
8061
|
-
console.warn("L1 gas estimation failed", err);
|
|
8062
8122
|
return void 0;
|
|
8063
8123
|
}
|
|
8064
8124
|
}
|
|
@@ -8090,14 +8150,13 @@ async function quoteL2Gas(input) {
|
|
|
8090
8150
|
const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
|
|
8091
8151
|
const pubdataOverhead = pubdataBytes * pp;
|
|
8092
8152
|
let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
|
|
8093
|
-
total = total
|
|
8153
|
+
total = applyGasBuffer(total);
|
|
8094
8154
|
return makeGasQuote({
|
|
8095
8155
|
gasLimit: total,
|
|
8096
8156
|
maxFeePerGas,
|
|
8097
8157
|
gasPerPubdata: pp
|
|
8098
8158
|
});
|
|
8099
|
-
} catch
|
|
8100
|
-
console.warn("L2 gas estimation failed", err);
|
|
8159
|
+
} catch {
|
|
8101
8160
|
return makeGasQuote({
|
|
8102
8161
|
gasLimit: l2GasLimit ?? 0n,
|
|
8103
8162
|
maxFeePerGas,
|
|
@@ -8260,8 +8319,22 @@ async function determineNonBaseL2Gas(input) {
|
|
|
8260
8319
|
try {
|
|
8261
8320
|
const l2TokenAddress = input.knownL2Token ?? (ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token));
|
|
8262
8321
|
if (l2TokenAddress === ZERO_L2_TOKEN_ADDRESS) {
|
|
8322
|
+
if (input.undeployedGasLimit != null) {
|
|
8323
|
+
return quoteL2Gas2({
|
|
8324
|
+
ctx,
|
|
8325
|
+
route,
|
|
8326
|
+
overrideGasLimit: input.undeployedGasLimit
|
|
8327
|
+
});
|
|
8328
|
+
}
|
|
8263
8329
|
return fallbackQuote();
|
|
8264
8330
|
}
|
|
8331
|
+
if (input.priorityFloorGasLimit != null) {
|
|
8332
|
+
return quoteL2Gas2({
|
|
8333
|
+
ctx,
|
|
8334
|
+
route,
|
|
8335
|
+
overrideGasLimit: input.priorityFloorGasLimit
|
|
8336
|
+
});
|
|
8337
|
+
}
|
|
8265
8338
|
const modelTx = {
|
|
8266
8339
|
to: input.modelTx?.to ?? ctx.sender,
|
|
8267
8340
|
from: input.modelTx?.from ?? ctx.sender,
|
|
@@ -8277,8 +8350,7 @@ async function determineNonBaseL2Gas(input) {
|
|
|
8277
8350
|
return fallbackQuote();
|
|
8278
8351
|
}
|
|
8279
8352
|
return gas;
|
|
8280
|
-
} catch
|
|
8281
|
-
console.warn("Failed to determine non-base deposit L2 gas; defaulting to safe gas limit.", err);
|
|
8353
|
+
} catch {
|
|
8282
8354
|
return fallbackQuote();
|
|
8283
8355
|
}
|
|
8284
8356
|
}
|
|
@@ -8295,7 +8367,9 @@ async function determineEthNonBaseL2Gas(input) {
|
|
|
8295
8367
|
route: "eth-nonbase",
|
|
8296
8368
|
l1Token: input.ctx.resolvedToken?.l1 ?? FORMAL_ETH_ADDRESS,
|
|
8297
8369
|
knownL2Token: input.ctx.resolvedToken?.l2,
|
|
8298
|
-
modelTx: input.modelTx
|
|
8370
|
+
modelTx: input.modelTx,
|
|
8371
|
+
priorityFloorGasLimit: input.priorityFloorGasLimit,
|
|
8372
|
+
undeployedGasLimit: input.undeployedGasLimit
|
|
8299
8373
|
});
|
|
8300
8374
|
}
|
|
8301
8375
|
|
|
@@ -8327,41 +8401,120 @@ function buildFeeBreakdown(p) {
|
|
|
8327
8401
|
};
|
|
8328
8402
|
}
|
|
8329
8403
|
|
|
8404
|
+
// src/core/resources/deposits/priority.ts
|
|
8405
|
+
var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
|
|
8406
|
+
var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
|
|
8407
|
+
var ERAVM_PRIORITY_L2_GAS_BUFFER = 30n;
|
|
8408
|
+
var maxBigInt2 = (a, b) => a > b ? a : b;
|
|
8409
|
+
var ceilDiv = (a, b) => (a + b - 1n) / b;
|
|
8410
|
+
function derivePriorityTxGasBreakdown(input) {
|
|
8411
|
+
const factoryDepsCount = input.factoryDepsCount ?? 0n;
|
|
8412
|
+
const minBodyGas = maxBigInt2(
|
|
8413
|
+
L1_TX_INTRINSIC_L2_GAS + ceilDiv(
|
|
8414
|
+
input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
|
|
8415
|
+
PRIORITY_TX_ENCODING_STEP_BYTES
|
|
8416
|
+
) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
|
|
8417
|
+
L1_TX_MIN_L2_GAS_BASE
|
|
8418
|
+
) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
|
|
8419
|
+
const overhead = maxBigInt2(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
|
|
8420
|
+
const derivedBodyGas = minBodyGas;
|
|
8421
|
+
return {
|
|
8422
|
+
encodedLength: input.encodedLength,
|
|
8423
|
+
minBodyGas,
|
|
8424
|
+
overhead,
|
|
8425
|
+
derivedBodyGas,
|
|
8426
|
+
derivedL2GasLimit: derivedBodyGas + overhead,
|
|
8427
|
+
priorityTxMaxGasLimit: PRIORITY_TX_MAX_GAS_LIMIT,
|
|
8428
|
+
priorityTxMaxGasLimitExceeded: derivedBodyGas > PRIORITY_TX_MAX_GAS_LIMIT
|
|
8429
|
+
};
|
|
8430
|
+
}
|
|
8431
|
+
function derivePriorityBodyGasEstimateCap(input) {
|
|
8432
|
+
return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
|
|
8433
|
+
}
|
|
8434
|
+
function applyPriorityL2GasLimitBuffer(input) {
|
|
8435
|
+
if (!isEraVmChain(input.chainIdL2)) {
|
|
8436
|
+
return input.gasLimit;
|
|
8437
|
+
}
|
|
8438
|
+
return input.gasLimit * (100n + ERAVM_PRIORITY_L2_GAS_BUFFER) / 100n;
|
|
8439
|
+
}
|
|
8440
|
+
var EMPTY_BYTES = "0x";
|
|
8441
|
+
var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
|
|
8442
|
+
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)";
|
|
8443
|
+
function hexByteLength(hex) {
|
|
8444
|
+
return BigInt(Math.max(hex.length - 2, 0) / 2);
|
|
8445
|
+
}
|
|
8446
|
+
function getPriorityTxEncodedLength(input) {
|
|
8447
|
+
const encoded = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8448
|
+
[L2_CANONICAL_TRANSACTION_TUPLE],
|
|
8449
|
+
[
|
|
8450
|
+
[
|
|
8451
|
+
0n,
|
|
8452
|
+
BigInt(input.sender),
|
|
8453
|
+
BigInt(input.l2Contract),
|
|
8454
|
+
0n,
|
|
8455
|
+
input.gasPerPubdata,
|
|
8456
|
+
0n,
|
|
8457
|
+
0n,
|
|
8458
|
+
0n,
|
|
8459
|
+
0n,
|
|
8460
|
+
input.l2Value,
|
|
8461
|
+
ZERO_RESERVED_WORDS,
|
|
8462
|
+
input.l2Calldata,
|
|
8463
|
+
EMPTY_BYTES,
|
|
8464
|
+
input.factoryDepsHashes ?? [],
|
|
8465
|
+
EMPTY_BYTES,
|
|
8466
|
+
EMPTY_BYTES
|
|
8467
|
+
]
|
|
8468
|
+
]
|
|
8469
|
+
);
|
|
8470
|
+
return hexByteLength(encoded);
|
|
8471
|
+
}
|
|
8472
|
+
function getPriorityTxGasBreakdown(input) {
|
|
8473
|
+
return derivePriorityTxGasBreakdown({
|
|
8474
|
+
encodedLength: getPriorityTxEncodedLength(input),
|
|
8475
|
+
gasPerPubdata: input.gasPerPubdata,
|
|
8476
|
+
factoryDepsCount: BigInt(input.factoryDepsHashes?.length ?? 0)
|
|
8477
|
+
});
|
|
8478
|
+
}
|
|
8479
|
+
|
|
8330
8480
|
// src/adapters/ethers/resources/deposits/routes/eth.ts
|
|
8481
|
+
var EMPTY_BYTES2 = "0x";
|
|
8331
8482
|
function routeEthDirect() {
|
|
8332
8483
|
return {
|
|
8333
8484
|
async build(p, ctx) {
|
|
8334
8485
|
const bh = await ctx.contracts.bridgehub();
|
|
8335
|
-
const
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8486
|
+
const l2Contract = p.to ?? ctx.sender;
|
|
8487
|
+
const l2Value = p.amount;
|
|
8488
|
+
const l2Calldata = EMPTY_BYTES2;
|
|
8489
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8490
|
+
sender: ctx.sender,
|
|
8491
|
+
l2Contract,
|
|
8492
|
+
l2Value,
|
|
8493
|
+
l2Calldata,
|
|
8494
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
8495
|
+
});
|
|
8496
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
8497
|
+
chainIdL2: ctx.chainIdL2,
|
|
8498
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
8499
|
+
});
|
|
8341
8500
|
const l2GasParams = await quoteL2Gas2({
|
|
8342
8501
|
ctx,
|
|
8343
8502
|
route: "eth-base",
|
|
8344
|
-
|
|
8345
|
-
overrideGasLimit: ctx.l2GasLimit,
|
|
8346
|
-
stateOverrides: {
|
|
8347
|
-
[ctx.sender]: {
|
|
8348
|
-
balance: "0xffffffffffffffffffff"
|
|
8349
|
-
}
|
|
8350
|
-
}
|
|
8503
|
+
overrideGasLimit: quotedL2GasLimit
|
|
8351
8504
|
});
|
|
8352
8505
|
if (!l2GasParams) {
|
|
8353
8506
|
throw new Error("Failed to estimate L2 gas for deposit.");
|
|
8354
8507
|
}
|
|
8355
8508
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
8356
|
-
const mintValue = baseCost + ctx.operatorTip +
|
|
8509
|
+
const mintValue = baseCost + ctx.operatorTip + l2Value;
|
|
8357
8510
|
const req = buildDirectRequestStruct({
|
|
8358
8511
|
chainId: ctx.chainIdL2,
|
|
8359
8512
|
mintValue,
|
|
8360
8513
|
l2GasLimit: l2GasParams.gasLimit,
|
|
8361
8514
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
8362
8515
|
refundRecipient: ctx.refundRecipient,
|
|
8363
|
-
l2Contract
|
|
8364
|
-
l2Value
|
|
8516
|
+
l2Contract,
|
|
8517
|
+
l2Value
|
|
8365
8518
|
});
|
|
8366
8519
|
const data = bh.interface.encodeFunctionData("requestL2TransactionDirect", [req]);
|
|
8367
8520
|
const l1TxCandidate = {
|
|
@@ -8406,6 +8559,56 @@ function routeEthDirect() {
|
|
|
8406
8559
|
};
|
|
8407
8560
|
}
|
|
8408
8561
|
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
8562
|
+
var ZERO_L2_TOKEN_ADDRESS2 = "0x0000000000000000000000000000000000000000";
|
|
8563
|
+
var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8564
|
+
async function getPriorityGasModel(input) {
|
|
8565
|
+
try {
|
|
8566
|
+
const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
|
|
8567
|
+
const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
|
|
8568
|
+
const { chainId: l1ChainId } = await input.ctx.client.l1.getNetwork();
|
|
8569
|
+
const isFirstBridge = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID || input.ctx.resolvedToken.originChainId === 0n;
|
|
8570
|
+
const erc20MetadataOriginChainId = isFirstBridge ? BigInt(l1ChainId) : input.ctx.resolvedToken.originChainId;
|
|
8571
|
+
const erc20Metadata = await l1NativeTokenVault.getERC20Getters(
|
|
8572
|
+
input.token,
|
|
8573
|
+
erc20MetadataOriginChainId
|
|
8574
|
+
);
|
|
8575
|
+
const bridgeMintCalldata = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8576
|
+
["address", "address", "address", "uint256", "bytes"],
|
|
8577
|
+
[input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
|
|
8578
|
+
);
|
|
8579
|
+
const l2Calldata = isFirstBridge ? new ethers.Interface(IL2AssetRouter_default).encodeFunctionData(
|
|
8580
|
+
"finalizeDeposit(address,address,address,uint256,bytes)",
|
|
8581
|
+
[input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
|
|
8582
|
+
) : await (() => {
|
|
8583
|
+
return l1AssetRouter.getDepositCalldata(
|
|
8584
|
+
input.ctx.sender,
|
|
8585
|
+
input.ctx.resolvedToken.assetId,
|
|
8586
|
+
bridgeMintCalldata
|
|
8587
|
+
);
|
|
8588
|
+
})();
|
|
8589
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8590
|
+
sender: input.ctx.l1AssetRouter,
|
|
8591
|
+
l2Contract: L2_ASSET_ROUTER_ADDRESS,
|
|
8592
|
+
l2Value: 0n,
|
|
8593
|
+
l2Calldata,
|
|
8594
|
+
gasPerPubdata: input.ctx.gasPerPubdata
|
|
8595
|
+
});
|
|
8596
|
+
const model = {
|
|
8597
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
8598
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
8599
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
8600
|
+
})
|
|
8601
|
+
};
|
|
8602
|
+
if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS2) {
|
|
8603
|
+
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
8604
|
+
minBodyGas: priorityFloorBreakdown.minBodyGas
|
|
8605
|
+
}) + priorityFloorBreakdown.overhead;
|
|
8606
|
+
}
|
|
8607
|
+
return model;
|
|
8608
|
+
} catch {
|
|
8609
|
+
return {};
|
|
8610
|
+
}
|
|
8611
|
+
}
|
|
8409
8612
|
function routeErc20NonBase() {
|
|
8410
8613
|
return {
|
|
8411
8614
|
async preflight(p, ctx) {
|
|
@@ -8426,11 +8629,29 @@ function routeErc20NonBase() {
|
|
|
8426
8629
|
const l1Signer = ctx.client.getL1Signer();
|
|
8427
8630
|
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
8428
8631
|
const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
|
|
8632
|
+
const receiver = p.to ?? ctx.sender;
|
|
8633
|
+
const secondBridgeCalldata = await wrapAs3(
|
|
8634
|
+
"INTERNAL",
|
|
8635
|
+
OP_DEPOSITS.nonbase.encodeCalldata,
|
|
8636
|
+
() => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, receiver)),
|
|
8637
|
+
{
|
|
8638
|
+
ctx: { where: "encodeSecondBridgeErc20Args" },
|
|
8639
|
+
message: "Failed to encode bridging calldata."
|
|
8640
|
+
}
|
|
8641
|
+
);
|
|
8642
|
+
const priorityGasModel = await getPriorityGasModel({
|
|
8643
|
+
ctx,
|
|
8644
|
+
token: p.token,
|
|
8645
|
+
amount: p.amount,
|
|
8646
|
+
receiver
|
|
8647
|
+
});
|
|
8429
8648
|
const l2GasParams = await determineErc20L2Gas({
|
|
8430
8649
|
ctx,
|
|
8431
8650
|
l1Token: p.token,
|
|
8651
|
+
priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
|
|
8652
|
+
undeployedGasLimit: priorityGasModel.undeployedGasLimit,
|
|
8432
8653
|
modelTx: {
|
|
8433
|
-
to:
|
|
8654
|
+
to: receiver,
|
|
8434
8655
|
from: ctx.sender,
|
|
8435
8656
|
data: "0x",
|
|
8436
8657
|
value: 0n
|
|
@@ -8492,15 +8713,6 @@ function routeErc20NonBase() {
|
|
|
8492
8713
|
});
|
|
8493
8714
|
}
|
|
8494
8715
|
}
|
|
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
8716
|
const requestStruct = {
|
|
8505
8717
|
chainId: ctx.chainIdL2,
|
|
8506
8718
|
mintValue,
|
|
@@ -8557,7 +8769,71 @@ function routeErc20NonBase() {
|
|
|
8557
8769
|
}
|
|
8558
8770
|
};
|
|
8559
8771
|
}
|
|
8772
|
+
|
|
8773
|
+
// src/core/codec/ntv.ts
|
|
8774
|
+
function createNTVCodec(deps) {
|
|
8775
|
+
function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
|
|
8776
|
+
const encoded = deps.encode(
|
|
8777
|
+
["uint256", "address", "address"],
|
|
8778
|
+
[originChainId, ntvAddress, tokenAddress]
|
|
8779
|
+
);
|
|
8780
|
+
return deps.keccak256(encoded);
|
|
8781
|
+
}
|
|
8782
|
+
return {
|
|
8783
|
+
encodeAssetId
|
|
8784
|
+
};
|
|
8785
|
+
}
|
|
8786
|
+
|
|
8787
|
+
// src/adapters/ethers/resources/deposits/routes/eth-nonbase.ts
|
|
8560
8788
|
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
8789
|
+
var ZERO_L2_TOKEN_ADDRESS3 = "0x0000000000000000000000000000000000000000";
|
|
8790
|
+
var ZERO_ASSET_ID2 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8791
|
+
var ntvCodec = createNTVCodec({
|
|
8792
|
+
encode: (types, values) => ethers.AbiCoder.defaultAbiCoder().encode(types, values),
|
|
8793
|
+
keccak256: (data) => ethers.keccak256(data)
|
|
8794
|
+
});
|
|
8795
|
+
async function getPriorityGasModel2(input) {
|
|
8796
|
+
try {
|
|
8797
|
+
const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
|
|
8798
|
+
const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
|
|
8799
|
+
const originChainId = input.ctx.resolvedToken.originChainId !== 0n ? input.ctx.resolvedToken.originChainId : BigInt((await input.ctx.client.l1.getNetwork()).chainId);
|
|
8800
|
+
const resolvedAssetId = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID2 ? ntvCodec.encodeAssetId(originChainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, ETH_ADDRESS) : input.ctx.resolvedToken.assetId;
|
|
8801
|
+
const erc20Metadata = await l1NativeTokenVault.getERC20Getters(
|
|
8802
|
+
ETH_ADDRESS,
|
|
8803
|
+
originChainId
|
|
8804
|
+
);
|
|
8805
|
+
const bridgeMintCalldata = ethers.AbiCoder.defaultAbiCoder().encode(
|
|
8806
|
+
["address", "address", "address", "uint256", "bytes"],
|
|
8807
|
+
[input.ctx.sender, input.receiver, ETH_ADDRESS, input.amount, erc20Metadata]
|
|
8808
|
+
);
|
|
8809
|
+
const l2Calldata = await l1AssetRouter.getDepositCalldata(
|
|
8810
|
+
input.ctx.sender,
|
|
8811
|
+
resolvedAssetId,
|
|
8812
|
+
bridgeMintCalldata
|
|
8813
|
+
);
|
|
8814
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
8815
|
+
sender: input.ctx.l1AssetRouter,
|
|
8816
|
+
l2Contract: L2_ASSET_ROUTER_ADDRESS,
|
|
8817
|
+
l2Value: 0n,
|
|
8818
|
+
l2Calldata,
|
|
8819
|
+
gasPerPubdata: input.ctx.gasPerPubdata
|
|
8820
|
+
});
|
|
8821
|
+
const model = {
|
|
8822
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
8823
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
8824
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
8825
|
+
})
|
|
8826
|
+
};
|
|
8827
|
+
if (input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS3) {
|
|
8828
|
+
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
8829
|
+
minBodyGas: priorityFloorBreakdown.minBodyGas
|
|
8830
|
+
}) + priorityFloorBreakdown.overhead;
|
|
8831
|
+
}
|
|
8832
|
+
return model;
|
|
8833
|
+
} catch {
|
|
8834
|
+
return {};
|
|
8835
|
+
}
|
|
8836
|
+
}
|
|
8561
8837
|
function routeEthNonBase() {
|
|
8562
8838
|
return {
|
|
8563
8839
|
async preflight(p, ctx) {
|
|
@@ -8606,15 +8882,23 @@ function routeEthNonBase() {
|
|
|
8606
8882
|
async build(p, ctx) {
|
|
8607
8883
|
const l1Signer = ctx.client.getL1Signer();
|
|
8608
8884
|
const baseToken = ctx.baseTokenL1;
|
|
8885
|
+
const receiver = p.to ?? ctx.sender;
|
|
8886
|
+
const priorityGasModel = await getPriorityGasModel2({
|
|
8887
|
+
ctx,
|
|
8888
|
+
amount: p.amount,
|
|
8889
|
+
receiver
|
|
8890
|
+
});
|
|
8609
8891
|
const l2TxModel = {
|
|
8610
|
-
to:
|
|
8892
|
+
to: receiver,
|
|
8611
8893
|
from: ctx.sender,
|
|
8612
8894
|
data: "0x",
|
|
8613
8895
|
value: 0n
|
|
8614
8896
|
};
|
|
8615
8897
|
const l2GasParams = await determineEthNonBaseL2Gas({
|
|
8616
8898
|
ctx,
|
|
8617
|
-
modelTx: l2TxModel
|
|
8899
|
+
modelTx: l2TxModel,
|
|
8900
|
+
priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
|
|
8901
|
+
undeployedGasLimit: priorityGasModel.undeployedGasLimit
|
|
8618
8902
|
});
|
|
8619
8903
|
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
8620
8904
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
@@ -8648,12 +8932,12 @@ function routeEthNonBase() {
|
|
|
8648
8932
|
const secondBridgeCalldata = await wrapAs4(
|
|
8649
8933
|
"INTERNAL",
|
|
8650
8934
|
OP_DEPOSITS.ethNonBase.encodeCalldata,
|
|
8651
|
-
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount,
|
|
8935
|
+
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, receiver)),
|
|
8652
8936
|
{
|
|
8653
8937
|
ctx: {
|
|
8654
8938
|
where: "encodeSecondBridgeEthArgs",
|
|
8655
8939
|
amount: p.amount.toString(),
|
|
8656
|
-
to:
|
|
8940
|
+
to: receiver
|
|
8657
8941
|
}
|
|
8658
8942
|
}
|
|
8659
8943
|
);
|
|
@@ -8714,6 +8998,7 @@ function routeEthNonBase() {
|
|
|
8714
8998
|
};
|
|
8715
8999
|
}
|
|
8716
9000
|
var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
|
|
9001
|
+
var EMPTY_BYTES3 = "0x";
|
|
8717
9002
|
function routeErc20Base() {
|
|
8718
9003
|
return {
|
|
8719
9004
|
async preflight(p, ctx) {
|
|
@@ -8744,17 +9029,24 @@ function routeErc20Base() {
|
|
|
8744
9029
|
async build(p, ctx) {
|
|
8745
9030
|
const l1Signer = ctx.client.getL1Signer();
|
|
8746
9031
|
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
8747
|
-
const
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
9032
|
+
const l2Contract = p.to ?? ctx.sender;
|
|
9033
|
+
const l2Value = p.amount;
|
|
9034
|
+
const l2Calldata = EMPTY_BYTES3;
|
|
9035
|
+
const priorityFloorBreakdown = getPriorityTxGasBreakdown({
|
|
9036
|
+
sender: ctx.sender,
|
|
9037
|
+
l2Contract,
|
|
9038
|
+
l2Value,
|
|
9039
|
+
l2Calldata,
|
|
9040
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
9041
|
+
});
|
|
9042
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
9043
|
+
chainIdL2: ctx.chainIdL2,
|
|
9044
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
9045
|
+
});
|
|
8753
9046
|
const l2GasParams = await quoteL2Gas2({
|
|
8754
9047
|
ctx,
|
|
8755
9048
|
route: "erc20-base",
|
|
8756
|
-
|
|
8757
|
-
overrideGasLimit: ctx.l2GasLimit
|
|
9049
|
+
overrideGasLimit: quotedL2GasLimit
|
|
8758
9050
|
});
|
|
8759
9051
|
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
8760
9052
|
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
@@ -8793,8 +9085,8 @@ function routeErc20Base() {
|
|
|
8793
9085
|
l2GasLimit: l2GasParams.gasLimit,
|
|
8794
9086
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
8795
9087
|
refundRecipient: ctx.refundRecipient,
|
|
8796
|
-
l2Contract
|
|
8797
|
-
l2Value
|
|
9088
|
+
l2Contract,
|
|
9089
|
+
l2Value
|
|
8798
9090
|
});
|
|
8799
9091
|
const bridgehub = await ctx.contracts.bridgehub();
|
|
8800
9092
|
const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
|
|
@@ -8841,25 +9133,9 @@ function routeErc20Base() {
|
|
|
8841
9133
|
}
|
|
8842
9134
|
};
|
|
8843
9135
|
}
|
|
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
9136
|
var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
|
|
8861
9137
|
var abi = ethers.AbiCoder.defaultAbiCoder();
|
|
8862
|
-
var
|
|
9138
|
+
var ntvCodec2 = createNTVCodec({
|
|
8863
9139
|
encode: (types, values) => abi.encode(types, values),
|
|
8864
9140
|
keccak256: (data) => ethers.ethers.keccak256(data)
|
|
8865
9141
|
});
|
|
@@ -8978,7 +9254,7 @@ function createTokensResource(client) {
|
|
|
8978
9254
|
return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
|
|
8979
9255
|
const baseAssetId = await getBaseTokenAssetId();
|
|
8980
9256
|
const l1ChainId = await getL1ChainId();
|
|
8981
|
-
const ethAssetId =
|
|
9257
|
+
const ethAssetId = ntvCodec2.encodeAssetId(
|
|
8982
9258
|
l1ChainId,
|
|
8983
9259
|
L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
8984
9260
|
ETH_ADDRESS
|
|
@@ -9192,6 +9468,8 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
9192
9468
|
async () => {
|
|
9193
9469
|
const plan = await prepare(p);
|
|
9194
9470
|
const stepHashes = {};
|
|
9471
|
+
const { chainId } = await client.l2.getNetwork();
|
|
9472
|
+
const chainIdL2 = BigInt(chainId);
|
|
9195
9473
|
const managed = new ethers.NonceManager(client.signer);
|
|
9196
9474
|
const from = await managed.getAddress();
|
|
9197
9475
|
let next;
|
|
@@ -9237,8 +9515,14 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
9237
9515
|
}
|
|
9238
9516
|
if (!p.l1TxOverrides?.gasLimit) {
|
|
9239
9517
|
try {
|
|
9518
|
+
const preparedGasLimit = step.tx.gasLimit != null ? BigInt(step.tx.gasLimit.toString()) : void 0;
|
|
9240
9519
|
const est = await client.l1.estimateGas(step.tx);
|
|
9241
|
-
step.tx.gasLimit =
|
|
9520
|
+
step.tx.gasLimit = resolveCreateDepositL1GasLimit({
|
|
9521
|
+
chainIdL2,
|
|
9522
|
+
stepKey: step.key,
|
|
9523
|
+
preparedGasLimit,
|
|
9524
|
+
estimatedGasLimit: BigInt(est)
|
|
9525
|
+
});
|
|
9242
9526
|
} catch {
|
|
9243
9527
|
}
|
|
9244
9528
|
}
|
|
@@ -9989,7 +10273,7 @@ var ROUTES2 = {
|
|
|
9989
10273
|
};
|
|
9990
10274
|
function createWithdrawalsResource(client, tokens, contracts) {
|
|
9991
10275
|
const svc = createFinalizationServices(client);
|
|
9992
|
-
const { wrap:
|
|
10276
|
+
const { wrap: wrap8, toResult: toResult3 } = createErrorHandlers("withdrawals");
|
|
9993
10277
|
const tokensResource = tokens ?? createTokensResource(client);
|
|
9994
10278
|
const contractsResource = contracts ?? createContractsResource(client);
|
|
9995
10279
|
async function buildPlan(p) {
|
|
@@ -10010,7 +10294,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10010
10294
|
};
|
|
10011
10295
|
}
|
|
10012
10296
|
const finalizeCache = /* @__PURE__ */ new Map();
|
|
10013
|
-
const quote = (p) =>
|
|
10297
|
+
const quote = (p) => wrap8(
|
|
10014
10298
|
OP_WITHDRAWALS.quote,
|
|
10015
10299
|
async () => {
|
|
10016
10300
|
const plan = await buildPlan(p);
|
|
@@ -10032,7 +10316,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10032
10316
|
ctx: { token: p.token, where: "withdrawals.tryQuote" }
|
|
10033
10317
|
}
|
|
10034
10318
|
);
|
|
10035
|
-
const prepare = (p) =>
|
|
10319
|
+
const prepare = (p) => wrap8(OP_WITHDRAWALS.prepare, () => buildPlan(p), {
|
|
10036
10320
|
message: "Internal error while preparing a withdrawal plan.",
|
|
10037
10321
|
ctx: { token: p.token, where: "withdrawals.prepare" }
|
|
10038
10322
|
});
|
|
@@ -10040,7 +10324,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10040
10324
|
message: "Internal error while preparing a withdrawal plan.",
|
|
10041
10325
|
ctx: { token: p.token, where: "withdrawals.tryPrepare" }
|
|
10042
10326
|
});
|
|
10043
|
-
const create = (p) =>
|
|
10327
|
+
const create = (p) => wrap8(
|
|
10044
10328
|
OP_WITHDRAWALS.create,
|
|
10045
10329
|
async () => {
|
|
10046
10330
|
const plan = await prepare(p);
|
|
@@ -10111,7 +10395,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10111
10395
|
message: "Internal error while creating withdrawal transactions.",
|
|
10112
10396
|
ctx: { token: p.token, amount: p.amount, to: p.to, where: "withdrawals.tryCreate" }
|
|
10113
10397
|
});
|
|
10114
|
-
const status = (h) =>
|
|
10398
|
+
const status = (h) => wrap8(
|
|
10115
10399
|
OP_WITHDRAWALS.status,
|
|
10116
10400
|
async () => {
|
|
10117
10401
|
const l2TxHash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
|
|
@@ -10166,7 +10450,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10166
10450
|
const wait = (h, opts = {
|
|
10167
10451
|
for: "l2",
|
|
10168
10452
|
pollMs: 5500
|
|
10169
|
-
}) =>
|
|
10453
|
+
}) => wrap8(
|
|
10170
10454
|
OP_WITHDRAWALS.wait,
|
|
10171
10455
|
async () => {
|
|
10172
10456
|
const l2Hash = typeof h === "string" ? h : "l2TxHash" in h && h.l2TxHash ? h.l2TxHash : "0x";
|
|
@@ -10231,7 +10515,7 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
10231
10515
|
}
|
|
10232
10516
|
}
|
|
10233
10517
|
);
|
|
10234
|
-
const finalize = (l2TxHash) =>
|
|
10518
|
+
const finalize = (l2TxHash) => wrap8(
|
|
10235
10519
|
OP_WITHDRAWALS.finalize.send,
|
|
10236
10520
|
async () => {
|
|
10237
10521
|
const pack = await (async () => {
|
|
@@ -10357,9 +10641,11 @@ function createCallAttributes(codec) {
|
|
|
10357
10641
|
function createBundleAttributes(codec) {
|
|
10358
10642
|
const executionAddress = (executor) => codec.encode("executionAddress", [executor]);
|
|
10359
10643
|
const unbundlerAddress = (addr) => codec.encode("unbundlerAddress", [addr]);
|
|
10644
|
+
const useFixedFee = (enabled) => codec.encode("useFixedFee", [enabled]);
|
|
10360
10645
|
return {
|
|
10361
10646
|
executionAddress,
|
|
10362
|
-
unbundlerAddress
|
|
10647
|
+
unbundlerAddress,
|
|
10648
|
+
useFixedFee
|
|
10363
10649
|
};
|
|
10364
10650
|
}
|
|
10365
10651
|
|
|
@@ -10380,6 +10666,7 @@ function getInteropAttributes(params, ctx) {
|
|
|
10380
10666
|
if (params.unbundling?.by) {
|
|
10381
10667
|
bundleAttributes.push(ctx.attributes.bundle.unbundlerAddress(params.unbundling.by));
|
|
10382
10668
|
}
|
|
10669
|
+
bundleAttributes.push(ctx.attributes.bundle.useFixedFee(params.fee?.useFixed ?? false));
|
|
10383
10670
|
const callAttributes = params.actions.map((action) => {
|
|
10384
10671
|
switch (action.type) {
|
|
10385
10672
|
case "sendNative": {
|
|
@@ -10409,11 +10696,6 @@ function createEthersAttributesResource(opts = {}) {
|
|
|
10409
10696
|
}
|
|
10410
10697
|
|
|
10411
10698
|
// 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
10699
|
function isInteropMessageProof(obj) {
|
|
10418
10700
|
if (typeof obj !== "object" || obj === null) return false;
|
|
10419
10701
|
const proof = obj;
|
|
@@ -10422,7 +10704,7 @@ function isInteropMessageProof(obj) {
|
|
|
10422
10704
|
function isInteropFinalizationInfo(obj) {
|
|
10423
10705
|
if (typeof obj !== "object" || obj === null) return false;
|
|
10424
10706
|
const info = obj;
|
|
10425
|
-
return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) &&
|
|
10707
|
+
return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) && isInteropMessageProof(info.proof);
|
|
10426
10708
|
}
|
|
10427
10709
|
|
|
10428
10710
|
// src/core/resources/interop/route.ts
|
|
@@ -10475,7 +10757,7 @@ function preflightDirect(params, ctx) {
|
|
|
10475
10757
|
}
|
|
10476
10758
|
}
|
|
10477
10759
|
}
|
|
10478
|
-
function buildDirectBundle(params, ctx, attrs) {
|
|
10760
|
+
function buildDirectBundle(params, ctx, attrs, interopFeeInfo) {
|
|
10479
10761
|
const totalActionValue = sumActionMsgValue(params.actions);
|
|
10480
10762
|
const starters = params.actions.map((action, index) => {
|
|
10481
10763
|
const to = ctx.codec.formatAddress(action.to);
|
|
@@ -10493,7 +10775,8 @@ function buildDirectBundle(params, ctx, attrs) {
|
|
|
10493
10775
|
dstChain: ctx.codec.formatChain(ctx.dstChainId),
|
|
10494
10776
|
starters,
|
|
10495
10777
|
bundleAttributes: attrs.bundleAttributes,
|
|
10496
|
-
approvals: [],
|
|
10778
|
+
approvals: interopFeeInfo.approval ? [interopFeeInfo.approval] : [],
|
|
10779
|
+
interopFee: interopFeeInfo.fee,
|
|
10497
10780
|
quoteExtras: {
|
|
10498
10781
|
totalActionValue,
|
|
10499
10782
|
bridgedTokenTotal: 0n
|
|
@@ -10538,7 +10821,7 @@ function preflightIndirect(params, ctx) {
|
|
|
10538
10821
|
}
|
|
10539
10822
|
}
|
|
10540
10823
|
}
|
|
10541
|
-
function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
10824
|
+
function buildIndirectBundle(params, ctx, attrs, starterData, interopFeeInfo) {
|
|
10542
10825
|
const totalActionValue = sumActionMsgValue(params.actions);
|
|
10543
10826
|
const bridgedTokenTotal = sumErc20Amounts(params.actions);
|
|
10544
10827
|
const approvalMap = /* @__PURE__ */ new Map();
|
|
@@ -10557,6 +10840,7 @@ function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
|
10557
10840
|
}
|
|
10558
10841
|
}
|
|
10559
10842
|
const approvals = Array.from(approvalMap.values());
|
|
10843
|
+
if (interopFeeInfo.approval) approvals.push(interopFeeInfo.approval);
|
|
10560
10844
|
const starters = params.actions.map((action, index) => {
|
|
10561
10845
|
const callAttributes = attrs.callAttributes[index] ?? [];
|
|
10562
10846
|
if (starterData[index]?.assetRouterPayload) {
|
|
@@ -10580,6 +10864,7 @@ function buildIndirectBundle(params, ctx, attrs, starterData) {
|
|
|
10580
10864
|
starters,
|
|
10581
10865
|
bundleAttributes: attrs.bundleAttributes,
|
|
10582
10866
|
approvals,
|
|
10867
|
+
interopFee: interopFeeInfo.fee,
|
|
10583
10868
|
quoteExtras: {
|
|
10584
10869
|
totalActionValue,
|
|
10585
10870
|
bridgedTokenTotal
|
|
@@ -10626,6 +10911,29 @@ function buildEnsureTokenSteps(erc20Tokens, ctx) {
|
|
|
10626
10911
|
}
|
|
10627
10912
|
}));
|
|
10628
10913
|
}
|
|
10914
|
+
async function buildApproveSteps(approvals, ctx) {
|
|
10915
|
+
const steps = [];
|
|
10916
|
+
for (const approval of approvals) {
|
|
10917
|
+
const erc20 = new ethers.Contract(approval.token, IERC20_default, ctx.client.l2);
|
|
10918
|
+
const currentAllowance = await erc20.allowance(ctx.sender, approval.spender);
|
|
10919
|
+
if (currentAllowance < approval.amount) {
|
|
10920
|
+
steps.push({
|
|
10921
|
+
key: `approve:${approval.token}:${approval.spender}`,
|
|
10922
|
+
kind: "approve",
|
|
10923
|
+
description: `Approve ${approval.spender} to spend ${approval.amount} of ${approval.token}`,
|
|
10924
|
+
tx: {
|
|
10925
|
+
to: approval.token,
|
|
10926
|
+
data: erc20.interface.encodeFunctionData("approve", [
|
|
10927
|
+
approval.spender,
|
|
10928
|
+
approval.amount
|
|
10929
|
+
]),
|
|
10930
|
+
...ctx.gasOverrides
|
|
10931
|
+
}
|
|
10932
|
+
});
|
|
10933
|
+
}
|
|
10934
|
+
}
|
|
10935
|
+
return steps;
|
|
10936
|
+
}
|
|
10629
10937
|
async function resolveErc20AssetIds(erc20Tokens, ctx) {
|
|
10630
10938
|
const assetIds = /* @__PURE__ */ new Map();
|
|
10631
10939
|
if (erc20Tokens.length === 0) return assetIds;
|
|
@@ -10679,6 +10987,44 @@ async function getStarterData(params, ctx, erc20AssetIds) {
|
|
|
10679
10987
|
}
|
|
10680
10988
|
return starterData;
|
|
10681
10989
|
}
|
|
10990
|
+
var { wrap: wrap3 } = createErrorHandlers("interop");
|
|
10991
|
+
async function buildFeeInfo(params, ctx, numStarters) {
|
|
10992
|
+
const useFixed = params.fee?.useFixed ?? false;
|
|
10993
|
+
const interopCenter = new ethers.Contract(ctx.interopCenter, IInteropCenter_default, ctx.client.l2);
|
|
10994
|
+
if (useFixed) {
|
|
10995
|
+
const zkFeePerCall = await wrap3(
|
|
10996
|
+
OP_INTEROP.svc.fees.zkInteropFee,
|
|
10997
|
+
() => interopCenter.ZK_INTEROP_FEE(),
|
|
10998
|
+
{ message: "Failed to fetch ZK interop fee from InteropCenter." }
|
|
10999
|
+
);
|
|
11000
|
+
const zkFeeTotal = zkFeePerCall * BigInt(numStarters);
|
|
11001
|
+
const zkTokenAddress = await wrap3(
|
|
11002
|
+
OP_INTEROP.svc.fees.zkToken,
|
|
11003
|
+
() => interopCenter.zkToken(),
|
|
11004
|
+
{ message: "Failed to fetch ZK token address from InteropCenter." }
|
|
11005
|
+
);
|
|
11006
|
+
const approval = {
|
|
11007
|
+
token: zkTokenAddress,
|
|
11008
|
+
spender: ctx.interopCenter,
|
|
11009
|
+
amount: zkFeeTotal
|
|
11010
|
+
};
|
|
11011
|
+
return {
|
|
11012
|
+
approval,
|
|
11013
|
+
fee: { token: zkTokenAddress, amount: zkFeeTotal }
|
|
11014
|
+
};
|
|
11015
|
+
} else {
|
|
11016
|
+
const protocolFeePerCall = await wrap3(
|
|
11017
|
+
OP_INTEROP.svc.fees.protocolFee,
|
|
11018
|
+
() => interopCenter.interopProtocolFee(),
|
|
11019
|
+
{ message: "Failed to fetch interop protocol fee from InteropCenter." }
|
|
11020
|
+
);
|
|
11021
|
+
const totalFee = protocolFeePerCall * BigInt(numStarters);
|
|
11022
|
+
return {
|
|
11023
|
+
approval: null,
|
|
11024
|
+
fee: { token: ctx.baseTokens.src, amount: totalFee }
|
|
11025
|
+
};
|
|
11026
|
+
}
|
|
11027
|
+
}
|
|
10682
11028
|
|
|
10683
11029
|
// src/adapters/ethers/resources/interop/routes/indirect.ts
|
|
10684
11030
|
function routeIndirect() {
|
|
@@ -10694,7 +11040,10 @@ function routeIndirect() {
|
|
|
10694
11040
|
async build(params, ctx) {
|
|
10695
11041
|
const steps = [];
|
|
10696
11042
|
const erc20Tokens = getErc20Tokens(params);
|
|
10697
|
-
const erc20AssetIds = await
|
|
11043
|
+
const [erc20AssetIds, feeInfo] = await Promise.all([
|
|
11044
|
+
resolveErc20AssetIds(erc20Tokens, ctx),
|
|
11045
|
+
buildFeeInfo(params, ctx, params.actions.length)
|
|
11046
|
+
]);
|
|
10698
11047
|
const attributes = getInteropAttributes(params, ctx);
|
|
10699
11048
|
const starterData = await getStarterData(params, ctx, erc20AssetIds);
|
|
10700
11049
|
const bundle = buildIndirectBundle(
|
|
@@ -10707,32 +11056,11 @@ function routeIndirect() {
|
|
|
10707
11056
|
codec: interopCodec
|
|
10708
11057
|
},
|
|
10709
11058
|
attributes,
|
|
10710
|
-
starterData
|
|
11059
|
+
starterData,
|
|
11060
|
+
feeInfo
|
|
10711
11061
|
);
|
|
10712
11062
|
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
|
-
}
|
|
11063
|
+
steps.push(...await buildApproveSteps(bundle.approvals, ctx));
|
|
10736
11064
|
const data = ctx.ifaces.interopCenter.encodeFunctionData("sendBundle", [
|
|
10737
11065
|
bundle.dstChain,
|
|
10738
11066
|
bundle.starters,
|
|
@@ -10745,14 +11073,15 @@ function routeIndirect() {
|
|
|
10745
11073
|
tx: {
|
|
10746
11074
|
to: ctx.interopCenter,
|
|
10747
11075
|
data,
|
|
10748
|
-
value: bundle.quoteExtras.totalActionValue,
|
|
11076
|
+
value: bundle.quoteExtras.totalActionValue + feeInfo.fee.amount,
|
|
10749
11077
|
...ctx.gasOverrides
|
|
10750
11078
|
}
|
|
10751
11079
|
});
|
|
10752
11080
|
return {
|
|
10753
11081
|
steps,
|
|
10754
11082
|
approvals: bundle.approvals,
|
|
10755
|
-
quoteExtras: bundle.quoteExtras
|
|
11083
|
+
quoteExtras: bundle.quoteExtras,
|
|
11084
|
+
interopFee: feeInfo.fee
|
|
10756
11085
|
};
|
|
10757
11086
|
}
|
|
10758
11087
|
};
|
|
@@ -10769,10 +11098,10 @@ function routeDirect() {
|
|
|
10769
11098
|
l2AssetRouter: ctx.l2AssetRouter,
|
|
10770
11099
|
l2NativeTokenVault: ctx.l2NativeTokenVault});
|
|
10771
11100
|
},
|
|
10772
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
10773
11101
|
async build(params, ctx) {
|
|
10774
11102
|
const steps = [];
|
|
10775
11103
|
const attrs = getInteropAttributes(params, ctx);
|
|
11104
|
+
const feeInfo = await buildFeeInfo(params, ctx, params.actions.length);
|
|
10776
11105
|
const built = buildDirectBundle(
|
|
10777
11106
|
params,
|
|
10778
11107
|
{
|
|
@@ -10782,8 +11111,10 @@ function routeDirect() {
|
|
|
10782
11111
|
l2NativeTokenVault: ctx.l2NativeTokenVault,
|
|
10783
11112
|
codec: interopCodec
|
|
10784
11113
|
},
|
|
10785
|
-
attrs
|
|
11114
|
+
attrs,
|
|
11115
|
+
feeInfo
|
|
10786
11116
|
);
|
|
11117
|
+
steps.push(...await buildApproveSteps(built.approvals, ctx));
|
|
10787
11118
|
const data = ctx.ifaces.interopCenter.encodeFunctionData("sendBundle", [
|
|
10788
11119
|
built.dstChain,
|
|
10789
11120
|
built.starters,
|
|
@@ -10793,43 +11124,47 @@ function routeDirect() {
|
|
|
10793
11124
|
key: "sendBundle",
|
|
10794
11125
|
kind: "interop.center",
|
|
10795
11126
|
description: `Send interop bundle (direct route; ${params.actions.length} actions)`,
|
|
10796
|
-
//
|
|
10797
|
-
// all calls (sendNative.amount + call.value).
|
|
11127
|
+
// msg.value = forwarded action value + protocol fee.
|
|
10798
11128
|
tx: {
|
|
10799
11129
|
to: ctx.interopCenter,
|
|
10800
11130
|
data,
|
|
10801
|
-
value: built.quoteExtras.totalActionValue,
|
|
11131
|
+
value: built.quoteExtras.totalActionValue + feeInfo.fee.amount,
|
|
10802
11132
|
...ctx.gasOverrides
|
|
10803
11133
|
}
|
|
10804
11134
|
});
|
|
10805
11135
|
return {
|
|
10806
11136
|
steps,
|
|
10807
11137
|
approvals: built.approvals,
|
|
10808
|
-
quoteExtras: built.quoteExtras
|
|
11138
|
+
quoteExtras: built.quoteExtras,
|
|
11139
|
+
interopFee: feeInfo.fee
|
|
10809
11140
|
};
|
|
10810
11141
|
}
|
|
10811
11142
|
};
|
|
10812
11143
|
}
|
|
11144
|
+
|
|
11145
|
+
// src/core/resources/interop/protocol.ts
|
|
10813
11146
|
var MIN_INTEROP_PROTOCOL = 31;
|
|
11147
|
+
function assertProtocolVersion(chainId, protocolVersion) {
|
|
11148
|
+
if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
|
|
11149
|
+
throw createError("VALIDATION", {
|
|
11150
|
+
resource: "interop",
|
|
11151
|
+
operation: OP_INTEROP.context.protocolVersion,
|
|
11152
|
+
message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
|
|
11153
|
+
context: {
|
|
11154
|
+
chainId,
|
|
11155
|
+
requiredMinor: MIN_INTEROP_PROTOCOL,
|
|
11156
|
+
semver: protocolVersion
|
|
11157
|
+
}
|
|
11158
|
+
});
|
|
11159
|
+
}
|
|
11160
|
+
}
|
|
11161
|
+
|
|
11162
|
+
// src/adapters/ethers/resources/interop/context.ts
|
|
10814
11163
|
async function assertInteropProtocolVersion(client, srcChainId, dstChainId) {
|
|
10815
11164
|
const [srcProtocolVersion, dstProtocolVersion] = await Promise.all([
|
|
10816
11165
|
client.getProtocolVersion(srcChainId),
|
|
10817
11166
|
client.getProtocolVersion(dstChainId)
|
|
10818
11167
|
]);
|
|
10819
|
-
const assertProtocolVersion = (chainId, protocolVersion) => {
|
|
10820
|
-
if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
|
|
10821
|
-
throw createError("VALIDATION", {
|
|
10822
|
-
resource: "interop",
|
|
10823
|
-
operation: OP_INTEROP.context.protocolVersion,
|
|
10824
|
-
message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
|
|
10825
|
-
context: {
|
|
10826
|
-
chainId,
|
|
10827
|
-
requiredMinor: MIN_INTEROP_PROTOCOL,
|
|
10828
|
-
semver: protocolVersion
|
|
10829
|
-
}
|
|
10830
|
-
});
|
|
10831
|
-
}
|
|
10832
|
-
};
|
|
10833
11168
|
assertProtocolVersion(srcChainId, srcProtocolVersion);
|
|
10834
11169
|
assertProtocolVersion(dstChainId, dstProtocolVersion);
|
|
10835
11170
|
}
|
|
@@ -10885,7 +11220,7 @@ function getTopics() {
|
|
|
10885
11220
|
};
|
|
10886
11221
|
return { topics, centerIface };
|
|
10887
11222
|
}
|
|
10888
|
-
var { wrap:
|
|
11223
|
+
var { wrap: wrap4 } = createErrorHandlers("interop");
|
|
10889
11224
|
var DEFAULT_BLOCKS_RANGE_SIZE = 1e4;
|
|
10890
11225
|
var DEFAULT_MAX_BLOCKS_BACK = 2e4;
|
|
10891
11226
|
var SAFE_BLOCKS_RANGE_SIZE = 1e3;
|
|
@@ -10898,9 +11233,16 @@ function parseMaxBlockRangeLimit(error) {
|
|
|
10898
11233
|
return Number.isInteger(limit) && limit > 0 ? limit : null;
|
|
10899
11234
|
}
|
|
10900
11235
|
async function getTxReceipt(provider, txHash) {
|
|
10901
|
-
const receipt = await
|
|
11236
|
+
const receipt = await wrap4(
|
|
10902
11237
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
10903
|
-
() =>
|
|
11238
|
+
async () => {
|
|
11239
|
+
try {
|
|
11240
|
+
return await provider.getTransactionReceipt(txHash);
|
|
11241
|
+
} catch (error) {
|
|
11242
|
+
if (isReceiptNotFound(error)) return null;
|
|
11243
|
+
throw error;
|
|
11244
|
+
}
|
|
11245
|
+
},
|
|
10904
11246
|
{
|
|
10905
11247
|
ctx: { where: "l2.getTransactionReceipt", l2SrcTxHash: txHash },
|
|
10906
11248
|
message: "Failed to fetch source L2 receipt for interop tx."
|
|
@@ -10919,7 +11261,7 @@ async function getTxReceipt(provider, txHash) {
|
|
|
10919
11261
|
async function getLogs(provider, address, topics, opts) {
|
|
10920
11262
|
const maxBlocksBack = opts?.maxBlocksBack ?? DEFAULT_MAX_BLOCKS_BACK;
|
|
10921
11263
|
const initialChunkSize = opts?.logChunkSize ?? DEFAULT_BLOCKS_RANGE_SIZE;
|
|
10922
|
-
return await
|
|
11264
|
+
return await wrap4(
|
|
10923
11265
|
OP_INTEROP.svc.status.dstLogs,
|
|
10924
11266
|
async () => {
|
|
10925
11267
|
const currentBlock = await provider.getBlockNumber();
|
|
@@ -10966,7 +11308,7 @@ async function getLogs(provider, address, topics, opts) {
|
|
|
10966
11308
|
);
|
|
10967
11309
|
}
|
|
10968
11310
|
async function getInteropRoot(provider, rootChainId, batchNumber) {
|
|
10969
|
-
return await
|
|
11311
|
+
return await wrap4(
|
|
10970
11312
|
OP_INTEROP.svc.status.getRoot,
|
|
10971
11313
|
async () => {
|
|
10972
11314
|
const rootStorage = new ethers.Contract(
|
|
@@ -10984,7 +11326,7 @@ async function getInteropRoot(provider, rootChainId, batchNumber) {
|
|
|
10984
11326
|
}
|
|
10985
11327
|
|
|
10986
11328
|
// src/adapters/ethers/resources/interop/services/finalization/bundle.ts
|
|
10987
|
-
var { wrap:
|
|
11329
|
+
var { wrap: wrap5 } = createErrorHandlers("interop");
|
|
10988
11330
|
async function getBundleStatus(client, dstProvider, topics, bundleHash, opts) {
|
|
10989
11331
|
const { interopHandler } = await client.ensureAddresses();
|
|
10990
11332
|
const bundleLogs = await getLogs(dstProvider, interopHandler, [null, bundleHash], opts);
|
|
@@ -11016,7 +11358,7 @@ async function executeBundle(client, dstProvider, info, opts) {
|
|
|
11016
11358
|
context: { bundleHash }
|
|
11017
11359
|
});
|
|
11018
11360
|
}
|
|
11019
|
-
const signer = await
|
|
11361
|
+
const signer = await wrap5(OP_INTEROP.exec.sendStep, () => client.signerFor(dstProvider), {
|
|
11020
11362
|
message: "Failed to resolve destination signer."
|
|
11021
11363
|
});
|
|
11022
11364
|
const { interopHandler } = await client.ensureAddresses();
|
|
@@ -11178,11 +11520,6 @@ function getBundleEncodedData(messageData) {
|
|
|
11178
11520
|
return `0x${messageData.slice(4)}`;
|
|
11179
11521
|
}
|
|
11180
11522
|
function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
|
|
11181
|
-
const expectedRoot = {
|
|
11182
|
-
rootChainId: bundleInfo.sourceChainId,
|
|
11183
|
-
batchNumber: proof.batchNumber,
|
|
11184
|
-
expectedRoot: proof.root
|
|
11185
|
-
};
|
|
11186
11523
|
const messageProof = {
|
|
11187
11524
|
chainId: bundleInfo.sourceChainId,
|
|
11188
11525
|
l1BatchNumber: proof.batchNumber,
|
|
@@ -11198,7 +11535,6 @@ function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
|
|
|
11198
11535
|
l2SrcTxHash: ids.l2SrcTxHash,
|
|
11199
11536
|
bundleHash: bundleInfo.bundleHash,
|
|
11200
11537
|
dstChainId: bundleInfo.dstChainId,
|
|
11201
|
-
expectedRoot,
|
|
11202
11538
|
proof: messageProof,
|
|
11203
11539
|
encodedData: getBundleEncodedData(messageData)
|
|
11204
11540
|
};
|
|
@@ -11221,7 +11557,7 @@ function decodeL1MessageData(log) {
|
|
|
11221
11557
|
}
|
|
11222
11558
|
|
|
11223
11559
|
// src/adapters/ethers/resources/interop/services/finalization/polling.ts
|
|
11224
|
-
var { wrap:
|
|
11560
|
+
var { wrap: wrap6 } = createErrorHandlers("interop");
|
|
11225
11561
|
function isProofNotReadyError(error) {
|
|
11226
11562
|
return isZKsyncError(error, {
|
|
11227
11563
|
operation: "zksrpc.getL2ToL1LogProof",
|
|
@@ -11258,30 +11594,26 @@ async function waitForProof(client, l2SrcTxHash, logIndex, blockNumber, pollMs,
|
|
|
11258
11594
|
});
|
|
11259
11595
|
}
|
|
11260
11596
|
try {
|
|
11261
|
-
return await client.zks.getL2ToL1LogProof(l2SrcTxHash, logIndex);
|
|
11597
|
+
return await client.zks.getL2ToL1LogProof(l2SrcTxHash, logIndex, "messageRoot" /* MessageRoot */);
|
|
11262
11598
|
} catch (error) {
|
|
11263
11599
|
if (!isProofNotReadyError(error)) throw error;
|
|
11264
11600
|
}
|
|
11265
11601
|
await sleep(pollMs);
|
|
11266
11602
|
}
|
|
11267
11603
|
}
|
|
11268
|
-
async function waitForRoot(provider,
|
|
11604
|
+
async function waitForRoot(provider, chainId, batchNumber, pollMs, deadline) {
|
|
11269
11605
|
while (true) {
|
|
11270
11606
|
if (Date.now() > deadline) {
|
|
11271
11607
|
throw createError("TIMEOUT", {
|
|
11272
11608
|
resource: "interop",
|
|
11273
11609
|
operation: OP_INTEROP.svc.wait.timeout,
|
|
11274
11610
|
message: "Timed out waiting for interop root to become available.",
|
|
11275
|
-
context: {
|
|
11611
|
+
context: { chainId, batchNumber }
|
|
11276
11612
|
});
|
|
11277
11613
|
}
|
|
11278
11614
|
let interopRoot = null;
|
|
11279
11615
|
try {
|
|
11280
|
-
const root = await getInteropRoot(
|
|
11281
|
-
provider,
|
|
11282
|
-
expectedRoot.rootChainId,
|
|
11283
|
-
expectedRoot.batchNumber
|
|
11284
|
-
);
|
|
11616
|
+
const root = await getInteropRoot(provider, chainId, batchNumber);
|
|
11285
11617
|
if (root !== ZERO_HASH) {
|
|
11286
11618
|
interopRoot = root;
|
|
11287
11619
|
}
|
|
@@ -11290,18 +11622,7 @@ async function waitForRoot(provider, expectedRoot, pollMs, deadline) {
|
|
|
11290
11622
|
interopRoot = null;
|
|
11291
11623
|
}
|
|
11292
11624
|
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
|
-
});
|
|
11625
|
+
return interopRoot;
|
|
11305
11626
|
}
|
|
11306
11627
|
await sleep(pollMs);
|
|
11307
11628
|
}
|
|
@@ -11316,7 +11637,7 @@ async function waitForTxReceipt(client, txHash, pollMs, deadline) {
|
|
|
11316
11637
|
context: { txHash }
|
|
11317
11638
|
});
|
|
11318
11639
|
}
|
|
11319
|
-
const receipt = await
|
|
11640
|
+
const receipt = await wrap6(
|
|
11320
11641
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
11321
11642
|
() => client.zks.getReceiptWithL2ToL1(txHash),
|
|
11322
11643
|
{
|
|
@@ -11330,7 +11651,7 @@ async function waitForTxReceipt(client, txHash, pollMs, deadline) {
|
|
|
11330
11651
|
await sleep(pollMs);
|
|
11331
11652
|
}
|
|
11332
11653
|
}
|
|
11333
|
-
async function waitForFinalization(client, dstProvider, input, opts) {
|
|
11654
|
+
async function waitForFinalization(client, dstProvider, gwProvider, input, opts) {
|
|
11334
11655
|
const { topics, centerIface } = getTopics();
|
|
11335
11656
|
const pollMs = opts?.pollMs ?? DEFAULT_POLL_MS;
|
|
11336
11657
|
const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -11379,7 +11700,16 @@ async function waitForFinalization(client, dstProvider, input, opts) {
|
|
|
11379
11700
|
proof,
|
|
11380
11701
|
bundleInfo.l1MessageData
|
|
11381
11702
|
);
|
|
11382
|
-
|
|
11703
|
+
if (proof.gatewayBlockNumber == null) {
|
|
11704
|
+
throw createError("STATE", {
|
|
11705
|
+
resource: "interop",
|
|
11706
|
+
operation: OP_INTEROP.svc.wait.timeout,
|
|
11707
|
+
message: "Proof missing gatewayBlockNumber required for interop finalization.",
|
|
11708
|
+
context: { l2SrcTxHash: ids.l2SrcTxHash }
|
|
11709
|
+
});
|
|
11710
|
+
}
|
|
11711
|
+
const { chainId: gwChainId } = await gwProvider.getNetwork();
|
|
11712
|
+
await waitForRoot(dstProvider, gwChainId, proof.gatewayBlockNumber, pollMs, deadline);
|
|
11383
11713
|
return finalizationInfo;
|
|
11384
11714
|
}
|
|
11385
11715
|
|
|
@@ -11425,8 +11755,8 @@ function createInteropFinalizationServices(client) {
|
|
|
11425
11755
|
status(dstProvider, input, opts) {
|
|
11426
11756
|
return getStatus(client, dstProvider, input, opts);
|
|
11427
11757
|
},
|
|
11428
|
-
wait(dstProvider, input, opts) {
|
|
11429
|
-
return waitForFinalization(client, dstProvider, input, opts);
|
|
11758
|
+
wait(dstProvider, gwProvider, input, opts) {
|
|
11759
|
+
return waitForFinalization(client, dstProvider, gwProvider, input, opts);
|
|
11430
11760
|
},
|
|
11431
11761
|
async finalize(dstProvider, info, opts) {
|
|
11432
11762
|
const execResult = await executeBundle(client, dstProvider, info, opts);
|
|
@@ -11438,24 +11768,56 @@ function createInteropFinalizationServices(client) {
|
|
|
11438
11768
|
}
|
|
11439
11769
|
};
|
|
11440
11770
|
}
|
|
11441
|
-
function
|
|
11442
|
-
return typeof
|
|
11771
|
+
function resolveChainRef(ref) {
|
|
11772
|
+
return typeof ref === "string" ? new ethers.JsonRpcProvider(ref) : ref;
|
|
11443
11773
|
}
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
|
|
11449
|
-
|
|
11774
|
+
|
|
11775
|
+
// src/adapters/ethers/resources/interop/services/gas.ts
|
|
11776
|
+
async function quoteStepsL2Fee(steps, ctx) {
|
|
11777
|
+
if (steps.length === 0) return 0n;
|
|
11778
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
11779
|
+
let maxFeePerGas;
|
|
11780
|
+
try {
|
|
11781
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
11782
|
+
maxFeePerGas = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
|
|
11783
|
+
} catch {
|
|
11784
|
+
return void 0;
|
|
11785
|
+
}
|
|
11786
|
+
let total = 0n;
|
|
11787
|
+
for (const step of steps) {
|
|
11788
|
+
try {
|
|
11789
|
+
const coreTx = toCoreTx({ ...step.tx, from: ctx.sender });
|
|
11790
|
+
const est = await estimator.estimateGas(coreTx);
|
|
11791
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
11792
|
+
total += buffered * maxFeePerGas;
|
|
11793
|
+
} catch {
|
|
11794
|
+
return void 0;
|
|
11795
|
+
}
|
|
11796
|
+
}
|
|
11797
|
+
return total;
|
|
11450
11798
|
}
|
|
11451
11799
|
|
|
11452
11800
|
// src/adapters/ethers/resources/interop/index.ts
|
|
11453
|
-
var { wrap:
|
|
11801
|
+
var { wrap: wrap7, toResult: toResult2 } = createErrorHandlers("interop");
|
|
11454
11802
|
var ROUTES3 = {
|
|
11455
11803
|
direct: routeDirect(),
|
|
11456
11804
|
indirect: routeIndirect()
|
|
11457
11805
|
};
|
|
11458
|
-
function createInteropResource(client, tokens, contracts, attributes) {
|
|
11806
|
+
function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
11807
|
+
let gwProviderCache;
|
|
11808
|
+
function requireConfig() {
|
|
11809
|
+
if (!config)
|
|
11810
|
+
throw createError("STATE", {
|
|
11811
|
+
resource: "interop",
|
|
11812
|
+
operation: "interop.init",
|
|
11813
|
+
message: "Interop is not configured. Pass gwChain in createEthersSdk options."
|
|
11814
|
+
});
|
|
11815
|
+
return config;
|
|
11816
|
+
}
|
|
11817
|
+
function getGwProvider() {
|
|
11818
|
+
if (!gwProviderCache) gwProviderCache = resolveChainRef(requireConfig().gwChain);
|
|
11819
|
+
return gwProviderCache;
|
|
11820
|
+
}
|
|
11459
11821
|
const svc = createInteropFinalizationServices(client);
|
|
11460
11822
|
const tokensResource = tokens ?? createTokensResource(client);
|
|
11461
11823
|
const contractsResource = contracts ?? createContractsResource(client);
|
|
@@ -11479,11 +11841,11 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11479
11841
|
baseTokenDst: ctx.baseTokens.dst
|
|
11480
11842
|
}
|
|
11481
11843
|
});
|
|
11482
|
-
await
|
|
11844
|
+
await wrap7(OP_INTEROP.routes[route].preflight, () => ROUTES3[route].preflight?.(params, ctx), {
|
|
11483
11845
|
message: "Interop preflight failed.",
|
|
11484
11846
|
ctx: { where: `routes.${route}.preflight` }
|
|
11485
11847
|
});
|
|
11486
|
-
const { steps, approvals, quoteExtras } = await
|
|
11848
|
+
const { steps, approvals, quoteExtras, interopFee } = await wrap7(
|
|
11487
11849
|
OP_INTEROP.routes[route].build,
|
|
11488
11850
|
() => ROUTES3[route].build(params, ctx),
|
|
11489
11851
|
{
|
|
@@ -11491,11 +11853,14 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11491
11853
|
ctx: { where: `routes.${route}.build` }
|
|
11492
11854
|
}
|
|
11493
11855
|
);
|
|
11856
|
+
const l2Fee = await quoteStepsL2Fee(steps, ctx).catch(() => void 0);
|
|
11494
11857
|
const summary = {
|
|
11495
11858
|
route,
|
|
11496
11859
|
approvalsNeeded: approvals,
|
|
11497
11860
|
totalActionValue: quoteExtras.totalActionValue,
|
|
11498
|
-
bridgedTokenTotal: quoteExtras.bridgedTokenTotal
|
|
11861
|
+
bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
|
|
11862
|
+
interopFee,
|
|
11863
|
+
l2Fee
|
|
11499
11864
|
};
|
|
11500
11865
|
return { plan: { route, summary, steps }, ctx };
|
|
11501
11866
|
}
|
|
@@ -11503,20 +11868,23 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11503
11868
|
const { plan } = await buildPlanWithCtx(dstProvider, params);
|
|
11504
11869
|
return plan;
|
|
11505
11870
|
}
|
|
11506
|
-
const quote = (params) =>
|
|
11507
|
-
const plan = await buildPlan(
|
|
11871
|
+
const quote = (dstChain, params) => wrap7(OP_INTEROP.quote, async () => {
|
|
11872
|
+
const plan = await buildPlan(resolveChainRef(dstChain), params);
|
|
11508
11873
|
return plan.summary;
|
|
11509
11874
|
});
|
|
11510
|
-
const tryQuote = (params) => toResult2(OP_INTEROP.tryQuote, () => quote(params));
|
|
11511
|
-
const prepare = (params) =>
|
|
11875
|
+
const tryQuote = (dstChain, params) => toResult2(OP_INTEROP.tryQuote, () => quote(dstChain, params));
|
|
11876
|
+
const prepare = (dstChain, params) => wrap7(OP_INTEROP.prepare, () => buildPlan(resolveChainRef(dstChain), params), {
|
|
11512
11877
|
message: "Internal error while preparing an interop plan.",
|
|
11513
11878
|
ctx: { where: "interop.prepare" }
|
|
11514
11879
|
});
|
|
11515
|
-
const tryPrepare = (params) => toResult2(
|
|
11516
|
-
|
|
11880
|
+
const tryPrepare = (dstChain, params) => toResult2(
|
|
11881
|
+
OP_INTEROP.tryPrepare,
|
|
11882
|
+
() => prepare(dstChain, params)
|
|
11883
|
+
);
|
|
11884
|
+
const create = (dstChain, params) => wrap7(
|
|
11517
11885
|
OP_INTEROP.create,
|
|
11518
11886
|
async () => {
|
|
11519
|
-
const { plan, ctx } = await buildPlanWithCtx(
|
|
11887
|
+
const { plan, ctx } = await buildPlanWithCtx(resolveChainRef(dstChain), params);
|
|
11520
11888
|
const signer = ctx.client.signerFor(ctx.client.l2);
|
|
11521
11889
|
const srcProvider = ctx.client.l2;
|
|
11522
11890
|
const from = await signer.getAddress();
|
|
@@ -11578,7 +11946,6 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11578
11946
|
const last = Object.values(stepHashes).pop();
|
|
11579
11947
|
return {
|
|
11580
11948
|
kind: "interop",
|
|
11581
|
-
dstChain: params.dstChain,
|
|
11582
11949
|
stepHashes,
|
|
11583
11950
|
plan,
|
|
11584
11951
|
l2SrcTxHash: last ?? "0x"
|
|
@@ -11589,46 +11956,27 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11589
11956
|
ctx: { where: "interop.create" }
|
|
11590
11957
|
}
|
|
11591
11958
|
);
|
|
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(
|
|
11959
|
+
const tryCreate = (dstChain, params) => toResult2(
|
|
11960
|
+
OP_INTEROP.tryCreate,
|
|
11961
|
+
() => create(dstChain, params)
|
|
11962
|
+
);
|
|
11963
|
+
const status = (dstChain, h, opts) => wrap7(OP_INTEROP.status, () => svc.status(resolveChainRef(dstChain), h, opts), {
|
|
11964
|
+
message: "Internal error while checking interop status.",
|
|
11965
|
+
ctx: { where: "interop.status" }
|
|
11966
|
+
});
|
|
11967
|
+
const wait = (dstChain, h, opts) => wrap7(OP_INTEROP.wait, () => svc.wait(resolveChainRef(dstChain), getGwProvider(), h, opts), {
|
|
11968
|
+
message: "Internal error while waiting for interop finalization.",
|
|
11969
|
+
ctx: { where: "interop.wait" }
|
|
11970
|
+
});
|
|
11971
|
+
const tryWait = (dstChain, h, opts) => toResult2(OP_INTEROP.tryWait, () => wait(dstChain, h, opts));
|
|
11972
|
+
const finalize = (dstChain, h, opts) => wrap7(
|
|
11616
11973
|
OP_INTEROP.finalize,
|
|
11617
11974
|
async () => {
|
|
11975
|
+
const dstProvider = resolveChainRef(dstChain);
|
|
11618
11976
|
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);
|
|
11977
|
+
return svc.finalize(dstProvider, h, opts);
|
|
11629
11978
|
}
|
|
11630
|
-
const
|
|
11631
|
-
const info = await svc.wait(dstProvider, waitable);
|
|
11979
|
+
const info = await svc.wait(dstProvider, getGwProvider(), h);
|
|
11632
11980
|
return svc.finalize(dstProvider, info, opts);
|
|
11633
11981
|
},
|
|
11634
11982
|
{
|
|
@@ -11636,7 +11984,7 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11636
11984
|
ctx: { where: "interop.finalize" }
|
|
11637
11985
|
}
|
|
11638
11986
|
);
|
|
11639
|
-
const tryFinalize = (h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(h, opts));
|
|
11987
|
+
const tryFinalize = (dstChain, h, opts) => toResult2(OP_INTEROP.tryFinalize, () => finalize(dstChain, h, opts));
|
|
11640
11988
|
return {
|
|
11641
11989
|
quote,
|
|
11642
11990
|
tryQuote,
|
|
@@ -11653,10 +12001,10 @@ function createInteropResource(client, tokens, contracts, attributes) {
|
|
|
11653
12001
|
}
|
|
11654
12002
|
|
|
11655
12003
|
// src/adapters/ethers/sdk.ts
|
|
11656
|
-
function createEthersSdk(client) {
|
|
12004
|
+
function createEthersSdk(client, options) {
|
|
11657
12005
|
const tokens = createTokensResource(client);
|
|
11658
12006
|
const contracts = createContractsResource(client);
|
|
11659
|
-
const interop = createInteropResource(client);
|
|
12007
|
+
const interop = createInteropResource(client, options?.interop, tokens, contracts);
|
|
11660
12008
|
return {
|
|
11661
12009
|
deposits: createDepositsResource(client, tokens, contracts),
|
|
11662
12010
|
withdrawals: createWithdrawalsResource(client, tokens, contracts),
|