@aztec/ethereum 3.0.0-rc.5 → 4.0.0-nightly.20260107

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 (84) hide show
  1. package/dest/client.js +6 -2
  2. package/dest/config.d.ts +4 -1
  3. package/dest/config.d.ts.map +1 -1
  4. package/dest/config.js +6 -0
  5. package/dest/contracts/empire_base.d.ts +2 -1
  6. package/dest/contracts/empire_base.d.ts.map +1 -1
  7. package/dest/contracts/empire_slashing_proposer.d.ts +2 -1
  8. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  9. package/dest/contracts/empire_slashing_proposer.js +9 -0
  10. package/dest/contracts/governance_proposer.d.ts +2 -1
  11. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  12. package/dest/contracts/governance_proposer.js +391 -8
  13. package/dest/contracts/inbox.d.ts +5 -1
  14. package/dest/contracts/inbox.d.ts.map +1 -1
  15. package/dest/contracts/inbox.js +4 -0
  16. package/dest/contracts/rollup.d.ts +125 -73
  17. package/dest/contracts/rollup.d.ts.map +1 -1
  18. package/dest/contracts/rollup.js +614 -125
  19. package/dest/deploy_aztec_l1_contracts.d.ts +3 -1
  20. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
  21. package/dest/deploy_aztec_l1_contracts.js +7 -2
  22. package/dest/l1_artifacts.d.ts +3370 -104
  23. package/dest/l1_artifacts.d.ts.map +1 -1
  24. package/dest/l1_contract_addresses.d.ts +1 -1
  25. package/dest/l1_contract_addresses.d.ts.map +1 -1
  26. package/dest/l1_contract_addresses.js +3 -3
  27. package/dest/l1_tx_utils/constants.d.ts +7 -1
  28. package/dest/l1_tx_utils/constants.d.ts.map +1 -1
  29. package/dest/l1_tx_utils/constants.js +25 -0
  30. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  31. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  32. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  33. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  34. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  35. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  36. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  37. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  38. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  39. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  40. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  41. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  42. package/dest/l1_tx_utils/index.d.ts +3 -1
  43. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  44. package/dest/l1_tx_utils/index.js +2 -0
  45. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  46. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  47. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  48. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +4 -15
  49. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  50. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +34 -142
  51. package/dest/queries.d.ts +1 -1
  52. package/dest/queries.d.ts.map +1 -1
  53. package/dest/queries.js +8 -3
  54. package/dest/test/chain_monitor.js +1 -2
  55. package/dest/test/eth_cheat_codes.js +3 -1
  56. package/dest/test/rollup_cheat_codes.js +3 -1
  57. package/dest/test/tx_delayer.js +1 -1
  58. package/dest/utils.d.ts +14 -2
  59. package/dest/utils.d.ts.map +1 -1
  60. package/dest/utils.js +18 -0
  61. package/package.json +6 -5
  62. package/src/client.ts +2 -2
  63. package/src/config.ts +8 -0
  64. package/src/contracts/empire_base.ts +1 -1
  65. package/src/contracts/empire_slashing_proposer.ts +6 -1
  66. package/src/contracts/governance_proposer.ts +6 -1
  67. package/src/contracts/inbox.ts +5 -0
  68. package/src/contracts/rollup.ts +252 -84
  69. package/src/deploy_aztec_l1_contracts.ts +12 -2
  70. package/src/l1_contract_addresses.ts +22 -20
  71. package/src/l1_tx_utils/constants.ts +11 -0
  72. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  73. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  74. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  75. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  76. package/src/l1_tx_utils/index.ts +2 -0
  77. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  78. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +46 -184
  79. package/src/queries.ts +8 -2
  80. package/src/test/chain_monitor.ts +1 -1
  81. package/src/test/eth_cheat_codes.ts +1 -1
  82. package/src/test/rollup_cheat_codes.ts +1 -1
  83. package/src/test/tx_delayer.ts +1 -1
  84. package/src/utils.ts +29 -0
@@ -1,4 +1,4 @@
1
- import { getKeys, median, merge, pick, times } from '@aztec/foundation/collection';
1
+ import { getKeys, merge, pick, times } from '@aztec/foundation/collection';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { makeBackoff, retry } from '@aztec/foundation/retry';
4
4
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
@@ -6,8 +6,10 @@ import pickBy from 'lodash.pickby';
6
6
  import { MethodNotFoundRpcError, MethodNotSupportedRpcError, decodeErrorResult, formatGwei, getContractError, hexToBytes } from 'viem';
7
7
  import { defaultL1TxUtilsConfig, l1TxUtilsConfigMappings } from './config.js';
8
8
  import { BLOCK_TIME_MS, LARGE_GAS_LIMIT, MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE, MIN_REPLACEMENT_BUMP_PERCENTAGE, WEI_CONST } from './constants.js';
9
+ import { P75AllTxsPriorityFeeStrategy } from './fee-strategies/index.js';
9
10
  import { getCalldataGasUsage, tryGetCustomErrorNameContractFunction } from './utils.js';
10
- const HISTORICAL_BLOCK_COUNT = 5;
11
+ // Change this to the current strategy we want to use
12
+ const CurrentStrategy = P75AllTxsPriorityFeeStrategy;
11
13
  export class ReadOnlyL1TxUtils {
12
14
  client;
13
15
  logger;
@@ -35,150 +37,43 @@ export class ReadOnlyL1TxUtils {
35
37
  getBlockNumber() {
36
38
  return this.client.getBlockNumber();
37
39
  }
38
- /**
39
- * Analyzes pending transactions and recent fee history to determine a competitive priority fee.
40
- * Falls back to network estimate if data is unavailable or fails.
41
- * @param networkEstimateResult - Result from estimateMaxPriorityFeePerGas RPC call
42
- * @param pendingBlockResult - Result from getBlock with pending tag RPC call
43
- * @param feeHistoryResult - Result from getFeeHistory RPC call
44
- * @returns A competitive priority fee based on pending txs and recent block history
45
- */ getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult) {
46
- const networkEstimate = networkEstimateResult.status === 'fulfilled' && typeof networkEstimateResult.value === 'bigint' ? networkEstimateResult.value : 0n;
47
- let competitiveFee = networkEstimate;
48
- if (pendingBlockResult.status === 'fulfilled' && pendingBlockResult.value !== null && pendingBlockResult.value.transactions && pendingBlockResult.value.transactions.length > 0) {
49
- const pendingBlock = pendingBlockResult.value;
50
- // Extract priority fees from pending transactions
51
- const pendingFees = pendingBlock.transactions.map((tx)=>{
52
- // Transaction can be just a hash string, so we need to check if it's an object
53
- if (typeof tx === 'string') {
54
- return 0n;
55
- }
56
- const fee = tx.maxPriorityFeePerGas || 0n;
57
- // Debug: Log suspicious fees
58
- if (fee > 100n * WEI_CONST) {
59
- this.logger?.warn('Suspicious high priority fee in pending tx', {
60
- txHash: tx.hash,
61
- maxPriorityFeePerGas: formatGwei(fee),
62
- maxFeePerGas: formatGwei(tx.maxFeePerGas || 0n),
63
- maxFeePerBlobGas: tx.maxFeePerBlobGas ? formatGwei(tx.maxFeePerBlobGas) : 'N/A'
64
- });
65
- }
66
- return fee;
67
- }).filter((fee)=>fee > 0n);
68
- if (pendingFees.length > 0) {
69
- // Use 75th percentile of pending fees to be competitive
70
- const sortedPendingFees = [
71
- ...pendingFees
72
- ].sort((a, b)=>a < b ? -1 : a > b ? 1 : 0);
73
- const percentile75Index = Math.floor((sortedPendingFees.length - 1) * 0.75);
74
- const pendingCompetitiveFee = sortedPendingFees[percentile75Index];
75
- if (pendingCompetitiveFee > competitiveFee) {
76
- competitiveFee = pendingCompetitiveFee;
77
- }
78
- this.logger?.debug('Analyzed pending transactions for competitive pricing', {
79
- pendingTxCount: pendingFees.length,
80
- pendingP75: formatGwei(pendingCompetitiveFee)
81
- });
82
- }
83
- }
84
- if (feeHistoryResult.status === 'fulfilled' && feeHistoryResult.value !== null && feeHistoryResult.value.reward && feeHistoryResult.value.reward.length > 0) {
85
- const feeHistory = feeHistoryResult.value;
86
- // Extract 75th percentile fees from each block
87
- const percentile75Fees = feeHistory.reward.map((rewards)=>rewards[0] || 0n).filter((fee)=>fee > 0n);
88
- if (percentile75Fees.length > 0) {
89
- // Calculate median of the 75th percentile fees across blocks
90
- const medianHistoricalFee = median(percentile75Fees) ?? 0n;
91
- // Debug: Log suspicious fees from history
92
- if (medianHistoricalFee > 100n * WEI_CONST) {
93
- this.logger?.warn('Suspicious high fee in history', {
94
- historicalMedian: formatGwei(medianHistoricalFee),
95
- allP75Fees: percentile75Fees.map((f)=>formatGwei(f))
96
- });
97
- }
98
- if (medianHistoricalFee > competitiveFee) {
99
- competitiveFee = medianHistoricalFee;
100
- }
101
- this.logger?.debug('Analyzed fee history for competitive pricing', {
102
- historicalMedian: formatGwei(medianHistoricalFee)
103
- });
104
- }
105
- }
106
- // Sanity check: cap competitive fee at 100x network estimate to avoid using unrealistic fees
107
- // (e.g., Anvil returns inflated historical fees that don't reflect actual network conditions)
108
- const maxReasonableFee = networkEstimate * 100n;
109
- if (competitiveFee > maxReasonableFee) {
110
- this.logger?.warn('Competitive fee exceeds sanity cap, using capped value', {
111
- competitiveFee: formatGwei(competitiveFee),
112
- networkEstimate: formatGwei(networkEstimate),
113
- cappedTo: formatGwei(maxReasonableFee)
114
- });
115
- competitiveFee = maxReasonableFee;
116
- }
117
- // Log final decision
118
- if (competitiveFee > networkEstimate) {
119
- this.logger?.debug('Using competitive fee from market analysis', {
120
- networkEstimate: formatGwei(networkEstimate),
121
- competitive: formatGwei(competitiveFee)
122
- });
123
- }
124
- return competitiveFee;
40
+ getCode(address) {
41
+ return this.client.getCode({
42
+ address: address.toString()
43
+ });
125
44
  }
126
45
  /**
127
46
  * Gets the current gas price with bounds checking
128
47
  */ async getGasPrice(gasConfigOverrides, isBlobTx = false, attempt = 0, previousGasPrice) {
129
48
  const gasConfig = merge(this.config, gasConfigOverrides);
130
- // Make all RPC calls in parallel upfront with retry logic
131
- const latestBlockPromise = this.tryTwice(()=>this.client.getBlock({
132
- blockTag: 'latest'
133
- }), 'Getting latest block');
134
- const networkEstimatePromise = this.tryTwice(()=>this.client.estimateMaxPriorityFeePerGas(), 'Estimating max priority fee per gas');
135
- const pendingBlockPromise = this.tryTwice(()=>this.client.getBlock({
136
- blockTag: 'pending',
137
- includeTransactions: true
138
- }), 'Getting pending block');
139
- const feeHistoryPromise = this.tryTwice(()=>this.client.getFeeHistory({
140
- blockCount: HISTORICAL_BLOCK_COUNT,
141
- rewardPercentiles: [
142
- 75
143
- ]
144
- }), 'Getting fee history');
145
- const blobBaseFeePromise = isBlobTx ? this.tryTwice(()=>this.client.getBlobBaseFee(), 'Getting blob base fee') : null;
146
- const [latestBlockResult, networkEstimateResult, pendingBlockResult, feeHistoryResult, blobBaseFeeResult] = await Promise.allSettled([
147
- latestBlockPromise,
148
- networkEstimatePromise,
149
- pendingBlockPromise,
150
- feeHistoryPromise,
151
- blobBaseFeePromise ?? Promise.resolve(0n)
152
- ]);
153
- // Extract results
154
- const baseFee = latestBlockResult.status === 'fulfilled' && typeof latestBlockResult.value === 'object' && latestBlockResult.value.baseFeePerGas ? latestBlockResult.value.baseFeePerGas : 0n;
155
- // Get blob base fee if available
156
- let blobBaseFee = 0n;
157
- if (isBlobTx && blobBaseFeeResult.status === 'fulfilled' && typeof blobBaseFeeResult.value === 'bigint') {
158
- blobBaseFee = blobBaseFeeResult.value;
159
- } else if (isBlobTx) {
49
+ // Execute strategy - it handles all RPC calls internally and returns everything we need
50
+ const strategyResult = await retry(()=>CurrentStrategy.execute(this.client, {
51
+ gasConfig,
52
+ isBlobTx,
53
+ logger: this.logger
54
+ }), 'Executing priority fee strategy', makeBackoff(times(2, ()=>0)), this.logger, true);
55
+ const { latestBlock, blobBaseFee, priorityFee: strategyPriorityFee } = strategyResult;
56
+ // Extract base fee from latest block
57
+ const baseFee = latestBlock.baseFeePerGas ?? 0n;
58
+ // Handle blob base fee
59
+ if (isBlobTx && blobBaseFee === undefined) {
160
60
  this.logger?.warn('Failed to get L1 blob base fee', attempt);
161
61
  }
162
- // Get competitive priority fee
163
- let priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
164
- // Apply minimum priority fee as a floor if configured
62
+ let priorityFee = strategyPriorityFee;
63
+ // Apply minimum priority fee floor if configured
165
64
  if (gasConfig.minimumPriorityFeePerGas) {
166
- const minimumFee = BigInt(Math.trunc(gasConfig.minimumPriorityFeePerGas * Number(WEI_CONST)));
167
- if (minimumFee > priorityFee) {
168
- this.logger?.debug('Using minimum priority fee as floor', {
169
- minimumPriorityFeePerGas: formatGwei(minimumFee),
170
- competitiveFee: formatGwei(priorityFee)
171
- });
172
- priorityFee = minimumFee;
173
- } else {
174
- this.logger?.debug('Competitive fee exceeds minimum, using competitive fee', {
175
- minimumPriorityFeePerGas: formatGwei(minimumFee),
176
- competitiveFee: formatGwei(priorityFee)
65
+ const minimumPriorityFee = BigInt(Math.trunc(gasConfig.minimumPriorityFeePerGas * Number(WEI_CONST)));
66
+ if (priorityFee < minimumPriorityFee) {
67
+ this.logger?.debug('Applying minimum priority fee floor', {
68
+ calculatedPriorityFee: formatGwei(priorityFee),
69
+ minimumPriorityFeePerGas: gasConfig.minimumPriorityFeePerGas,
70
+ appliedFee: formatGwei(minimumPriorityFee)
177
71
  });
72
+ priorityFee = minimumPriorityFee;
178
73
  }
179
74
  }
180
75
  let maxFeePerGas = baseFee;
181
- let maxFeePerBlobGas = blobBaseFee;
76
+ let maxFeePerBlobGas = blobBaseFee ?? 0n;
182
77
  // Bump base fee so it's valid for next blocks if it stalls
183
78
  const numBlocks = Math.ceil(gasConfig.stallTimeMs / BLOCK_TIME_MS);
184
79
  for(let i = 0; i < numBlocks; i++){
@@ -248,7 +143,7 @@ export class ReadOnlyL1TxUtils {
248
143
  baseFee: formatGwei(baseFee),
249
144
  maxFeePerGas: formatGwei(maxFeePerGas),
250
145
  maxPriorityFeePerGas: formatGwei(maxPriorityFeePerGas),
251
- blobBaseFee: formatGwei(blobBaseFee),
146
+ blobBaseFee: formatGwei(blobBaseFee ?? 0n),
252
147
  maxFeePerBlobGas: formatGwei(maxFeePerBlobGas)
253
148
  });
254
149
  return {
@@ -275,14 +170,16 @@ export class ReadOnlyL1TxUtils {
275
170
  ...request,
276
171
  ..._blobInputs,
277
172
  maxFeePerBlobGas: gasPrice.maxFeePerBlobGas,
278
- gas: LARGE_GAS_LIMIT
173
+ gas: LARGE_GAS_LIMIT,
174
+ blockTag: 'latest'
279
175
  });
280
176
  this.logger?.trace(`Estimated gas for blob tx: ${initialEstimate}`);
281
177
  } else {
282
178
  initialEstimate = await this.client.estimateGas({
283
179
  account,
284
180
  ...request,
285
- gas: LARGE_GAS_LIMIT
181
+ gas: LARGE_GAS_LIMIT,
182
+ blockTag: 'latest'
286
183
  });
287
184
  this.logger?.trace(`Estimated gas for non-blob tx: ${initialEstimate}`);
288
185
  }
@@ -423,9 +320,4 @@ export class ReadOnlyL1TxUtils {
423
320
  });
424
321
  return bumpedGasLimit;
425
322
  }
426
- /**
427
- * Helper function to retry RPC calls twice
428
- */ tryTwice(fn, description) {
429
- return retry(fn, description, makeBackoff(times(2, ()=>0)), this.logger, true);
430
- }
431
323
  }
package/dest/queries.d.ts CHANGED
@@ -11,4 +11,4 @@ export declare function getL1ContractsConfig(publicClient: ViemPublicClient, add
11
11
  rollupVersion: number;
12
12
  genesisArchiveTreeRoot: `0x${string}`;
13
13
  }>;
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3F1ZXJpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBSXJELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRW5ELHFEQUFxRDtBQUNyRCx3QkFBc0Isb0JBQW9CLENBQ3hDLFlBQVksRUFBRSxnQkFBZ0IsRUFDOUIsU0FBUyxFQUFFO0lBQUUsaUJBQWlCLEVBQUUsVUFBVSxDQUFDO0lBQUMsYUFBYSxDQUFDLEVBQUUsVUFBVSxDQUFBO0NBQUUsR0FDdkUsT0FBTyxDQUNSLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxzQkFBc0IsQ0FBQyxHQUFHO0lBQ2hELFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsYUFBYSxFQUFFLE1BQU0sQ0FBQztJQUN0QixhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLHNCQUFzQixFQUFFLEtBQUssTUFBTSxFQUFFLENBQUM7Q0FDdkMsQ0FDRixDQWdHQSJ9
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3F1ZXJpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBS3JELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRW5ELHFEQUFxRDtBQUNyRCx3QkFBc0Isb0JBQW9CLENBQ3hDLFlBQVksRUFBRSxnQkFBZ0IsRUFDOUIsU0FBUyxFQUFFO0lBQUUsaUJBQWlCLEVBQUUsVUFBVSxDQUFDO0lBQUMsYUFBYSxDQUFDLEVBQUUsVUFBVSxDQUFBO0NBQUUsR0FDdkUsT0FBTyxDQUNSLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxzQkFBc0IsQ0FBQyxHQUFHO0lBQ2hELFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsYUFBYSxFQUFFLE1BQU0sQ0FBQztJQUN0QixhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLHNCQUFzQixFQUFFLEtBQUssTUFBTSxFQUFFLENBQUM7Q0FDdkMsQ0FDRixDQXFHQSJ9
@@ -1 +1 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,qDAAqD;AACrD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE;IAAE,iBAAiB,EAAE,UAAU,CAAC;IAAC,aAAa,CAAC,EAAE,UAAU,CAAA;CAAE,GACvE,OAAO,CACR,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,GAAG;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,KAAK,MAAM,EAAE,CAAC;CACvC,CACF,CAgGA"}
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,qDAAqD;AACrD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE;IAAE,iBAAiB,EAAE,UAAU,CAAC;IAAC,aAAa,CAAC,EAAE,UAAU,CAAA;CAAE,GACvE,OAAO,CACR,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,GAAG;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,KAAK,MAAM,EAAE,CAAC;CACvC,CACF,CAqGA"}
package/dest/queries.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import { ReadOnlyGovernanceContract } from './contracts/governance.js';
3
3
  import { GovernanceProposerContract } from './contracts/governance_proposer.js';
4
+ import { InboxContract } from './contracts/inbox.js';
4
5
  import { RollupContract } from './contracts/rollup.js';
5
6
  /** Reads the L1ContractsConfig from L1 contracts. */ export async function getL1ContractsConfig(publicClient, addresses) {
6
7
  const governance = new ReadOnlyGovernanceContract(addresses.governanceAddress.toString(), publicClient);
@@ -10,7 +11,9 @@ import { RollupContract } from './contracts/rollup.js';
10
11
  const rollup = new RollupContract(publicClient, rollupAddress.toString());
11
12
  const slasherProposer = await rollup.getSlashingProposer();
12
13
  const slasher = await rollup.getSlasherContract();
13
- const [l1StartBlock, l1GenesisTime, aztecEpochDuration, aztecSlotDuration, aztecProofSubmissionEpochs, aztecTargetCommitteeSize, lagInEpochsForValidatorSet, lagInEpochsForRandao, activationThreshold, ejectionThreshold, localEjectionThreshold, governanceProposerQuorum, governanceProposerRoundSize, slashingQuorum, slashingRoundSize, slashingLifetimeInRounds, slashingExecutionDelayInRounds, slashingOffsetInRounds, slashingAmounts, slashingVetoer, slashingDisableDuration, manaTarget, provingCostPerMana, rollupVersion, genesisArchiveTreeRoot, exitDelay] = await Promise.all([
14
+ const rollupAddresses = await rollup.getRollupAddresses();
15
+ const inboxContract = new InboxContract(publicClient, rollupAddresses.inboxAddress.toString());
16
+ const [l1StartBlock, l1GenesisTime, aztecEpochDuration, aztecSlotDuration, aztecProofSubmissionEpochs, aztecTargetCommitteeSize, lagInEpochsForValidatorSet, lagInEpochsForRandao, inboxLag, activationThreshold, ejectionThreshold, localEjectionThreshold, governanceProposerQuorum, governanceProposerRoundSize, slashingQuorum, slashingRoundSize, slashingLifetimeInRounds, slashingExecutionDelayInRounds, slashingOffsetInRounds, slashingAmounts, slashingVetoer, slashingDisableDuration, manaTarget, provingCostPerMana, rollupVersion, genesisArchiveTreeRoot, exitDelay] = await Promise.all([
14
17
  rollup.getL1StartBlock(),
15
18
  rollup.getL1GenesisTime(),
16
19
  rollup.getEpochDuration(),
@@ -19,6 +22,7 @@ import { RollupContract } from './contracts/rollup.js';
19
22
  rollup.getTargetCommitteeSize(),
20
23
  rollup.getLagInEpochsForValidatorSet(),
21
24
  rollup.getLagInEpochsForRandao(),
25
+ inboxContract.getLag(),
22
26
  rollup.getActivationThreshold(),
23
27
  rollup.getEjectionThreshold(),
24
28
  rollup.getLocalEjectionThreshold(),
@@ -51,13 +55,14 @@ import { RollupContract } from './contracts/rollup.js';
51
55
  aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize),
52
56
  lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
53
57
  lagInEpochsForRandao: Number(lagInEpochsForRandao),
58
+ inboxLag: Number(inboxLag),
54
59
  governanceProposerQuorum: Number(governanceProposerQuorum),
55
60
  governanceProposerRoundSize: Number(governanceProposerRoundSize),
56
61
  activationThreshold,
57
62
  ejectionThreshold,
58
63
  localEjectionThreshold,
59
64
  slashingQuorum: Number(slashingQuorum),
60
- slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
65
+ slashingRoundSizeInEpochs: Number(Number(slashingRoundSize) / aztecEpochDuration),
61
66
  slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
62
67
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
63
68
  slashingVetoer,
@@ -65,7 +70,7 @@ import { RollupContract } from './contracts/rollup.js';
65
70
  manaTarget,
66
71
  provingCostPerMana: provingCostPerMana,
67
72
  rollupVersion: Number(rollupVersion),
68
- genesisArchiveTreeRoot,
73
+ genesisArchiveTreeRoot: genesisArchiveTreeRoot.toString(),
69
74
  exitDelaySeconds: Number(exitDelay),
70
75
  slasherFlavor: slasherProposer?.type ?? 'tally',
71
76
  slashingOffsetInRounds: Number(slashingOffsetInRounds),
@@ -1,5 +1,4 @@
1
1
  import { InboxContract } from '@aztec/ethereum/contracts';
2
- import { EthAddress } from '@aztec/foundation/eth-address';
3
2
  import { createLogger } from '@aztec/foundation/log';
4
3
  import { promiseWithResolvers } from '@aztec/foundation/promise';
5
4
  import { DateProvider } from '@aztec/foundation/timer';
@@ -125,7 +124,7 @@ import { EventEmitter } from 'events';
125
124
  let committee;
126
125
  if (l2Epoch !== this.l2EpochNumber) {
127
126
  this.l2EpochNumber = l2Epoch;
128
- committee = (await this.rollup.getCurrentEpochCommittee())?.map((addr)=>EthAddress.fromString(addr));
127
+ committee = await this.rollup.getCurrentEpochCommittee();
129
128
  this.emit('l2-epoch', {
130
129
  l2EpochNumber: l2Epoch,
131
130
  timestamp,
@@ -27,7 +27,9 @@ import { foundry } from 'viem/chains';
27
27
  this.logger = logger;
28
28
  this.chain = chain;
29
29
  this.publicClient = createPublicClient({
30
- transport: fallback(this.rpcUrls.map((url)=>http(url))),
30
+ transport: fallback(this.rpcUrls.map((url)=>http(url, {
31
+ batch: false
32
+ }))),
31
33
  chain: chain
32
34
  });
33
35
  }
@@ -15,7 +15,9 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
15
15
  this.logger = createLogger('aztecjs:cheat_codes');
16
16
  this.client = createPublicClient({
17
17
  chain: ethCheatCodes.chain,
18
- transport: fallback(ethCheatCodes.rpcUrls.map((url)=>http(url)))
18
+ transport: fallback(ethCheatCodes.rpcUrls.map((url)=>http(url, {
19
+ batch: false
20
+ })))
19
21
  });
20
22
  this.rollup = getContract({
21
23
  abi: RollupAbi,
@@ -156,7 +156,7 @@ class DelayerImpl {
156
156
  return Promise.resolve(txHash);
157
157
  } else {
158
158
  const txHash = await client.sendRawTransaction(...args);
159
- logger.verbose(`Sent tx immediately ${txHash}`);
159
+ logger.debug(`Sent tx immediately ${txHash}`);
160
160
  delayer.sentTxHashes.push(txHash);
161
161
  return txHash;
162
162
  }
package/dest/utils.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { Logger } from '@aztec/foundation/log';
3
- import { type Abi, type ContractEventName, type DecodeEventLogReturnType, type Hex, type Log } from 'viem';
3
+ import { type Abi, type ContractEventName, type DecodeEventLogReturnType, type FormattedTransaction, type Hex, type Log } from 'viem';
4
4
  export interface L2Claim {
5
5
  claimSecret: Fr;
6
6
  claimAmount: Fr;
@@ -22,4 +22,16 @@ export declare function prettyLogViemErrorMsg(err: any): any;
22
22
  */
23
23
  export declare function formatViemError(error: any, abi?: Abi): FormattedViemError;
24
24
  export declare function tryGetCustomErrorName(err: any): string | undefined;
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUdwRCxPQUFPLEVBQ0wsS0FBSyxHQUFHLEVBRVIsS0FBSyxpQkFBaUIsRUFFdEIsS0FBSyx3QkFBd0IsRUFDN0IsS0FBSyxHQUFHLEVBQ1IsS0FBSyxHQUFHLEVBR1QsTUFBTSxNQUFNLENBQUM7QUFFZCxNQUFNLFdBQVcsT0FBTztJQUN0QixXQUFXLEVBQUUsRUFBRSxDQUFDO0lBQ2hCLFdBQVcsRUFBRSxFQUFFLENBQUM7SUFDaEIsV0FBVyxFQUFFLEdBQUcsQ0FBQztJQUNqQixnQkFBZ0IsRUFBRSxNQUFNLENBQUM7Q0FDMUI7QUFFRCxxQkFBYSxrQkFBbUIsU0FBUSxLQUFLO0lBQzNDLFlBQVksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBRXJCLFlBQVksT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFJaEQ7Q0FDRjtBQUVELHdCQUFnQixZQUFZLENBQzFCLEtBQUssQ0FBQyxJQUFJLFNBQVMsR0FBRyxHQUFHLFNBQVMsT0FBTyxFQUFFLEVBQzNDLFVBQVUsU0FBUyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFDMUMsVUFBVSxHQUFHLHdCQUF3QixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxFQUUvRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQ1gsT0FBTyxFQUFFLEdBQUcsRUFDWixHQUFHLEVBQUUsSUFBSSxFQUNULFNBQVMsRUFBRSxVQUFVLEVBQ3JCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsS0FBSyxPQUFPLEVBQ3JDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sR0FDZCxVQUFVLENBTVo7QUFFRCx3QkFBZ0IsZUFBZSxDQUM3QixLQUFLLENBQUMsSUFBSSxTQUFTLEdBQUcsR0FBRyxTQUFTLE9BQU8sRUFBRSxFQUMzQyxVQUFVLFNBQVMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQzFDLFVBQVUsR0FBRyx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFFL0UsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUNYLE9BQU8sRUFBRSxHQUFHLEVBQ1osR0FBRyxFQUFFLElBQUksRUFDVCxTQUFTLEVBQUUsVUFBVSxFQUNyQixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLEtBQUssT0FBTyxFQUNyQyxNQUFNLENBQUMsRUFBRSxNQUFNLEdBQ2QsVUFBVSxHQUFHLFNBQVMsQ0FnQnhCO0FBRUQsd0JBQWdCLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxHQUFHLE9BVzdDO0FBMEJEOzs7OztHQUtHO0FBQ0gsd0JBQWdCLGVBQWUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRSxHQUFlLEdBQUcsa0JBQWtCLENBd0VwRjtBQXlCRCx3QkFBZ0IscUJBQXFCLENBQUMsR0FBRyxFQUFFLEdBQUcsc0JBYTdDIn0=
25
+ /**
26
+ * Type guard to check if a transaction is a blob transaction (EIP-4844).
27
+ * Blob transactions have maxFeePerBlobGas and blobVersionedHashes fields.
28
+ */
29
+ export declare function isBlobTransaction(tx: FormattedTransaction): tx is FormattedTransaction & {
30
+ maxFeePerBlobGas: bigint;
31
+ blobVersionedHashes: readonly Hex[];
32
+ };
33
+ /**
34
+ * Calculates a percentile from an array of bigints
35
+ */
36
+ export declare function calculatePercentile(values: bigint[], percentile: number): bigint;
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUdwRCxPQUFPLEVBQ0wsS0FBSyxHQUFHLEVBRVIsS0FBSyxpQkFBaUIsRUFFdEIsS0FBSyx3QkFBd0IsRUFDN0IsS0FBSyxvQkFBb0IsRUFDekIsS0FBSyxHQUFHLEVBQ1IsS0FBSyxHQUFHLEVBR1QsTUFBTSxNQUFNLENBQUM7QUFFZCxNQUFNLFdBQVcsT0FBTztJQUN0QixXQUFXLEVBQUUsRUFBRSxDQUFDO0lBQ2hCLFdBQVcsRUFBRSxFQUFFLENBQUM7SUFDaEIsV0FBVyxFQUFFLEdBQUcsQ0FBQztJQUNqQixnQkFBZ0IsRUFBRSxNQUFNLENBQUM7Q0FDMUI7QUFFRCxxQkFBYSxrQkFBbUIsU0FBUSxLQUFLO0lBQzNDLFlBQVksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBRXJCLFlBQVksT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFJaEQ7Q0FDRjtBQUVELHdCQUFnQixZQUFZLENBQzFCLEtBQUssQ0FBQyxJQUFJLFNBQVMsR0FBRyxHQUFHLFNBQVMsT0FBTyxFQUFFLEVBQzNDLFVBQVUsU0FBUyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFDMUMsVUFBVSxHQUFHLHdCQUF3QixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxFQUUvRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQ1gsT0FBTyxFQUFFLEdBQUcsRUFDWixHQUFHLEVBQUUsSUFBSSxFQUNULFNBQVMsRUFBRSxVQUFVLEVBQ3JCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsS0FBSyxPQUFPLEVBQ3JDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sR0FDZCxVQUFVLENBTVo7QUFFRCx3QkFBZ0IsZUFBZSxDQUM3QixLQUFLLENBQUMsSUFBSSxTQUFTLEdBQUcsR0FBRyxTQUFTLE9BQU8sRUFBRSxFQUMzQyxVQUFVLFNBQVMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQzFDLFVBQVUsR0FBRyx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFFL0UsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUNYLE9BQU8sRUFBRSxHQUFHLEVBQ1osR0FBRyxFQUFFLElBQUksRUFDVCxTQUFTLEVBQUUsVUFBVSxFQUNyQixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLEtBQUssT0FBTyxFQUNyQyxNQUFNLENBQUMsRUFBRSxNQUFNLEdBQ2QsVUFBVSxHQUFHLFNBQVMsQ0FnQnhCO0FBRUQsd0JBQWdCLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxHQUFHLE9BVzdDO0FBMEJEOzs7OztHQUtHO0FBQ0gsd0JBQWdCLGVBQWUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRSxHQUFlLEdBQUcsa0JBQWtCLENBd0VwRjtBQXlCRCx3QkFBZ0IscUJBQXFCLENBQUMsR0FBRyxFQUFFLEdBQUcsc0JBYTdDO0FBRUQ7OztHQUdHO0FBQ0gsd0JBQWdCLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxvQkFBb0IsR0FBRyxFQUFFLElBQUksb0JBQW9CLEdBQUc7SUFDeEYsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDO0lBQ3pCLG1CQUFtQixFQUFFLFNBQVMsR0FBRyxFQUFFLENBQUM7Q0FDckMsQ0FPQTtBQUVEOztHQUVHO0FBQ0gsd0JBQWdCLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FPaEYifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IAErB,YAAY,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE,EAIhD;CACF;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CAwEpF;AAyBD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IAErB,YAAY,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE,EAIhD;CACF;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CAwEpF;AAyBD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,oBAAoB,GAAG,EAAE,IAAI,oBAAoB,GAAG;IACxF,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,SAAS,GAAG,EAAE,CAAC;CACrC,CAOA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAOhF"}
package/dest/utils.js CHANGED
@@ -162,3 +162,21 @@ export function tryGetCustomErrorName(err) {
162
162
  return undefined;
163
163
  }
164
164
  }
165
+ /**
166
+ * Type guard to check if a transaction is a blob transaction (EIP-4844).
167
+ * Blob transactions have maxFeePerBlobGas and blobVersionedHashes fields.
168
+ */ export function isBlobTransaction(tx) {
169
+ return 'maxFeePerBlobGas' in tx && tx.maxFeePerBlobGas !== undefined && 'blobVersionedHashes' in tx && tx.blobVersionedHashes !== undefined;
170
+ }
171
+ /**
172
+ * Calculates a percentile from an array of bigints
173
+ */ export function calculatePercentile(values, percentile) {
174
+ if (values.length === 0) {
175
+ return 0n;
176
+ }
177
+ const sorted = [
178
+ ...values
179
+ ].sort((a, b)=>a < b ? -1 : a > b ? 1 : 0);
180
+ const index = Math.ceil((sorted.length - 1) * (percentile / 100));
181
+ return sorted[index];
182
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "3.0.0-rc.5",
3
+ "version": "4.0.0-nightly.20260107",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./account": "./dest/account.js",
@@ -17,6 +17,7 @@
17
17
  "./forwarder-proxy": "./dest/forwarder_proxy.js",
18
18
  "./l1-artifacts": "./dest/l1_artifacts.js",
19
19
  "./l1-contract-addresses": "./dest/l1_contract_addresses.js",
20
+ "./l1-fee-analysis": "./dest/l1_tx_utils/l1_fee_analyzer.js",
20
21
  "./l1-reader": "./dest/l1_reader.js",
21
22
  "./l1-tx-utils": "./dest/l1_tx_utils/index.js",
22
23
  "./l1-tx-utils-with-blobs": "./dest/l1_tx_utils/index-blobs.js",
@@ -48,10 +49,10 @@
48
49
  "../package.common.json"
49
50
  ],
50
51
  "dependencies": {
51
- "@aztec/blob-lib": "3.0.0-rc.5",
52
- "@aztec/constants": "3.0.0-rc.5",
53
- "@aztec/foundation": "3.0.0-rc.5",
54
- "@aztec/l1-artifacts": "3.0.0-rc.5",
52
+ "@aztec/blob-lib": "4.0.0-nightly.20260107",
53
+ "@aztec/constants": "4.0.0-nightly.20260107",
54
+ "@aztec/foundation": "4.0.0-nightly.20260107",
55
+ "@aztec/l1-artifacts": "4.0.0-nightly.20260107",
55
56
  "@viem/anvil": "^0.0.10",
56
57
  "dotenv": "^16.0.3",
57
58
  "lodash.chunk": "^4.2.0",
package/src/client.ts CHANGED
@@ -36,7 +36,7 @@ export function getPublicClient(config: Config): ViemPublicClient {
36
36
  const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
37
37
  return createPublicClient({
38
38
  chain: chain.chainInfo,
39
- transport: fallback(config.l1RpcUrls.map(url => http(url))),
39
+ transport: fallback(config.l1RpcUrls.map(url => http(url, { batch: false }))),
40
40
  pollingInterval: config.viemPollingIntervalMS,
41
41
  });
42
42
  }
@@ -88,7 +88,7 @@ export function createExtendedL1Client(
88
88
  const extendedClient = createWalletClient({
89
89
  account: hdAccount,
90
90
  chain,
91
- transport: fallback(rpcUrls.map(url => http(url))),
91
+ transport: fallback(rpcUrls.map(url => http(url, { batch: false }))),
92
92
  pollingInterval: pollingIntervalMS,
93
93
  }).extend(publicActions);
94
94
 
package/src/config.ts CHANGED
@@ -32,6 +32,8 @@ export type L1ContractsConfig = {
32
32
  lagInEpochsForValidatorSet: number;
33
33
  /** The number of epochs to lag behind the current epoch for randao selection. */
34
34
  lagInEpochsForRandao: number;
35
+ /** The number of checkpoints to lag in the inbox (prevents sequencer DOS attacks). */
36
+ inboxLag: number;
35
37
  /** The number of epochs after an epoch ends that proofs are still accepted. */
36
38
  aztecProofSubmissionEpochs: number;
37
39
  /** The deposit amount for a validator */
@@ -81,6 +83,7 @@ export const DefaultL1ContractsConfig = {
81
83
  aztecTargetCommitteeSize: 48,
82
84
  lagInEpochsForValidatorSet: 2,
83
85
  lagInEpochsForRandao: 2, // For PROD, this value should be > lagInEpochsForValidatorSet
86
+ inboxLag: 1, // Default inbox lag to prevent sequencer DOS attacks
84
87
  aztecProofSubmissionEpochs: 1, // you have a full epoch to submit a proof after the epoch to prove ends
85
88
  activationThreshold: 100n * 10n ** 18n,
86
89
  ejectionThreshold: 50n * 10n ** 18n,
@@ -132,6 +135,11 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
132
135
  description: 'The number of epochs to lag behind the current epoch for randao selection.',
133
136
  ...numberConfigHelper(DefaultL1ContractsConfig.lagInEpochsForRandao),
134
137
  },
138
+ inboxLag: {
139
+ env: 'AZTEC_INBOX_LAG',
140
+ description: 'The number of checkpoints to lag in the inbox (prevents sequencer DOS attacks).',
141
+ ...numberConfigHelper(DefaultL1ContractsConfig.inboxLag),
142
+ },
135
143
  aztecProofSubmissionEpochs: {
136
144
  env: 'AZTEC_PROOF_SUBMISSION_EPOCHS',
137
145
  description: 'The number of epochs after an epoch ends that proofs are still accepted.',
@@ -12,7 +12,7 @@ export interface IEmpireBase {
12
12
  getRoundInfo(
13
13
  rollupAddress: Hex,
14
14
  round: bigint,
15
- ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }>;
15
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; quorumReached: boolean; executed: boolean }>;
16
16
  computeRound(slot: SlotNumber): Promise<bigint>;
17
17
  createSignalRequest(payload: Hex): L1TxRequest;
18
18
  createSignalRequestWithSignature(
@@ -79,11 +79,16 @@ export class EmpireSlashingProposerContract extends EventEmitter implements IEmp
79
79
  public async getRoundInfo(
80
80
  rollupAddress: Hex,
81
81
  round: bigint,
82
- ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }> {
82
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; quorumReached: boolean; executed: boolean }> {
83
83
  const result = await this.proposer.read.getRoundData([rollupAddress, round]);
84
+ const [signalCount, quorum] = await Promise.all([
85
+ this.proposer.read.signalCount([rollupAddress, round, result.payloadWithMostSignals]),
86
+ this.getQuorumSize(),
87
+ ]);
84
88
  return {
85
89
  lastSignalSlot: SlotNumber.fromBigInt(result.lastSignalSlot),
86
90
  payloadWithMostSignals: result.payloadWithMostSignals,
91
+ quorumReached: signalCount >= quorum,
87
92
  executed: result.executed,
88
93
  };
89
94
  }
@@ -62,11 +62,16 @@ export class GovernanceProposerContract implements IEmpireBase {
62
62
  public async getRoundInfo(
63
63
  rollupAddress: Hex,
64
64
  round: bigint,
65
- ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }> {
65
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; quorumReached: boolean; executed: boolean }> {
66
66
  const result = await this.proposer.read.getRoundData([rollupAddress, round]);
67
+ const [signalCount, quorum] = await Promise.all([
68
+ this.proposer.read.signalCount([rollupAddress, round, result.payloadWithMostSignals]),
69
+ this.getQuorumSize(),
70
+ ]);
67
71
  return {
68
72
  lastSignalSlot: SlotNumber.fromBigInt(result.lastSignalSlot),
69
73
  payloadWithMostSignals: result.payloadWithMostSignals,
74
+ quorumReached: signalCount >= quorum,
70
75
  executed: result.executed,
71
76
  };
72
77
  }
@@ -45,6 +45,11 @@ export class InboxContract {
45
45
  return this.inbox;
46
46
  }
47
47
 
48
+ public async getLag(opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}): Promise<bigint> {
49
+ await checkBlockTag(opts.blockNumber, this.client);
50
+ return await this.inbox.read.LAG(opts);
51
+ }
52
+
48
53
  public async getState(opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}): Promise<InboxContractState> {
49
54
  await checkBlockTag(opts.blockNumber, this.client);
50
55
  const state = await this.inbox.read.getState(opts);