@matterlabs/zksync-js 0.0.14 → 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.map +1 -1
- package/dist/adapters/ethers/client.d.ts +1 -2
- package/dist/adapters/ethers/client.js +4 -5
- package/dist/adapters/ethers/index.cjs +117 -28
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.js +6 -7
- package/dist/adapters/ethers/resources/interop/services/gas.d.ts +12 -0
- package/dist/adapters/ethers/sdk.cjs +117 -28
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.js +5 -6
- package/dist/adapters/viem/client.cjs +787 -3
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.d.ts +6 -1
- package/dist/adapters/viem/client.js +4 -5
- package/dist/adapters/viem/index.cjs +6463 -3014
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.d.ts +5 -0
- package/dist/adapters/viem/index.js +6 -7
- package/dist/adapters/viem/resources/interop/address.d.ts +18 -0
- package/dist/adapters/viem/resources/interop/attributes/resource.d.ts +6 -0
- package/dist/adapters/viem/resources/interop/context.d.ts +31 -0
- package/dist/adapters/viem/resources/interop/index.d.ts +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 +6608 -3203
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +8 -1
- package/dist/adapters/viem/sdk.js +5 -5
- package/dist/{chunk-75IOOODG.js → chunk-4PZCNTQ3.js} +1142 -26
- package/dist/{chunk-5RRJDPAJ.js → chunk-65HAYKVL.js} +2 -2
- package/dist/{chunk-XKRNLFET.js → chunk-HGB3DOV2.js} +73 -376
- package/dist/{chunk-J47RI3G7.js → chunk-HVHMLAYH.js} +1 -1
- package/dist/{chunk-OTXPSNNC.js → chunk-JHRYNLZG.js} +64 -7
- package/dist/{chunk-JY62QO3W.js → chunk-JXR5V5YK.js} +419 -6
- package/dist/chunk-K2UVKMLN.js +658 -0
- package/dist/{chunk-HP3EWKJL.js → chunk-MDPX5LNW.js} +1 -1
- package/dist/{chunk-7CAVFIMW.js → chunk-MZBKM3GH.js} +2 -3
- package/dist/{chunk-XDRCN4FC.js → chunk-YIWXIP2M.js} +10 -2
- package/dist/core/index.js +2 -3
- package/dist/core/resources/deposits/chains.d.ts +1 -0
- package/dist/core/resources/deposits/gas.d.ts +7 -0
- package/dist/core/resources/deposits/priority.d.ts +4 -0
- package/dist/core/resources/interop/protocol.d.ts +3 -0
- package/dist/core/types/flows/interop.d.ts +0 -2
- package/dist/core/types/primitives.d.ts +2 -0
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/dist/chunk-DYJKK5FW.js +0 -417
- package/dist/chunk-EOBXYHTZ.js +0 -265
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createErrorOps, REVERT_TO_READINESS } from './chunk-
|
|
2
|
-
import { IL1Nullifier_default, IERC20_default, L1NativeTokenVault_default, L2NativeTokenVault_default, Mailbox_default, IL1ContractErrors_default, IInteropErrors_default } from './chunk-
|
|
1
|
+
import { createErrorOps, REVERT_TO_READINESS } from './chunk-MDPX5LNW.js';
|
|
2
|
+
import { IL1Nullifier_default, IERC20_default, L1NativeTokenVault_default, L2NativeTokenVault_default, Mailbox_default, IL1ContractErrors_default, IInteropErrors_default } from './chunk-JXR5V5YK.js';
|
|
3
3
|
import { Interface } from 'ethers';
|
|
4
4
|
|
|
5
5
|
var ERROR_IFACES = [];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createErrorHandlers, toZKsyncError, classifyReadinessFromRevert } from './chunk-
|
|
2
|
-
import { createNTVCodec, toGasOverrides, buildFeeBreakdown, derivePriorityTxGasBreakdown, quoteL2Gas, quoteL2BaseCost, quoteL1Gas, derivePriorityBodyGasEstimateCap, quoteL2Gas2 } from './chunk-
|
|
3
|
-
import { findL1MessageSentLog, messengerLogIndex,
|
|
4
|
-
import { isHash66, IL1Nullifier_default, OP_WITHDRAWALS, createError, normalizeL1Token, isAddressEq, hexEq, OP_DEPOSITS, IERC20_default, isZKsyncError, isReceiptNotFound, OP_INTEROP, IInteropHandler_default, IERC7786Attributes_default,
|
|
5
|
-
import { ETH_ADDRESS, TOPIC_CANONICAL_ASSIGNED, TOPIC_CANONICAL_SUCCESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
6
|
-
import { Interface, keccak256, AbiCoder, ethers, getBytes, Contract, NonceManager, JsonRpcProvider,
|
|
1
|
+
import { createErrorHandlers, toZKsyncError, classifyReadinessFromRevert } from './chunk-65HAYKVL.js';
|
|
2
|
+
import { createNTVCodec, resolveCreateDepositL1GasLimit, isInteropFinalizationInfo, DEFAULT_POLL_MS, DEFAULT_TIMEOUT_MS, resolveIdsFromWaitable, parseBundleReceiptInfo, buildFinalizationInfo, parseBundleSentFromReceipt, createAttributesResource, pickInteropRoute, ZERO_HASH, toGasOverrides, applyPriorityL2GasLimitBuffer, buildFeeBreakdown, buildIndirectBundle, preflightIndirect, buildDirectBundle, preflightDirect, derivePriorityTxGasBreakdown, quoteL2Gas, quoteL2BaseCost, quoteL1Gas, derivePriorityBodyGasEstimateCap, quoteL2Gas2, assertProtocolVersion } from './chunk-K2UVKMLN.js';
|
|
3
|
+
import { findL1MessageSentLog, messengerLogIndex, pickWithdrawRoute } from './chunk-3HHUZXSV.js';
|
|
4
|
+
import { isHash66, IL1Nullifier_default, OP_WITHDRAWALS, createError, normalizeL1Token, isAddressEq, hexEq, OP_DEPOSITS, IERC20_default, isZKsyncError, isReceiptNotFound, OP_INTEROP, IInteropHandler_default, IERC7786Attributes_default, IInteropCenter_default, sleep, isETH, normalizeAddrEq, IInteropRootStorage_default, IL2AssetRouter_default, L2NativeTokenVault_default, assertNever } from './chunk-JXR5V5YK.js';
|
|
5
|
+
import { ETH_ADDRESS, TOPIC_CANONICAL_ASSIGNED, TOPIC_CANONICAL_SUCCESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS, BUFFER, L2_INTEROP_ROOT_STORAGE_ADDRESS, SAFE_L1_BRIDGE_GAS, L2_ASSET_ROUTER_ADDRESS, FORMAL_ETH_ADDRESS } from './chunk-MT4X5FEO.js';
|
|
6
|
+
import { Interface, keccak256, AbiCoder, ethers, getBytes, Contract, NonceManager, JsonRpcProvider, getAddress, concat, hexlify, toBeArray, toBeHex, isError } from 'ethers';
|
|
7
7
|
|
|
8
8
|
var I_BRIDGEHUB = new Interface([
|
|
9
9
|
"event NewPriorityRequest(uint256 indexed chainId, address indexed sender, bytes32 txHash, uint256 txId, bytes data)"
|
|
@@ -388,7 +388,10 @@ function routeEthDirect() {
|
|
|
388
388
|
l2Calldata,
|
|
389
389
|
gasPerPubdata: ctx.gasPerPubdata
|
|
390
390
|
});
|
|
391
|
-
const quotedL2GasLimit = ctx.l2GasLimit ??
|
|
391
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
392
|
+
chainIdL2: ctx.chainIdL2,
|
|
393
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
394
|
+
});
|
|
392
395
|
const l2GasParams = await quoteL2Gas3({
|
|
393
396
|
ctx,
|
|
394
397
|
route: "eth-base",
|
|
@@ -450,11 +453,6 @@ function routeEthDirect() {
|
|
|
450
453
|
}
|
|
451
454
|
};
|
|
452
455
|
}
|
|
453
|
-
|
|
454
|
-
// src/core/types/primitives.ts
|
|
455
|
-
var ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
456
|
-
|
|
457
|
-
// src/adapters/ethers/resources/deposits/routes/erc20-nonbase.ts
|
|
458
456
|
var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
|
|
459
457
|
var ZERO_L2_TOKEN_ADDRESS2 = "0x0000000000000000000000000000000000000000";
|
|
460
458
|
var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
@@ -491,7 +489,10 @@ async function getPriorityGasModel(input) {
|
|
|
491
489
|
gasPerPubdata: input.ctx.gasPerPubdata
|
|
492
490
|
});
|
|
493
491
|
const model = {
|
|
494
|
-
priorityFloorGasLimit:
|
|
492
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
493
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
494
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
495
|
+
})
|
|
495
496
|
};
|
|
496
497
|
if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS2) {
|
|
497
498
|
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
@@ -697,7 +698,10 @@ async function getPriorityGasModel2(input) {
|
|
|
697
698
|
gasPerPubdata: input.ctx.gasPerPubdata
|
|
698
699
|
});
|
|
699
700
|
const model = {
|
|
700
|
-
priorityFloorGasLimit:
|
|
701
|
+
priorityFloorGasLimit: applyPriorityL2GasLimitBuffer({
|
|
702
|
+
chainIdL2: input.ctx.chainIdL2,
|
|
703
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
704
|
+
})
|
|
701
705
|
};
|
|
702
706
|
if (input.ctx.resolvedToken.l2.toLowerCase() === ZERO_L2_TOKEN_ADDRESS3) {
|
|
703
707
|
model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
|
|
@@ -914,7 +918,10 @@ function routeErc20Base() {
|
|
|
914
918
|
l2Calldata,
|
|
915
919
|
gasPerPubdata: ctx.gasPerPubdata
|
|
916
920
|
});
|
|
917
|
-
const quotedL2GasLimit = ctx.l2GasLimit ??
|
|
921
|
+
const quotedL2GasLimit = ctx.l2GasLimit ?? applyPriorityL2GasLimitBuffer({
|
|
922
|
+
chainIdL2: ctx.chainIdL2,
|
|
923
|
+
gasLimit: priorityFloorBreakdown.derivedL2GasLimit
|
|
924
|
+
});
|
|
918
925
|
const l2GasParams = await quoteL2Gas3({
|
|
919
926
|
ctx,
|
|
920
927
|
route: "erc20-base",
|
|
@@ -1340,6 +1347,8 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
1340
1347
|
async () => {
|
|
1341
1348
|
const plan = await prepare(p);
|
|
1342
1349
|
const stepHashes = {};
|
|
1350
|
+
const { chainId } = await client.l2.getNetwork();
|
|
1351
|
+
const chainIdL2 = BigInt(chainId);
|
|
1343
1352
|
const managed = new NonceManager(client.signer);
|
|
1344
1353
|
const from = await managed.getAddress();
|
|
1345
1354
|
let next;
|
|
@@ -1385,8 +1394,14 @@ function createDepositsResource(client, tokens, contracts) {
|
|
|
1385
1394
|
}
|
|
1386
1395
|
if (!p.l1TxOverrides?.gasLimit) {
|
|
1387
1396
|
try {
|
|
1397
|
+
const preparedGasLimit = step.tx.gasLimit != null ? BigInt(step.tx.gasLimit.toString()) : void 0;
|
|
1388
1398
|
const est = await client.l1.estimateGas(step.tx);
|
|
1389
|
-
step.tx.gasLimit =
|
|
1399
|
+
step.tx.gasLimit = resolveCreateDepositL1GasLimit({
|
|
1400
|
+
chainIdL2,
|
|
1401
|
+
stepKey: step.key,
|
|
1402
|
+
preparedGasLimit,
|
|
1403
|
+
estimatedGasLimit: BigInt(est)
|
|
1404
|
+
});
|
|
1390
1405
|
} catch {
|
|
1391
1406
|
}
|
|
1392
1407
|
}
|
|
@@ -2374,38 +2389,6 @@ function createWithdrawalsResource(client, tokens, contracts) {
|
|
|
2374
2389
|
tryWait
|
|
2375
2390
|
};
|
|
2376
2391
|
}
|
|
2377
|
-
|
|
2378
|
-
// src/core/resources/interop/attributes/call.ts
|
|
2379
|
-
function createCallAttributes(codec) {
|
|
2380
|
-
const indirectCall = (messageValue) => codec.encode("indirectCall", [messageValue]);
|
|
2381
|
-
const interopCallValue = (bridgedAmount) => codec.encode("interopCallValue", [bridgedAmount]);
|
|
2382
|
-
return {
|
|
2383
|
-
indirectCall,
|
|
2384
|
-
interopCallValue
|
|
2385
|
-
};
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
// src/core/resources/interop/attributes/bundle.ts
|
|
2389
|
-
function createBundleAttributes(codec) {
|
|
2390
|
-
const executionAddress = (executor) => codec.encode("executionAddress", [executor]);
|
|
2391
|
-
const unbundlerAddress = (addr) => codec.encode("unbundlerAddress", [addr]);
|
|
2392
|
-
const useFixedFee = (enabled) => codec.encode("useFixedFee", [enabled]);
|
|
2393
|
-
return {
|
|
2394
|
-
executionAddress,
|
|
2395
|
-
unbundlerAddress,
|
|
2396
|
-
useFixedFee
|
|
2397
|
-
};
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
|
-
// src/core/resources/interop/attributes/resource.ts
|
|
2401
|
-
function createAttributesResource(codec) {
|
|
2402
|
-
return {
|
|
2403
|
-
call: createCallAttributes(codec),
|
|
2404
|
-
bundle: createBundleAttributes(codec)
|
|
2405
|
-
};
|
|
2406
|
-
}
|
|
2407
|
-
|
|
2408
|
-
// src/adapters/ethers/resources/interop/attributes/resource.ts
|
|
2409
2392
|
function getInteropAttributes(params, ctx) {
|
|
2410
2393
|
const bundleAttributes = [];
|
|
2411
2394
|
if (params.execution?.only) {
|
|
@@ -2442,183 +2425,6 @@ function createEthersAttributesResource(opts = {}) {
|
|
|
2442
2425
|
const encode2 = (fn, args) => iface.encodeFunctionData(fn, args);
|
|
2443
2426
|
return createAttributesResource({ encode: encode2 });
|
|
2444
2427
|
}
|
|
2445
|
-
|
|
2446
|
-
// src/core/types/flows/interop.ts
|
|
2447
|
-
function isInteropMessageProof(obj) {
|
|
2448
|
-
if (typeof obj !== "object" || obj === null) return false;
|
|
2449
|
-
const proof = obj;
|
|
2450
|
-
return isBigint(proof.chainId) && isBigint(proof.l1BatchNumber) && isBigint(proof.l2MessageIndex) && typeof proof.message === "object" && proof.message !== null && isNumber(proof.message.txNumberInBatch) && isAddress(proof.message.sender) && isHash(proof.message.data) && isHash66Array(proof.proof);
|
|
2451
|
-
}
|
|
2452
|
-
function isInteropFinalizationInfo(obj) {
|
|
2453
|
-
if (typeof obj !== "object" || obj === null) return false;
|
|
2454
|
-
const info = obj;
|
|
2455
|
-
return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) && isInteropMessageProof(info.proof);
|
|
2456
|
-
}
|
|
2457
|
-
|
|
2458
|
-
// src/core/resources/interop/route.ts
|
|
2459
|
-
function sumActionMsgValue(actions) {
|
|
2460
|
-
let sum = 0n;
|
|
2461
|
-
for (const a of actions) {
|
|
2462
|
-
if (a.type === "sendNative") sum += a.amount;
|
|
2463
|
-
else if (a.type === "call" && a.value) sum += a.value;
|
|
2464
|
-
}
|
|
2465
|
-
return sum;
|
|
2466
|
-
}
|
|
2467
|
-
function sumErc20Amounts(actions) {
|
|
2468
|
-
let sum = 0n;
|
|
2469
|
-
for (const a of actions) if (a.type === "sendErc20") sum += a.amount;
|
|
2470
|
-
return sum;
|
|
2471
|
-
}
|
|
2472
|
-
function pickInteropRoute(args) {
|
|
2473
|
-
const hasErc20 = args.actions.some((a) => a.type === "sendErc20");
|
|
2474
|
-
const baseMatches = args.ctx.baseTokenSrc.toLowerCase() === args.ctx.baseTokenDst.toLowerCase();
|
|
2475
|
-
if (hasErc20) return "indirect";
|
|
2476
|
-
if (!baseMatches) return "indirect";
|
|
2477
|
-
return "direct";
|
|
2478
|
-
}
|
|
2479
|
-
|
|
2480
|
-
// src/core/resources/interop/plan.ts
|
|
2481
|
-
function preflightDirect(params, ctx) {
|
|
2482
|
-
if (!params.actions?.length) {
|
|
2483
|
-
throw new Error('route "direct" requires at least one action.');
|
|
2484
|
-
}
|
|
2485
|
-
const baseMatch = ctx.baseTokens.src.toLowerCase() === ctx.baseTokens.dst.toLowerCase();
|
|
2486
|
-
if (!baseMatch) {
|
|
2487
|
-
throw new Error('route "direct" requires matching base tokens between source and destination.');
|
|
2488
|
-
}
|
|
2489
|
-
for (const action of params.actions) {
|
|
2490
|
-
switch (action.type) {
|
|
2491
|
-
case "sendNative":
|
|
2492
|
-
if (action.amount < 0n) {
|
|
2493
|
-
throw new Error("sendNative.amount must be >= 0.");
|
|
2494
|
-
}
|
|
2495
|
-
break;
|
|
2496
|
-
case "call":
|
|
2497
|
-
if (action.value != null && action.value < 0n) {
|
|
2498
|
-
throw new Error("call.value must be >= 0 when provided.");
|
|
2499
|
-
}
|
|
2500
|
-
break;
|
|
2501
|
-
default:
|
|
2502
|
-
throw new Error(
|
|
2503
|
-
`route "direct" does not support ${action.type} actions; use the indirect route.`
|
|
2504
|
-
);
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
|
-
function buildDirectBundle(params, ctx, attrs, interopFeeInfo) {
|
|
2509
|
-
const totalActionValue = sumActionMsgValue(params.actions);
|
|
2510
|
-
const starters = params.actions.map((action, index) => {
|
|
2511
|
-
const to = ctx.codec.formatAddress(action.to);
|
|
2512
|
-
const callAttributes = attrs.callAttributes[index] ?? [];
|
|
2513
|
-
switch (action.type) {
|
|
2514
|
-
case "sendNative":
|
|
2515
|
-
return [to, "0x", callAttributes];
|
|
2516
|
-
case "call":
|
|
2517
|
-
return [to, action.data ?? "0x", callAttributes];
|
|
2518
|
-
default:
|
|
2519
|
-
throw new Error(`buildDirectBundle: unsupported action type "${action.type}".`);
|
|
2520
|
-
}
|
|
2521
|
-
});
|
|
2522
|
-
return {
|
|
2523
|
-
dstChain: ctx.codec.formatChain(ctx.dstChainId),
|
|
2524
|
-
starters,
|
|
2525
|
-
bundleAttributes: attrs.bundleAttributes,
|
|
2526
|
-
approvals: interopFeeInfo.approval ? [interopFeeInfo.approval] : [],
|
|
2527
|
-
interopFee: interopFeeInfo.fee,
|
|
2528
|
-
quoteExtras: {
|
|
2529
|
-
totalActionValue,
|
|
2530
|
-
bridgedTokenTotal: 0n
|
|
2531
|
-
}
|
|
2532
|
-
};
|
|
2533
|
-
}
|
|
2534
|
-
function preflightIndirect(params, ctx) {
|
|
2535
|
-
if (!params.actions?.length) {
|
|
2536
|
-
throw new Error('route "indirect" requires at least one action.');
|
|
2537
|
-
}
|
|
2538
|
-
const hasErc20 = params.actions.some((a) => a.type === "sendErc20");
|
|
2539
|
-
const baseMatches = ctx.baseTokens.src.toLowerCase() === ctx.baseTokens.dst.toLowerCase();
|
|
2540
|
-
if (!hasErc20 && baseMatches) {
|
|
2541
|
-
throw new Error(
|
|
2542
|
-
'route "indirect" requires ERC-20 actions or mismatched base tokens; use the direct route instead.'
|
|
2543
|
-
);
|
|
2544
|
-
}
|
|
2545
|
-
for (const action of params.actions) {
|
|
2546
|
-
switch (action.type) {
|
|
2547
|
-
case "sendNative":
|
|
2548
|
-
if (action.amount < 0n) {
|
|
2549
|
-
throw new Error("sendNative.amount must be >= 0.");
|
|
2550
|
-
}
|
|
2551
|
-
break;
|
|
2552
|
-
case "sendErc20":
|
|
2553
|
-
if (action.amount < 0n) {
|
|
2554
|
-
throw new Error("sendErc20.amount must be >= 0.");
|
|
2555
|
-
}
|
|
2556
|
-
break;
|
|
2557
|
-
case "call":
|
|
2558
|
-
if (action.value != null) {
|
|
2559
|
-
if (action.value < 0n) {
|
|
2560
|
-
throw new Error("call.value must be >= 0 when provided.");
|
|
2561
|
-
}
|
|
2562
|
-
if (action.value > 0n && !baseMatches) {
|
|
2563
|
-
throw new Error("indirect route does not support call.value when base tokens differ.");
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
break;
|
|
2567
|
-
default:
|
|
2568
|
-
assertNever(action);
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
|
-
function buildIndirectBundle(params, ctx, attrs, starterData, interopFeeInfo) {
|
|
2573
|
-
const totalActionValue = sumActionMsgValue(params.actions);
|
|
2574
|
-
const bridgedTokenTotal = sumErc20Amounts(params.actions);
|
|
2575
|
-
const approvalMap = /* @__PURE__ */ new Map();
|
|
2576
|
-
for (const action of params.actions) {
|
|
2577
|
-
if (action.type !== "sendErc20") continue;
|
|
2578
|
-
const key = action.token.toLowerCase();
|
|
2579
|
-
const existing = approvalMap.get(key);
|
|
2580
|
-
if (existing) {
|
|
2581
|
-
existing.amount += action.amount;
|
|
2582
|
-
} else {
|
|
2583
|
-
approvalMap.set(key, {
|
|
2584
|
-
token: action.token,
|
|
2585
|
-
spender: ctx.l2NativeTokenVault,
|
|
2586
|
-
amount: action.amount
|
|
2587
|
-
});
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
const approvals = Array.from(approvalMap.values());
|
|
2591
|
-
if (interopFeeInfo.approval) approvals.push(interopFeeInfo.approval);
|
|
2592
|
-
const starters = params.actions.map((action, index) => {
|
|
2593
|
-
const callAttributes = attrs.callAttributes[index] ?? [];
|
|
2594
|
-
if (starterData[index]?.assetRouterPayload) {
|
|
2595
|
-
const l2AssetRouter = ctx.codec.formatAddress(ctx.l2AssetRouter);
|
|
2596
|
-
return [l2AssetRouter, starterData[index].assetRouterPayload, callAttributes];
|
|
2597
|
-
}
|
|
2598
|
-
const directTo = ctx.codec.formatAddress(action.to);
|
|
2599
|
-
switch (action.type) {
|
|
2600
|
-
case "sendNative":
|
|
2601
|
-
return [directTo, "0x", callAttributes];
|
|
2602
|
-
case "call":
|
|
2603
|
-
return [directTo, action.data ?? "0x", callAttributes];
|
|
2604
|
-
case "sendErc20":
|
|
2605
|
-
throw new Error("buildIndirectBundle: missing assetRouterPayload for sendErc20 action.");
|
|
2606
|
-
default:
|
|
2607
|
-
return assertNever(action);
|
|
2608
|
-
}
|
|
2609
|
-
});
|
|
2610
|
-
return {
|
|
2611
|
-
dstChain: ctx.codec.formatChain(ctx.dstChainId),
|
|
2612
|
-
starters,
|
|
2613
|
-
bundleAttributes: attrs.bundleAttributes,
|
|
2614
|
-
approvals,
|
|
2615
|
-
interopFee: interopFeeInfo.fee,
|
|
2616
|
-
quoteExtras: {
|
|
2617
|
-
totalActionValue,
|
|
2618
|
-
bridgedTokenTotal
|
|
2619
|
-
}
|
|
2620
|
-
};
|
|
2621
|
-
}
|
|
2622
2428
|
var PREFIX_EVM_CHAIN = getBytes("0x00010000");
|
|
2623
2429
|
var PREFIX_EVM_ADDRESS = getBytes("0x000100000014");
|
|
2624
2430
|
function formatInteropEvmChain(chainId) {
|
|
@@ -2783,7 +2589,9 @@ function routeIndirect() {
|
|
|
2783
2589
|
dstChainId: ctx.dstChainId,
|
|
2784
2590
|
baseTokens: ctx.baseTokens,
|
|
2785
2591
|
l2AssetRouter: ctx.l2AssetRouter,
|
|
2786
|
-
l2NativeTokenVault: ctx.l2NativeTokenVault
|
|
2592
|
+
l2NativeTokenVault: ctx.l2NativeTokenVault,
|
|
2593
|
+
codec: interopCodec
|
|
2594
|
+
});
|
|
2787
2595
|
},
|
|
2788
2596
|
async build(params, ctx) {
|
|
2789
2597
|
const steps = [];
|
|
@@ -2844,7 +2652,9 @@ function routeDirect() {
|
|
|
2844
2652
|
dstChainId: ctx.dstChainId,
|
|
2845
2653
|
baseTokens: ctx.baseTokens,
|
|
2846
2654
|
l2AssetRouter: ctx.l2AssetRouter,
|
|
2847
|
-
l2NativeTokenVault: ctx.l2NativeTokenVault
|
|
2655
|
+
l2NativeTokenVault: ctx.l2NativeTokenVault,
|
|
2656
|
+
codec: interopCodec
|
|
2657
|
+
});
|
|
2848
2658
|
},
|
|
2849
2659
|
async build(params, ctx) {
|
|
2850
2660
|
const steps = [];
|
|
@@ -2889,26 +2699,11 @@ function routeDirect() {
|
|
|
2889
2699
|
}
|
|
2890
2700
|
};
|
|
2891
2701
|
}
|
|
2892
|
-
var MIN_INTEROP_PROTOCOL = 31;
|
|
2893
2702
|
async function assertInteropProtocolVersion(client, srcChainId, dstChainId) {
|
|
2894
2703
|
const [srcProtocolVersion, dstProtocolVersion] = await Promise.all([
|
|
2895
2704
|
client.getProtocolVersion(srcChainId),
|
|
2896
2705
|
client.getProtocolVersion(dstChainId)
|
|
2897
2706
|
]);
|
|
2898
|
-
const assertProtocolVersion = (chainId, protocolVersion) => {
|
|
2899
|
-
if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
|
|
2900
|
-
throw createError("VALIDATION", {
|
|
2901
|
-
resource: "interop",
|
|
2902
|
-
operation: OP_INTEROP.context.protocolVersion,
|
|
2903
|
-
message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
|
|
2904
|
-
context: {
|
|
2905
|
-
chainId,
|
|
2906
|
-
requiredMinor: MIN_INTEROP_PROTOCOL,
|
|
2907
|
-
semver: protocolVersion
|
|
2908
|
-
}
|
|
2909
|
-
});
|
|
2910
|
-
}
|
|
2911
|
-
};
|
|
2912
2707
|
assertProtocolVersion(srcChainId, srcProtocolVersion);
|
|
2913
2708
|
assertProtocolVersion(dstChainId, dstProtocolVersion);
|
|
2914
2709
|
}
|
|
@@ -2979,7 +2774,14 @@ function parseMaxBlockRangeLimit(error) {
|
|
|
2979
2774
|
async function getTxReceipt(provider, txHash) {
|
|
2980
2775
|
const receipt = await wrap3(
|
|
2981
2776
|
OP_INTEROP.svc.status.sourceReceipt,
|
|
2982
|
-
() =>
|
|
2777
|
+
async () => {
|
|
2778
|
+
try {
|
|
2779
|
+
return await provider.getTransactionReceipt(txHash);
|
|
2780
|
+
} catch (error) {
|
|
2781
|
+
if (isReceiptNotFound(error)) return null;
|
|
2782
|
+
throw error;
|
|
2783
|
+
}
|
|
2784
|
+
},
|
|
2983
2785
|
{
|
|
2984
2786
|
ctx: { where: "l2.getTransactionReceipt", l2SrcTxHash: txHash },
|
|
2985
2787
|
message: "Failed to fetch source L2 receipt for interop tx."
|
|
@@ -3144,138 +2946,6 @@ async function executeBundle(client, dstProvider, info, opts) {
|
|
|
3144
2946
|
);
|
|
3145
2947
|
}
|
|
3146
2948
|
}
|
|
3147
|
-
|
|
3148
|
-
// src/core/resources/interop/finalization.ts
|
|
3149
|
-
var DEFAULT_POLL_MS = 1e3;
|
|
3150
|
-
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
3151
|
-
function resolveIdsFromWaitable(input) {
|
|
3152
|
-
if (typeof input === "string") {
|
|
3153
|
-
return { l2SrcTxHash: input };
|
|
3154
|
-
}
|
|
3155
|
-
return {
|
|
3156
|
-
l2SrcTxHash: input.l2SrcTxHash,
|
|
3157
|
-
bundleHash: input.bundleHash,
|
|
3158
|
-
dstExecTxHash: input.dstExecTxHash
|
|
3159
|
-
};
|
|
3160
|
-
}
|
|
3161
|
-
function parseBundleSentFromReceipt(input) {
|
|
3162
|
-
const { receipt, interopCenter, interopBundleSentTopic, decodeInteropBundleSent: decodeInteropBundleSent2 } = input;
|
|
3163
|
-
const bundleSentLog = receipt.logs.find(
|
|
3164
|
-
(log) => log.address.toLowerCase() === interopCenter.toLowerCase() && log.topics[0].toLowerCase() === interopBundleSentTopic.toLowerCase()
|
|
3165
|
-
);
|
|
3166
|
-
if (!bundleSentLog) {
|
|
3167
|
-
throw createError("STATE", {
|
|
3168
|
-
resource: "interop",
|
|
3169
|
-
operation: OP_INTEROP.svc.status.parseSentLog,
|
|
3170
|
-
message: "Failed to locate InteropBundleSent event in source receipt.",
|
|
3171
|
-
context: { receipt, interopCenter }
|
|
3172
|
-
});
|
|
3173
|
-
}
|
|
3174
|
-
const decoded = decodeInteropBundleSent2({
|
|
3175
|
-
data: bundleSentLog.data,
|
|
3176
|
-
topics: bundleSentLog.topics
|
|
3177
|
-
});
|
|
3178
|
-
return { bundleHash: decoded.bundleHash, dstChainId: decoded.destinationChainId };
|
|
3179
|
-
}
|
|
3180
|
-
function parseBundleReceiptInfo(params) {
|
|
3181
|
-
const {
|
|
3182
|
-
rawReceipt,
|
|
3183
|
-
interopCenter,
|
|
3184
|
-
interopBundleSentTopic,
|
|
3185
|
-
decodeInteropBundleSent: decodeInteropBundleSent2,
|
|
3186
|
-
decodeL1MessageData: decodeL1MessageData2,
|
|
3187
|
-
l2SrcTxHash
|
|
3188
|
-
} = params;
|
|
3189
|
-
let l2ToL1LogIndex = -1;
|
|
3190
|
-
let l1MessageData = null;
|
|
3191
|
-
let found;
|
|
3192
|
-
for (const log of rawReceipt.logs) {
|
|
3193
|
-
if (isL1MessageSentLog(log)) {
|
|
3194
|
-
l2ToL1LogIndex += 1;
|
|
3195
|
-
try {
|
|
3196
|
-
l1MessageData = decodeL1MessageData2(log);
|
|
3197
|
-
} catch (e) {
|
|
3198
|
-
throw createError("STATE", {
|
|
3199
|
-
resource: "interop",
|
|
3200
|
-
operation: OP_INTEROP.svc.status.parseSentLog,
|
|
3201
|
-
message: "Failed to decode L1MessageSent log data for interop bundle.",
|
|
3202
|
-
context: { l2SrcTxHash, l2ToL1LogIndex },
|
|
3203
|
-
cause: e
|
|
3204
|
-
});
|
|
3205
|
-
}
|
|
3206
|
-
continue;
|
|
3207
|
-
}
|
|
3208
|
-
if (log.address.toLowerCase() !== interopCenter.toLowerCase() || log.topics[0].toLowerCase() !== interopBundleSentTopic.toLowerCase())
|
|
3209
|
-
continue;
|
|
3210
|
-
const decoded = decodeInteropBundleSent2({
|
|
3211
|
-
data: log.data,
|
|
3212
|
-
topics: log.topics
|
|
3213
|
-
});
|
|
3214
|
-
found = {
|
|
3215
|
-
bundleHash: decoded.bundleHash,
|
|
3216
|
-
dstChainId: decoded.destinationChainId,
|
|
3217
|
-
sourceChainId: decoded.sourceChainId
|
|
3218
|
-
};
|
|
3219
|
-
break;
|
|
3220
|
-
}
|
|
3221
|
-
if (!found) {
|
|
3222
|
-
throw createError("STATE", {
|
|
3223
|
-
resource: "interop",
|
|
3224
|
-
operation: OP_INTEROP.svc.status.parseSentLog,
|
|
3225
|
-
message: "Failed to locate InteropBundleSent event in source receipt.",
|
|
3226
|
-
context: { l2SrcTxHash, interopCenter }
|
|
3227
|
-
});
|
|
3228
|
-
}
|
|
3229
|
-
if (!l1MessageData) {
|
|
3230
|
-
throw createError("STATE", {
|
|
3231
|
-
resource: "interop",
|
|
3232
|
-
operation: OP_INTEROP.svc.status.parseSentLog,
|
|
3233
|
-
message: "Failed to locate L1MessageSent log data for interop bundle.",
|
|
3234
|
-
context: { l2SrcTxHash, interopCenter }
|
|
3235
|
-
});
|
|
3236
|
-
}
|
|
3237
|
-
return {
|
|
3238
|
-
bundleHash: found.bundleHash,
|
|
3239
|
-
dstChainId: found.dstChainId,
|
|
3240
|
-
sourceChainId: found.sourceChainId,
|
|
3241
|
-
l1MessageData,
|
|
3242
|
-
l2ToL1LogIndex,
|
|
3243
|
-
txNumberInBatch: Number(rawReceipt.transactionIndex),
|
|
3244
|
-
rawReceipt
|
|
3245
|
-
};
|
|
3246
|
-
}
|
|
3247
|
-
function getBundleEncodedData(messageData) {
|
|
3248
|
-
const prefix = `0x${messageData.slice(2, 4)}`;
|
|
3249
|
-
if (prefix !== BUNDLE_IDENTIFIER) {
|
|
3250
|
-
throw createError("STATE", {
|
|
3251
|
-
resource: "interop",
|
|
3252
|
-
operation: OP_INTEROP.wait,
|
|
3253
|
-
message: "Unexpected bundle prefix in L1MessageSent data.",
|
|
3254
|
-
context: { prefix, expected: BUNDLE_IDENTIFIER }
|
|
3255
|
-
});
|
|
3256
|
-
}
|
|
3257
|
-
return `0x${messageData.slice(4)}`;
|
|
3258
|
-
}
|
|
3259
|
-
function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
|
|
3260
|
-
const messageProof = {
|
|
3261
|
-
chainId: bundleInfo.sourceChainId,
|
|
3262
|
-
l1BatchNumber: proof.batchNumber,
|
|
3263
|
-
l2MessageIndex: proof.id,
|
|
3264
|
-
message: {
|
|
3265
|
-
txNumberInBatch: bundleInfo.txNumberInBatch,
|
|
3266
|
-
sender: L2_INTEROP_CENTER_ADDRESS,
|
|
3267
|
-
data: messageData
|
|
3268
|
-
},
|
|
3269
|
-
proof: proof.proof
|
|
3270
|
-
};
|
|
3271
|
-
return {
|
|
3272
|
-
l2SrcTxHash: ids.l2SrcTxHash,
|
|
3273
|
-
bundleHash: bundleInfo.bundleHash,
|
|
3274
|
-
dstChainId: bundleInfo.dstChainId,
|
|
3275
|
-
proof: messageProof,
|
|
3276
|
-
encodedData: getBundleEncodedData(messageData)
|
|
3277
|
-
};
|
|
3278
|
-
}
|
|
3279
2949
|
function decodeInteropBundleSent(centerIface, log) {
|
|
3280
2950
|
const decoded = centerIface.decodeEventLog(
|
|
3281
2951
|
"InteropBundleSent",
|
|
@@ -3509,6 +3179,31 @@ function resolveChainRef(ref) {
|
|
|
3509
3179
|
return typeof ref === "string" ? new JsonRpcProvider(ref) : ref;
|
|
3510
3180
|
}
|
|
3511
3181
|
|
|
3182
|
+
// src/adapters/ethers/resources/interop/services/gas.ts
|
|
3183
|
+
async function quoteStepsL2Fee(steps, ctx) {
|
|
3184
|
+
if (steps.length === 0) return 0n;
|
|
3185
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
3186
|
+
let maxFeePerGas;
|
|
3187
|
+
try {
|
|
3188
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
3189
|
+
maxFeePerGas = fees.maxFeePerGas ?? fees.gasPrice ?? await estimator.getGasPrice();
|
|
3190
|
+
} catch {
|
|
3191
|
+
return void 0;
|
|
3192
|
+
}
|
|
3193
|
+
let total = 0n;
|
|
3194
|
+
for (const step of steps) {
|
|
3195
|
+
try {
|
|
3196
|
+
const coreTx = toCoreTx({ ...step.tx, from: ctx.sender });
|
|
3197
|
+
const est = await estimator.estimateGas(coreTx);
|
|
3198
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
3199
|
+
total += buffered * maxFeePerGas;
|
|
3200
|
+
} catch {
|
|
3201
|
+
return void 0;
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
return total;
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3512
3207
|
// src/adapters/ethers/resources/interop/index.ts
|
|
3513
3208
|
var { wrap: wrap6, toResult: toResult2 } = createErrorHandlers("interop");
|
|
3514
3209
|
var ROUTES3 = {
|
|
@@ -3565,12 +3260,14 @@ function createInteropResource(client, config, tokens, contracts, attributes) {
|
|
|
3565
3260
|
ctx: { where: `routes.${route}.build` }
|
|
3566
3261
|
}
|
|
3567
3262
|
);
|
|
3263
|
+
const l2Fee = await quoteStepsL2Fee(steps, ctx).catch(() => void 0);
|
|
3568
3264
|
const summary = {
|
|
3569
3265
|
route,
|
|
3570
3266
|
approvalsNeeded: approvals,
|
|
3571
3267
|
totalActionValue: quoteExtras.totalActionValue,
|
|
3572
3268
|
bridgedTokenTotal: quoteExtras.bridgedTokenTotal,
|
|
3573
|
-
interopFee
|
|
3269
|
+
interopFee,
|
|
3270
|
+
l2Fee
|
|
3574
3271
|
};
|
|
3575
3272
|
return { plan: { route, summary, steps }, ctx };
|
|
3576
3273
|
}
|