@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.
Files changed (96) hide show
  1. package/dist/adapters/ethers/client.cjs +13 -4
  2. package/dist/adapters/ethers/client.cjs.map +1 -1
  3. package/dist/adapters/ethers/client.d.ts +1 -2
  4. package/dist/adapters/ethers/client.js +6 -6
  5. package/dist/adapters/ethers/index.cjs +607 -259
  6. package/dist/adapters/ethers/index.cjs.map +1 -1
  7. package/dist/adapters/ethers/index.js +9 -9
  8. package/dist/adapters/ethers/resources/deposits/routes/priority.d.ts +12 -0
  9. package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +4 -0
  10. package/dist/adapters/ethers/resources/interop/index.d.ts +14 -14
  11. package/dist/adapters/ethers/resources/interop/resolvers.d.ts +3 -8
  12. package/dist/adapters/ethers/resources/interop/routes/types.d.ts +2 -1
  13. package/dist/adapters/ethers/resources/interop/services/erc20.d.ts +10 -0
  14. package/dist/adapters/ethers/resources/interop/services/fee.d.ts +12 -0
  15. package/dist/adapters/ethers/resources/interop/services/finalization/index.d.ts +1 -1
  16. package/dist/adapters/ethers/resources/interop/services/finalization/polling.d.ts +1 -1
  17. package/dist/adapters/ethers/resources/interop/services/gas.d.ts +12 -0
  18. package/dist/adapters/ethers/resources/interop/types.d.ts +6 -14
  19. package/dist/adapters/ethers/sdk.cjs +1008 -259
  20. package/dist/adapters/ethers/sdk.cjs.map +1 -1
  21. package/dist/adapters/ethers/sdk.d.ts +6 -1
  22. package/dist/adapters/ethers/sdk.js +7 -7
  23. package/dist/adapters/viem/client.cjs +795 -7
  24. package/dist/adapters/viem/client.cjs.map +1 -1
  25. package/dist/adapters/viem/client.d.ts +6 -1
  26. package/dist/adapters/viem/client.js +6 -6
  27. package/dist/adapters/viem/index.cjs +6490 -2799
  28. package/dist/adapters/viem/index.cjs.map +1 -1
  29. package/dist/adapters/viem/index.d.ts +5 -0
  30. package/dist/adapters/viem/index.js +9 -9
  31. package/dist/adapters/viem/resources/deposits/routes/priority.d.ts +13 -0
  32. package/dist/adapters/viem/resources/deposits/services/gas.d.ts +4 -0
  33. package/dist/adapters/viem/resources/interop/address.d.ts +18 -0
  34. package/dist/adapters/viem/resources/interop/attributes/resource.d.ts +6 -0
  35. package/dist/adapters/viem/resources/interop/context.d.ts +31 -0
  36. package/dist/adapters/viem/resources/interop/index.d.ts +62 -0
  37. package/dist/adapters/viem/resources/interop/resolvers.d.ts +4 -0
  38. package/dist/adapters/viem/resources/interop/routes/direct.d.ts +2 -0
  39. package/dist/adapters/viem/resources/interop/routes/indirect.d.ts +2 -0
  40. package/dist/adapters/viem/resources/interop/routes/types.d.ts +23 -0
  41. package/dist/adapters/viem/resources/interop/services/erc20.d.ts +25 -0
  42. package/dist/adapters/viem/resources/interop/services/fee.d.ts +12 -0
  43. package/dist/adapters/viem/resources/interop/services/finalization/bundle.d.ts +15 -0
  44. package/dist/adapters/viem/resources/interop/services/finalization/data-fetchers.d.ts +17 -0
  45. package/dist/adapters/viem/resources/interop/services/finalization/decoders.d.ts +11 -0
  46. package/dist/adapters/viem/resources/interop/services/finalization/index.d.ts +13 -0
  47. package/dist/adapters/viem/resources/interop/services/finalization/polling.d.ts +7 -0
  48. package/dist/adapters/viem/resources/interop/services/finalization/status.d.ts +5 -0
  49. package/dist/adapters/viem/resources/interop/services/finalization/topics.d.ts +4 -0
  50. package/dist/adapters/viem/resources/interop/services/gas.d.ts +12 -0
  51. package/dist/adapters/viem/resources/interop/services/starter-data.d.ts +6 -0
  52. package/dist/adapters/viem/resources/interop/types.d.ts +8 -0
  53. package/dist/adapters/viem/sdk.cjs +6401 -2758
  54. package/dist/adapters/viem/sdk.cjs.map +1 -1
  55. package/dist/adapters/viem/sdk.d.ts +8 -1
  56. package/dist/adapters/viem/sdk.js +7 -7
  57. package/dist/{chunk-E3KP7XCG.js → chunk-3HHUZXSV.js} +1 -1
  58. package/dist/{chunk-EDWBCPO3.js → chunk-4PZCNTQ3.js} +1387 -71
  59. package/dist/{chunk-UDBRUBEK.js → chunk-65HAYKVL.js} +2 -2
  60. package/dist/chunk-BWKWWLY4.js +9 -0
  61. package/dist/{chunk-JHO2UQ5F.js → chunk-HGB3DOV2.js} +445 -554
  62. package/dist/{chunk-HI64OOAR.js → chunk-HVHMLAYH.js} +1 -1
  63. package/dist/{chunk-2RIARDXZ.js → chunk-JHRYNLZG.js} +65 -7
  64. package/dist/{chunk-RI73VJSH.js → chunk-JXR5V5YK.js} +463 -27
  65. package/dist/chunk-K2UVKMLN.js +658 -0
  66. package/dist/{chunk-53MC5BR2.js → chunk-MDPX5LNW.js} +1 -1
  67. package/dist/{chunk-QQ2OR434.js → chunk-MT4X5FEO.js} +18 -2
  68. package/dist/{chunk-R5WRFPK2.js → chunk-MZBKM3GH.js} +4 -4
  69. package/dist/{chunk-5R7L5NM5.js → chunk-YIWXIP2M.js} +10 -2
  70. package/dist/core/constants.cjs +17 -1
  71. package/dist/core/constants.cjs.map +1 -1
  72. package/dist/core/constants.d.ts +9 -1
  73. package/dist/core/constants.js +1 -1
  74. package/dist/core/index.cjs +52 -24
  75. package/dist/core/index.cjs.map +1 -1
  76. package/dist/core/index.js +5 -5
  77. package/dist/core/internal/abis/IERC7786Attributes.d.ts +21 -11
  78. package/dist/core/internal/abis/IInteropCenter.d.ts +4 -0
  79. package/dist/core/resources/deposits/chains.d.ts +1 -0
  80. package/dist/core/resources/deposits/gas.d.ts +7 -0
  81. package/dist/core/resources/deposits/priority.d.ts +41 -0
  82. package/dist/core/resources/interop/attributes/bundle.d.ts +1 -0
  83. package/dist/core/resources/interop/attributes/resource.d.ts +1 -0
  84. package/dist/core/resources/interop/plan.d.ts +11 -3
  85. package/dist/core/resources/interop/protocol.d.ts +3 -0
  86. package/dist/core/rpc/types.d.ts +1 -0
  87. package/dist/core/rpc/zks.d.ts +5 -1
  88. package/dist/core/types/errors.d.ts +5 -0
  89. package/dist/core/types/flows/interop.d.ts +11 -20
  90. package/dist/core/types/primitives.d.ts +2 -0
  91. package/dist/index.cjs +69 -25
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.js +5 -5
  94. package/package.json +1 -1
  95. package/dist/chunk-4S4XDA4N.js +0 -415
  96. package/dist/chunk-5L6EYUJB.js +0 -237
@@ -0,0 +1,658 @@
1
+ import { isL1MessageSentLog } from './chunk-3HHUZXSV.js';
2
+ import { IBridgehub_default, isHash66, isBigint, isHash, assertNever, createError, OP_INTEROP, isNumber, isAddress, isHash66Array } from './chunk-JXR5V5YK.js';
3
+ import { BUFFER, DEFAULT_ABI_BYTES, DEFAULT_PUBDATA_BYTES, TX_MEMORY_OVERHEAD_GAS, TX_OVERHEAD_GAS, L1_TX_MIN_L2_GAS_BASE, L1_TX_INTRINSIC_L2_GAS, L1_TX_DELTA_544_ENCODING_BYTES, L1_TX_DELTA_FACTORY_DEPS_L2_GAS, L1_TX_INTRINSIC_PUBDATA, L1_TX_DELTA_FACTORY_DEPS_PUBDATA, TX_SLOT_OVERHEAD_L2_GAS, PRIORITY_TX_MAX_GAS_LIMIT, L2_INTEROP_CENTER_ADDRESS, BUNDLE_IDENTIFIER } from './chunk-MT4X5FEO.js';
4
+
5
+ // src/core/resources/deposits/chains.ts
6
+ var ERAVM_CHAIN_IDS = /* @__PURE__ */ new Set([324n, 2741n, 11124n, 300n]);
7
+ function isEraVmChain(chainIdL2) {
8
+ return ERAVM_CHAIN_IDS.has(chainIdL2);
9
+ }
10
+
11
+ // src/core/resources/deposits/gas.ts
12
+ var CREATE_REESTIMATE_BUFFER = 15n;
13
+ var maxBigInt = (a, b) => a > b ? a : b;
14
+ function applyGasBuffer(gasLimit, bufferPct = BUFFER) {
15
+ return gasLimit * (100n + bufferPct) / 100n;
16
+ }
17
+ function resolveCreateDepositL1GasLimit(input) {
18
+ const { chainIdL2, stepKey, preparedGasLimit, estimatedGasLimit } = input;
19
+ if (estimatedGasLimit == null) {
20
+ return preparedGasLimit;
21
+ }
22
+ const isEraVmBridgeStep = isEraVmChain(chainIdL2) && stepKey.startsWith("bridgehub:");
23
+ const reestimatedGasLimit = applyGasBuffer(
24
+ estimatedGasLimit,
25
+ isEraVmBridgeStep ? BUFFER : CREATE_REESTIMATE_BUFFER
26
+ );
27
+ if (isEraVmBridgeStep && preparedGasLimit != null) {
28
+ return maxBigInt(preparedGasLimit, reestimatedGasLimit);
29
+ }
30
+ return reestimatedGasLimit;
31
+ }
32
+ function makeGasQuote(p) {
33
+ const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
34
+ return {
35
+ gasLimit: p.gasLimit,
36
+ maxFeePerGas: p.maxFeePerGas,
37
+ maxPriorityFeePerGas,
38
+ gasPerPubdata: p.gasPerPubdata,
39
+ maxCost: p.gasLimit * p.maxFeePerGas
40
+ };
41
+ }
42
+ async function fetchFees(estimator) {
43
+ try {
44
+ const fees = await estimator.estimateFeesPerGas();
45
+ if (fees.maxFeePerGas != null) {
46
+ return {
47
+ maxFeePerGas: fees.maxFeePerGas,
48
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
49
+ };
50
+ }
51
+ if (fees.gasPrice != null) {
52
+ return {
53
+ maxFeePerGas: fees.gasPrice,
54
+ maxPriorityFeePerGas: 0n
55
+ };
56
+ }
57
+ } catch {
58
+ }
59
+ try {
60
+ const gp = await estimator.getGasPrice();
61
+ return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
62
+ } catch {
63
+ return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
64
+ }
65
+ }
66
+ async function quoteL1Gas(input) {
67
+ const { estimator, tx, overrides, fallbackGasLimit } = input;
68
+ let market;
69
+ const getMarket = async () => {
70
+ if (market) return market;
71
+ market = await fetchFees(estimator);
72
+ return market;
73
+ };
74
+ const maxFeePerGas = overrides?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : (await getMarket()).maxFeePerGas);
75
+ const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : (await getMarket()).maxPriorityFeePerGas);
76
+ const explicitGasLimit = overrides?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
77
+ if (explicitGasLimit != null) {
78
+ return makeGasQuote({ gasLimit: explicitGasLimit, maxFeePerGas, maxPriorityFeePerGas });
79
+ }
80
+ try {
81
+ const est = await estimator.estimateGas(tx);
82
+ const buffered = applyGasBuffer(BigInt(est));
83
+ return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
84
+ } catch {
85
+ if (fallbackGasLimit != null) {
86
+ return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
87
+ }
88
+ return void 0;
89
+ }
90
+ }
91
+ async function quoteL2Gas(input) {
92
+ const { estimator, route, tx, gasPerPubdata, l2GasLimit, overrideGasLimit, stateOverrides } = input;
93
+ const market = await fetchFees(estimator);
94
+ const maxFeePerGas = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
95
+ const txGasLimit = tx?.gasLimit != null ? BigInt(tx.gasLimit) : void 0;
96
+ const explicit = overrideGasLimit ?? txGasLimit;
97
+ if (explicit != null) {
98
+ return makeGasQuote({
99
+ gasLimit: explicit,
100
+ maxFeePerGas,
101
+ gasPerPubdata
102
+ });
103
+ }
104
+ if (!tx) {
105
+ return makeGasQuote({
106
+ gasLimit: l2GasLimit ?? 0n,
107
+ maxFeePerGas,
108
+ gasPerPubdata
109
+ });
110
+ }
111
+ try {
112
+ const execEstimate = await estimator.estimateGas(tx, stateOverrides);
113
+ const memoryBytes = route === "erc20-nonbase" ? 500n : DEFAULT_ABI_BYTES;
114
+ const pubdataBytes = route === "erc20-nonbase" ? 200n : DEFAULT_PUBDATA_BYTES;
115
+ const pp = gasPerPubdata ?? 800n;
116
+ const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
117
+ const pubdataOverhead = pubdataBytes * pp;
118
+ let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
119
+ total = applyGasBuffer(total);
120
+ return makeGasQuote({
121
+ gasLimit: total,
122
+ maxFeePerGas,
123
+ gasPerPubdata: pp
124
+ });
125
+ } catch {
126
+ return makeGasQuote({
127
+ gasLimit: l2GasLimit ?? 0n,
128
+ maxFeePerGas,
129
+ gasPerPubdata
130
+ });
131
+ }
132
+ }
133
+ async function quoteL2BaseCost(input) {
134
+ const { estimator, encode, bridgehub, chainIdL2, l2GasLimit, gasPerPubdata } = input;
135
+ const market = await fetchFees(estimator);
136
+ const l1GasPrice = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
137
+ if (l1GasPrice === 0n) {
138
+ throw new Error("Could not fetch L1 gas price for Bridgehub base cost calculation.");
139
+ }
140
+ const data = encode(IBridgehub_default, "l2TransactionBaseCost", [
141
+ chainIdL2,
142
+ l1GasPrice,
143
+ l2GasLimit,
144
+ gasPerPubdata
145
+ ]);
146
+ const raw = await estimator.call({
147
+ to: bridgehub,
148
+ data
149
+ });
150
+ return BigInt(raw);
151
+ }
152
+
153
+ // src/core/codec/ntv.ts
154
+ function createNTVCodec(deps) {
155
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
156
+ const encoded = deps.encode(
157
+ ["uint256", "address", "address"],
158
+ [originChainId, ntvAddress, tokenAddress]
159
+ );
160
+ return deps.keccak256(encoded);
161
+ }
162
+ return {
163
+ encodeAssetId
164
+ };
165
+ }
166
+
167
+ // src/core/types/flows/interop.ts
168
+ function isInteropMessageProof(obj) {
169
+ if (typeof obj !== "object" || obj === null) return false;
170
+ const proof = obj;
171
+ 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);
172
+ }
173
+ function isInteropFinalizationInfo(obj) {
174
+ if (typeof obj !== "object" || obj === null) return false;
175
+ const info = obj;
176
+ return isHash66(info.l2SrcTxHash) && isHash66(info.bundleHash) && isBigint(info.dstChainId) && isHash(info.encodedData) && isInteropMessageProof(info.proof);
177
+ }
178
+
179
+ // src/core/resources/interop/route.ts
180
+ function sumActionMsgValue(actions) {
181
+ let sum = 0n;
182
+ for (const a of actions) {
183
+ if (a.type === "sendNative") sum += a.amount;
184
+ else if (a.type === "call" && a.value) sum += a.value;
185
+ }
186
+ return sum;
187
+ }
188
+ function sumErc20Amounts(actions) {
189
+ let sum = 0n;
190
+ for (const a of actions) if (a.type === "sendErc20") sum += a.amount;
191
+ return sum;
192
+ }
193
+ function pickInteropRoute(args) {
194
+ const hasErc20 = args.actions.some((a) => a.type === "sendErc20");
195
+ const baseMatches = args.ctx.baseTokenSrc.toLowerCase() === args.ctx.baseTokenDst.toLowerCase();
196
+ if (hasErc20) return "indirect";
197
+ if (!baseMatches) return "indirect";
198
+ return "direct";
199
+ }
200
+
201
+ // src/core/types/primitives.ts
202
+ var ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000";
203
+
204
+ // src/core/types/fees.ts
205
+ function toGasOverrides(overrides) {
206
+ const { nonce: _, ...gas } = overrides;
207
+ return gas;
208
+ }
209
+
210
+ // src/core/resources/deposits/fee.ts
211
+ function buildFeeBreakdown(p) {
212
+ const l1MaxTotal = p.l1Gas?.maxCost ?? 0n;
213
+ const l2Total = p.l2BaseCost + p.operatorTip;
214
+ const l1 = {
215
+ gasLimit: p.l1Gas?.gasLimit ?? 0n,
216
+ maxFeePerGas: p.l1Gas?.maxFeePerGas ?? 0n,
217
+ maxPriorityFeePerGas: p.l1Gas?.maxPriorityFeePerGas,
218
+ maxTotal: l1MaxTotal
219
+ };
220
+ const l2 = {
221
+ total: l2Total,
222
+ baseCost: p.l2BaseCost,
223
+ operatorTip: p.operatorTip,
224
+ gasLimit: p.l2Gas?.gasLimit ?? 0n,
225
+ maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
226
+ maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas,
227
+ gasPerPubdata: p.l2Gas?.gasPerPubdata ?? 0n
228
+ };
229
+ return {
230
+ token: p.feeToken,
231
+ maxTotal: l1MaxTotal + l2Total,
232
+ mintValue: p.mintValue,
233
+ l1,
234
+ l2
235
+ };
236
+ }
237
+
238
+ // src/core/resources/deposits/priority.ts
239
+ var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
240
+ var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
241
+ var ERAVM_PRIORITY_L2_GAS_BUFFER = 30n;
242
+ var maxBigInt2 = (a, b) => a > b ? a : b;
243
+ var ceilDiv = (a, b) => (a + b - 1n) / b;
244
+ function derivePriorityTxGasBreakdown(input) {
245
+ const factoryDepsCount = input.factoryDepsCount ?? 0n;
246
+ const minBodyGas = maxBigInt2(
247
+ L1_TX_INTRINSIC_L2_GAS + ceilDiv(
248
+ input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
249
+ PRIORITY_TX_ENCODING_STEP_BYTES
250
+ ) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
251
+ L1_TX_MIN_L2_GAS_BASE
252
+ ) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
253
+ const overhead = maxBigInt2(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
254
+ const derivedBodyGas = minBodyGas;
255
+ return {
256
+ encodedLength: input.encodedLength,
257
+ minBodyGas,
258
+ overhead,
259
+ derivedBodyGas,
260
+ derivedL2GasLimit: derivedBodyGas + overhead,
261
+ priorityTxMaxGasLimit: PRIORITY_TX_MAX_GAS_LIMIT,
262
+ priorityTxMaxGasLimitExceeded: derivedBodyGas > PRIORITY_TX_MAX_GAS_LIMIT
263
+ };
264
+ }
265
+ function derivePriorityBodyGasEstimateCap(input) {
266
+ return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
267
+ }
268
+ function applyPriorityL2GasLimitBuffer(input) {
269
+ if (!isEraVmChain(input.chainIdL2)) {
270
+ return input.gasLimit;
271
+ }
272
+ return input.gasLimit * (100n + ERAVM_PRIORITY_L2_GAS_BUFFER) / 100n;
273
+ }
274
+
275
+ // src/core/resources/interop/attributes/call.ts
276
+ function createCallAttributes(codec) {
277
+ const indirectCall = (messageValue) => codec.encode("indirectCall", [messageValue]);
278
+ const interopCallValue = (bridgedAmount) => codec.encode("interopCallValue", [bridgedAmount]);
279
+ return {
280
+ indirectCall,
281
+ interopCallValue
282
+ };
283
+ }
284
+
285
+ // src/core/resources/interop/attributes/bundle.ts
286
+ function createBundleAttributes(codec) {
287
+ const executionAddress = (executor) => codec.encode("executionAddress", [executor]);
288
+ const unbundlerAddress = (addr) => codec.encode("unbundlerAddress", [addr]);
289
+ const useFixedFee = (enabled) => codec.encode("useFixedFee", [enabled]);
290
+ return {
291
+ executionAddress,
292
+ unbundlerAddress,
293
+ useFixedFee
294
+ };
295
+ }
296
+
297
+ // src/core/resources/interop/attributes/resource.ts
298
+ function createAttributesResource(codec) {
299
+ return {
300
+ call: createCallAttributes(codec),
301
+ bundle: createBundleAttributes(codec)
302
+ };
303
+ }
304
+
305
+ // src/core/resources/interop/plan.ts
306
+ function preflightDirect(params, ctx) {
307
+ if (!params.actions?.length) {
308
+ throw new Error('route "direct" requires at least one action.');
309
+ }
310
+ const baseMatch = ctx.baseTokens.src.toLowerCase() === ctx.baseTokens.dst.toLowerCase();
311
+ if (!baseMatch) {
312
+ throw new Error('route "direct" requires matching base tokens between source and destination.');
313
+ }
314
+ for (const action of params.actions) {
315
+ switch (action.type) {
316
+ case "sendNative":
317
+ if (action.amount < 0n) {
318
+ throw new Error("sendNative.amount must be >= 0.");
319
+ }
320
+ break;
321
+ case "call":
322
+ if (action.value != null && action.value < 0n) {
323
+ throw new Error("call.value must be >= 0 when provided.");
324
+ }
325
+ break;
326
+ default:
327
+ throw new Error(
328
+ `route "direct" does not support ${action.type} actions; use the indirect route.`
329
+ );
330
+ }
331
+ }
332
+ }
333
+ function buildDirectBundle(params, ctx, attrs, interopFeeInfo) {
334
+ const totalActionValue = sumActionMsgValue(params.actions);
335
+ const starters = params.actions.map((action, index) => {
336
+ const to = ctx.codec.formatAddress(action.to);
337
+ const callAttributes = attrs.callAttributes[index] ?? [];
338
+ switch (action.type) {
339
+ case "sendNative":
340
+ return [to, "0x", callAttributes];
341
+ case "call":
342
+ return [to, action.data ?? "0x", callAttributes];
343
+ default:
344
+ throw new Error(`buildDirectBundle: unsupported action type "${action.type}".`);
345
+ }
346
+ });
347
+ return {
348
+ dstChain: ctx.codec.formatChain(ctx.dstChainId),
349
+ starters,
350
+ bundleAttributes: attrs.bundleAttributes,
351
+ approvals: interopFeeInfo.approval ? [interopFeeInfo.approval] : [],
352
+ interopFee: interopFeeInfo.fee,
353
+ quoteExtras: {
354
+ totalActionValue,
355
+ bridgedTokenTotal: 0n
356
+ }
357
+ };
358
+ }
359
+ function preflightIndirect(params, ctx) {
360
+ if (!params.actions?.length) {
361
+ throw new Error('route "indirect" requires at least one action.');
362
+ }
363
+ const hasErc20 = params.actions.some((a) => a.type === "sendErc20");
364
+ const baseMatches = ctx.baseTokens.src.toLowerCase() === ctx.baseTokens.dst.toLowerCase();
365
+ if (!hasErc20 && baseMatches) {
366
+ throw new Error(
367
+ 'route "indirect" requires ERC-20 actions or mismatched base tokens; use the direct route instead.'
368
+ );
369
+ }
370
+ for (const action of params.actions) {
371
+ switch (action.type) {
372
+ case "sendNative":
373
+ if (action.amount < 0n) {
374
+ throw new Error("sendNative.amount must be >= 0.");
375
+ }
376
+ break;
377
+ case "sendErc20":
378
+ if (action.amount < 0n) {
379
+ throw new Error("sendErc20.amount must be >= 0.");
380
+ }
381
+ break;
382
+ case "call":
383
+ if (action.value != null) {
384
+ if (action.value < 0n) {
385
+ throw new Error("call.value must be >= 0 when provided.");
386
+ }
387
+ if (action.value > 0n && !baseMatches) {
388
+ throw new Error("indirect route does not support call.value when base tokens differ.");
389
+ }
390
+ }
391
+ break;
392
+ default:
393
+ assertNever(action);
394
+ }
395
+ }
396
+ }
397
+ function buildIndirectBundle(params, ctx, attrs, starterData, interopFeeInfo) {
398
+ const totalActionValue = sumActionMsgValue(params.actions);
399
+ const bridgedTokenTotal = sumErc20Amounts(params.actions);
400
+ const approvalMap = /* @__PURE__ */ new Map();
401
+ for (const action of params.actions) {
402
+ if (action.type !== "sendErc20") continue;
403
+ const key = action.token.toLowerCase();
404
+ const existing = approvalMap.get(key);
405
+ if (existing) {
406
+ existing.amount += action.amount;
407
+ } else {
408
+ approvalMap.set(key, {
409
+ token: action.token,
410
+ spender: ctx.l2NativeTokenVault,
411
+ amount: action.amount
412
+ });
413
+ }
414
+ }
415
+ const approvals = Array.from(approvalMap.values());
416
+ if (interopFeeInfo.approval) approvals.push(interopFeeInfo.approval);
417
+ const starters = params.actions.map((action, index) => {
418
+ const callAttributes = attrs.callAttributes[index] ?? [];
419
+ if (starterData[index]?.assetRouterPayload) {
420
+ const l2AssetRouter = ctx.codec.formatAddress(ctx.l2AssetRouter);
421
+ return [l2AssetRouter, starterData[index].assetRouterPayload, callAttributes];
422
+ }
423
+ const directTo = ctx.codec.formatAddress(action.to);
424
+ switch (action.type) {
425
+ case "sendNative":
426
+ return [directTo, "0x", callAttributes];
427
+ case "call":
428
+ return [directTo, action.data ?? "0x", callAttributes];
429
+ case "sendErc20":
430
+ throw new Error("buildIndirectBundle: missing assetRouterPayload for sendErc20 action.");
431
+ default:
432
+ return assertNever(action);
433
+ }
434
+ });
435
+ return {
436
+ dstChain: ctx.codec.formatChain(ctx.dstChainId),
437
+ starters,
438
+ bundleAttributes: attrs.bundleAttributes,
439
+ approvals,
440
+ interopFee: interopFeeInfo.fee,
441
+ quoteExtras: {
442
+ totalActionValue,
443
+ bridgedTokenTotal
444
+ }
445
+ };
446
+ }
447
+
448
+ // src/core/resources/interop/protocol.ts
449
+ var MIN_INTEROP_PROTOCOL = 31;
450
+ function assertProtocolVersion(chainId, protocolVersion) {
451
+ if (protocolVersion[1] < MIN_INTEROP_PROTOCOL) {
452
+ throw createError("VALIDATION", {
453
+ resource: "interop",
454
+ operation: OP_INTEROP.context.protocolVersion,
455
+ message: `Interop requires protocol version 31.0+. Found: ${protocolVersion[1]}.${protocolVersion[2]} for chain: ${chainId}.`,
456
+ context: {
457
+ chainId,
458
+ requiredMinor: MIN_INTEROP_PROTOCOL,
459
+ semver: protocolVersion
460
+ }
461
+ });
462
+ }
463
+ }
464
+
465
+ // src/core/resources/interop/finalization.ts
466
+ var DEFAULT_POLL_MS = 1e3;
467
+ var DEFAULT_TIMEOUT_MS = 3e5;
468
+ function resolveIdsFromWaitable(input) {
469
+ if (typeof input === "string") {
470
+ return { l2SrcTxHash: input };
471
+ }
472
+ return {
473
+ l2SrcTxHash: input.l2SrcTxHash,
474
+ bundleHash: input.bundleHash,
475
+ dstExecTxHash: input.dstExecTxHash
476
+ };
477
+ }
478
+ function parseBundleSentFromReceipt(input) {
479
+ const { receipt, interopCenter, interopBundleSentTopic, decodeInteropBundleSent } = input;
480
+ const bundleSentLog = receipt.logs.find(
481
+ (log) => log.address.toLowerCase() === interopCenter.toLowerCase() && log.topics[0].toLowerCase() === interopBundleSentTopic.toLowerCase()
482
+ );
483
+ if (!bundleSentLog) {
484
+ throw createError("STATE", {
485
+ resource: "interop",
486
+ operation: OP_INTEROP.svc.status.parseSentLog,
487
+ message: "Failed to locate InteropBundleSent event in source receipt.",
488
+ context: { receipt, interopCenter }
489
+ });
490
+ }
491
+ const decoded = decodeInteropBundleSent({
492
+ data: bundleSentLog.data,
493
+ topics: bundleSentLog.topics
494
+ });
495
+ return { bundleHash: decoded.bundleHash, dstChainId: decoded.destinationChainId };
496
+ }
497
+ function parseBundleReceiptInfo(params) {
498
+ const {
499
+ rawReceipt,
500
+ interopCenter,
501
+ interopBundleSentTopic,
502
+ decodeInteropBundleSent,
503
+ decodeL1MessageData,
504
+ l2SrcTxHash
505
+ } = params;
506
+ let l2ToL1LogIndex = -1;
507
+ let l1MessageData = null;
508
+ let found;
509
+ for (const log of rawReceipt.logs) {
510
+ if (isL1MessageSentLog(log)) {
511
+ l2ToL1LogIndex += 1;
512
+ try {
513
+ l1MessageData = decodeL1MessageData(log);
514
+ } catch (e) {
515
+ throw createError("STATE", {
516
+ resource: "interop",
517
+ operation: OP_INTEROP.svc.status.parseSentLog,
518
+ message: "Failed to decode L1MessageSent log data for interop bundle.",
519
+ context: { l2SrcTxHash, l2ToL1LogIndex },
520
+ cause: e
521
+ });
522
+ }
523
+ continue;
524
+ }
525
+ if (log.address.toLowerCase() !== interopCenter.toLowerCase() || log.topics[0].toLowerCase() !== interopBundleSentTopic.toLowerCase())
526
+ continue;
527
+ const decoded = decodeInteropBundleSent({
528
+ data: log.data,
529
+ topics: log.topics
530
+ });
531
+ found = {
532
+ bundleHash: decoded.bundleHash,
533
+ dstChainId: decoded.destinationChainId,
534
+ sourceChainId: decoded.sourceChainId
535
+ };
536
+ break;
537
+ }
538
+ if (!found) {
539
+ throw createError("STATE", {
540
+ resource: "interop",
541
+ operation: OP_INTEROP.svc.status.parseSentLog,
542
+ message: "Failed to locate InteropBundleSent event in source receipt.",
543
+ context: { l2SrcTxHash, interopCenter }
544
+ });
545
+ }
546
+ if (!l1MessageData) {
547
+ throw createError("STATE", {
548
+ resource: "interop",
549
+ operation: OP_INTEROP.svc.status.parseSentLog,
550
+ message: "Failed to locate L1MessageSent log data for interop bundle.",
551
+ context: { l2SrcTxHash, interopCenter }
552
+ });
553
+ }
554
+ return {
555
+ bundleHash: found.bundleHash,
556
+ dstChainId: found.dstChainId,
557
+ sourceChainId: found.sourceChainId,
558
+ l1MessageData,
559
+ l2ToL1LogIndex,
560
+ txNumberInBatch: Number(rawReceipt.transactionIndex),
561
+ rawReceipt
562
+ };
563
+ }
564
+ function getBundleEncodedData(messageData) {
565
+ const prefix = `0x${messageData.slice(2, 4)}`;
566
+ if (prefix !== BUNDLE_IDENTIFIER) {
567
+ throw createError("STATE", {
568
+ resource: "interop",
569
+ operation: OP_INTEROP.wait,
570
+ message: "Unexpected bundle prefix in L1MessageSent data.",
571
+ context: { prefix, expected: BUNDLE_IDENTIFIER }
572
+ });
573
+ }
574
+ return `0x${messageData.slice(4)}`;
575
+ }
576
+ function buildFinalizationInfo(ids, bundleInfo, proof, messageData) {
577
+ const messageProof = {
578
+ chainId: bundleInfo.sourceChainId,
579
+ l1BatchNumber: proof.batchNumber,
580
+ l2MessageIndex: proof.id,
581
+ message: {
582
+ txNumberInBatch: bundleInfo.txNumberInBatch,
583
+ sender: L2_INTEROP_CENTER_ADDRESS,
584
+ data: messageData
585
+ },
586
+ proof: proof.proof
587
+ };
588
+ return {
589
+ l2SrcTxHash: ids.l2SrcTxHash,
590
+ bundleHash: bundleInfo.bundleHash,
591
+ dstChainId: bundleInfo.dstChainId,
592
+ proof: messageProof,
593
+ encodedData: getBundleEncodedData(messageData)
594
+ };
595
+ }
596
+
597
+ // src/core/resources/withdrawals/gas.ts
598
+ function makeGasQuote2(p) {
599
+ return {
600
+ gasLimit: p.gasLimit,
601
+ maxFeePerGas: p.maxFeePerGas,
602
+ maxPriorityFeePerGas: p.maxPriorityFeePerGas,
603
+ maxCost: p.gasLimit * p.maxFeePerGas
604
+ };
605
+ }
606
+ async function fetchFees2(estimator) {
607
+ try {
608
+ const fees = await estimator.estimateFeesPerGas();
609
+ if (fees.maxFeePerGas != null) {
610
+ return {
611
+ maxFeePerGas: fees.maxFeePerGas,
612
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
613
+ };
614
+ }
615
+ if (fees.gasPrice != null) {
616
+ return {
617
+ maxFeePerGas: fees.gasPrice,
618
+ maxPriorityFeePerGas: 0n
619
+ };
620
+ }
621
+ } catch {
622
+ }
623
+ try {
624
+ const gp = await estimator.getGasPrice();
625
+ return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
626
+ } catch {
627
+ return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
628
+ }
629
+ }
630
+ async function quoteL2Gas2(input) {
631
+ const { estimator, tx, overrides } = input;
632
+ const market = await fetchFees2(estimator);
633
+ const o = overrides;
634
+ const maxFeePerGas = o?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : market.maxFeePerGas);
635
+ const maxPriorityFeePerGas = o?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : market.maxPriorityFeePerGas);
636
+ const explicitGasLimit = o?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
637
+ if (explicitGasLimit != null) {
638
+ return makeGasQuote2({
639
+ gasLimit: explicitGasLimit,
640
+ maxFeePerGas,
641
+ maxPriorityFeePerGas
642
+ });
643
+ }
644
+ try {
645
+ const est = await estimator.estimateGas(tx);
646
+ const buffered = BigInt(est) * (100n + BUFFER) / 100n;
647
+ return makeGasQuote2({
648
+ gasLimit: buffered,
649
+ maxFeePerGas,
650
+ maxPriorityFeePerGas
651
+ });
652
+ } catch (err) {
653
+ console.warn("Failed to estimate L2 gas for withdrawal.", err);
654
+ return void 0;
655
+ }
656
+ }
657
+
658
+ export { DEFAULT_POLL_MS, DEFAULT_TIMEOUT_MS, ZERO_HASH, applyPriorityL2GasLimitBuffer, assertProtocolVersion, buildDirectBundle, buildFeeBreakdown, buildFinalizationInfo, buildIndirectBundle, createAttributesResource, createNTVCodec, derivePriorityBodyGasEstimateCap, derivePriorityTxGasBreakdown, isInteropFinalizationInfo, parseBundleReceiptInfo, parseBundleSentFromReceipt, pickInteropRoute, preflightDirect, preflightIndirect, quoteL1Gas, quoteL2BaseCost, quoteL2Gas, quoteL2Gas2, resolveCreateDepositL1GasLimit, resolveIdsFromWaitable, toGasOverrides };
@@ -1,4 +1,4 @@
1
- import { isZKsyncError, createError, shapeCause } from './chunk-RI73VJSH.js';
1
+ import { isZKsyncError, createError, shapeCause } from './chunk-JXR5V5YK.js';
2
2
 
3
3
  // src/core/errors/error-ops.ts
4
4
  function resolveMessage(op, msg) {