@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,9 +1,10 @@
1
- export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-EDWBCPO3.js';
2
- import '../../chunk-5L6EYUJB.js';
3
- import '../../chunk-E3KP7XCG.js';
4
- export { createViemClient as createClient, createViemClient } from '../../chunk-2RIARDXZ.js';
5
- export { classifyReadinessFromRevert, createErrorHandlers, decodeRevert, registerErrorAbi, toZKsyncError } from '../../chunk-5R7L5NM5.js';
6
- import '../../chunk-4S4XDA4N.js';
7
- import '../../chunk-53MC5BR2.js';
8
- import '../../chunk-RI73VJSH.js';
9
- import '../../chunk-QQ2OR434.js';
1
+ export { buildDirectRequestStruct, createContractsResource, createDepositsResource, createFinalizationServices, createTokensResource, createViemSdk, createWithdrawalsResource, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs, getL2TransactionHashFromLogs } from '../../chunk-75IOOODG.js';
2
+ import '../../chunk-EOBXYHTZ.js';
3
+ import '../../chunk-3HHUZXSV.js';
4
+ export { createViemClient as createClient, createViemClient } from '../../chunk-OTXPSNNC.js';
5
+ export { classifyReadinessFromRevert, createErrorHandlers, decodeRevert, registerErrorAbi, toZKsyncError } from '../../chunk-XDRCN4FC.js';
6
+ import '../../chunk-BWKWWLY4.js';
7
+ import '../../chunk-HP3EWKJL.js';
8
+ import '../../chunk-DYJKK5FW.js';
9
+ import '../../chunk-JY62QO3W.js';
10
+ import '../../chunk-MT4X5FEO.js';
@@ -0,0 +1,13 @@
1
+ import { type Hex } from 'viem';
2
+ import { type PriorityTxGasBreakdown } from '../../../../../core/resources/deposits/priority.ts';
3
+ import type { Address } from '../../../../../core/types/primitives';
4
+ export type CanonicalPriorityTxInput = {
5
+ sender: Address;
6
+ l2Contract: Address;
7
+ l2Value: bigint;
8
+ l2Calldata: Hex;
9
+ gasPerPubdata: bigint;
10
+ factoryDepsHashes?: bigint[];
11
+ };
12
+ export declare function getPriorityTxEncodedLength(input: CanonicalPriorityTxInput): bigint;
13
+ export declare function getPriorityTxGasBreakdown(input: CanonicalPriorityTxInput): PriorityTxGasBreakdown;
@@ -30,8 +30,12 @@ export declare function determineErc20L2Gas(input: {
30
30
  ctx: BuildCtx;
31
31
  l1Token: Address;
32
32
  modelTx?: TransactionRequest;
33
+ priorityFloorGasLimit?: bigint;
34
+ undeployedGasLimit?: bigint;
33
35
  }): Promise<GasQuote | undefined>;
34
36
  export declare function determineEthNonBaseL2Gas(input: {
35
37
  ctx: BuildCtx;
36
38
  modelTx?: TransactionRequest;
39
+ priorityFloorGasLimit?: bigint;
40
+ undeployedGasLimit?: bigint;
37
41
  }): Promise<GasQuote | undefined>;
@@ -3709,7 +3709,15 @@ var TX_OVERHEAD_GAS = 10000n;
3709
3709
  var TX_MEMORY_OVERHEAD_GAS = 10n;
3710
3710
  var DEFAULT_PUBDATA_BYTES = 155n;
3711
3711
  var DEFAULT_ABI_BYTES = 400n;
3712
- var SAFE_L1_BRIDGE_GAS = 800000n;
3712
+ var SAFE_L1_BRIDGE_GAS = 3000000n;
3713
+ var L1_TX_INTRINSIC_L2_GAS = 167157n;
3714
+ var L1_TX_INTRINSIC_PUBDATA = 88n;
3715
+ var L1_TX_MIN_L2_GAS_BASE = 173484n;
3716
+ var L1_TX_DELTA_544_ENCODING_BYTES = 1656n;
3717
+ var L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473n;
3718
+ var L1_TX_DELTA_FACTORY_DEPS_PUBDATA = 64n;
3719
+ var TX_SLOT_OVERHEAD_L2_GAS = 10000n;
3720
+ var PRIORITY_TX_MAX_GAS_LIMIT = 72000000n;
3713
3721
 
3714
3722
  // src/adapters/viem/resources/utils.ts
3715
3723
  function encodeSecondBridgeArgs(token, amount, l2Receiver) {
@@ -4318,11 +4326,10 @@ async function quoteL1Gas(input) {
4318
4326
  const est = await estimator.estimateGas(tx);
4319
4327
  const buffered = BigInt(est) * (100n + BUFFER) / 100n;
4320
4328
  return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
4321
- } catch (err) {
4329
+ } catch {
4322
4330
  if (fallbackGasLimit != null) {
4323
4331
  return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
4324
4332
  }
4325
- console.warn("L1 gas estimation failed", err);
4326
4333
  return void 0;
4327
4334
  }
4328
4335
  }
@@ -4360,8 +4367,7 @@ async function quoteL2Gas(input) {
4360
4367
  maxFeePerGas,
4361
4368
  gasPerPubdata: pp
4362
4369
  });
4363
- } catch (err) {
4364
- console.warn("L2 gas estimation failed", err);
4370
+ } catch {
4365
4371
  return makeGasQuote({
4366
4372
  gasLimit: l2GasLimit ?? 0n,
4367
4373
  maxFeePerGas,
@@ -4495,8 +4501,22 @@ async function determineNonBaseL2Gas(input) {
4495
4501
  try {
4496
4502
  const l2TokenAddress = input.knownL2Token ?? (ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).read.l2TokenAddress([l1Token]));
4497
4503
  if (l2TokenAddress === viem.zeroAddress) {
4504
+ if (input.undeployedGasLimit != null) {
4505
+ return quoteL2Gas2({
4506
+ ctx,
4507
+ route,
4508
+ overrideGasLimit: input.undeployedGasLimit
4509
+ });
4510
+ }
4498
4511
  return fallbackQuote();
4499
4512
  }
4513
+ if (input.priorityFloorGasLimit != null) {
4514
+ return quoteL2Gas2({
4515
+ ctx,
4516
+ route,
4517
+ overrideGasLimit: input.priorityFloorGasLimit
4518
+ });
4519
+ }
4500
4520
  const modelTx = {
4501
4521
  to: input.modelTx?.to ?? ctx.sender,
4502
4522
  from: input.modelTx?.from ?? ctx.sender,
@@ -4512,8 +4532,7 @@ async function determineNonBaseL2Gas(input) {
4512
4532
  return fallbackQuote();
4513
4533
  }
4514
4534
  return gas;
4515
- } catch (err) {
4516
- console.warn("Failed to determine non-base deposit L2 gas; defaulting to safe gas limit.", err);
4535
+ } catch {
4517
4536
  return fallbackQuote();
4518
4537
  }
4519
4538
  }
@@ -4530,7 +4549,9 @@ async function determineEthNonBaseL2Gas(input) {
4530
4549
  route: "eth-nonbase",
4531
4550
  l1Token: input.ctx.resolvedToken?.l1 ?? FORMAL_ETH_ADDRESS,
4532
4551
  knownL2Token: input.ctx.resolvedToken?.l2,
4533
- modelTx: input.modelTx
4552
+ modelTx: input.modelTx,
4553
+ priorityFloorGasLimit: input.priorityFloorGasLimit,
4554
+ undeployedGasLimit: input.undeployedGasLimit
4534
4555
  });
4535
4556
  }
4536
4557
 
@@ -4584,34 +4605,123 @@ function buildFeeBreakdown(p) {
4584
4605
  };
4585
4606
  }
4586
4607
 
4608
+ // src/core/resources/deposits/priority.ts
4609
+ var PRIORITY_TX_ENCODING_STEP_BYTES = 544n;
4610
+ var DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER = 6n;
4611
+ var maxBigInt = (a, b) => a > b ? a : b;
4612
+ var ceilDiv = (a, b) => (a + b - 1n) / b;
4613
+ function derivePriorityTxGasBreakdown(input) {
4614
+ const factoryDepsCount = input.factoryDepsCount ?? 0n;
4615
+ const minBodyGas = maxBigInt(
4616
+ L1_TX_INTRINSIC_L2_GAS + ceilDiv(
4617
+ input.encodedLength * L1_TX_DELTA_544_ENCODING_BYTES,
4618
+ PRIORITY_TX_ENCODING_STEP_BYTES
4619
+ ) + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_L2_GAS,
4620
+ L1_TX_MIN_L2_GAS_BASE
4621
+ ) + L1_TX_INTRINSIC_PUBDATA * input.gasPerPubdata + factoryDepsCount * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * input.gasPerPubdata;
4622
+ const overhead = maxBigInt(TX_SLOT_OVERHEAD_L2_GAS, TX_MEMORY_OVERHEAD_GAS * input.encodedLength);
4623
+ const derivedBodyGas = minBodyGas;
4624
+ return {
4625
+ encodedLength: input.encodedLength,
4626
+ minBodyGas,
4627
+ overhead,
4628
+ derivedBodyGas,
4629
+ derivedL2GasLimit: derivedBodyGas + overhead,
4630
+ priorityTxMaxGasLimit: PRIORITY_TX_MAX_GAS_LIMIT,
4631
+ priorityTxMaxGasLimitExceeded: derivedBodyGas > PRIORITY_TX_MAX_GAS_LIMIT
4632
+ };
4633
+ }
4634
+ function derivePriorityBodyGasEstimateCap(input) {
4635
+ return input.minBodyGas * (input.multiplier ?? DEFAULT_PRIORITY_BODY_GAS_ESTIMATE_MULTIPLIER);
4636
+ }
4637
+
4638
+ // src/adapters/viem/resources/deposits/routes/priority.ts
4639
+ var EMPTY_BYTES = "0x";
4640
+ var ZERO_RESERVED_WORDS = [0n, 0n, 0n, 0n];
4641
+ var L2_CANONICAL_TRANSACTION_PARAMETER = {
4642
+ type: "tuple",
4643
+ components: [
4644
+ { name: "txType", type: "uint256" },
4645
+ { name: "from", type: "uint256" },
4646
+ { name: "to", type: "uint256" },
4647
+ { name: "gasLimit", type: "uint256" },
4648
+ { name: "gasPerPubdataByteLimit", type: "uint256" },
4649
+ { name: "maxFeePerGas", type: "uint256" },
4650
+ { name: "maxPriorityFeePerGas", type: "uint256" },
4651
+ { name: "paymaster", type: "uint256" },
4652
+ { name: "nonce", type: "uint256" },
4653
+ { name: "value", type: "uint256" },
4654
+ { name: "reserved", type: "uint256[4]" },
4655
+ { name: "data", type: "bytes" },
4656
+ { name: "signature", type: "bytes" },
4657
+ { name: "factoryDeps", type: "uint256[]" },
4658
+ { name: "paymasterInput", type: "bytes" },
4659
+ { name: "reservedDynamic", type: "bytes" }
4660
+ ]
4661
+ };
4662
+ function hexByteLength(hex) {
4663
+ return BigInt(Math.max(hex.length - 2, 0) / 2);
4664
+ }
4665
+ function getPriorityTxEncodedLength(input) {
4666
+ const encoded = viem.encodeAbiParameters(
4667
+ [L2_CANONICAL_TRANSACTION_PARAMETER],
4668
+ [
4669
+ {
4670
+ txType: 0n,
4671
+ from: BigInt(input.sender),
4672
+ to: BigInt(input.l2Contract),
4673
+ gasLimit: 0n,
4674
+ gasPerPubdataByteLimit: input.gasPerPubdata,
4675
+ maxFeePerGas: 0n,
4676
+ maxPriorityFeePerGas: 0n,
4677
+ paymaster: 0n,
4678
+ nonce: 0n,
4679
+ value: input.l2Value,
4680
+ reserved: ZERO_RESERVED_WORDS,
4681
+ data: input.l2Calldata,
4682
+ signature: EMPTY_BYTES,
4683
+ factoryDeps: input.factoryDepsHashes ?? [],
4684
+ paymasterInput: EMPTY_BYTES,
4685
+ reservedDynamic: EMPTY_BYTES
4686
+ }
4687
+ ]
4688
+ );
4689
+ return hexByteLength(encoded);
4690
+ }
4691
+ function getPriorityTxGasBreakdown(input) {
4692
+ return derivePriorityTxGasBreakdown({
4693
+ encodedLength: getPriorityTxEncodedLength(input),
4694
+ gasPerPubdata: input.gasPerPubdata,
4695
+ factoryDepsCount: BigInt(input.factoryDepsHashes?.length ?? 0)
4696
+ });
4697
+ }
4698
+
4587
4699
  // src/adapters/viem/resources/deposits/routes/eth.ts
4588
4700
  var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
4701
+ var EMPTY_BYTES2 = "0x";
4589
4702
  function routeEthDirect() {
4590
4703
  return {
4591
4704
  async build(p, ctx) {
4592
- const l2TxModel = {
4593
- to: p.to ?? ctx.sender,
4594
- from: ctx.sender,
4595
- data: "0x",
4596
- value: p.amount
4597
- };
4705
+ const l2Contract = p.to ?? ctx.sender;
4706
+ const l2Value = p.amount;
4707
+ const l2Calldata = EMPTY_BYTES2;
4708
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
4709
+ sender: ctx.sender,
4710
+ l2Contract,
4711
+ l2Value,
4712
+ l2Calldata,
4713
+ gasPerPubdata: ctx.gasPerPubdata
4714
+ });
4715
+ const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
4598
4716
  const l2GasParams = await quoteL2Gas2({
4599
4717
  ctx,
4600
4718
  route: "eth-base",
4601
- l2TxForModeling: l2TxModel,
4602
- overrideGasLimit: ctx.l2GasLimit,
4603
- stateOverrides: {
4604
- [ctx.sender]: {
4605
- balance: "0xffffffffffffffffffff"
4606
- }
4607
- }
4719
+ overrideGasLimit: quotedL2GasLimit
4608
4720
  });
4609
4721
  if (!l2GasParams) {
4610
4722
  throw new Error("Failed to estimate L2 gas for deposit.");
4611
4723
  }
4612
4724
  const baseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2GasParams.gasLimit });
4613
- const l2Contract = p.to ?? ctx.sender;
4614
- const l2Value = p.amount;
4615
4725
  const mintValue = baseCost + ctx.operatorTip + l2Value;
4616
4726
  const req = buildDirectRequestStruct({
4617
4727
  chainId: ctx.chainIdL2,
@@ -4680,6 +4790,59 @@ function routeEthDirect() {
4680
4790
  };
4681
4791
  }
4682
4792
  var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
4793
+ var ZERO_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000000";
4794
+ async function getPriorityGasModel(input) {
4795
+ try {
4796
+ const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
4797
+ const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
4798
+ const l1ChainId = BigInt(await input.ctx.client.l1.getChainId());
4799
+ const isFirstBridge = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID || input.ctx.resolvedToken.originChainId === 0n;
4800
+ const erc20MetadataOriginChainId = isFirstBridge ? l1ChainId : input.ctx.resolvedToken.originChainId;
4801
+ const erc20Metadata = await l1NativeTokenVault.read.getERC20Getters([
4802
+ input.token,
4803
+ erc20MetadataOriginChainId
4804
+ ]);
4805
+ const bridgeMintCalldata = viem.encodeAbiParameters(
4806
+ [
4807
+ { type: "address", name: "originalCaller" },
4808
+ { type: "address", name: "receiver" },
4809
+ { type: "address", name: "originToken" },
4810
+ { type: "uint256", name: "amount" },
4811
+ { type: "bytes", name: "erc20Metadata" }
4812
+ ],
4813
+ [input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
4814
+ );
4815
+ const l2Calldata = isFirstBridge ? viem.encodeFunctionData({
4816
+ abi: IL2AssetRouter_default,
4817
+ functionName: "finalizeDeposit",
4818
+ args: [input.ctx.sender, input.receiver, input.token, input.amount, erc20Metadata]
4819
+ }) : await (async () => {
4820
+ return await l1AssetRouter.read.getDepositCalldata([
4821
+ input.ctx.sender,
4822
+ input.ctx.resolvedToken.assetId,
4823
+ bridgeMintCalldata
4824
+ ]);
4825
+ })();
4826
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
4827
+ sender: input.ctx.l1AssetRouter,
4828
+ l2Contract: L2_ASSET_ROUTER_ADDRESS,
4829
+ l2Value: 0n,
4830
+ l2Calldata,
4831
+ gasPerPubdata: input.ctx.gasPerPubdata
4832
+ });
4833
+ const model = {
4834
+ priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
4835
+ };
4836
+ if (isFirstBridge || input.ctx.resolvedToken.l2.toLowerCase() === viem.zeroAddress) {
4837
+ model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
4838
+ minBodyGas: priorityFloorBreakdown.minBodyGas
4839
+ }) + priorityFloorBreakdown.overhead;
4840
+ }
4841
+ return model;
4842
+ } catch {
4843
+ return {};
4844
+ }
4845
+ }
4683
4846
  function routeErc20NonBase() {
4684
4847
  return {
4685
4848
  // TODO: do we even need these validations?
@@ -4710,11 +4873,33 @@ function routeErc20NonBase() {
4710
4873
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
4711
4874
  const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
4712
4875
  const assetRouter = ctx.l1AssetRouter;
4876
+ const receiver = p.to ?? ctx.sender;
4877
+ const secondBridgeCalldata = await wrapAs3(
4878
+ "INTERNAL",
4879
+ OP_DEPOSITS.nonbase.encodeCalldata,
4880
+ () => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, receiver)),
4881
+ {
4882
+ ctx: {
4883
+ where: "encodeSecondBridgeErc20Args",
4884
+ token: p.token,
4885
+ amount: p.amount.toString()
4886
+ },
4887
+ message: "Failed to encode bridging calldata."
4888
+ }
4889
+ );
4890
+ const priorityGasModel = await getPriorityGasModel({
4891
+ ctx,
4892
+ token: p.token,
4893
+ amount: p.amount,
4894
+ receiver
4895
+ });
4713
4896
  const l2Gas = await determineErc20L2Gas({
4714
4897
  ctx,
4715
4898
  l1Token: p.token,
4899
+ priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
4900
+ undeployedGasLimit: priorityGasModel.undeployedGasLimit,
4716
4901
  modelTx: {
4717
- to: p.to ?? ctx.sender,
4902
+ to: receiver,
4718
4903
  from: ctx.sender,
4719
4904
  data: "0x",
4720
4905
  value: 0n
@@ -4803,19 +4988,6 @@ function routeErc20NonBase() {
4803
4988
  });
4804
4989
  }
4805
4990
  }
4806
- const secondBridgeCalldata = await wrapAs3(
4807
- "INTERNAL",
4808
- OP_DEPOSITS.nonbase.encodeCalldata,
4809
- () => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, p.to ?? ctx.sender)),
4810
- {
4811
- ctx: {
4812
- where: "encodeSecondBridgeErc20Args",
4813
- token: p.token,
4814
- amount: p.amount.toString()
4815
- },
4816
- message: "Failed to encode bridging calldata."
4817
- }
4818
- );
4819
4991
  const requestStruct = {
4820
4992
  chainId: ctx.chainIdL2,
4821
4993
  mintValue,
@@ -4906,7 +5078,76 @@ function routeErc20NonBase() {
4906
5078
  }
4907
5079
  };
4908
5080
  }
5081
+
5082
+ // src/core/codec/ntv.ts
5083
+ function createNTVCodec(deps) {
5084
+ function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
5085
+ const encoded = deps.encode(
5086
+ ["uint256", "address", "address"],
5087
+ [originChainId, ntvAddress, tokenAddress]
5088
+ );
5089
+ return deps.keccak256(encoded);
5090
+ }
5091
+ return {
5092
+ encodeAssetId
5093
+ };
5094
+ }
5095
+
5096
+ // src/adapters/viem/resources/deposits/routes/eth-nonbase.ts
4909
5097
  var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
5098
+ var ZERO_ASSET_ID2 = "0x0000000000000000000000000000000000000000000000000000000000000000";
5099
+ var ntvCodec = createNTVCodec({
5100
+ encode: (types, values) => viem.encodeAbiParameters(
5101
+ types.map((type, index) => ({ type, name: `arg${index}` })),
5102
+ values
5103
+ ),
5104
+ keccak256: viem.keccak256
5105
+ });
5106
+ async function getPriorityGasModel2(input) {
5107
+ try {
5108
+ const l1AssetRouter = await input.ctx.contracts.l1AssetRouter();
5109
+ const l1NativeTokenVault = await input.ctx.contracts.l1NativeTokenVault();
5110
+ const originChainId = input.ctx.resolvedToken.originChainId !== 0n ? input.ctx.resolvedToken.originChainId : BigInt(await input.ctx.client.l1.getChainId());
5111
+ const resolvedAssetId = input.ctx.resolvedToken.assetId.toLowerCase() === ZERO_ASSET_ID2 ? ntvCodec.encodeAssetId(originChainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, ETH_ADDRESS) : input.ctx.resolvedToken.assetId;
5112
+ const erc20Metadata = await l1NativeTokenVault.read.getERC20Getters([
5113
+ ETH_ADDRESS,
5114
+ originChainId
5115
+ ]);
5116
+ const bridgeMintCalldata = viem.encodeAbiParameters(
5117
+ [
5118
+ { type: "address", name: "originalCaller" },
5119
+ { type: "address", name: "receiver" },
5120
+ { type: "address", name: "originToken" },
5121
+ { type: "uint256", name: "amount" },
5122
+ { type: "bytes", name: "erc20Metadata" }
5123
+ ],
5124
+ [input.ctx.sender, input.receiver, ETH_ADDRESS, input.amount, erc20Metadata]
5125
+ );
5126
+ const l2Calldata = await l1AssetRouter.read.getDepositCalldata([
5127
+ input.ctx.sender,
5128
+ resolvedAssetId,
5129
+ bridgeMintCalldata
5130
+ ]);
5131
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
5132
+ sender: input.ctx.l1AssetRouter,
5133
+ l2Contract: L2_ASSET_ROUTER_ADDRESS,
5134
+ l2Value: 0n,
5135
+ l2Calldata,
5136
+ gasPerPubdata: input.ctx.gasPerPubdata
5137
+ });
5138
+ const model = {
5139
+ priorityFloorGasLimit: priorityFloorBreakdown.derivedL2GasLimit
5140
+ };
5141
+ if (input.ctx.resolvedToken.l2.toLowerCase() === viem.zeroAddress) {
5142
+ model.undeployedGasLimit = derivePriorityBodyGasEstimateCap({
5143
+ minBodyGas: priorityFloorBreakdown.minBodyGas
5144
+ }) + priorityFloorBreakdown.overhead;
5145
+ }
5146
+ return model;
5147
+ } catch {
5148
+ return {};
5149
+ }
5150
+ }
4910
5151
  function routeEthNonBase() {
4911
5152
  return {
4912
5153
  // TODO: do we even need these validations?
@@ -4953,15 +5194,23 @@ function routeEthNonBase() {
4953
5194
  },
4954
5195
  async build(p, ctx) {
4955
5196
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5197
+ const receiver = p.to ?? ctx.sender;
5198
+ const priorityGasModel = await getPriorityGasModel2({
5199
+ ctx,
5200
+ amount: p.amount,
5201
+ receiver
5202
+ });
4956
5203
  const l2TxModel = {
4957
- to: p.to ?? ctx.sender,
5204
+ to: receiver,
4958
5205
  from: ctx.sender,
4959
5206
  data: "0x",
4960
5207
  value: 0n
4961
5208
  };
4962
5209
  const l2Gas = await determineEthNonBaseL2Gas({
4963
5210
  ctx,
4964
- modelTx: l2TxModel
5211
+ modelTx: l2TxModel,
5212
+ priorityFloorGasLimit: priorityGasModel.priorityFloorGasLimit,
5213
+ undeployedGasLimit: priorityGasModel.undeployedGasLimit
4965
5214
  });
4966
5215
  if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
4967
5216
  const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
@@ -5010,12 +5259,12 @@ function routeEthNonBase() {
5010
5259
  const secondBridgeCalldata = await wrapAs4(
5011
5260
  "INTERNAL",
5012
5261
  OP_DEPOSITS.ethNonBase.encodeCalldata,
5013
- () => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, p.to ?? ctx.sender)),
5262
+ () => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, receiver)),
5014
5263
  {
5015
5264
  ctx: {
5016
5265
  where: "encodeSecondBridgeEthArgs",
5017
5266
  amount: p.amount.toString(),
5018
- to: p.to ?? ctx.sender
5267
+ to: receiver
5019
5268
  },
5020
5269
  message: "Failed to encode ETH bridging calldata."
5021
5270
  }
@@ -5116,6 +5365,7 @@ function routeEthNonBase() {
5116
5365
  };
5117
5366
  }
5118
5367
  var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
5368
+ var EMPTY_BYTES3 = "0x";
5119
5369
  function routeErc20Base() {
5120
5370
  return {
5121
5371
  async preflight(p, ctx) {
@@ -5143,17 +5393,21 @@ function routeErc20Base() {
5143
5393
  },
5144
5394
  async build(p, ctx) {
5145
5395
  const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
5146
- const l2TxModel = {
5147
- to: p.to ?? ctx.sender,
5148
- from: ctx.sender,
5149
- data: "0x",
5150
- value: 0n
5151
- };
5396
+ const l2Contract = p.to ?? ctx.sender;
5397
+ const l2Value = p.amount;
5398
+ const l2Calldata = EMPTY_BYTES3;
5399
+ const priorityFloorBreakdown = getPriorityTxGasBreakdown({
5400
+ sender: ctx.sender,
5401
+ l2Contract,
5402
+ l2Value,
5403
+ l2Calldata,
5404
+ gasPerPubdata: ctx.gasPerPubdata
5405
+ });
5406
+ const quotedL2GasLimit = ctx.l2GasLimit ?? priorityFloorBreakdown.derivedL2GasLimit;
5152
5407
  const l2Gas = await quoteL2Gas2({
5153
5408
  ctx,
5154
5409
  route: "erc20-base",
5155
- l2TxForModeling: l2TxModel,
5156
- overrideGasLimit: ctx.l2GasLimit
5410
+ overrideGasLimit: quotedL2GasLimit
5157
5411
  });
5158
5412
  if (!l2Gas) throw new Error("Failed to estimate L2 gas parameters.");
5159
5413
  const l2BaseCost = await quoteL2BaseCost({ ctx, l2GasLimit: l2Gas.gasLimit });
@@ -5205,8 +5459,8 @@ function routeErc20Base() {
5205
5459
  l2GasLimit: l2Gas.gasLimit,
5206
5460
  gasPerPubdata: ctx.gasPerPubdata,
5207
5461
  refundRecipient: ctx.refundRecipient,
5208
- l2Contract: p.to ?? ctx.sender,
5209
- l2Value: p.amount
5462
+ l2Contract,
5463
+ l2Value
5210
5464
  });
5211
5465
  let bridgeTx;
5212
5466
  let calldata;
@@ -5367,24 +5621,8 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
5367
5621
  }
5368
5622
  return { l2Receipt, l2TxHash };
5369
5623
  }
5370
-
5371
- // src/core/codec/ntv.ts
5372
- function createNTVCodec(deps) {
5373
- function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
5374
- const encoded = deps.encode(
5375
- ["uint256", "address", "address"],
5376
- [originChainId, ntvAddress, tokenAddress]
5377
- );
5378
- return deps.keccak256(encoded);
5379
- }
5380
- return {
5381
- encodeAssetId
5382
- };
5383
- }
5384
-
5385
- // src/adapters/viem/resources/tokens/tokens.ts
5386
5624
  var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
5387
- var ntvCodec = createNTVCodec({
5625
+ var ntvCodec2 = createNTVCodec({
5388
5626
  encode: (types, values) => viem.encodeAbiParameters(
5389
5627
  types.map((t, i) => ({ type: t, name: `arg${i}` })),
5390
5628
  values
@@ -5498,7 +5736,7 @@ function createTokensResource(client) {
5498
5736
  return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
5499
5737
  const baseAssetId = await getBaseTokenAssetId();
5500
5738
  const l1ChainId = await getL1ChainId();
5501
- const ethAssetId = ntvCodec.encodeAssetId(
5739
+ const ethAssetId = ntvCodec2.encodeAssetId(
5502
5740
  l1ChainId,
5503
5741
  L2_NATIVE_TOKEN_VAULT_ADDRESS,
5504
5742
  ETH_ADDRESS