@matterlabs/zksync-js 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) 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.js +7 -6
  4. package/dist/adapters/ethers/index.cjs +501 -242
  5. package/dist/adapters/ethers/index.cjs.map +1 -1
  6. package/dist/adapters/ethers/index.js +10 -9
  7. package/dist/adapters/ethers/resources/deposits/routes/priority.d.ts +12 -0
  8. package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +4 -0
  9. package/dist/adapters/ethers/resources/interop/index.d.ts +14 -14
  10. package/dist/adapters/ethers/resources/interop/resolvers.d.ts +3 -8
  11. package/dist/adapters/ethers/resources/interop/routes/types.d.ts +2 -1
  12. package/dist/adapters/ethers/resources/interop/services/erc20.d.ts +10 -0
  13. package/dist/adapters/ethers/resources/interop/services/fee.d.ts +12 -0
  14. package/dist/adapters/ethers/resources/interop/services/finalization/index.d.ts +1 -1
  15. package/dist/adapters/ethers/resources/interop/services/finalization/polling.d.ts +1 -1
  16. package/dist/adapters/ethers/resources/interop/types.d.ts +6 -14
  17. package/dist/adapters/ethers/sdk.cjs +912 -252
  18. package/dist/adapters/ethers/sdk.cjs.map +1 -1
  19. package/dist/adapters/ethers/sdk.d.ts +6 -1
  20. package/dist/adapters/ethers/sdk.js +8 -7
  21. package/dist/adapters/viem/client.cjs +8 -4
  22. package/dist/adapters/viem/client.cjs.map +1 -1
  23. package/dist/adapters/viem/client.js +7 -6
  24. package/dist/adapters/viem/index.cjs +315 -73
  25. package/dist/adapters/viem/index.cjs.map +1 -1
  26. package/dist/adapters/viem/index.js +10 -9
  27. package/dist/adapters/viem/resources/deposits/routes/priority.d.ts +13 -0
  28. package/dist/adapters/viem/resources/deposits/services/gas.d.ts +4 -0
  29. package/dist/adapters/viem/sdk.cjs +307 -69
  30. package/dist/adapters/viem/sdk.cjs.map +1 -1
  31. package/dist/adapters/viem/sdk.js +7 -7
  32. package/dist/{chunk-E3KP7XCG.js → chunk-3HHUZXSV.js} +1 -1
  33. package/dist/{chunk-UDBRUBEK.js → chunk-5RRJDPAJ.js} +2 -2
  34. package/dist/{chunk-EDWBCPO3.js → chunk-75IOOODG.js} +253 -53
  35. package/dist/{chunk-R5WRFPK2.js → chunk-7CAVFIMW.js} +5 -4
  36. package/dist/chunk-BWKWWLY4.js +9 -0
  37. package/dist/{chunk-4S4XDA4N.js → chunk-DYJKK5FW.js} +17 -15
  38. package/dist/{chunk-5L6EYUJB.js → chunk-EOBXYHTZ.js} +35 -7
  39. package/dist/{chunk-53MC5BR2.js → chunk-HP3EWKJL.js} +1 -1
  40. package/dist/{chunk-HI64OOAR.js → chunk-J47RI3G7.js} +1 -1
  41. package/dist/{chunk-RI73VJSH.js → chunk-JY62QO3W.js} +44 -21
  42. package/dist/{chunk-QQ2OR434.js → chunk-MT4X5FEO.js} +18 -2
  43. package/dist/{chunk-2RIARDXZ.js → chunk-OTXPSNNC.js} +5 -4
  44. package/dist/{chunk-5R7L5NM5.js → chunk-XDRCN4FC.js} +2 -2
  45. package/dist/{chunk-JHO2UQ5F.js → chunk-XKRNLFET.js} +394 -200
  46. package/dist/core/constants.cjs +17 -1
  47. package/dist/core/constants.cjs.map +1 -1
  48. package/dist/core/constants.d.ts +9 -1
  49. package/dist/core/constants.js +1 -1
  50. package/dist/core/index.cjs +52 -24
  51. package/dist/core/index.cjs.map +1 -1
  52. package/dist/core/index.js +6 -5
  53. package/dist/core/internal/abis/IERC7786Attributes.d.ts +21 -11
  54. package/dist/core/internal/abis/IInteropCenter.d.ts +4 -0
  55. package/dist/core/resources/deposits/priority.d.ts +37 -0
  56. package/dist/core/resources/interop/attributes/bundle.d.ts +1 -0
  57. package/dist/core/resources/interop/attributes/resource.d.ts +1 -0
  58. package/dist/core/resources/interop/plan.d.ts +11 -3
  59. package/dist/core/rpc/types.d.ts +1 -0
  60. package/dist/core/rpc/zks.d.ts +5 -1
  61. package/dist/core/types/errors.d.ts +5 -0
  62. package/dist/core/types/flows/interop.d.ts +11 -18
  63. package/dist/index.cjs +69 -25
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.js +6 -5
  66. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
- export { createViemClient } from '../../chunk-2RIARDXZ.js';
2
- import '../../chunk-5R7L5NM5.js';
3
- import '../../chunk-4S4XDA4N.js';
4
- import '../../chunk-53MC5BR2.js';
5
- import '../../chunk-RI73VJSH.js';
6
- import '../../chunk-QQ2OR434.js';
1
+ export { createViemClient } from '../../chunk-OTXPSNNC.js';
2
+ import '../../chunk-XDRCN4FC.js';
3
+ import '../../chunk-BWKWWLY4.js';
4
+ import '../../chunk-HP3EWKJL.js';
5
+ import '../../chunk-DYJKK5FW.js';
6
+ import '../../chunk-JY62QO3W.js';
7
+ import '../../chunk-MT4X5FEO.js';
@@ -33,7 +33,15 @@ var TX_OVERHEAD_GAS = 10000n;
33
33
  var TX_MEMORY_OVERHEAD_GAS = 10n;
34
34
  var DEFAULT_PUBDATA_BYTES = 155n;
35
35
  var DEFAULT_ABI_BYTES = 400n;
36
- var SAFE_L1_BRIDGE_GAS = 800000n;
36
+ var SAFE_L1_BRIDGE_GAS = 3000000n;
37
+ var L1_TX_INTRINSIC_L2_GAS = 167157n;
38
+ var L1_TX_INTRINSIC_PUBDATA = 88n;
39
+ var L1_TX_MIN_L2_GAS_BASE = 173484n;
40
+ var L1_TX_DELTA_544_ENCODING_BYTES = 1656n;
41
+ var L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473n;
42
+ var L1_TX_DELTA_FACTORY_DEPS_PUBDATA = 64n;
43
+ var TX_SLOT_OVERHEAD_L2_GAS = 10000n;
44
+ var PRIORITY_TX_MAX_GAS_LIMIT = 72000000n;
37
45
 
38
46
  // src/core/utils/addr.ts
39
47
  function isAddressEq(a, b) {
@@ -407,6 +415,7 @@ function normalizeProof(p) {
407
415
  const raw = p ?? {};
408
416
  const idRaw = raw?.id ?? raw?.index;
409
417
  const bnRaw = raw?.batch_number ?? raw?.batchNumber;
418
+ const gwBlockNumberRaw = raw?.gatewayBlockNumber;
410
419
  if (idRaw == null || bnRaw == null) {
411
420
  throw createError("RPC", {
412
421
  resource: "zksrpc",
@@ -427,7 +436,8 @@ function normalizeProof(p) {
427
436
  id: toBig(idRaw),
428
437
  batchNumber: toBig(bnRaw),
429
438
  proof: toHexArray(raw?.proof),
430
- root: raw.root
439
+ root: raw.root,
440
+ gatewayBlockNumber: gwBlockNumberRaw != null ? toBig(gwBlockNumberRaw) : void 0
431
441
  };
432
442
  } catch (e) {
433
443
  if (isZKsyncError(e)) throw e;
@@ -704,13 +714,15 @@ function createZksRpc(transport) {
704
714
  );
705
715
  },
706
716
  // Fetches a proof for an L2→L1 log emitted in the given transaction.
707
- async getL2ToL1LogProof(txHash, index) {
717
+ async getL2ToL1LogProof(txHash, index, proofTarget) {
708
718
  return withRpcOp(
709
719
  "zksrpc.getL2ToL1LogProof",
710
720
  "Failed to fetch L2\u2192L1 log proof.",
711
- { txHash, index },
721
+ { txHash, index, proofTarget },
712
722
  async () => {
713
- const proof = await transport(METHODS.getL2ToL1LogProof, [txHash, index]);
723
+ const params = [txHash, index];
724
+ if (proofTarget != void 0) params.push(proofTarget);
725
+ const proof = await transport(METHODS.getL2ToL1LogProof, params);
714
726
  if (!proof) {
715
727
  throw createError("STATE", {
716
728
  resource: "zksrpc",
@@ -5718,11 +5730,10 @@ async function quoteL1Gas(input) {
5718
5730
  const est = await estimator.estimateGas(tx);
5719
5731
  const buffered = BigInt(est) * (100n + BUFFER) / 100n;
5720
5732
  return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
5721
- } catch (err) {
5733
+ } catch {
5722
5734
  if (fallbackGasLimit != null) {
5723
5735
  return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
5724
5736
  }
5725
- console.warn("L1 gas estimation failed", err);
5726
5737
  return void 0;
5727
5738
  }
5728
5739
  }
@@ -5760,8 +5771,7 @@ async function quoteL2Gas(input) {
5760
5771
  maxFeePerGas,
5761
5772
  gasPerPubdata: pp
5762
5773
  });
5763
- } catch (err) {
5764
- console.warn("L2 gas estimation failed", err);
5774
+ } catch {
5765
5775
  return makeGasQuote({
5766
5776
  gasLimit: l2GasLimit ?? 0n,
5767
5777
  maxFeePerGas,
@@ -5895,8 +5905,22 @@ async function determineNonBaseL2Gas(input) {
5895
5905
  try {
5896
5906
  const l2TokenAddress = input.knownL2Token ?? (ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).read.l2TokenAddress([l1Token]));
5897
5907
  if (l2TokenAddress === viem.zeroAddress) {
5908
+ if (input.undeployedGasLimit != null) {
5909
+ return quoteL2Gas2({
5910
+ ctx,
5911
+ route,
5912
+ overrideGasLimit: input.undeployedGasLimit
5913
+ });
5914
+ }
5898
5915
  return fallbackQuote();
5899
5916
  }
5917
+ if (input.priorityFloorGasLimit != null) {
5918
+ return quoteL2Gas2({
5919
+ ctx,
5920
+ route,
5921
+ overrideGasLimit: input.priorityFloorGasLimit
5922
+ });
5923
+ }
5900
5924
  const modelTx = {
5901
5925
  to: input.modelTx?.to ?? ctx.sender,
5902
5926
  from: input.modelTx?.from ?? ctx.sender,
@@ -5912,8 +5936,7 @@ async function determineNonBaseL2Gas(input) {
5912
5936
  return fallbackQuote();
5913
5937
  }
5914
5938
  return gas;
5915
- } catch (err) {
5916
- console.warn("Failed to determine non-base deposit L2 gas; defaulting to safe gas limit.", err);
5939
+ } catch {
5917
5940
  return fallbackQuote();
5918
5941
  }
5919
5942
  }
@@ -5930,7 +5953,9 @@ async function determineEthNonBaseL2Gas(input) {
5930
5953
  route: "eth-nonbase",
5931
5954
  l1Token: input.ctx.resolvedToken?.l1 ?? FORMAL_ETH_ADDRESS,
5932
5955
  knownL2Token: input.ctx.resolvedToken?.l2,
5933
- modelTx: input.modelTx
5956
+ modelTx: input.modelTx,
5957
+ priorityFloorGasLimit: input.priorityFloorGasLimit,
5958
+ undeployedGasLimit: input.undeployedGasLimit
5934
5959
  });
5935
5960
  }
5936
5961
 
@@ -5984,34 +6009,123 @@ function buildFeeBreakdown(p) {
5984
6009
  };
5985
6010
  }
5986
6011
 
6012
+ // src/core/resources/deposits/priority.ts
6013
+ var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
6014
+ var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
6015
+ var maxBigInt = (a, b) => a > b ? a : b;
6016
+ var ceilDiv = (a, b) => (a + b - 1n) / b;
6017
+ function derivePriorityTxGasBreakdown(input) {
6018
+ const factoryDepsCount = input.factoryDepsCount ?? 0n;
6019
+ const minBodyGas = maxBigInt(
6020
+ L1_TX_INTRINSIC_L2_GAS + ceilDiv(
6021
+ input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
6022
+ PRIORITY_TX_ENCODING_STEP_BYTES
6023
+ ) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
6024
+ L1_TX_MIN_L2_GAS_BASE
6025
+ ) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
6026
+ const overhead = maxBigInt(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
6027
+ const derivedBodyGas = minBodyGas;
6028
+ return {
6029
+ encodedLength: input.encodedLength,
6030
+ minBodyGas,
6031
+ overhead,
6032
+ derivedBodyGas,
6033
+ derivedL2GasLimit: derivedBodyGas + overhead,
6034
+ priorityTxMaxGasLimit: PRIORITY_TX_MAX_GAS_LIMIT,
6035
+ priorityTxMaxGasLimitExceeded: derivedBodyGas > PRIORITY_TX_MAX_GAS_LIMIT
6036
+ };
6037
+ }
6038
+ function derivePriorityBodyGasEstimateCap(input) {
6039
+ return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
6040
+ }
6041
+
6042
+ // src/adapters/viem/resources/deposits/routes/priority.ts
6043
+ var EMPTY_BYTES = "0x";
6044
+ var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
6045
+ var L2_CANONICAL_TRANSACTION_PARAMETER = {
6046
+ type: "tuple",
6047
+ components: [
6048
+ { name: "txType", type: "uint256" },
6049
+ { name: "from", type: "uint256" },
6050
+ { name: "to", type: "uint256" },
6051
+ { name: "gasLimit", type: "uint256" },
6052
+ { name: "gasPerPubdataByteLimit", type: "uint256" },
6053
+ { name: "maxFeePerGas", type: "uint256" },
6054
+ { name: "maxPriorityFeePerGas", type: "uint256" },
6055
+ { name: "paymaster", type: "uint256" },
6056
+ { name: "nonce", type: "uint256" },
6057
+ { name: "value", type: "uint256" },
6058
+ { name: "reserved", type: "uint256[4]" },
6059
+ { name: "data", type: "bytes" },
6060
+ { name: "signature", type: "bytes" },
6061
+ { name: "factoryDeps", type: "uint256[]" },
6062
+ { name: "paymasterInput", type: "bytes" },
6063
+ { name: "reservedDynamic", type: "bytes" }
6064
+ ]
6065
+ };
6066
+ function hexByteLength(hex) {
6067
+ return BigInt(Math.max(hex.length - 2, 0) / 2);
6068
+ }
6069
+ function getPriorityTxEncodedLength(input) {
6070
+ const encoded = viem.encodeAbiParameters(
6071
+ [L2_CANONICAL_TRANSACTION_PARAMETER],
6072
+ [
6073
+ {
6074
+ txType: 0n,
6075
+ from: BigInt(input.sender),
6076
+ to: BigInt(input.l2Contract),
6077
+ gasLimit: 0n,
6078
+ gasPerPubdataByteLimit: input.gasPerPubdata,
6079
+ maxFeePerGas: 0n,
6080
+ maxPriorityFeePerGas: 0n,
6081
+ paymaster: 0n,
6082
+ nonce: 0n,
6083
+ value: input.l2Value,
6084
+ reserved: ZERO_RESERVED_WORDS,
6085
+ data: input.l2Calldata,
6086
+ signature: EMPTY_BYTES,
6087
+ factoryDeps: input.factoryDepsHashes ?? [],
6088
+ paymasterInput: EMPTY_BYTES,
6089
+ reservedDynamic: EMPTY_BYTES
6090
+ }
6091
+ ]
6092
+ );
6093
+ return hexByteLength(encoded);
6094
+ }
6095
+ function getPriorityTxGasBreakdown(input) {
6096
+ return derivePriorityTxGasBreakdown({
6097
+ encodedLength: getPriorityTxEncodedLength(input),
6098
+ gasPerPubdata: input.gasPerPubdata,
6099
+ factoryDepsCount: BigInt(input.factoryDepsHashes?.length ?? 0)
6100
+ });
6101
+ }
6102
+
5987
6103
  // src/adapters/viem/resources/deposits/routes/eth.ts
5988
6104
  var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
6105
+ var EMPTY_BYTES2 = "0x";
5989
6106
  function routeEthDirect() {
5990
6107
  return {
5991
6108
  async build(p, ctx) {
5992
- const l2TxModel = {
5993
- to: p.to ?? ctx.sender,
5994
- from: ctx.sender,
5995
- data: "0x",
5996
- value: p.amount
5997
- };
6109
+ const l2Contract = p.to ?? ctx.sender;
6110
+ const l2Value = p.amount;
6111
+ const l2Calldata = EMPTY_BYTES2;
6112
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
6113
+ sender: ctx.sender,
6114
+ l2Contract,
6115
+ l2Value,
6116
+ l2Calldata,
6117
+ gasPerPubdata: ctx.gasPerPubdata
6118
+ });
6119
+ const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
5998
6120
  const l2GasParams = await quoteL2Gas2({
5999
6121
  ctx,
6000
6122
  route: "eth-base",
6001
- l2TxForModeling: l2TxModel,
6002
- overrideGasLimit: ctx.l2GasLimit,
6003
- stateOverrides: {
6004
- [ctx.sender]: {
6005
- balance: "0xffffffffffffffffffff"
6006
- }
6007
- }
6123
+ overrideGasLimit: quotedL2GasLimit
6008
6124
  });
6009
6125
  if (!l2GasParams) {
6010
6126
  throw new Error("Failed to estimate L2 gas for deposit.");
6011
6127
  }
6012
6128
  const baseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2GasParams.gasLimit });
6013
- const l2Contract = p.to ?? ctx.sender;
6014
- const l2Value = p.amount;
6015
6129
  const mintValue = baseCost + ctx.operatorTip + l2Value;
6016
6130
  const req = buildDirectRequestStruct({
6017
6131
  chainId: ctx.chainIdL2,
@@ -6080,6 +6194,59 @@ function routeEthDirect() {
6080
6194
  };
6081
6195
  }
6082
6196
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
6197
+ var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
6198
+ async function getPriorityGasModel(input) {
6199
+ try {
6200
+ const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
6201
+ const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
6202
+ const l1ChainId = BigInt(await input.ctx.client.l1.getChainId());
6203
+ const isFirstBridge = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID || input.ctx.resolvedToken.originChainId === 0n;
6204
+ const erc20MetadataOriginChainId = isFirstBridge ? l1ChainId : input.ctx.resolvedToken.originChainId;
6205
+ const erc20Metadata = await l1NativeTokenVault.read.getERC20Getters([
6206
+ input.token,
6207
+ erc20MetadataOriginChainId
6208
+ ]);
6209
+ const bridgeMintCalldata = viem.encodeAbiParameters(
6210
+ [
6211
+ { type: "address", name: "originalCaller" },
6212
+ { type: "address", name: "receiver" },
6213
+ { type: "address", name: "originToken" },
6214
+ { type: "uint256", name: "amount" },
6215
+ { type: "bytes", name: "erc20Metadata" }
6216
+ ],
6217
+ [input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
6218
+ );
6219
+ const l2Calldata = isFirstBridge ? viem.encodeFunctionData({
6220
+ abi: IL2AssetRouter_default,
6221
+ functionName: "finalizeDeposit",
6222
+ args: [input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
6223
+ }) : await (async () => {
6224
+ return await l1AssetRouter.read.getDepositCalldata([
6225
+ input.ctx.sender,
6226
+ input.ctx.resolvedToken.assetId,
6227
+ bridgeMintCalldata
6228
+ ]);
6229
+ })();
6230
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
6231
+ sender: input.ctx.l1AssetRouter,
6232
+ l2Contract: L2_ASSET_ROUTER_ADDRESS,
6233
+ l2Value: 0n,
6234
+ l2Calldata,
6235
+ gasPerPubdata: input.ctx.gasPerPubdata
6236
+ });
6237
+ const model = {
6238
+ priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
6239
+ };
6240
+ if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === viem.zeroAddress) {
6241
+ model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
6242
+ minBodyGas: priorityFloorBreakdown.minBodyGas
6243
+ }) + priorityFloorBreakdown.overhead;
6244
+ }
6245
+ return model;
6246
+ } catch {
6247
+ return {};
6248
+ }
6249
+ }
6083
6250
  function routeErc20NonBase() {
6084
6251
  return {
6085
6252
  // TODO: do we even need these validations?
@@ -6110,11 +6277,33 @@ function routeErc20NonBase() {
6110
6277
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
6111
6278
  const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
6112
6279
  const assetRouter = ctx.l1AssetRouter;
6280
+ const receiver = p.to ?? ctx.sender;
6281
+ const secondBridgeCalldata = await wrapAs3(
6282
+ "INTERNAL",
6283
+ OP_DEPOSITS.nonbase.encodeCalldata,
6284
+ () => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, receiver)),
6285
+ {
6286
+ ctx: {
6287
+ where: "encodeSecondBridgeErc20Args",
6288
+ token: p.token,
6289
+ amount: p.amount.toString()
6290
+ },
6291
+ message: "Failed to encode bridging calldata."
6292
+ }
6293
+ );
6294
+ const priorityGasModel = await getPriorityGasModel({
6295
+ ctx,
6296
+ token: p.token,
6297
+ amount: p.amount,
6298
+ receiver
6299
+ });
6113
6300
  const l2Gas = await determineErc20L2Gas({
6114
6301
  ctx,
6115
6302
  l1Token: p.token,
6303
+ priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
6304
+ undeployedGasLimit: priorityGasModel.undeployedGasLimit,
6116
6305
  modelTx: {
6117
- to: p.to ?? ctx.sender,
6306
+ to: receiver,
6118
6307
  from: ctx.sender,
6119
6308
  data: "0x",
6120
6309
  value: 0n
@@ -6203,19 +6392,6 @@ function routeErc20NonBase() {
6203
6392
  });
6204
6393
  }
6205
6394
  }
6206
- const secondBridgeCalldata = await wrapAs3(
6207
- "INTERNAL",
6208
- OP_DEPOSITS.nonbase.encodeCalldata,
6209
- () => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, p.to ?? ctx.sender)),
6210
- {
6211
- ctx: {
6212
- where: "encodeSecondBridgeErc20Args",
6213
- token: p.token,
6214
- amount: p.amount.toString()
6215
- },
6216
- message: "Failed to encode bridging calldata."
6217
- }
6218
- );
6219
6395
  const requestStruct = {
6220
6396
  chainId: ctx.chainIdL2,
6221
6397
  mintValue,
@@ -6306,7 +6482,76 @@ function routeErc20NonBase() {
6306
6482
  }
6307
6483
  };
6308
6484
  }
6485
+
6486
+ // src/core/codec/ntv.ts
6487
+ function createNTVCodec(deps) {
6488
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
6489
+ const encoded = deps.encode(
6490
+ ["uint256", "address", "address"],
6491
+ [originChainId, ntvAddress, tokenAddress]
6492
+ );
6493
+ return deps.keccak256(encoded);
6494
+ }
6495
+ return {
6496
+ encodeAssetId
6497
+ };
6498
+ }
6499
+
6500
+ // src/adapters/viem/resources/deposits/routes/eth-nonbase.ts
6309
6501
  var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
6502
+ var ZERO_ASSET_ID2 = "0x0000000000000000000000000000000000000000000000000000000000000000";
6503
+ var ntvCodec = createNTVCodec({
6504
+ encode: (types, values) => viem.encodeAbiParameters(
6505
+ types.map((type, index) => ({ type, name: `arg${index}` })),
6506
+ values
6507
+ ),
6508
+ keccak256: viem.keccak256
6509
+ });
6510
+ async function getPriorityGasModel2(input) {
6511
+ try {
6512
+ const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
6513
+ const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
6514
+ const originChainId = input.ctx.resolvedToken.originChainId !== 0n ? input.ctx.resolvedToken.originChainId : BigInt(await input.ctx.client.l1.getChainId());
6515
+ const resolvedAssetId = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID2 ? ntvCodec.encodeAssetId(originChainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, ETH_ADDRESS) : input.ctx.resolvedToken.assetId;
6516
+ const erc20Metadata = await l1NativeTokenVault.read.getERC20Getters([
6517
+ ETH_ADDRESS,
6518
+ originChainId
6519
+ ]);
6520
+ const bridgeMintCalldata = viem.encodeAbiParameters(
6521
+ [
6522
+ { type: "address", name: "originalCaller" },
6523
+ { type: "address", name: "receiver" },
6524
+ { type: "address", name: "originToken" },
6525
+ { type: "uint256", name: "amount" },
6526
+ { type: "bytes", name: "erc20Metadata" }
6527
+ ],
6528
+ [input.ctx.sender, input.receiver, ETH_ADDRESS, input.amount, erc20Metadata]
6529
+ );
6530
+ const l2Calldata = await l1AssetRouter.read.getDepositCalldata([
6531
+ input.ctx.sender,
6532
+ resolvedAssetId,
6533
+ bridgeMintCalldata
6534
+ ]);
6535
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
6536
+ sender: input.ctx.l1AssetRouter,
6537
+ l2Contract: L2_ASSET_ROUTER_ADDRESS,
6538
+ l2Value: 0n,
6539
+ l2Calldata,
6540
+ gasPerPubdata: input.ctx.gasPerPubdata
6541
+ });
6542
+ const model = {
6543
+ priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
6544
+ };
6545
+ if (input.ctx.resolvedToken.l2.toLowerCase() === viem.zeroAddress) {
6546
+ model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
6547
+ minBodyGas: priorityFloorBreakdown.minBodyGas
6548
+ }) + priorityFloorBreakdown.overhead;
6549
+ }
6550
+ return model;
6551
+ } catch {
6552
+ return {};
6553
+ }
6554
+ }
6310
6555
  function routeEthNonBase() {
6311
6556
  return {
6312
6557
  // TODO: do we even need these validations?
@@ -6353,15 +6598,23 @@ function routeEthNonBase() {
6353
6598
  },
6354
6599
  async build(p, ctx) {
6355
6600
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
6601
+ const receiver = p.to ?? ctx.sender;
6602
+ const priorityGasModel = await getPriorityGasModel2({
6603
+ ctx,
6604
+ amount: p.amount,
6605
+ receiver
6606
+ });
6356
6607
  const l2TxModel = {
6357
- to: p.to ?? ctx.sender,
6608
+ to: receiver,
6358
6609
  from: ctx.sender,
6359
6610
  data: "0x",
6360
6611
  value: 0n
6361
6612
  };
6362
6613
  const l2Gas = await determineEthNonBaseL2Gas({
6363
6614
  ctx,
6364
- modelTx: l2TxModel
6615
+ modelTx: l2TxModel,
6616
+ priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
6617
+ undeployedGasLimit: priorityGasModel.undeployedGasLimit
6365
6618
  });
6366
6619
  if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
6367
6620
  const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
@@ -6410,12 +6663,12 @@ function routeEthNonBase() {
6410
6663
  const secondBridgeCalldata = await wrapAs4(
6411
6664
  "INTERNAL",
6412
6665
  OP_DEPOSITS.ethNonBase.encodeCalldata,
6413
- () => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, p.to ?? ctx.sender)),
6666
+ () => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, receiver)),
6414
6667
  {
6415
6668
  ctx: {
6416
6669
  where: "encodeSecondBridgeEthArgs",
6417
6670
  amount: p.amount.toString(),
6418
- to: p.to ?? ctx.sender
6671
+ to: receiver
6419
6672
  },
6420
6673
  message: "Failed to encode ETH bridging calldata."
6421
6674
  }
@@ -6516,6 +6769,7 @@ function routeEthNonBase() {
6516
6769
  };
6517
6770
  }
6518
6771
  var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
6772
+ var EMPTY_BYTES3 = "0x";
6519
6773
  function routeErc20Base() {
6520
6774
  return {
6521
6775
  async preflight(p, ctx) {
@@ -6543,17 +6797,21 @@ function routeErc20Base() {
6543
6797
  },
6544
6798
  async build(p, ctx) {
6545
6799
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
6546
- const l2TxModel = {
6547
- to: p.to ?? ctx.sender,
6548
- from: ctx.sender,
6549
- data: "0x",
6550
- value: 0n
6551
- };
6800
+ const l2Contract = p.to ?? ctx.sender;
6801
+ const l2Value = p.amount;
6802
+ const l2Calldata = EMPTY_BYTES3;
6803
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
6804
+ sender: ctx.sender,
6805
+ l2Contract,
6806
+ l2Value,
6807
+ l2Calldata,
6808
+ gasPerPubdata: ctx.gasPerPubdata
6809
+ });
6810
+ const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
6552
6811
  const l2Gas = await quoteL2Gas2({
6553
6812
  ctx,
6554
6813
  route: "erc20-base",
6555
- l2TxForModeling: l2TxModel,
6556
- overrideGasLimit: ctx.l2GasLimit
6814
+ overrideGasLimit: quotedL2GasLimit
6557
6815
  });
6558
6816
  if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
6559
6817
  const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
@@ -6605,8 +6863,8 @@ function routeErc20Base() {
6605
6863
  l2GasLimit: l2Gas.gasLimit,
6606
6864
  gasPerPubdata: ctx.gasPerPubdata,
6607
6865
  refundRecipient: ctx.refundRecipient,
6608
- l2Contract: p.to ?? ctx.sender,
6609
- l2Value: p.amount
6866
+ l2Contract,
6867
+ l2Value
6610
6868
  });
6611
6869
  let bridgeTx;
6612
6870
  let calldata;
@@ -6767,24 +7025,8 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
6767
7025
  }
6768
7026
  return { l2Receipt, l2TxHash };
6769
7027
  }
6770
-
6771
- // src/core/codec/ntv.ts
6772
- function createNTVCodec(deps) {
6773
- function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
6774
- const encoded = deps.encode(
6775
- ["uint256", "address", "address"],
6776
- [originChainId, ntvAddress, tokenAddress]
6777
- );
6778
- return deps.keccak256(encoded);
6779
- }
6780
- return {
6781
- encodeAssetId
6782
- };
6783
- }
6784
-
6785
- // src/adapters/viem/resources/tokens/tokens.ts
6786
7028
  var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
6787
- var ntvCodec = createNTVCodec({
7029
+ var ntvCodec2 = createNTVCodec({
6788
7030
  encode: (types, values) => viem.encodeAbiParameters(
6789
7031
  types.map((t, i) => ({ type: t, name: `arg${i}` })),
6790
7032
  values
@@ -6898,7 +7140,7 @@ function createTokensResource(client) {
6898
7140
  return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
6899
7141
  const baseAssetId = await getBaseTokenAssetId();
6900
7142
  const l1ChainId = await getL1ChainId();
6901
- const ethAssetId = ntvCodec.encodeAssetId(
7143
+ const ethAssetId = ntvCodec2.encodeAssetId(
6902
7144
  l1ChainId,
6903
7145
  L2_NATIVE_TOKEN_VAULT_ADDRESS,
6904
7146
  ETH_ADDRESS