@aztec/ethereum 0.0.1-commit.b655e406 → 0.0.1-commit.c0b82b2

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 (226) hide show
  1. package/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +1 -1
  4. package/dest/client.js +6 -2
  5. package/dest/config.d.ts +22 -68
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +61 -380
  8. package/dest/constants.d.ts +1 -1
  9. package/dest/contracts/empire_base.d.ts +9 -5
  10. package/dest/contracts/empire_base.d.ts.map +1 -1
  11. package/dest/contracts/empire_base.js +1 -1
  12. package/dest/contracts/empire_slashing_proposer.d.ts +8 -4
  13. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  14. package/dest/contracts/empire_slashing_proposer.js +39 -17
  15. package/dest/contracts/errors.d.ts +1 -1
  16. package/dest/contracts/errors.d.ts.map +1 -1
  17. package/dest/contracts/fee_asset_handler.d.ts +6 -5
  18. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  19. package/dest/contracts/fee_asset_handler.js +11 -9
  20. package/dest/contracts/fee_asset_price_oracle.d.ts +101 -0
  21. package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
  22. package/dest/contracts/fee_asset_price_oracle.js +651 -0
  23. package/dest/contracts/fee_juice.d.ts +1 -1
  24. package/dest/contracts/fee_juice.d.ts.map +1 -1
  25. package/dest/contracts/governance.d.ts +18 -16
  26. package/dest/contracts/governance.d.ts.map +1 -1
  27. package/dest/contracts/governance.js +14 -4
  28. package/dest/contracts/governance_proposer.d.ts +8 -4
  29. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  30. package/dest/contracts/governance_proposer.js +412 -11
  31. package/dest/contracts/gse.d.ts +1 -1
  32. package/dest/contracts/gse.d.ts.map +1 -1
  33. package/dest/contracts/inbox.d.ts +24 -3
  34. package/dest/contracts/inbox.d.ts.map +1 -1
  35. package/dest/contracts/inbox.js +36 -1
  36. package/dest/contracts/index.d.ts +4 -1
  37. package/dest/contracts/index.d.ts.map +1 -1
  38. package/dest/contracts/index.js +3 -0
  39. package/dest/contracts/log.d.ts +13 -0
  40. package/dest/contracts/log.d.ts.map +1 -0
  41. package/dest/contracts/log.js +1 -0
  42. package/dest/contracts/multicall.d.ts +2 -2
  43. package/dest/contracts/multicall.d.ts.map +1 -1
  44. package/dest/contracts/multicall.js +2 -1
  45. package/dest/contracts/outbox.d.ts +41 -0
  46. package/dest/contracts/outbox.d.ts.map +1 -0
  47. package/dest/contracts/outbox.js +86 -0
  48. package/dest/contracts/registry.d.ts +1 -1
  49. package/dest/contracts/registry.d.ts.map +1 -1
  50. package/dest/contracts/rollup.d.ts +195 -123
  51. package/dest/contracts/rollup.d.ts.map +1 -1
  52. package/dest/contracts/rollup.js +765 -187
  53. package/dest/contracts/slasher_contract.d.ts +1 -1
  54. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  55. package/dest/contracts/tally_slashing_proposer.d.ts +9 -7
  56. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  57. package/dest/contracts/tally_slashing_proposer.js +11 -4
  58. package/dest/contracts/utils.d.ts +1 -1
  59. package/dest/deploy_aztec_l1_contracts.d.ts +259 -0
  60. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
  61. package/dest/deploy_aztec_l1_contracts.js +413 -0
  62. package/dest/deploy_l1_contract.d.ts +68 -0
  63. package/dest/deploy_l1_contract.d.ts.map +1 -0
  64. package/dest/deploy_l1_contract.js +312 -0
  65. package/dest/eth-signer/eth-signer.d.ts +1 -1
  66. package/dest/eth-signer/index.d.ts +1 -1
  67. package/dest/forwarder_proxy.d.ts +32 -0
  68. package/dest/forwarder_proxy.d.ts.map +1 -0
  69. package/dest/forwarder_proxy.js +93 -0
  70. package/dest/generated/l1-contracts-defaults.d.ts +30 -0
  71. package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
  72. package/dest/generated/l1-contracts-defaults.js +30 -0
  73. package/dest/l1_artifacts.d.ts +7608 -2048
  74. package/dest/l1_artifacts.d.ts.map +1 -1
  75. package/dest/l1_contract_addresses.d.ts +3 -3
  76. package/dest/l1_contract_addresses.d.ts.map +1 -1
  77. package/dest/l1_contract_addresses.js +3 -3
  78. package/dest/l1_reader.d.ts +3 -1
  79. package/dest/l1_reader.d.ts.map +1 -1
  80. package/dest/l1_reader.js +6 -0
  81. package/dest/l1_tx_utils/config.d.ts +11 -5
  82. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  83. package/dest/l1_tx_utils/config.js +43 -7
  84. package/dest/l1_tx_utils/constants.d.ts +8 -2
  85. package/dest/l1_tx_utils/constants.d.ts.map +1 -1
  86. package/dest/l1_tx_utils/constants.js +27 -2
  87. package/dest/l1_tx_utils/factory.d.ts +18 -10
  88. package/dest/l1_tx_utils/factory.d.ts.map +1 -1
  89. package/dest/l1_tx_utils/factory.js +17 -7
  90. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  91. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  92. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  93. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  94. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  95. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  96. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  97. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  98. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  99. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  100. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  101. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  102. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  103. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  104. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +42 -0
  105. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  106. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  107. package/dest/l1_tx_utils/index-blobs.js +2 -0
  108. package/dest/l1_tx_utils/index.d.ts +4 -1
  109. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  110. package/dest/l1_tx_utils/index.js +3 -0
  111. package/dest/l1_tx_utils/interfaces.d.ts +2 -2
  112. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -1
  113. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  114. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  115. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  116. package/dest/l1_tx_utils/l1_tx_utils.d.ts +16 -8
  117. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  118. package/dest/l1_tx_utils/l1_tx_utils.js +64 -46
  119. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +19 -30
  120. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  121. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +55 -163
  122. package/dest/l1_tx_utils/signer.d.ts +1 -1
  123. package/dest/l1_tx_utils/tx_delayer.d.ts +56 -0
  124. package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
  125. package/dest/{test → l1_tx_utils}/tx_delayer.js +65 -36
  126. package/dest/l1_tx_utils/types.d.ts +1 -1
  127. package/dest/l1_tx_utils/types.d.ts.map +1 -1
  128. package/dest/l1_tx_utils/utils.d.ts +1 -1
  129. package/dest/l1_types.d.ts +1 -1
  130. package/dest/publisher_manager.d.ts +3 -2
  131. package/dest/publisher_manager.d.ts.map +1 -1
  132. package/dest/publisher_manager.js +2 -2
  133. package/dest/queries.d.ts +2 -2
  134. package/dest/queries.d.ts.map +1 -1
  135. package/dest/queries.js +16 -6
  136. package/dest/test/chain_monitor.d.ts +27 -24
  137. package/dest/test/chain_monitor.d.ts.map +1 -1
  138. package/dest/test/chain_monitor.js +33 -36
  139. package/dest/test/eth_cheat_codes.d.ts +11 -3
  140. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  141. package/dest/test/eth_cheat_codes.js +11 -3
  142. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  143. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  144. package/dest/test/index.d.ts +1 -3
  145. package/dest/test/index.d.ts.map +1 -1
  146. package/dest/test/index.js +0 -2
  147. package/dest/test/rollup_cheat_codes.d.ts +17 -13
  148. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  149. package/dest/test/rollup_cheat_codes.js +62 -38
  150. package/dest/test/start_anvil.d.ts +11 -2
  151. package/dest/test/start_anvil.d.ts.map +1 -1
  152. package/dest/test/start_anvil.js +128 -28
  153. package/dest/test/upgrade_utils.d.ts +1 -1
  154. package/dest/test/upgrade_utils.js +2 -2
  155. package/dest/types.d.ts +57 -2
  156. package/dest/types.d.ts.map +1 -1
  157. package/dest/utils.d.ts +16 -3
  158. package/dest/utils.d.ts.map +1 -1
  159. package/dest/utils.js +64 -0
  160. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  161. package/package.json +34 -16
  162. package/src/client.ts +2 -2
  163. package/src/config.ts +74 -460
  164. package/src/contracts/README.md +157 -0
  165. package/src/contracts/empire_base.ts +8 -5
  166. package/src/contracts/empire_slashing_proposer.ts +38 -32
  167. package/src/contracts/fee_asset_handler.ts +10 -7
  168. package/src/contracts/fee_asset_price_oracle.ts +280 -0
  169. package/src/contracts/governance.ts +13 -4
  170. package/src/contracts/governance_proposer.ts +26 -6
  171. package/src/contracts/inbox.ts +55 -3
  172. package/src/contracts/index.ts +3 -0
  173. package/src/contracts/log.ts +13 -0
  174. package/src/contracts/multicall.ts +5 -2
  175. package/src/contracts/outbox.ts +98 -0
  176. package/src/contracts/rollup.ts +446 -167
  177. package/src/contracts/tally_slashing_proposer.ts +15 -8
  178. package/src/deploy_aztec_l1_contracts.ts +650 -0
  179. package/src/deploy_l1_contract.ts +362 -0
  180. package/src/forwarder_proxy.ts +108 -0
  181. package/src/generated/l1-contracts-defaults.ts +32 -0
  182. package/src/l1_contract_addresses.ts +22 -20
  183. package/src/l1_reader.ts +8 -0
  184. package/src/l1_tx_utils/config.ts +52 -11
  185. package/src/l1_tx_utils/constants.ts +13 -2
  186. package/src/l1_tx_utils/factory.ts +31 -31
  187. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  188. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  189. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  190. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  191. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +108 -0
  192. package/src/l1_tx_utils/index-blobs.ts +2 -0
  193. package/src/l1_tx_utils/index.ts +3 -0
  194. package/src/l1_tx_utils/interfaces.ts +1 -1
  195. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  196. package/src/l1_tx_utils/l1_tx_utils.ts +71 -36
  197. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +69 -209
  198. package/src/{test → l1_tx_utils}/tx_delayer.ts +82 -52
  199. package/src/publisher_manager.ts +4 -2
  200. package/src/queries.ts +17 -6
  201. package/src/test/chain_monitor.ts +51 -49
  202. package/src/test/eth_cheat_codes.ts +9 -3
  203. package/src/test/index.ts +0 -2
  204. package/src/test/rollup_cheat_codes.ts +63 -43
  205. package/src/test/start_anvil.ts +148 -27
  206. package/src/test/upgrade_utils.ts +2 -2
  207. package/src/types.ts +62 -0
  208. package/src/utils.ts +83 -1
  209. package/dest/deploy_l1_contracts.d.ts +0 -226
  210. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  211. package/dest/deploy_l1_contracts.js +0 -1473
  212. package/dest/index.d.ts +0 -18
  213. package/dest/index.d.ts.map +0 -1
  214. package/dest/index.js +0 -17
  215. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +0 -26
  216. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +0 -1
  217. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +0 -26
  218. package/dest/test/delayed_tx_utils.d.ts +0 -13
  219. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  220. package/dest/test/delayed_tx_utils.js +0 -28
  221. package/dest/test/tx_delayer.d.ts +0 -36
  222. package/dest/test/tx_delayer.d.ts.map +0 -1
  223. package/src/deploy_l1_contracts.ts +0 -1849
  224. package/src/index.ts +0 -17
  225. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +0 -77
  226. package/src/test/delayed_tx_utils.ts +0 -52
@@ -7,12 +7,12 @@ import { sleep } from '@aztec/foundation/sleep';
7
7
  import { DateProvider } from '@aztec/foundation/timer';
8
8
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
9
9
  import pickBy from 'lodash.pickby';
10
- import { createNonceManager, formatGwei, serializeTransaction } from 'viem';
11
- import { jsonRpc } from 'viem/nonce';
10
+ import { formatGwei, serializeTransaction } from 'viem';
12
11
  import { formatViemError } from '../utils.js';
13
12
  import { l1TxUtilsConfigMappings } from './config.js';
14
- import { LARGE_GAS_LIMIT } from './constants.js';
13
+ import { MAX_L1_TX_LIMIT } from './constants.js';
15
14
  import { ReadOnlyL1TxUtils } from './readonly_l1_tx_utils.js';
15
+ import { createDelayer, wrapClientWithDelayer } from './tx_delayer.js';
16
16
  import { DroppedTransactionError, TerminalTxUtilsState, TxUtilsState, UnknownMinedTxError } from './types.js';
17
17
  const MAX_L1_TX_STATES = 32;
18
18
  export class L1TxUtils extends ReadOnlyL1TxUtils {
@@ -21,13 +21,26 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
21
21
  signer;
22
22
  store;
23
23
  metrics;
24
- nonceManager;
25
24
  txs;
26
- constructor(client, address, signer, logger = createLogger('ethereum:publisher'), dateProvider = new DateProvider(), config, debugMaxGasLimit = false, store, metrics){
25
+ /** Tx delayer for testing. Only set when enableDelayer config is true. */ delayer;
26
+ /** KZG instance for blob operations. */ kzg;
27
+ constructor(client, address, signer, logger = createLogger('ethereum:publisher'), dateProvider = new DateProvider(), config, debugMaxGasLimit = false, store, metrics, kzg, delayer){
27
28
  super(client, logger, dateProvider, config, debugMaxGasLimit), this.client = client, this.address = address, this.signer = signer, this.store = store, this.metrics = metrics, this.txs = [];
28
- this.nonceManager = createNonceManager({
29
- source: jsonRpc()
30
- });
29
+ this.kzg = kzg;
30
+ // Set up delayer: use provided one or create new
31
+ if (config?.enableDelayer && config?.ethereumSlotDuration) {
32
+ this.delayer = delayer ?? this.createDelayer({
33
+ ethereumSlotDuration: config.ethereumSlotDuration
34
+ }, logger.getBindings());
35
+ this.client = wrapClientWithDelayer(this.client, this.delayer);
36
+ if (config.txDelayerMaxInclusionTimeIntoSlot !== undefined) {
37
+ this.delayer.setMaxInclusionTimeIntoSlot(config.txDelayerMaxInclusionTimeIntoSlot);
38
+ }
39
+ } else if (delayer) {
40
+ // Delayer provided but enableDelayer not set — just store it without wrapping
41
+ logger.warn('Delayer provided but enableDelayer config is not set; delayer will not be used');
42
+ this.delayer = delayer;
43
+ }
31
44
  }
32
45
  get state() {
33
46
  return this.txs.at(-1)?.status ?? TxUtilsState.IDLE;
@@ -75,11 +88,24 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
75
88
  this.logger.debug(`No states to rehydrate for account ${account}`);
76
89
  return;
77
90
  }
78
- // Convert loaded states (which have id) to the txs format
79
- this.txs = loadedStates;
80
- this.logger.info(`Rehydrated ${loadedStates.length} tx states for account ${account}`);
91
+ // Clean up excess states if we have more than MAX_L1_TX_STATES
92
+ if (loadedStates.length > MAX_L1_TX_STATES) {
93
+ this.logger.warn(`Found ${loadedStates.length} tx states for account ${account}, pruning to most recent ${MAX_L1_TX_STATES}`);
94
+ // Keep only the most recent MAX_L1_TX_STATES
95
+ const statesToKeep = loadedStates.slice(-MAX_L1_TX_STATES);
96
+ const statesToDelete = loadedStates.slice(0, -MAX_L1_TX_STATES);
97
+ // Batch delete old states in a transaction for efficiency
98
+ const idsToDelete = statesToDelete.map((s)=>s.id);
99
+ await this.store.deleteState(account, ...idsToDelete);
100
+ this.txs = statesToKeep;
101
+ this.logger.info(`Cleaned up ${statesToDelete.length} old tx states, kept ${statesToKeep.length} for account ${account}`);
102
+ } else {
103
+ // Convert loaded states (which have id) to the txs format
104
+ this.txs = loadedStates;
105
+ this.logger.info(`Rehydrated ${loadedStates.length} tx states for account ${account}`);
106
+ }
81
107
  // Find all pending states and resume monitoring
82
- const pendingStates = loadedStates.filter((state)=>!TerminalTxUtilsState.includes(state.status));
108
+ const pendingStates = this.txs.filter((state)=>!TerminalTxUtilsState.includes(state.status));
83
109
  if (pendingStates.length === 0) {
84
110
  return;
85
111
  }
@@ -121,7 +147,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
121
147
  const account = this.getSenderAddress().toString();
122
148
  let gasLimit;
123
149
  if (this.debugMaxGasLimit) {
124
- gasLimit = LARGE_GAS_LIMIT;
150
+ gasLimit = MAX_L1_TX_LIMIT;
125
151
  } else if (gasConfig.gasLimit) {
126
152
  gasLimit = gasConfig.gasLimit;
127
153
  } else {
@@ -135,10 +161,13 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
135
161
  if (this.interrupted) {
136
162
  throw new InterruptError(`Transaction sending is interrupted`);
137
163
  }
138
- const nonce = await this.nonceManager.consume({
139
- client: this.client,
164
+ const now = new Date(await this.getL1Timestamp());
165
+ if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) {
166
+ throw new TimeoutError(`Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`);
167
+ }
168
+ const nonce = await this.client.getTransactionCount({
140
169
  address: account,
141
- chainId: this.client.chain.id
170
+ blockTag: 'pending'
142
171
  });
143
172
  const baseState = {
144
173
  request,
@@ -150,10 +179,6 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
150
179
  const txData = this.makeTxData(baseState, {
151
180
  isCancelTx: false
152
181
  });
153
- const now = new Date(await this.getL1Timestamp());
154
- if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) {
155
- throw new TimeoutError(`Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`);
156
- }
157
182
  // Send the new tx
158
183
  const signedRequest = await this.prepareSignedTransaction(txData);
159
184
  const txHash = await this.client.sendRawTransaction({
@@ -204,7 +229,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
204
229
  };
205
230
  } catch (err) {
206
231
  const viemError = formatViemError(err, request.abi);
207
- this.logger.error(`Failed to send L1 transaction`, viemError, {
232
+ this.logger.error(`Failed to send L1 transaction: ${viemError.message}`, viemError, {
208
233
  request: pick(request, 'to', 'value')
209
234
  });
210
235
  throw viemError;
@@ -333,10 +358,6 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
333
358
  timePassed
334
359
  });
335
360
  await this.updateState(state, TxUtilsState.NOT_MINED);
336
- this.nonceManager.reset({
337
- address: account,
338
- chainId: this.client.chain.id
339
- });
340
361
  throw new DroppedTransactionError(nonce, account);
341
362
  }
342
363
  // Break if the tx has timed out (ie expired)
@@ -408,15 +429,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
408
429
  }
409
430
  // Oh no, the transaction has timed out!
410
431
  if (isCancelTx || !gasConfig.cancelTxOnTimeout) {
411
- // If this was already a cancellation tx, or we are configured to not cancel txs, we just mark it as NOT_MINED
412
- // and reset the nonce manager, so the next tx that comes along can reuse the nonce if/when this tx gets dropped.
413
- // This is the nastiest scenario for us, since the new tx could acquire the next nonce, but then this tx is dropped,
414
- // and the new tx would never get mined. Eventually, the new tx would also drop.
415
432
  await this.updateState(state, TxUtilsState.NOT_MINED);
416
- this.nonceManager.reset({
417
- address: account,
418
- chainId: this.client.chain.id
419
- });
420
433
  } else {
421
434
  // Otherwise we fire the cancellation without awaiting to avoid blocking the caller,
422
435
  // and monitor it in the background so we can speed it up as needed.
@@ -509,11 +522,11 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
509
522
  from: request.from ?? this.getSenderAddress().toString(),
510
523
  maxFeePerGas: gasPrice.maxFeePerGas,
511
524
  maxPriorityFeePerGas: gasPrice.maxPriorityFeePerGas,
512
- gas: request.gas ?? LARGE_GAS_LIMIT
525
+ gas: request.gas ?? MAX_L1_TX_LIMIT
513
526
  };
514
527
  if (!request.gas && !gasConfig.ignoreBlockGasLimit) {
515
- // LARGE_GAS_LIMIT is set as call.gas, increase block gasLimit
516
- blockOverrides.gasLimit = LARGE_GAS_LIMIT * 2n;
528
+ // MAX_L1_TX_LIMIT is set as call.gas, ensure block gasLimit is sufficient
529
+ blockOverrides.gasLimit = MAX_L1_TX_LIMIT;
517
530
  }
518
531
  return this._simulate(call, blockOverrides, stateOverrides, gasConfig, abi);
519
532
  }
@@ -532,10 +545,6 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
532
545
  account
533
546
  });
534
547
  await this.updateState(state, TxUtilsState.NOT_MINED);
535
- this.nonceManager.reset({
536
- address: account,
537
- chainId: this.client.chain.id
538
- });
539
548
  return;
540
549
  }
541
550
  // Check if the original tx is still pending
@@ -550,10 +559,6 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
550
559
  currentNonce
551
560
  });
552
561
  await this.updateState(state, TxUtilsState.NOT_MINED);
553
- this.nonceManager.reset({
554
- address: account,
555
- chainId: this.client.chain.id
556
- });
557
562
  return;
558
563
  }
559
564
  // Get gas price with higher priority fee for cancellation
@@ -604,7 +609,20 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
604
609
  });
605
610
  return Number(timestamp) * 1000;
606
611
  }
607
- /** Makes empty blob inputs for the cancellation tx. To be overridden in L1TxUtilsWithBlobs. */ makeEmptyBlobInputs(_maxFeePerBlobGas) {
608
- throw new Error('Cannot make empty blob inputs for cancellation');
612
+ /** Makes empty blob inputs for the cancellation tx. */ makeEmptyBlobInputs(maxFeePerBlobGas) {
613
+ if (!this.kzg) {
614
+ throw new Error('Cannot make empty blob inputs for cancellation without kzg');
615
+ }
616
+ const blobData = new Uint8Array(131072).fill(0);
617
+ return {
618
+ blobs: [
619
+ blobData
620
+ ],
621
+ kzg: this.kzg,
622
+ maxFeePerBlobGas
623
+ };
624
+ }
625
+ /** Creates a new delayer instance. */ createDelayer(opts, bindings) {
626
+ return createDelayer(this.dateProvider, opts, bindings);
609
627
  }
610
628
  }
@@ -1,6 +1,7 @@
1
+ import type { EthAddress } from '@aztec/foundation/eth-address';
1
2
  import { type Logger } from '@aztec/foundation/log';
2
3
  import { DateProvider } from '@aztec/foundation/timer';
3
- import { type Abi, type Account, type BlockOverrides, type Hex, type StateOverride } from 'viem';
4
+ import { type Abi, type Account, type BlockOverrides, type GetCodeReturnType, type Hex, type StateOverride } from 'viem';
4
5
  import type { ViemClient } from '../types.js';
5
6
  import { type L1TxUtilsConfig } from './config.js';
6
7
  import type { GasPrice, L1BlobInputs, L1TxRequest, TransactionStats } from './types.js';
@@ -15,44 +16,36 @@ export declare class ReadOnlyL1TxUtils {
15
16
  interrupt(): void;
16
17
  restart(): void;
17
18
  getBlock(): Promise<{
18
- number: bigint;
19
- hash: `0x${string}`;
20
- nonce: `0x${string}`;
21
- logsBloom: `0x${string}`;
22
19
  baseFeePerGas: bigint | null;
23
20
  blobGasUsed: bigint;
24
21
  difficulty: bigint;
25
22
  excessBlobGas: bigint;
26
- extraData: Hex;
23
+ extraData: `0x${string}`;
27
24
  gasLimit: bigint;
28
25
  gasUsed: bigint;
29
- miner: import("viem").Address;
30
- mixHash: import("viem").Hash;
26
+ hash: `0x${string}`;
27
+ logsBloom: `0x${string}`;
28
+ miner: `0x${string}`;
29
+ mixHash: `0x${string}`;
30
+ nonce: `0x${string}`;
31
+ number: bigint;
31
32
  parentBeaconBlockRoot?: `0x${string}` | undefined;
32
- parentHash: import("viem").Hash;
33
- receiptsRoot: Hex;
34
- sealFields: Hex[];
35
- sha3Uncles: import("viem").Hash;
33
+ parentHash: `0x${string}`;
34
+ receiptsRoot: `0x${string}`;
35
+ sealFields: `0x${string}`[];
36
+ sha3Uncles: `0x${string}`;
36
37
  size: bigint;
37
- stateRoot: import("viem").Hash;
38
+ stateRoot: `0x${string}`;
38
39
  timestamp: bigint;
39
40
  totalDifficulty: bigint | null;
40
- transactionsRoot: import("viem").Hash;
41
- uncles: import("viem").Hash[];
42
- withdrawals?: import("viem").Withdrawal[] | undefined | undefined;
41
+ transactionsRoot: `0x${string}`;
42
+ uncles: `0x${string}`[];
43
+ withdrawals?: import("viem").Withdrawal[] | undefined;
43
44
  withdrawalsRoot?: `0x${string}` | undefined;
44
45
  transactions: `0x${string}`[];
45
46
  }>;
46
47
  getBlockNumber(): Promise<bigint>;
47
- /**
48
- * Analyzes pending transactions and recent fee history to determine a competitive priority fee.
49
- * Falls back to network estimate if data is unavailable or fails.
50
- * @param networkEstimateResult - Result from estimateMaxPriorityFeePerGas RPC call
51
- * @param pendingBlockResult - Result from getBlock with pending tag RPC call
52
- * @param feeHistoryResult - Result from getFeeHistory RPC call
53
- * @returns A competitive priority fee based on pending txs and recent block history
54
- */
55
- protected getCompetitivePriorityFee(networkEstimateResult: PromiseSettledResult<bigint | null>, pendingBlockResult: PromiseSettledResult<Awaited<ReturnType<ViemClient['getBlock']>> | null>, feeHistoryResult: PromiseSettledResult<Awaited<ReturnType<ViemClient['getFeeHistory']>> | null>): bigint;
48
+ getCode(address: EthAddress): Promise<GetCodeReturnType>;
56
49
  /**
57
50
  * Gets the current gas price with bounds checking
58
51
  */
@@ -86,9 +79,5 @@ export declare class ReadOnlyL1TxUtils {
86
79
  result: `0x${string}`;
87
80
  }>;
88
81
  bumpGasLimit(gasLimit: bigint, _gasConfig?: L1TxUtilsConfig): bigint;
89
- /**
90
- * Helper function to retry RPC calls twice
91
- */
92
- private tryTwice;
93
82
  }
94
- //# sourceMappingURL=readonly_l1_tx_utils.d.ts.map
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZG9ubHlfbDFfdHhfdXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sMV90eF91dGlscy9yZWFkb25seV9sMV90eF91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFFbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBSXZELE9BQU8sRUFDTCxLQUFLLEdBQUcsRUFDUixLQUFLLE9BQU8sRUFFWixLQUFLLGNBQWMsRUFFbkIsS0FBSyxpQkFBaUIsRUFDdEIsS0FBSyxHQUFHLEVBR1IsS0FBSyxhQUFhLEVBS25CLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBbUQsTUFBTSxhQUFhLENBQUM7QUFTcEcsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFNeEYscUJBQWEsaUJBQWlCO0lBS25CLE1BQU0sRUFBRSxVQUFVO0lBQ3pCLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTTthQUNSLFlBQVksRUFBRSxZQUFZO0lBRTFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPO0lBUjlCLE1BQU0sRUFBRSxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDekMsU0FBUyxDQUFDLFdBQVcsVUFBUztJQUU5QixZQUNTLE1BQU0sRUFBRSxVQUFVLEVBQ2YsTUFBTSxvQkFBcUQsRUFDckQsWUFBWSxFQUFFLFlBQVksRUFDMUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUN2QixnQkFBZ0IsR0FBRSxPQUFlLEVBRzVDO0lBRU0sU0FBUyxTQUVmO0lBRU0sT0FBTyxTQUViO0lBRU0sUUFBUTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQUVkO0lBRU0sY0FBYyxvQkFFcEI7SUFFTSxPQUFPLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FFOUQ7SUFFRDs7T0FFRztJQUNVLFdBQVcsQ0FDdEIsa0JBQWtCLENBQUMsRUFBRSxlQUFlLEVBQ3BDLFFBQVEsR0FBRSxPQUFlLEVBQ3pCLE9BQU8sR0FBRSxNQUFVLEVBQ25CLGdCQUFnQixDQUFDLEVBQUUsT0FBTyxPQUFPLFNBQVMsQ0FBQyxHQUFHLEtBQUssR0FBRyxRQUFRLEdBQzdELE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FtSm5CO0lBRUQ7O09BRUc7SUFDVSxXQUFXLENBQ3RCLE9BQU8sRUFBRSxPQUFPLEdBQUcsR0FBRyxFQUN0QixPQUFPLEVBQUUsV0FBVyxFQUNwQixVQUFVLENBQUMsRUFBRSxlQUFlLEVBQzVCLFdBQVcsQ0FBQyxFQUFFLFlBQVksR0FDekIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQThCakI7SUFFSyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsQ0FZL0U7SUFFWSx5QkFBeUIsQ0FDcEMsSUFBSSxFQUFFLEdBQUcsRUFDVCxJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNyQixZQUFZLEVBQUUsTUFBTSxDQUFDO1FBQ3JCLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDVCxPQUFPLEVBQUUsR0FBRyxDQUFDO0tBQ2QsRUFDRCxVQUFVLEVBQUUsQ0FBQyxZQUFZLEdBQUc7UUFBRSxnQkFBZ0IsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDLEdBQUcsU0FBUyxFQUNyRSxhQUFhLEdBQUUsYUFBa0IsK0JBZ0RsQztJQUVZLFFBQVEsQ0FDbkIsT0FBTyxFQUFFLFdBQVcsR0FBRztRQUFFLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQTtLQUFFLEVBQ25ELGNBQWMsR0FBRSxjQUFjLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBTSxFQUNuRCxjQUFjLEdBQUUsYUFBa0IsRUFDbEMsR0FBRyxHQUFFLEdBQWUsRUFDcEIsVUFBVSxDQUFDLEVBQUUsZUFBZSxHQUFHO1FBQUUsbUJBQW1CLENBQUMsRUFBRSxNQUFNLENBQUE7S0FBRSxHQUM5RCxPQUFPLENBQUM7UUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDO1FBQUMsTUFBTSxFQUFFLEtBQUssTUFBTSxFQUFFLENBQUE7S0FBRSxDQUFDLENBVXJEO0lBRUQsVUFBZ0IsU0FBUyxDQUN2QixJQUFJLEVBQUUsR0FBRyxFQUNULGNBQWMsNENBQXFDLEVBQ25ELGNBQWMsMkJBQW9CLEVBQ2xDLFNBQVMsRUFBRSxlQUFlLEdBQUc7UUFBRSxtQkFBbUIsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBQzdELEdBQUcsRUFBRSxHQUFHOzs7T0FvQ1Q7SUFFTSxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxlQUFlLEdBQUcsTUFBTSxDQVcxRTtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"readonly_l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/readonly_l1_tx_utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readonly_l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/readonly_l1_tx_utils.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,15 @@
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';
5
5
  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
- import { BLOCK_TIME_MS, LARGE_GAS_LIMIT, MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE, MIN_REPLACEMENT_BUMP_PERCENTAGE, WEI_CONST } from './constants.js';
8
+ import { BLOCK_TIME_MS, MAX_L1_TX_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,143 +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 = gasConfig.fixedPriorityFeePerGas ? null : this.tryTwice(()=>this.client.estimateMaxPriorityFeePerGas(), 'Estimating max priority fee per gas');
135
- const pendingBlockPromise = gasConfig.fixedPriorityFeePerGas ? null : this.tryTwice(()=>this.client.getBlock({
136
- blockTag: 'pending',
137
- includeTransactions: true
138
- }), 'Getting pending block');
139
- const feeHistoryPromise = gasConfig.fixedPriorityFeePerGas ? null : 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 ?? Promise.resolve(0n),
149
- pendingBlockPromise ?? Promise.resolve(null),
150
- feeHistoryPromise ?? Promise.resolve(null),
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
- let priorityFee;
163
- if (gasConfig.fixedPriorityFeePerGas) {
164
- this.logger?.debug('Using fixed priority fee per L1 gas', {
165
- fixedPriorityFeePerGas: gasConfig.fixedPriorityFeePerGas
166
- });
167
- // try to maintain precision up to 1000000 wei
168
- priorityFee = BigInt(gasConfig.fixedPriorityFeePerGas * 1_000_000) * (WEI_CONST / 1_000_000n);
169
- } else {
170
- // Get competitive priority fee (includes network estimate + analysis)
171
- priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
62
+ let priorityFee = strategyPriorityFee;
63
+ // Apply minimum priority fee floor if configured
64
+ if (gasConfig.minimumPriorityFeePerGas) {
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)
71
+ });
72
+ priorityFee = minimumPriorityFee;
73
+ }
172
74
  }
173
75
  let maxFeePerGas = baseFee;
174
- let maxFeePerBlobGas = blobBaseFee;
76
+ let maxFeePerBlobGas = blobBaseFee ?? 0n;
175
77
  // Bump base fee so it's valid for next blocks if it stalls
176
78
  const numBlocks = Math.ceil(gasConfig.stallTimeMs / BLOCK_TIME_MS);
177
79
  for(let i = 0; i < numBlocks; i++){
@@ -189,17 +91,14 @@ export class ReadOnlyL1TxUtils {
189
91
  // multiply by 100 & divide by 100 to maintain some precision
190
92
  const minPriorityFee = previousGasPrice.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
191
93
  const minMaxFee = previousGasPrice.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
192
- let competitivePriorityFee = priorityFee;
193
- if (!gasConfig.fixedPriorityFeePerGas) {
194
- // Apply bump percentage to competitive fee
195
- competitivePriorityFee = priorityFee * (100_00n + BigInt(configBump * 1_00)) / 100_00n;
196
- this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
197
- networkEstimate: formatGwei(priorityFee),
198
- competitiveFee: formatGwei(competitivePriorityFee),
199
- minRequired: formatGwei(minPriorityFee),
200
- bumpPercentage: configBump
201
- });
202
- }
94
+ // Apply bump percentage to competitive fee
95
+ const competitivePriorityFee = priorityFee * (100_00n + BigInt(configBump * 1_00)) / 100_00n;
96
+ this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
97
+ networkEstimate: formatGwei(priorityFee),
98
+ competitiveFee: formatGwei(competitivePriorityFee),
99
+ minRequired: formatGwei(minPriorityFee),
100
+ bumpPercentage: configBump
101
+ });
203
102
  // Use maximum between competitive fee and minimum required bump
204
103
  const finalPriorityFee = competitivePriorityFee > minPriorityFee ? competitivePriorityFee : minPriorityFee;
205
104
  const feeSource = finalPriorityFee === competitivePriorityFee ? 'competitive' : 'minimum-bump';
@@ -207,25 +106,21 @@ export class ReadOnlyL1TxUtils {
207
106
  // Add the final priority fee to maxFeePerGas
208
107
  maxFeePerGas += finalPriorityFee;
209
108
  maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
210
- if (!gasConfig.fixedPriorityFeePerGas) {
211
- this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
212
- finalPriorityFee: formatGwei(finalPriorityFee)
213
- });
214
- }
109
+ this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
110
+ finalPriorityFee: formatGwei(finalPriorityFee)
111
+ });
215
112
  } else {
216
113
  // First attempt: apply configured bump percentage to competitive fee
217
114
  // multiply by 100 & divide by 100 to maintain some precision
218
- if (!gasConfig.fixedPriorityFeePerGas) {
219
- priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
220
- this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
221
- networkEstimate: formatGwei(priorityFee)
222
- });
223
- }
115
+ priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
116
+ this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
117
+ networkEstimate: formatGwei(priorityFee)
118
+ });
224
119
  maxFeePerGas += priorityFee;
225
120
  }
226
121
  // maxGwei and maxBlobGwei are hard limits
227
- const effectiveMaxGwei = gasConfig.maxGwei * WEI_CONST;
228
- const effectiveMaxBlobGwei = gasConfig.maxBlobGwei * WEI_CONST;
122
+ const effectiveMaxGwei = BigInt(Math.trunc(gasConfig.maxGwei * Number(WEI_CONST)));
123
+ const effectiveMaxBlobGwei = BigInt(Math.trunc(gasConfig.maxBlobGwei * Number(WEI_CONST)));
229
124
  // Ensure we don't exceed maxGwei
230
125
  if (effectiveMaxGwei > 0n) {
231
126
  maxFeePerGas = maxFeePerGas > effectiveMaxGwei ? effectiveMaxGwei : maxFeePerGas;
@@ -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: MAX_L1_TX_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: MAX_L1_TX_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
  }
@@ -1,4 +1,4 @@
1
1
  import { type WalletClient } from 'viem';
2
2
  import type { SigningCallback } from './types.js';
3
3
  export declare function createViemSigner(client: WalletClient): SigningCallback;
4
- //# sourceMappingURL=signer.d.ts.map
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbDFfdHhfdXRpbHMvc2lnbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBZ0MsS0FBSyxZQUFZLEVBQW9CLE1BQU0sTUFBTSxDQUFDO0FBRXpGLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVsRCx3QkFBZ0IsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFlBQVksbUJBb0JwRCJ9