@aztec/ethereum 3.0.0-nightly.20250924 → 3.0.0-nightly.20250926

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 (89) hide show
  1. package/dest/config.d.ts +1 -1
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +4 -4
  4. package/dest/contracts/empire_base.d.ts +1 -1
  5. package/dest/contracts/empire_base.d.ts.map +1 -1
  6. package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
  7. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  8. package/dest/contracts/fee_asset_handler.d.ts +3 -3
  9. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  10. package/dest/contracts/governance.js +1 -1
  11. package/dest/contracts/governance_proposer.d.ts +1 -1
  12. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  13. package/dest/contracts/multicall.d.ts +4 -4
  14. package/dest/contracts/multicall.d.ts.map +1 -1
  15. package/dest/contracts/rollup.d.ts +3 -3
  16. package/dest/contracts/rollup.d.ts.map +1 -1
  17. package/dest/deploy_l1_contracts.d.ts +6 -2
  18. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  19. package/dest/deploy_l1_contracts.js +43 -33
  20. package/dest/index.d.ts +1 -1
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +1 -1
  23. package/dest/l1_artifacts.d.ts +26 -1738
  24. package/dest/l1_artifacts.d.ts.map +1 -1
  25. package/dest/l1_tx_utils/config.d.ts +56 -0
  26. package/dest/l1_tx_utils/config.d.ts.map +1 -0
  27. package/dest/l1_tx_utils/config.js +67 -0
  28. package/dest/l1_tx_utils/constants.d.ts +6 -0
  29. package/dest/l1_tx_utils/constants.d.ts.map +1 -0
  30. package/dest/l1_tx_utils/constants.js +14 -0
  31. package/dest/l1_tx_utils/factory.d.ts +9 -0
  32. package/dest/l1_tx_utils/factory.d.ts.map +1 -0
  33. package/dest/l1_tx_utils/factory.js +14 -0
  34. package/dest/l1_tx_utils/index.d.ts +9 -0
  35. package/dest/l1_tx_utils/index.d.ts.map +1 -0
  36. package/dest/l1_tx_utils/index.js +9 -0
  37. package/dest/l1_tx_utils/l1_tx_utils.d.ts +80 -0
  38. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
  39. package/dest/{l1_tx_utils.js → l1_tx_utils/l1_tx_utils.js} +14 -433
  40. package/dest/{l1_tx_utils_with_blobs.d.ts → l1_tx_utils/l1_tx_utils_with_blobs.d.ts} +6 -4
  41. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
  42. package/dest/{l1_tx_utils_with_blobs.js → l1_tx_utils/l1_tx_utils_with_blobs.js} +2 -1
  43. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +81 -0
  44. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
  45. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +304 -0
  46. package/dest/l1_tx_utils/signer.d.ts +4 -0
  47. package/dest/l1_tx_utils/signer.d.ts.map +1 -0
  48. package/dest/l1_tx_utils/signer.js +16 -0
  49. package/dest/l1_tx_utils/types.d.ts +44 -0
  50. package/dest/l1_tx_utils/types.d.ts.map +1 -0
  51. package/dest/l1_tx_utils/types.js +9 -0
  52. package/dest/l1_tx_utils/utils.d.ts +4 -0
  53. package/dest/l1_tx_utils/utils.d.ts.map +1 -0
  54. package/dest/l1_tx_utils/utils.js +14 -0
  55. package/dest/publisher_manager.d.ts +1 -1
  56. package/dest/publisher_manager.d.ts.map +1 -1
  57. package/dest/publisher_manager.js +1 -1
  58. package/dest/test/delayed_tx_utils.d.ts +2 -2
  59. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  60. package/dest/test/delayed_tx_utils.js +2 -2
  61. package/dest/test/upgrade_utils.js +1 -1
  62. package/package.json +6 -6
  63. package/src/config.ts +4 -4
  64. package/src/contracts/empire_base.ts +1 -1
  65. package/src/contracts/empire_slashing_proposer.ts +1 -1
  66. package/src/contracts/fee_asset_handler.ts +1 -1
  67. package/src/contracts/governance.ts +1 -1
  68. package/src/contracts/governance_proposer.ts +1 -1
  69. package/src/contracts/multicall.ts +1 -1
  70. package/src/contracts/rollup.ts +1 -1
  71. package/src/deploy_l1_contracts.ts +90 -47
  72. package/src/index.ts +1 -1
  73. package/src/l1_tx_utils/config.ts +129 -0
  74. package/src/l1_tx_utils/constants.ts +18 -0
  75. package/src/l1_tx_utils/factory.ts +44 -0
  76. package/src/l1_tx_utils/index.ts +11 -0
  77. package/src/l1_tx_utils/l1_tx_utils.ts +527 -0
  78. package/src/{l1_tx_utils_with_blobs.ts → l1_tx_utils/l1_tx_utils_with_blobs.ts} +7 -10
  79. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +368 -0
  80. package/src/l1_tx_utils/signer.ts +28 -0
  81. package/src/l1_tx_utils/types.ts +52 -0
  82. package/src/l1_tx_utils/utils.ts +16 -0
  83. package/src/publisher_manager.ts +1 -1
  84. package/src/test/delayed_tx_utils.ts +2 -2
  85. package/src/test/upgrade_utils.ts +1 -1
  86. package/dest/l1_tx_utils.d.ts +0 -252
  87. package/dest/l1_tx_utils.d.ts.map +0 -1
  88. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  89. package/src/l1_tx_utils.ts +0 -1125
@@ -14,7 +14,7 @@ import {
14
14
  } from 'viem';
15
15
 
16
16
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
17
- import { createL1TxUtilsFromViemWallet } from '../l1_tx_utils.js';
17
+ import { createL1TxUtilsFromViemWallet } from '../l1_tx_utils/index.js';
18
18
  import { type ExtendedViemWalletClient, type ViemClient, isExtendedClient } from '../types.js';
19
19
 
20
20
  export type L1GovernanceContractAddresses = Pick<
@@ -11,7 +11,7 @@ import {
11
11
  getContract,
12
12
  } from 'viem';
13
13
 
14
- import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
14
+ import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
15
15
  import type { ViemClient } from '../types.js';
16
16
  import { type IEmpireBase, encodeSignal, encodeSignalWithSignature, signSignalWithSig } from './empire_base.js';
17
17
  import { extractProposalIdFromLogs } from './governance.js';
@@ -4,7 +4,7 @@ import type { Logger } from '@aztec/foundation/log';
4
4
 
5
5
  import { type EncodeFunctionDataParameters, type Hex, encodeFunctionData, multicall3Abi } from 'viem';
6
6
 
7
- import type { L1BlobInputs, L1GasConfig, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
7
+ import type { L1BlobInputs, L1GasConfig, L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
8
8
  import type { ExtendedViemWalletClient } from '../types.js';
9
9
  import { FormattedViemError, formatViemError } from '../utils.js';
10
10
  import { RollupContract } from './rollup.js';
@@ -21,7 +21,7 @@ import { getPublicClient } from '../client.js';
21
21
  import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
22
22
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
23
23
  import type { L1ReaderConfig } from '../l1_reader.js';
24
- import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
24
+ import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
25
25
  import type { ViemClient } from '../types.js';
26
26
  import { formatViemError } from '../utils.js';
27
27
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
@@ -6,7 +6,7 @@ import type { Fr } from '@aztec/foundation/fields';
6
6
  import { jsonStringify } from '@aztec/foundation/json-rpc';
7
7
  import { type Logger, createLogger } from '@aztec/foundation/log';
8
8
  import { DateProvider } from '@aztec/foundation/timer';
9
- import type { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
9
+ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
10
10
 
11
11
  import type { Abi, Narrow } from 'abitype';
12
12
  import { mkdir, writeFile } from 'fs/promises';
@@ -69,7 +69,7 @@ import {
69
69
  type L1TxUtilsConfig,
70
70
  createL1TxUtilsFromViemWallet,
71
71
  getL1TxUtilsConfigEnvVars,
72
- } from './l1_tx_utils.js';
72
+ } from './l1_tx_utils/index.js';
73
73
  import type { ExtendedViemWalletClient } from './types.js';
74
74
  import { formatViemError } from './utils.js';
75
75
  import { ZK_PASSPORT_DOMAIN, ZK_PASSPORT_SCOPE, ZK_PASSPORT_VERIFIER_ADDRESS } from './zkPassportVerifierAddress.js';
@@ -187,27 +187,37 @@ export const deploySharedContracts = async (
187
187
 
188
188
  const txHashes: Hex[] = [];
189
189
 
190
- const feeAssetAddress = await deployer.deploy(FeeAssetArtifact, ['FeeJuice', 'FEE', l1Client.account.address]);
190
+ const { address: feeAssetAddress } = await deployer.deploy(FeeAssetArtifact, [
191
+ 'FeeJuice',
192
+ 'FEE',
193
+ l1Client.account.address,
194
+ ]);
191
195
  logger.verbose(`Deployed Fee Asset at ${feeAssetAddress}`);
192
196
 
193
- const stakingAssetAddress = await deployer.deploy(StakingAssetArtifact, ['Staking', 'STK', l1Client.account.address]);
194
- logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
195
-
196
- const gseAddress = await deployer.deploy(GSEArtifact, [
197
+ const { address: stakingAssetAddress } = await deployer.deploy(StakingAssetArtifact, [
198
+ 'Staking',
199
+ 'STK',
197
200
  l1Client.account.address,
198
- stakingAssetAddress.toString(),
199
- args.activationThreshold,
200
- args.ejectionThreshold,
201
201
  ]);
202
+ logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
203
+
204
+ const gseAddress = (
205
+ await deployer.deploy(GSEArtifact, [
206
+ l1Client.account.address,
207
+ stakingAssetAddress.toString(),
208
+ args.activationThreshold,
209
+ args.ejectionThreshold,
210
+ ])
211
+ ).address;
202
212
  logger.verbose(`Deployed GSE at ${gseAddress}`);
203
213
 
204
- const registryAddress = await deployer.deploy(RegistryArtifact, [
214
+ const { address: registryAddress } = await deployer.deploy(RegistryArtifact, [
205
215
  l1Client.account.address,
206
216
  feeAssetAddress.toString(),
207
217
  ]);
208
218
  logger.verbose(`Deployed Registry at ${registryAddress}`);
209
219
 
210
- const governanceProposerAddress = await deployer.deploy(GovernanceProposerArtifact, [
220
+ const { address: governanceProposerAddress } = await deployer.deploy(GovernanceProposerArtifact, [
211
221
  registryAddress.toString(),
212
222
  gseAddress.toString(),
213
223
  BigInt(args.governanceProposerQuorum ?? args.governanceProposerRoundSize / 2 + 1),
@@ -217,7 +227,7 @@ export const deploySharedContracts = async (
217
227
 
218
228
  // @note @LHerskind the assets are expected to be the same at some point, but for better
219
229
  // configurability they are different for now.
220
- const governanceAddress = await deployer.deploy(GovernanceArtifact, [
230
+ const { address: governanceAddress } = await deployer.deploy(GovernanceArtifact, [
221
231
  stakingAssetAddress.toString(),
222
232
  governanceProposerAddress.toString(),
223
233
  gseAddress.toString(),
@@ -259,11 +269,13 @@ export const deploySharedContracts = async (
259
269
  txHashes.push(txHash);
260
270
  }
261
271
 
262
- const coinIssuerAddress = await deployer.deploy(CoinIssuerArtifact, [
263
- feeAssetAddress.toString(),
264
- (25_000_000_000n * 10n ** 18n) / (60n * 60n * 24n * 365n),
265
- l1Client.account.address,
266
- ]);
272
+ const coinIssuerAddress = (
273
+ await deployer.deploy(CoinIssuerArtifact, [
274
+ feeAssetAddress.toString(),
275
+ (25_000_000_000n * 10n ** 18n) / (60n * 60n * 24n * 365n),
276
+ l1Client.account.address,
277
+ ])
278
+ ).address;
267
279
  logger.verbose(`Deployed CoinIssuer at ${coinIssuerAddress}`);
268
280
 
269
281
  logger.verbose(`Waiting for deployments to complete`);
@@ -281,11 +293,13 @@ export const deploySharedContracts = async (
281
293
  /* CHEAT CODES START HERE */
282
294
  /* -------------------------------------------------------------------------- */
283
295
 
284
- feeAssetHandlerAddress = await deployer.deploy(FeeAssetHandlerArtifact, [
285
- l1Client.account.address,
286
- feeAssetAddress.toString(),
287
- BigInt(1000n * 10n ** 18n),
288
- ]);
296
+ feeAssetHandlerAddress = (
297
+ await deployer.deploy(FeeAssetHandlerArtifact, [
298
+ l1Client.account.address,
299
+ feeAssetAddress.toString(),
300
+ BigInt(1000n * 10n ** 18n),
301
+ ])
302
+ ).address;
289
303
  logger.verbose(`Deployed FeeAssetHandler at ${feeAssetHandlerAddress}`);
290
304
 
291
305
  // Only if we are "fresh" will we be adding as a minter, otherwise above will simply get same address
@@ -328,7 +342,8 @@ export const deploySharedContracts = async (
328
342
  skipMerkleCheck: true, // skip merkle check - needed for testing without generating proofs
329
343
  } as const;
330
344
 
331
- stakingAssetHandlerAddress = await deployer.deploy(StakingAssetHandlerArtifact, [stakingAssetHandlerDeployArgs]);
345
+ stakingAssetHandlerAddress = (await deployer.deploy(StakingAssetHandlerArtifact, [stakingAssetHandlerDeployArgs]))
346
+ .address;
332
347
  logger.verbose(`Deployed StakingAssetHandler at ${stakingAssetHandlerAddress}`);
333
348
 
334
349
  const { txHash: stakingMinterTxHash } = await deployer.sendTransaction({
@@ -399,7 +414,7 @@ export const deploySharedContracts = async (
399
414
 
400
415
  const getZkPassportVerifierAddress = async (deployer: L1Deployer, args: DeployL1ContractsArgs): Promise<EthAddress> => {
401
416
  if (args.zkPassportArgs?.mockZkPassportVerifier) {
402
- return await deployer.deploy(mockVerifiers.mockZkPassportVerifier);
417
+ return (await deployer.deploy(mockVerifiers.mockZkPassportVerifier)).address;
403
418
  }
404
419
  return ZK_PASSPORT_VERIFIER_ADDRESS;
405
420
  };
@@ -452,7 +467,7 @@ export const deployRollupForUpgrade = async (
452
467
  };
453
468
 
454
469
  export const deploySlashFactory = async (deployer: L1Deployer, rollupAddress: Hex, logger: Logger) => {
455
- const slashFactoryAddress = await deployer.deploy(SlashFactoryArtifact, [rollupAddress]);
470
+ const slashFactoryAddress = (await deployer.deploy(SlashFactoryArtifact, [rollupAddress])).address;
456
471
  logger.verbose(`Deployed SlashFactory at ${slashFactoryAddress}`);
457
472
  return slashFactoryAddress;
458
473
  };
@@ -461,10 +476,12 @@ export const deployUpgradePayload = async (
461
476
  deployer: L1Deployer,
462
477
  addresses: Pick<L1ContractAddresses, 'registryAddress' | 'rollupAddress'>,
463
478
  ) => {
464
- const payloadAddress = await deployer.deploy(RegisterNewRollupVersionPayloadArtifact, [
465
- addresses.registryAddress.toString(),
466
- addresses.rollupAddress.toString(),
467
- ]);
479
+ const payloadAddress = (
480
+ await deployer.deploy(RegisterNewRollupVersionPayloadArtifact, [
481
+ addresses.registryAddress.toString(),
482
+ addresses.rollupAddress.toString(),
483
+ ])
484
+ ).address;
468
485
 
469
486
  return payloadAddress;
470
487
  };
@@ -517,10 +534,10 @@ export const deployRollup = async (
517
534
  let epochProofVerifier = EthAddress.ZERO;
518
535
 
519
536
  if (args.realVerifier) {
520
- epochProofVerifier = await deployer.deploy(l1ArtifactsVerifiers.honkVerifier);
537
+ epochProofVerifier = (await deployer.deploy(l1ArtifactsVerifiers.honkVerifier)).address;
521
538
  logger.verbose(`Rollup will use the real verifier at ${epochProofVerifier}`);
522
539
  } else {
523
- epochProofVerifier = await deployer.deploy(mockVerifiers.mockVerifier);
540
+ epochProofVerifier = (await deployer.deploy(mockVerifiers.mockVerifier)).address;
524
541
  logger.verbose(`Rollup will use the mock verifier at ${epochProofVerifier}`);
525
542
  }
526
543
 
@@ -582,8 +599,10 @@ export const deployRollup = async (
582
599
  rollupConfigArgs,
583
600
  ] as const;
584
601
 
585
- const rollupAddress = await deployer.deploy(RollupArtifact, rollupArgs, { gasLimit: 15_000_000n });
586
- logger.verbose(`Deployed Rollup at ${rollupAddress}`, rollupConfigArgs);
602
+ const { address: rollupAddress, existed: rollupExisted } = await deployer.deploy(RollupArtifact, rollupArgs, {
603
+ gasLimit: 15_000_000n,
604
+ });
605
+ logger.verbose(`Deployed Rollup at ${rollupAddress}, already existed: ${rollupExisted}`, rollupConfigArgs);
587
606
 
588
607
  const rollupContract = new RollupContract(extendedClient, rollupAddress);
589
608
 
@@ -608,7 +627,7 @@ export const deployRollup = async (
608
627
  txHashes.push(mintTxHash);
609
628
  }
610
629
 
611
- const slashFactoryAddress = await deployer.deploy(SlashFactoryArtifact, [rollupAddress.toString()]);
630
+ const slashFactoryAddress = (await deployer.deploy(SlashFactoryArtifact, [rollupAddress.toString()])).address;
612
631
  logger.verbose(`Deployed SlashFactory at ${slashFactoryAddress}`);
613
632
 
614
633
  // We need to call a function on the registry to set the various contract addresses.
@@ -670,7 +689,17 @@ export const deployRollup = async (
670
689
  logger.verbose(`Not the owner of the gse, skipping rollup addition`);
671
690
  }
672
691
 
673
- if (args.initialValidators && (await gseContract.read.isRollupRegistered([rollupContract.address]))) {
692
+ const activeAttestorCount = await rollupContract.getActiveAttesterCount();
693
+ const queuedAttestorCount = await rollupContract.getEntryQueueLength();
694
+ logger.info(`Rollup has ${activeAttestorCount} active attestors and ${queuedAttestorCount} queued attestors`);
695
+
696
+ const shouldAddValidators = activeAttestorCount === 0n && queuedAttestorCount === 0n;
697
+
698
+ if (
699
+ args.initialValidators &&
700
+ shouldAddValidators &&
701
+ (await gseContract.read.isRollupRegistered([rollupContract.address]))
702
+ ) {
674
703
  await addMultipleValidators(
675
704
  extendedClient,
676
705
  deployer,
@@ -886,7 +915,8 @@ export const addMultipleValidators = async (
886
915
  }
887
916
 
888
917
  const gseContract = new GSEContract(extendedClient, gseAddress);
889
- const multiAdder = await deployer.deploy(MultiAdderArtifact, [rollupAddress, deployer.client.account.address]);
918
+ const multiAdder = (await deployer.deploy(MultiAdderArtifact, [rollupAddress, deployer.client.account.address]))
919
+ .address;
890
920
 
891
921
  const makeValidatorTuples = async (validator: Operator) => {
892
922
  const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
@@ -1007,11 +1037,13 @@ export const cheat_initializeFeeAssetHandler = async (
1007
1037
  feeAssetHandlerAddress: EthAddress;
1008
1038
  txHash: Hex;
1009
1039
  }> => {
1010
- const feeAssetHandlerAddress = await deployer.deploy(FeeAssetHandlerArtifact, [
1011
- extendedClient.account.address,
1012
- feeAssetAddress.toString(),
1013
- BigInt(1e18),
1014
- ]);
1040
+ const feeAssetHandlerAddress = (
1041
+ await deployer.deploy(FeeAssetHandlerArtifact, [
1042
+ extendedClient.account.address,
1043
+ feeAssetAddress.toString(),
1044
+ BigInt(1e18),
1045
+ ])
1046
+ ).address;
1015
1047
  logger.verbose(`Deployed FeeAssetHandler at ${feeAssetHandlerAddress}`);
1016
1048
 
1017
1049
  const { txHash } = await deployer.sendTransaction({
@@ -1343,10 +1375,10 @@ export class L1Deployer {
1343
1375
  params: ContractArtifacts<TAbi>,
1344
1376
  args?: ContractConstructorArgs<TAbi>,
1345
1377
  opts: { gasLimit?: bigint } = {},
1346
- ): Promise<EthAddress> {
1378
+ ): Promise<{ address: EthAddress; existed: boolean }> {
1347
1379
  this.logger.debug(`Deploying ${params.name} contract`, { args });
1348
1380
  try {
1349
- const { txHash, address, deployedLibraries } = await deployL1Contract(
1381
+ const { txHash, address, deployedLibraries, existed } = await deployL1Contract(
1350
1382
  this.client,
1351
1383
  params.contractAbi,
1352
1384
  params.contractBytecode,
@@ -1384,7 +1416,10 @@ export class L1Deployer {
1384
1416
  libraries: deployedLibraries ?? [],
1385
1417
  });
1386
1418
  }
1387
- return address;
1419
+ return {
1420
+ address,
1421
+ existed,
1422
+ };
1388
1423
  } catch (error) {
1389
1424
  throw new Error(`Failed to deploy ${params.name}`, { cause: formatViemError(error) });
1390
1425
  }
@@ -1442,7 +1477,12 @@ export async function deployL1Contract(
1442
1477
  gasLimit?: bigint;
1443
1478
  acceleratedTestDeployments?: boolean;
1444
1479
  } = {},
1445
- ): Promise<{ address: EthAddress; txHash: Hex | undefined; deployedLibraries?: VerificationLibraryEntry[] }> {
1480
+ ): Promise<{
1481
+ address: EthAddress;
1482
+ txHash: Hex | undefined;
1483
+ deployedLibraries?: VerificationLibraryEntry[];
1484
+ existed: boolean;
1485
+ }> {
1446
1486
  let txHash: Hex | undefined = undefined;
1447
1487
  let resultingAddress: Hex | null | undefined = undefined;
1448
1488
  const deployedLibraries: VerificationLibraryEntry[] = [];
@@ -1544,6 +1584,8 @@ export async function deployL1Contract(
1544
1584
  }
1545
1585
  }
1546
1586
 
1587
+ let existed = false;
1588
+
1547
1589
  if (saltFromOpts) {
1548
1590
  logger?.info(`Deploying contract with salt ${saltFromOpts}`);
1549
1591
  const { address, paddedSalt: salt, calldata } = getExpectedAddress(abi, bytecode, args, saltFromOpts);
@@ -1565,6 +1607,7 @@ export async function deployL1Contract(
1565
1607
  logger?.verbose(`Deployed contract with salt ${salt} to address ${resultingAddress} in tx ${txHash}.`);
1566
1608
  } else {
1567
1609
  logger?.verbose(`Skipping existing deployment of contract with salt ${salt} to address ${resultingAddress}`);
1610
+ existed = true;
1568
1611
  }
1569
1612
  } else {
1570
1613
  const deployData = encodeDeployData({ abi, bytecode, args });
@@ -1584,7 +1627,7 @@ export async function deployL1Contract(
1584
1627
  }
1585
1628
  }
1586
1629
 
1587
- return { address: EthAddress.fromString(resultingAddress!), txHash, deployedLibraries };
1630
+ return { address: EthAddress.fromString(resultingAddress!), txHash, deployedLibraries, existed };
1588
1631
  }
1589
1632
 
1590
1633
  export function getExpectedAddress(
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from './constants.js';
2
2
  export * from './deploy_l1_contracts.js';
3
3
  export * from './chain.js';
4
- export * from './l1_tx_utils.js';
4
+ export * from './l1_tx_utils/index.js';
5
5
  export * from './l1_contract_addresses.js';
6
6
  export * from './l1_reader.js';
7
7
  export * from './utils.js';
@@ -0,0 +1,129 @@
1
+ import {
2
+ type ConfigMappingsType,
3
+ bigintConfigHelper,
4
+ booleanConfigHelper,
5
+ getConfigFromMappings,
6
+ getDefaultConfig,
7
+ numberConfigHelper,
8
+ } from '@aztec/foundation/config';
9
+
10
+ export interface L1TxUtilsConfig {
11
+ /**
12
+ * How much to increase calculated gas limit.
13
+ */
14
+ gasLimitBufferPercentage?: number;
15
+ /**
16
+ * Maximum gas price in gwei
17
+ */
18
+ maxGwei?: bigint;
19
+ /**
20
+ * Maximum blob fee per gas in gwei
21
+ */
22
+ maxBlobGwei?: bigint;
23
+ /**
24
+ * Priority fee bump percentage
25
+ */
26
+ priorityFeeBumpPercentage?: number;
27
+ /**
28
+ * How much to increase priority fee by each attempt (percentage)
29
+ */
30
+ priorityFeeRetryBumpPercentage?: number;
31
+ /**
32
+ * Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage config
33
+ */
34
+ fixedPriorityFeePerGas?: number;
35
+ /**
36
+ * Maximum number of speed-up attempts
37
+ */
38
+ maxAttempts?: number;
39
+ /**
40
+ * How often to check tx status
41
+ */
42
+ checkIntervalMs?: number;
43
+ /**
44
+ * How long before considering tx stalled
45
+ */
46
+ stallTimeMs?: number;
47
+ /**
48
+ * How long to wait for a tx to be mined before giving up
49
+ */
50
+ txTimeoutMs?: number;
51
+ /**
52
+ * How many attempts will be done to get a tx after it was sent?
53
+ * First attempt is done at 1s, second at 2s, third at 3s, etc.
54
+ */
55
+ txPropagationMaxQueryAttempts?: number;
56
+ /**
57
+ * Whether to attempt to cancel a tx if it's not mined after txTimeoutMs
58
+ */
59
+ cancelTxOnTimeout?: boolean;
60
+ }
61
+
62
+ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
63
+ gasLimitBufferPercentage: {
64
+ description: 'How much to increase calculated gas limit by (percentage)',
65
+ env: 'L1_GAS_LIMIT_BUFFER_PERCENTAGE',
66
+ ...numberConfigHelper(20),
67
+ },
68
+ maxGwei: {
69
+ description: 'Maximum gas price in gwei',
70
+ env: 'L1_GAS_PRICE_MAX',
71
+ ...bigintConfigHelper(500n),
72
+ },
73
+ maxBlobGwei: {
74
+ description: 'Maximum blob fee per gas in gwei',
75
+ env: 'L1_BLOB_FEE_PER_GAS_MAX',
76
+ ...bigintConfigHelper(1_500n),
77
+ },
78
+ priorityFeeBumpPercentage: {
79
+ description: 'How much to increase priority fee by each attempt (percentage)',
80
+ env: 'L1_PRIORITY_FEE_BUMP_PERCENTAGE',
81
+ ...numberConfigHelper(20),
82
+ },
83
+ priorityFeeRetryBumpPercentage: {
84
+ description: 'How much to increase priority fee by each retry attempt (percentage)',
85
+ env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
86
+ ...numberConfigHelper(50),
87
+ },
88
+ fixedPriorityFeePerGas: {
89
+ description: 'Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage',
90
+ env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
91
+ ...numberConfigHelper(0),
92
+ },
93
+ maxAttempts: {
94
+ description: 'Maximum number of speed-up attempts',
95
+ env: 'L1_TX_MONITOR_MAX_ATTEMPTS',
96
+ ...numberConfigHelper(3),
97
+ },
98
+ checkIntervalMs: {
99
+ description: 'How often to check tx status',
100
+ env: 'L1_TX_MONITOR_CHECK_INTERVAL_MS',
101
+ ...numberConfigHelper(1_000),
102
+ },
103
+ stallTimeMs: {
104
+ description: 'How long before considering tx stalled',
105
+ env: 'L1_TX_MONITOR_STALL_TIME_MS',
106
+ ...numberConfigHelper(24_000), // 24s, 2 ethereum slots
107
+ },
108
+ txTimeoutMs: {
109
+ description: 'How long to wait for a tx to be mined before giving up. Set to 0 to disable.',
110
+ env: 'L1_TX_MONITOR_TX_TIMEOUT_MS',
111
+ ...numberConfigHelper(120_000), // 2 mins
112
+ },
113
+ txPropagationMaxQueryAttempts: {
114
+ description: 'How many attempts will be done to get a tx after it was sent',
115
+ env: 'L1_TX_PROPAGATION_MAX_QUERY_ATTEMPTS',
116
+ ...numberConfigHelper(3),
117
+ },
118
+ cancelTxOnTimeout: {
119
+ description: "Whether to attempt to cancel a tx if it's not mined after txTimeoutMs",
120
+ env: 'L1_TX_MONITOR_CANCEL_TX_ON_TIMEOUT',
121
+ ...booleanConfigHelper(true),
122
+ },
123
+ };
124
+
125
+ export const defaultL1TxUtilsConfig = getDefaultConfig<L1TxUtilsConfig>(l1TxUtilsConfigMappings);
126
+
127
+ export function getL1TxUtilsConfigEnvVars(): L1TxUtilsConfig {
128
+ return getConfigFromMappings(l1TxUtilsConfigMappings);
129
+ }
@@ -0,0 +1,18 @@
1
+ // 1_000_000_000 Gwei = 1 ETH
2
+ // 1_000_000_000 Wei = 1 Gwei
3
+ // 1_000_000_000_000_000_000 Wei = 1 ETH
4
+ export const WEI_CONST = 1_000_000_000n;
5
+
6
+ // @note using this large gas limit to avoid the issue of `gas limit too low` when estimating gas in reth
7
+ export const LARGE_GAS_LIMIT = 12_000_000n;
8
+
9
+ // setting a minimum bump percentage to 10% due to geth's implementation
10
+ // https://github.com/ethereum/go-ethereum/blob/e3d61e6db028c412f74bc4d4c7e117a9e29d0de0/core/txpool/legacypool/list.go#L298
11
+ export const MIN_REPLACEMENT_BUMP_PERCENTAGE = 10;
12
+
13
+ // setting a minimum bump percentage to 100% due to geth's implementation
14
+ // https://github.com/ethereum/go-ethereum/blob/e3d61e6db028c412f74bc4d4c7e117a9e29d0de0/core/txpool/blobpool/config.go#L34
15
+ export const MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE = 100;
16
+
17
+ // Avg ethereum block time is ~12s
18
+ export const BLOCK_TIME_MS = 12_000;
@@ -0,0 +1,44 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import { DateProvider } from '@aztec/foundation/timer';
4
+
5
+ import type { TransactionSerializable } from 'viem';
6
+
7
+ import type { EthSigner } from '../eth-signer/eth-signer.js';
8
+ import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
9
+ import type { L1TxUtilsConfig } from './config.js';
10
+ import { L1TxUtils } from './l1_tx_utils.js';
11
+ import { createViemSigner } from './signer.js';
12
+ import type { SigningCallback } from './types.js';
13
+
14
+ export function createL1TxUtilsFromViemWallet(
15
+ client: ExtendedViemWalletClient,
16
+ logger: Logger = createLogger('L1TxUtils'),
17
+ dateProvider: DateProvider = new DateProvider(),
18
+ config?: Partial<L1TxUtilsConfig>,
19
+ debugMaxGasLimit: boolean = false,
20
+ ) {
21
+ return new L1TxUtils(
22
+ client,
23
+ EthAddress.fromString(client.account.address),
24
+ createViemSigner(client),
25
+ logger,
26
+ dateProvider,
27
+ config,
28
+ debugMaxGasLimit,
29
+ );
30
+ }
31
+
32
+ export function createL1TxUtilsFromEthSigner(
33
+ client: ViemClient,
34
+ signer: EthSigner,
35
+ logger: Logger = createLogger('L1TxUtils'),
36
+ dateProvider: DateProvider = new DateProvider(),
37
+ config?: Partial<L1TxUtilsConfig>,
38
+ debugMaxGasLimit: boolean = false,
39
+ ) {
40
+ const callback: SigningCallback = async (transaction: TransactionSerializable, _signingAddress) => {
41
+ return (await signer.signTransaction(transaction)).toViemTransactionSignature();
42
+ };
43
+ return new L1TxUtils(client, signer.address, callback, logger, dateProvider, config, debugMaxGasLimit);
44
+ }
@@ -0,0 +1,11 @@
1
+ export * from './config.js';
2
+ export * from './constants.js';
3
+ export * from './factory.js';
4
+ export * from './l1_tx_utils.js';
5
+ export * from './readonly_l1_tx_utils.js';
6
+ export * from './signer.js';
7
+ export * from './types.js';
8
+ export * from './utils.js';
9
+
10
+ // Note: We intentionally do not export l1_tx_utils_with_blobs.js
11
+ // to avoid accidentally importing blob-lib dependency.