@aztec/ethereum 2.1.8 → 2.1.9-rc.2

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 (37) hide show
  1. package/dest/forwarder_proxy.d.ts +33 -0
  2. package/dest/forwarder_proxy.d.ts.map +1 -0
  3. package/dest/forwarder_proxy.js +93 -0
  4. package/dest/index.d.ts +1 -0
  5. package/dest/index.d.ts.map +1 -1
  6. package/dest/index.js +1 -0
  7. package/dest/l1_reader.d.ts +2 -0
  8. package/dest/l1_reader.d.ts.map +1 -1
  9. package/dest/l1_reader.js +6 -0
  10. package/dest/l1_tx_utils/config.d.ts +2 -2
  11. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  12. package/dest/l1_tx_utils/config.js +17 -3
  13. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  14. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  15. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  16. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  17. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  18. package/dest/l1_tx_utils/index-blobs.js +2 -0
  19. package/dest/l1_tx_utils/interfaces.d.ts +1 -1
  20. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -1
  21. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  22. package/dest/l1_tx_utils/l1_tx_utils.js +17 -4
  23. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  24. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +38 -37
  25. package/dest/types.d.ts +56 -1
  26. package/dest/types.d.ts.map +1 -1
  27. package/package.json +6 -6
  28. package/src/forwarder_proxy.ts +108 -0
  29. package/src/index.ts +1 -0
  30. package/src/l1_reader.ts +8 -0
  31. package/src/l1_tx_utils/config.ts +24 -6
  32. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  33. package/src/l1_tx_utils/index-blobs.ts +2 -0
  34. package/src/l1_tx_utils/interfaces.ts +1 -1
  35. package/src/l1_tx_utils/l1_tx_utils.ts +24 -4
  36. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +48 -49
  37. package/src/types.ts +62 -0
@@ -0,0 +1,33 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import type { Logger } from '@aztec/foundation/log';
3
+ import { type Hex } from 'viem';
4
+ import type { ExtendedViemWalletClient } from './types.js';
5
+ export declare const FORWARDER_SOLIDITY_SOURCE = "\ncontract ForwarderProxy {\n function forward(address target, bytes calldata data) external payable returns (bytes memory) {\n (bool success, bytes memory result) = target.call{value: msg.value}(data);\n require(success, \"call failed\");\n return result;\n }\n}";
6
+ export declare const FORWARDER_ABI: readonly [{
7
+ readonly inputs: readonly [{
8
+ readonly internalType: "address";
9
+ readonly name: "target";
10
+ readonly type: "address";
11
+ }, {
12
+ readonly internalType: "bytes";
13
+ readonly name: "data";
14
+ readonly type: "bytes";
15
+ }];
16
+ readonly name: "forward";
17
+ readonly outputs: readonly [{
18
+ readonly internalType: "bytes";
19
+ readonly name: "";
20
+ readonly type: "bytes";
21
+ }];
22
+ readonly stateMutability: "payable";
23
+ readonly type: "function";
24
+ }];
25
+ export declare const FORWARDER_BYTECODE: Hex;
26
+ /**
27
+ * Deploys the forwarder proxy contract to L1.
28
+ * @param client - The L1 client to use for deployment
29
+ * @param logger - Optional logger
30
+ * @returns The deployed forwarder contract address
31
+ */
32
+ export declare function deployForwarderProxy(client: ExtendedViemWalletClient, logger?: Logger): Promise<EthAddress>;
33
+ //# sourceMappingURL=forwarder_proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwarder_proxy.d.ts","sourceRoot":"","sources":["../src/forwarder_proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIpD,OAAO,EAAE,KAAK,GAAG,EAAgB,MAAM,MAAM,CAAC;AAI9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,eAAO,MAAM,yBAAyB,uRAOpC,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAyBhB,CAAC;AAEX,eAAO,MAAM,kBAAkB,EACi6D,GAAG,CAAC;AAQp8D;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAUjH"}
@@ -0,0 +1,93 @@
1
+ /* eslint-disable no-console */ import { createLogger } from '@aztec/foundation/log';
2
+ import { DateProvider } from '@aztec/foundation/timer';
3
+ import { extractChain } from 'viem';
4
+ import { anvil, mainnet, sepolia } from 'viem/chains';
5
+ import { L1Deployer } from './deploy_l1_contracts.js';
6
+ export const FORWARDER_SOLIDITY_SOURCE = `
7
+ contract ForwarderProxy {
8
+ function forward(address target, bytes calldata data) external payable returns (bytes memory) {
9
+ (bool success, bytes memory result) = target.call{value: msg.value}(data);
10
+ require(success, "call failed");
11
+ return result;
12
+ }
13
+ }`;
14
+ export const FORWARDER_ABI = [
15
+ {
16
+ inputs: [
17
+ {
18
+ internalType: 'address',
19
+ name: 'target',
20
+ type: 'address'
21
+ },
22
+ {
23
+ internalType: 'bytes',
24
+ name: 'data',
25
+ type: 'bytes'
26
+ }
27
+ ],
28
+ name: 'forward',
29
+ outputs: [
30
+ {
31
+ internalType: 'bytes',
32
+ name: '',
33
+ type: 'bytes'
34
+ }
35
+ ],
36
+ stateMutability: 'payable',
37
+ type: 'function'
38
+ }
39
+ ];
40
+ export const FORWARDER_BYTECODE = '0x6080604052348015600e575f5ffd5b506103bf8061001c5f395ff3fe60806040526004361061001d575f3560e01c80636fadcf7214610021575b5f5ffd5b61003b600480360381019061003691906101d0565b610051565b604051610048919061029d565b60405180910390f35b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1634868660405161007d9291906102f9565b5f6040518083038185875af1925050503d805f81146100b7576040519150601f19603f3d011682016040523d82523d5f602084013e6100bc565b606091505b509150915081610101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100f89061036b565b60405180910390fd5b80925050509392505050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61013e82610115565b9050919050565b61014e81610134565b8114610158575f5ffd5b50565b5f8135905061016981610145565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126101905761018f61016f565b5b8235905067ffffffffffffffff8111156101ad576101ac610173565b5b6020830191508360018202830111156101c9576101c8610177565b5b9250929050565b5f5f5f604084860312156101e7576101e661010d565b5b5f6101f48682870161015b565b935050602084013567ffffffffffffffff81111561021557610214610111565b5b6102218682870161017b565b92509250509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61026f8261022d565b6102798185610237565b9350610289818560208601610247565b61029281610255565b840191505092915050565b5f6020820190508181035f8301526102b58184610265565b905092915050565b5f81905092915050565b828183375f83830152505050565b5f6102e083856102bd565b93506102ed8385846102c7565b82840190509392505050565b5f6103058284866102d5565b91508190509392505050565b5f82825260208201905092915050565b7f63616c6c206661696c65640000000000000000000000000000000000000000005f82015250565b5f610355600b83610311565b915061036082610321565b602082019050919050565b5f6020820190508181035f83015261038281610349565b905091905056fea26469706673582212209a1c8cf638cf1569450a731ef9457b862f9e153b0a46e5555429bcf4dffd999564736f6c634300081e0033';
41
+ const FORWARDER_ARTIFACT = {
42
+ name: 'Forwarder',
43
+ contractAbi: FORWARDER_ABI,
44
+ contractBytecode: FORWARDER_BYTECODE
45
+ };
46
+ /**
47
+ * Deploys the forwarder proxy contract to L1.
48
+ * @param client - The L1 client to use for deployment
49
+ * @param logger - Optional logger
50
+ * @returns The deployed forwarder contract address
51
+ */ export async function deployForwarderProxy(client, logger) {
52
+ const log = logger ?? createLogger('ethereum:forwarder');
53
+ const nonce = await client.getTransactionCount({
54
+ address: client.account.address
55
+ });
56
+ const deployer = new L1Deployer(client, nonce, new DateProvider(), false, log, undefined, false);
57
+ log.info('Deploying forwarder proxy contract');
58
+ const deployment = await deployer.deploy(FORWARDER_ARTIFACT, []);
59
+ log.info(`Forwarder proxy deployed at ${deployment.address.toString()}`);
60
+ return deployment.address;
61
+ }
62
+ /**
63
+ * Main function for deploying the forwarder proxy from command line.
64
+ * Usage: node forwarder_proxy.js <private_key> <rpc_url>
65
+ */ async function main() {
66
+ const args = process.argv.slice(2);
67
+ if (args.length < 3) {
68
+ console.error('Usage: node forwarder_proxy.js <private_key> <rpc_url> <chain_id>');
69
+ process.exit(1);
70
+ }
71
+ const [privateKey, rpcUrl, chainId] = args;
72
+ // Dynamic import to avoid pulling in dependencies at module load time
73
+ const { createExtendedL1Client } = await import('./client.js');
74
+ const client = createExtendedL1Client([
75
+ rpcUrl
76
+ ], privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`, extractChain({
77
+ chains: [
78
+ mainnet,
79
+ sepolia,
80
+ anvil
81
+ ],
82
+ id: parseInt(chainId)
83
+ }));
84
+ const address = await deployForwarderProxy(client);
85
+ console.log(`Forwarder proxy deployed at: ${address.toString()}`);
86
+ }
87
+ // Only run main if this is the entry point
88
+ if (import.meta.url === `file://${process.argv[1]}`) {
89
+ main().catch((err)=>{
90
+ console.error('Failed to deploy forwarder proxy:', err);
91
+ process.exit(1);
92
+ });
93
+ }
package/dest/index.d.ts CHANGED
@@ -15,4 +15,5 @@ export * from './l1_types.js';
15
15
  export * from './l1_artifacts.js';
16
16
  export * from './publisher_manager.js';
17
17
  export * from './eth-signer/index.js';
18
+ export * from './forwarder_proxy.js';
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
package/dest/index.js CHANGED
@@ -15,3 +15,4 @@ export * from './l1_types.js';
15
15
  export * from './l1_artifacts.js';
16
16
  export * from './publisher_manager.js';
17
17
  export * from './eth-signer/index.js';
18
+ export * from './forwarder_proxy.js';
@@ -4,6 +4,8 @@ import { type L1ContractAddresses } from './l1_contract_addresses.js';
4
4
  export interface L1ReaderConfig {
5
5
  /** The RPC Url of the ethereum host. */
6
6
  l1RpcUrls: string[];
7
+ /** The RPC Url of the ethereum debug host for trace and debug methods. */
8
+ l1DebugRpcUrls: string[];
7
9
  /** The chain ID of the ethereum host. */
8
10
  l1ChainId: number;
9
11
  /** The deployed l1 contract addresses */
@@ -1 +1 @@
1
- {"version":3,"file":"l1_reader.d.ts","sourceRoot":"","sources":["../src/l1_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,0BAA0B,CAAC;AAE9G,OAAO,EAAE,KAAK,mBAAmB,EAA8B,MAAM,4BAA4B,CAAC;AAElG,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,WAAW,EAAE,mBAAmB,CAAC;IACjC,2CAA2C;IAC3C,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,CAAC,cAAc,CAqBrE,CAAC;AAEF,wBAAgB,wBAAwB,IAAI,cAAc,CAEzD"}
1
+ {"version":3,"file":"l1_reader.d.ts","sourceRoot":"","sources":["../src/l1_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,0BAA0B,CAAC;AAE9G,OAAO,EAAE,KAAK,mBAAmB,EAA8B,MAAM,4BAA4B,CAAC;AAElG,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,0EAA0E;IAC1E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,WAAW,EAAE,mBAAmB,CAAC;IACjC,2CAA2C;IAC3C,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,CAAC,cAAc,CA2BrE,CAAC;AAEF,wBAAgB,wBAAwB,IAAI,cAAc,CAEzD"}
package/dest/l1_reader.js CHANGED
@@ -16,6 +16,12 @@ export const l1ReaderConfigMappings = {
16
16
  parseEnv: (val)=>val.split(',').map((url)=>url.trim()),
17
17
  defaultValue: []
18
18
  },
19
+ l1DebugRpcUrls: {
20
+ env: 'ETHEREUM_DEBUG_HOSTS',
21
+ description: 'The RPC Url of the ethereum debug host for trace and debug methods.',
22
+ parseEnv: (val)=>val.split(',').map((url)=>url.trim()),
23
+ defaultValue: []
24
+ },
19
25
  viemPollingIntervalMS: {
20
26
  env: 'L1_READER_VIEM_POLLING_INTERVAL_MS',
21
27
  description: 'The polling interval viem uses in ms',
@@ -21,9 +21,9 @@ export interface L1TxUtilsConfig {
21
21
  */
22
22
  priorityFeeRetryBumpPercentage?: number;
23
23
  /**
24
- * Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage config
24
+ * Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee.
25
25
  */
26
- fixedPriorityFeePerGas?: number;
26
+ minimumPriorityFeePerGas?: number;
27
27
  /**
28
28
  * Maximum number of speed-up attempts
29
29
  */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CAqEvE,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAE9B,QAAQ,CAAC,eAAe,CAAC,CAAC;AAE/B,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CAgFvE,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAE9B,QAAQ,CAAC,eAAe,CAAC,CAAC;AAE/B,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D"}
@@ -31,12 +31,23 @@ export const l1TxUtilsConfigMappings = {
31
31
  env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
32
32
  ...numberConfigHelper(50)
33
33
  },
34
- fixedPriorityFeePerGas: {
35
- description: 'Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage',
36
- env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
34
+ minimumPriorityFeePerGas: {
35
+ description: 'Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee. If network conditions require a higher fee, the higher fee will be used.',
36
+ env: 'L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI',
37
37
  fallback: [
38
+ 'L1_FIXED_PRIORITY_FEE_PER_GAS',
38
39
  'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'
39
40
  ],
41
+ deprecatedFallback: [
42
+ {
43
+ env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
44
+ message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS')
45
+ },
46
+ {
47
+ env: 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI',
48
+ message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI')
49
+ }
50
+ ],
40
51
  ...floatConfigHelper(0)
41
52
  },
42
53
  maxSpeedUpAttempts: {
@@ -80,3 +91,6 @@ export const defaultL1TxUtilsConfig = getDefaultConfig(l1TxUtilsConfigMappings);
80
91
  export function getL1TxUtilsConfigEnvVars() {
81
92
  return getConfigFromMappings(l1TxUtilsConfigMappings);
82
93
  }
94
+ function deprecatedFixedFeeMessage(envVar) {
95
+ return `Environment variable ${envVar} is deprecated. It is now used as a MINIMUM priority fee rather than a fixed value. ` + 'Please use L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI instead. If network conditions require a higher fee, the higher fee will be used.';
96
+ }
@@ -0,0 +1,41 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import type { Logger } from '@aztec/foundation/log';
3
+ import type { DateProvider } from '@aztec/foundation/timer';
4
+ import type { EthSigner } from '../eth-signer/eth-signer.js';
5
+ import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
6
+ import type { L1TxUtilsConfig } from './config.js';
7
+ import type { IL1TxMetrics, IL1TxStore } from './interfaces.js';
8
+ import { L1TxUtilsWithBlobs } from './l1_tx_utils_with_blobs.js';
9
+ import type { L1BlobInputs, L1TxConfig, L1TxRequest, SigningCallback } from './types.js';
10
+ /**
11
+ * Extends L1TxUtilsWithBlobs to wrap all transactions through a forwarder contract.
12
+ * This is mainly used for testing the archiver's ability to decode transactions that go through proxies.
13
+ */
14
+ export declare class ForwarderL1TxUtils extends L1TxUtilsWithBlobs {
15
+ private readonly forwarderAddress;
16
+ constructor(client: ViemClient | ExtendedViemWalletClient, senderAddress: EthAddress, signingCallback: SigningCallback, logger: Logger | undefined, dateProvider: DateProvider | undefined, config: Partial<L1TxUtilsConfig>, debugMaxGasLimit: boolean, store: IL1TxStore | undefined, metrics: IL1TxMetrics | undefined, forwarderAddress: EthAddress);
17
+ /**
18
+ * Wraps the transaction request in a call to the forwarder contract.
19
+ */
20
+ private wrapInForwarder;
21
+ /**
22
+ * Override sendAndMonitorTransaction to wrap the request in a forwarder call.
23
+ */
24
+ sendAndMonitorTransaction(request: L1TxRequest, gasConfig?: L1TxConfig, blobInputs?: L1BlobInputs): Promise<{
25
+ receipt: import("viem").TransactionReceipt;
26
+ state: import("./types.js").L1TxState;
27
+ }>;
28
+ }
29
+ export declare function createForwarderL1TxUtilsFromViemWallet(client: ExtendedViemWalletClient, forwarderAddress: EthAddress, deps?: {
30
+ logger?: Logger;
31
+ dateProvider?: DateProvider;
32
+ store?: IL1TxStore;
33
+ metrics?: IL1TxMetrics;
34
+ }, config?: Partial<L1TxUtilsConfig>, debugMaxGasLimit?: boolean): ForwarderL1TxUtils;
35
+ export declare function createForwarderL1TxUtilsFromEthSigner(client: ViemClient, signer: EthSigner, forwarderAddress: EthAddress, deps?: {
36
+ logger?: Logger;
37
+ dateProvider?: DateProvider;
38
+ store?: IL1TxStore;
39
+ metrics?: IL1TxMetrics;
40
+ }, config?: Partial<L1TxUtilsConfig>, debugMaxGasLimit?: boolean): ForwarderL1TxUtils;
41
+ //# sourceMappingURL=forwarder_l1_tx_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwarder_l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/forwarder_l1_tx_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEzF;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,kBAAkB;IAWtD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBATjC,MAAM,EAAE,UAAU,GAAG,wBAAwB,EAC7C,aAAa,EAAE,UAAU,EACzB,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,EAChC,gBAAgB,EAAE,OAAO,EACzB,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,OAAO,EAAE,YAAY,GAAG,SAAS,EAChB,gBAAgB,EAAE,UAAU;IAK/C;;OAEG;IACH,OAAO,CAAC,eAAe;IAevB;;OAEG;IACa,yBAAyB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,YAAY;;;;CAKlH;AAED,wBAAgB,sCAAsC,CACpD,MAAM,EAAE,wBAAwB,EAChC,gBAAgB,EAAE,UAAU,EAC5B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,YAAY,CAAC;CACnB,EACN,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,EACrC,gBAAgB,GAAE,OAAe,sBAclC;AAED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,SAAS,EACjB,gBAAgB,EAAE,UAAU,EAC5B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,YAAY,CAAC;CACnB,EACN,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,EACrC,gBAAgB,GAAE,OAAe,sBAkBlC"}
@@ -0,0 +1,48 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { encodeFunctionData } from 'viem';
3
+ import { FORWARDER_ABI } from '../forwarder_proxy.js';
4
+ import { L1TxUtilsWithBlobs } from './l1_tx_utils_with_blobs.js';
5
+ import { createViemSigner } from './signer.js';
6
+ /**
7
+ * Extends L1TxUtilsWithBlobs to wrap all transactions through a forwarder contract.
8
+ * This is mainly used for testing the archiver's ability to decode transactions that go through proxies.
9
+ */ export class ForwarderL1TxUtils extends L1TxUtilsWithBlobs {
10
+ forwarderAddress;
11
+ constructor(client, senderAddress, signingCallback, logger, dateProvider, config, debugMaxGasLimit, store, metrics, forwarderAddress){
12
+ super(client, senderAddress, signingCallback, logger, dateProvider, config, debugMaxGasLimit, store, metrics), this.forwarderAddress = forwarderAddress;
13
+ }
14
+ /**
15
+ * Wraps the transaction request in a call to the forwarder contract.
16
+ */ wrapInForwarder(request) {
17
+ const forwarderCalldata = encodeFunctionData({
18
+ abi: FORWARDER_ABI,
19
+ functionName: 'forward',
20
+ args: [
21
+ request.to,
22
+ request.data
23
+ ]
24
+ });
25
+ return {
26
+ to: this.forwarderAddress.toString(),
27
+ data: forwarderCalldata,
28
+ value: request.value,
29
+ abi: request.abi
30
+ };
31
+ }
32
+ /**
33
+ * Override sendAndMonitorTransaction to wrap the request in a forwarder call.
34
+ */ sendAndMonitorTransaction(request, gasConfig, blobInputs) {
35
+ this.logger.debug(`Wrapping transaction to ${request.to} in forwarder at ${this.forwarderAddress.toString()}`);
36
+ const wrappedRequest = this.wrapInForwarder(request);
37
+ return super.sendAndMonitorTransaction(wrappedRequest, gasConfig, blobInputs);
38
+ }
39
+ }
40
+ export function createForwarderL1TxUtilsFromViemWallet(client, forwarderAddress, deps = {}, config = {}, debugMaxGasLimit = false) {
41
+ return new ForwarderL1TxUtils(client, EthAddress.fromString(client.account.address), createViemSigner(client), deps.logger, deps.dateProvider, config, debugMaxGasLimit, deps.store, deps.metrics, forwarderAddress);
42
+ }
43
+ export function createForwarderL1TxUtilsFromEthSigner(client, signer, forwarderAddress, deps = {}, config = {}, debugMaxGasLimit = false) {
44
+ const callback = async (transaction, _signingAddress)=>{
45
+ return (await signer.signTransaction(transaction)).toViemTransactionSignature();
46
+ };
47
+ return new ForwarderL1TxUtils(client, signer.address, callback, deps.logger, deps.dateProvider, config, debugMaxGasLimit, deps.store, deps.metrics, forwarderAddress);
48
+ }
@@ -0,0 +1,3 @@
1
+ export * from './forwarder_l1_tx_utils.js';
2
+ export * from './l1_tx_utils_with_blobs.js';
3
+ //# sourceMappingURL=index-blobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-blobs.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/index-blobs.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './forwarder_l1_tx_utils.js';
2
+ export * from './l1_tx_utils_with_blobs.js';
@@ -40,7 +40,7 @@ export interface IL1TxStore {
40
40
  * @param account - The sender account address
41
41
  * @param stateId - The state ID to delete
42
42
  */
43
- deleteState(account: string, stateId: number): Promise<void>;
43
+ deleteState(account: string, ...stateId: number[]): Promise<void>;
44
44
  /**
45
45
  * Clears all transaction states for a specific account.
46
46
  * @param account - The sender account address
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErD;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjG;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAElD;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE5E;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;OAGG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IAEzD;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzC"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErD;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjG;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAElD;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE5E;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;OAGG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IAEzD;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/l1_tx_utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/l1_tx_utils.ts"],"names":[],"mappings":"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"}
@@ -75,11 +75,24 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
75
75
  this.logger.debug(`No states to rehydrate for account ${account}`);
76
76
  return;
77
77
  }
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}`);
78
+ // Clean up excess states if we have more than MAX_L1_TX_STATES
79
+ if (loadedStates.length > MAX_L1_TX_STATES) {
80
+ this.logger.warn(`Found ${loadedStates.length} tx states for account ${account}, pruning to most recent ${MAX_L1_TX_STATES}`);
81
+ // Keep only the most recent MAX_L1_TX_STATES
82
+ const statesToKeep = loadedStates.slice(-MAX_L1_TX_STATES);
83
+ const statesToDelete = loadedStates.slice(0, -MAX_L1_TX_STATES);
84
+ // Batch delete old states in a transaction for efficiency
85
+ const idsToDelete = statesToDelete.map((s)=>s.id);
86
+ await this.store.deleteState(account, ...idsToDelete);
87
+ this.txs = statesToKeep;
88
+ this.logger.info(`Cleaned up ${statesToDelete.length} old tx states, kept ${statesToKeep.length} for account ${account}`);
89
+ } else {
90
+ // Convert loaded states (which have id) to the txs format
91
+ this.txs = loadedStates;
92
+ this.logger.info(`Rehydrated ${loadedStates.length} tx states for account ${account}`);
93
+ }
81
94
  // Find all pending states and resume monitoring
82
- const pendingStates = loadedStates.filter((state)=>!TerminalTxUtilsState.includes(state.status));
95
+ const pendingStates = this.txs.filter((state)=>!TerminalTxUtilsState.includes(state.status));
83
96
  if (pendingStates.length === 0) {
84
97
  return;
85
98
  }
@@ -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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"}
@@ -131,12 +131,12 @@ export class ReadOnlyL1TxUtils {
131
131
  const latestBlockPromise = this.tryTwice(()=>this.client.getBlock({
132
132
  blockTag: 'latest'
133
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({
134
+ const networkEstimatePromise = this.tryTwice(()=>this.client.estimateMaxPriorityFeePerGas(), 'Estimating max priority fee per gas');
135
+ const pendingBlockPromise = this.tryTwice(()=>this.client.getBlock({
136
136
  blockTag: 'pending',
137
137
  includeTransactions: true
138
138
  }), 'Getting pending block');
139
- const feeHistoryPromise = gasConfig.fixedPriorityFeePerGas ? null : this.tryTwice(()=>this.client.getFeeHistory({
139
+ const feeHistoryPromise = this.tryTwice(()=>this.client.getFeeHistory({
140
140
  blockCount: HISTORICAL_BLOCK_COUNT,
141
141
  rewardPercentiles: [
142
142
  75
@@ -145,9 +145,9 @@ export class ReadOnlyL1TxUtils {
145
145
  const blobBaseFeePromise = isBlobTx ? this.tryTwice(()=>this.client.getBlobBaseFee(), 'Getting blob base fee') : null;
146
146
  const [latestBlockResult, networkEstimateResult, pendingBlockResult, feeHistoryResult, blobBaseFeeResult] = await Promise.allSettled([
147
147
  latestBlockPromise,
148
- networkEstimatePromise ?? Promise.resolve(0n),
149
- pendingBlockPromise ?? Promise.resolve(null),
150
- feeHistoryPromise ?? Promise.resolve(null),
148
+ networkEstimatePromise,
149
+ pendingBlockPromise,
150
+ feeHistoryPromise,
151
151
  blobBaseFeePromise ?? Promise.resolve(0n)
152
152
  ]);
153
153
  // Extract results
@@ -159,15 +159,23 @@ export class ReadOnlyL1TxUtils {
159
159
  } else if (isBlobTx) {
160
160
  this.logger?.warn('Failed to get L1 blob base fee', attempt);
161
161
  }
162
- let priorityFee;
163
- if (gasConfig.fixedPriorityFeePerGas) {
164
- this.logger?.debug('Using fixed priority fee per L1 gas', {
165
- fixedPriorityFeePerGas: gasConfig.fixedPriorityFeePerGas
166
- });
167
- priorityFee = BigInt(Math.trunc(gasConfig.fixedPriorityFeePerGas * Number(WEI_CONST)));
168
- } else {
169
- // Get competitive priority fee (includes network estimate + analysis)
170
- priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
162
+ // Get competitive priority fee
163
+ let priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
164
+ // Apply minimum priority fee as a floor if configured
165
+ 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)
177
+ });
178
+ }
171
179
  }
172
180
  let maxFeePerGas = baseFee;
173
181
  let maxFeePerBlobGas = blobBaseFee;
@@ -188,17 +196,14 @@ export class ReadOnlyL1TxUtils {
188
196
  // multiply by 100 & divide by 100 to maintain some precision
189
197
  const minPriorityFee = previousGasPrice.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
190
198
  const minMaxFee = previousGasPrice.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
191
- let competitivePriorityFee = priorityFee;
192
- if (!gasConfig.fixedPriorityFeePerGas) {
193
- // Apply bump percentage to competitive fee
194
- competitivePriorityFee = priorityFee * (100_00n + BigInt(configBump * 1_00)) / 100_00n;
195
- this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
196
- networkEstimate: formatGwei(priorityFee),
197
- competitiveFee: formatGwei(competitivePriorityFee),
198
- minRequired: formatGwei(minPriorityFee),
199
- bumpPercentage: configBump
200
- });
201
- }
199
+ // Apply bump percentage to competitive fee
200
+ const competitivePriorityFee = priorityFee * (100_00n + BigInt(configBump * 1_00)) / 100_00n;
201
+ this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
202
+ networkEstimate: formatGwei(priorityFee),
203
+ competitiveFee: formatGwei(competitivePriorityFee),
204
+ minRequired: formatGwei(minPriorityFee),
205
+ bumpPercentage: configBump
206
+ });
202
207
  // Use maximum between competitive fee and minimum required bump
203
208
  const finalPriorityFee = competitivePriorityFee > minPriorityFee ? competitivePriorityFee : minPriorityFee;
204
209
  const feeSource = finalPriorityFee === competitivePriorityFee ? 'competitive' : 'minimum-bump';
@@ -206,20 +211,16 @@ export class ReadOnlyL1TxUtils {
206
211
  // Add the final priority fee to maxFeePerGas
207
212
  maxFeePerGas += finalPriorityFee;
208
213
  maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
209
- if (!gasConfig.fixedPriorityFeePerGas) {
210
- this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
211
- finalPriorityFee: formatGwei(finalPriorityFee)
212
- });
213
- }
214
+ this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
215
+ finalPriorityFee: formatGwei(finalPriorityFee)
216
+ });
214
217
  } else {
215
218
  // First attempt: apply configured bump percentage to competitive fee
216
219
  // multiply by 100 & divide by 100 to maintain some precision
217
- if (!gasConfig.fixedPriorityFeePerGas) {
218
- priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
219
- this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
220
- networkEstimate: formatGwei(priorityFee)
221
- });
222
- }
220
+ priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
221
+ this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
222
+ networkEstimate: formatGwei(priorityFee)
223
+ });
223
224
  maxFeePerGas += priorityFee;
224
225
  }
225
226
  // maxGwei and maxBlobGwei are hard limits
package/dest/types.d.ts CHANGED
@@ -1,6 +1,61 @@
1
- import type { Abi, Account, Chain, Client, FallbackTransport, GetContractReturnType, HttpTransport, PublicActions, PublicClient, PublicRpcSchema, WalletActions, WalletRpcSchema } from 'viem';
1
+ import type { Abi, Account, Chain, Client, FallbackTransport, GetContractReturnType, Hex, HttpTransport, PublicActions, PublicClient, PublicRpcSchema, WalletActions, WalletRpcSchema } from 'viem';
2
2
  /** Type for a viem public client */
3
3
  export type ViemPublicClient = PublicClient<FallbackTransport<HttpTransport[]>, Chain>;
4
+ export type PublicRpcDebugSchema = [
5
+ {
6
+ Method: 'debug_traceTransaction';
7
+ Parameters: [txHash: `0x${string}`, options: {
8
+ tracer: 'callTracer';
9
+ }];
10
+ ReturnType: DebugCallTrace;
11
+ },
12
+ {
13
+ Method: 'trace_transaction';
14
+ Parameters: [txHash: `0x${string}`];
15
+ ReturnType: TraceTransactionResponse[];
16
+ }
17
+ ];
18
+ /** Return type for a debug_traceTransaction call */
19
+ export type DebugCallTrace = {
20
+ from: Hex;
21
+ to?: Hex;
22
+ type: string;
23
+ input?: Hex;
24
+ output?: Hex;
25
+ gas?: Hex;
26
+ gasUsed?: Hex;
27
+ value?: Hex;
28
+ error?: string;
29
+ calls?: DebugCallTrace[];
30
+ };
31
+ /** Action object for a trace_transaction call */
32
+ export type TraceAction = {
33
+ from: Hex;
34
+ to?: Hex;
35
+ callType: string;
36
+ gas?: Hex;
37
+ input?: Hex;
38
+ value?: Hex;
39
+ };
40
+ /** Result object for a trace_transaction call */
41
+ export type TraceResult = {
42
+ gasUsed?: Hex;
43
+ output?: Hex;
44
+ };
45
+ /** Return type for a single trace in trace_transaction response */
46
+ export type TraceTransactionResponse = {
47
+ action: TraceAction;
48
+ result?: TraceResult;
49
+ error?: string;
50
+ subtraces: number;
51
+ traceAddress: number[];
52
+ type: string;
53
+ };
54
+ /** Type for a viem public client with support for debug methods */
55
+ export type ViemPublicDebugClient = PublicClient<FallbackTransport<HttpTransport[]>, Chain, undefined, [
56
+ ...PublicRpcSchema,
57
+ ...PublicRpcDebugSchema
58
+ ]>;
4
59
  export type ExtendedViemWalletClient = Client<FallbackTransport<readonly HttpTransport[]>, Chain, Account, [
5
60
  ...PublicRpcSchema,
6
61
  ...WalletRpcSchema
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,OAAO,EACP,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,aAAa,EACb,eAAe,EAChB,MAAM,MAAM,CAAC;AAEd,oCAAoC;AACpC,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,iBAAiB,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;AAEvF,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAC3C,iBAAiB,CAAC,SAAS,aAAa,EAAE,CAAC,EAC3C,KAAK,EACL,OAAO,EACP;IAAC,GAAG,eAAe;IAAE,GAAG,eAAe;CAAC,EACxC,aAAa,CAAC,iBAAiB,CAAC,SAAS,aAAa,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAClG,CAAC;AAEF,4FAA4F;AAC5F,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,wBAAwB,CAAC;AAErE,6EAA6E;AAC7E,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,GAAG,IAAI,qBAAqB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;AAEnG,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,IAAI,wBAAwB,CAEvF"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "2.1.8",
3
+ "version": "2.1.9-rc.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -8,7 +8,7 @@
8
8
  "./contracts": "./dest/contracts/index.js",
9
9
  "./deploy-l1-contracts": "./dest/deploy_l1_contracts.js",
10
10
  "./l1-contract-addresses": "./dest/l1_contract_addresses.js",
11
- "./l1-tx-utils-with-blobs": "./dest/l1_tx_utils/l1_tx_utils_with_blobs.js",
11
+ "./l1-tx-utils-with-blobs": "./dest/l1_tx_utils/index-blobs.js",
12
12
  "./utils": "./dest/utils.js"
13
13
  },
14
14
  "typedocOptions": {
@@ -31,10 +31,10 @@
31
31
  "../package.common.json"
32
32
  ],
33
33
  "dependencies": {
34
- "@aztec/blob-lib": "2.1.8",
35
- "@aztec/constants": "2.1.8",
36
- "@aztec/foundation": "2.1.8",
37
- "@aztec/l1-artifacts": "2.1.8",
34
+ "@aztec/blob-lib": "2.1.9-rc.2",
35
+ "@aztec/constants": "2.1.9-rc.2",
36
+ "@aztec/foundation": "2.1.9-rc.2",
37
+ "@aztec/l1-artifacts": "2.1.9-rc.2",
38
38
  "@viem/anvil": "^0.0.10",
39
39
  "dotenv": "^16.0.3",
40
40
  "lodash.chunk": "^4.2.0",
@@ -0,0 +1,108 @@
1
+ /* eslint-disable no-console */
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import type { Logger } from '@aztec/foundation/log';
4
+ import { createLogger } from '@aztec/foundation/log';
5
+ import { DateProvider } from '@aztec/foundation/timer';
6
+
7
+ import { type Hex, extractChain } from 'viem';
8
+ import { anvil, mainnet, sepolia } from 'viem/chains';
9
+
10
+ import { L1Deployer } from './deploy_l1_contracts.js';
11
+ import type { ExtendedViemWalletClient } from './types.js';
12
+
13
+ export const FORWARDER_SOLIDITY_SOURCE = `
14
+ contract ForwarderProxy {
15
+ function forward(address target, bytes calldata data) external payable returns (bytes memory) {
16
+ (bool success, bytes memory result) = target.call{value: msg.value}(data);
17
+ require(success, "call failed");
18
+ return result;
19
+ }
20
+ }`;
21
+
22
+ export const FORWARDER_ABI = [
23
+ {
24
+ inputs: [
25
+ {
26
+ internalType: 'address',
27
+ name: 'target',
28
+ type: 'address',
29
+ },
30
+ {
31
+ internalType: 'bytes',
32
+ name: 'data',
33
+ type: 'bytes',
34
+ },
35
+ ],
36
+ name: 'forward',
37
+ outputs: [
38
+ {
39
+ internalType: 'bytes',
40
+ name: '',
41
+ type: 'bytes',
42
+ },
43
+ ],
44
+ stateMutability: 'payable',
45
+ type: 'function',
46
+ },
47
+ ] as const;
48
+
49
+ export const FORWARDER_BYTECODE =
50
+ '0x6080604052348015600e575f5ffd5b506103bf8061001c5f395ff3fe60806040526004361061001d575f3560e01c80636fadcf7214610021575b5f5ffd5b61003b600480360381019061003691906101d0565b610051565b604051610048919061029d565b60405180910390f35b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1634868660405161007d9291906102f9565b5f6040518083038185875af1925050503d805f81146100b7576040519150601f19603f3d011682016040523d82523d5f602084013e6100bc565b606091505b509150915081610101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100f89061036b565b60405180910390fd5b80925050509392505050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61013e82610115565b9050919050565b61014e81610134565b8114610158575f5ffd5b50565b5f8135905061016981610145565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126101905761018f61016f565b5b8235905067ffffffffffffffff8111156101ad576101ac610173565b5b6020830191508360018202830111156101c9576101c8610177565b5b9250929050565b5f5f5f604084860312156101e7576101e661010d565b5b5f6101f48682870161015b565b935050602084013567ffffffffffffffff81111561021557610214610111565b5b6102218682870161017b565b92509250509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61026f8261022d565b6102798185610237565b9350610289818560208601610247565b61029281610255565b840191505092915050565b5f6020820190508181035f8301526102b58184610265565b905092915050565b5f81905092915050565b828183375f83830152505050565b5f6102e083856102bd565b93506102ed8385846102c7565b82840190509392505050565b5f6103058284866102d5565b91508190509392505050565b5f82825260208201905092915050565b7f63616c6c206661696c65640000000000000000000000000000000000000000005f82015250565b5f610355600b83610311565b915061036082610321565b602082019050919050565b5f6020820190508181035f83015261038281610349565b905091905056fea26469706673582212209a1c8cf638cf1569450a731ef9457b862f9e153b0a46e5555429bcf4dffd999564736f6c634300081e0033' as Hex;
51
+
52
+ const FORWARDER_ARTIFACT = {
53
+ name: 'Forwarder',
54
+ contractAbi: FORWARDER_ABI,
55
+ contractBytecode: FORWARDER_BYTECODE,
56
+ };
57
+
58
+ /**
59
+ * Deploys the forwarder proxy contract to L1.
60
+ * @param client - The L1 client to use for deployment
61
+ * @param logger - Optional logger
62
+ * @returns The deployed forwarder contract address
63
+ */
64
+ export async function deployForwarderProxy(client: ExtendedViemWalletClient, logger?: Logger): Promise<EthAddress> {
65
+ const log = logger ?? createLogger('ethereum:forwarder');
66
+ const nonce = await client.getTransactionCount({ address: client.account.address });
67
+ const deployer = new L1Deployer(client, nonce, new DateProvider(), false, log, undefined, false);
68
+
69
+ log.info('Deploying forwarder proxy contract');
70
+ const deployment = await deployer.deploy(FORWARDER_ARTIFACT, []);
71
+ log.info(`Forwarder proxy deployed at ${deployment.address.toString()}`);
72
+
73
+ return deployment.address;
74
+ }
75
+
76
+ /**
77
+ * Main function for deploying the forwarder proxy from command line.
78
+ * Usage: node forwarder_proxy.js <private_key> <rpc_url>
79
+ */
80
+ async function main() {
81
+ const args = process.argv.slice(2);
82
+ if (args.length < 3) {
83
+ console.error('Usage: node forwarder_proxy.js <private_key> <rpc_url> <chain_id>');
84
+ process.exit(1);
85
+ }
86
+
87
+ const [privateKey, rpcUrl, chainId] = args;
88
+
89
+ // Dynamic import to avoid pulling in dependencies at module load time
90
+ const { createExtendedL1Client } = await import('./client.js');
91
+
92
+ const client = createExtendedL1Client(
93
+ [rpcUrl],
94
+ privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`,
95
+ extractChain({ chains: [mainnet, sepolia, anvil], id: parseInt(chainId) as any }),
96
+ );
97
+ const address = await deployForwarderProxy(client);
98
+
99
+ console.log(`Forwarder proxy deployed at: ${address.toString()}`);
100
+ }
101
+
102
+ // Only run main if this is the entry point
103
+ if (import.meta.url === `file://${process.argv[1]}`) {
104
+ main().catch(err => {
105
+ console.error('Failed to deploy forwarder proxy:', err);
106
+ process.exit(1);
107
+ });
108
+ }
package/src/index.ts CHANGED
@@ -15,3 +15,4 @@ export * from './l1_types.js';
15
15
  export * from './l1_artifacts.js';
16
16
  export * from './publisher_manager.js';
17
17
  export * from './eth-signer/index.js';
18
+ export * from './forwarder_proxy.js';
package/src/l1_reader.ts CHANGED
@@ -6,6 +6,8 @@ import { type L1ContractAddresses, l1ContractAddressesMapping } from './l1_contr
6
6
  export interface L1ReaderConfig {
7
7
  /** The RPC Url of the ethereum host. */
8
8
  l1RpcUrls: string[];
9
+ /** The RPC Url of the ethereum debug host for trace and debug methods. */
10
+ l1DebugRpcUrls: string[];
9
11
  /** The chain ID of the ethereum host. */
10
12
  l1ChainId: number;
11
13
  /** The deployed l1 contract addresses */
@@ -30,6 +32,12 @@ export const l1ReaderConfigMappings: ConfigMappingsType<L1ReaderConfig> = {
30
32
  parseEnv: (val: string) => val.split(',').map(url => url.trim()),
31
33
  defaultValue: [],
32
34
  },
35
+ l1DebugRpcUrls: {
36
+ env: 'ETHEREUM_DEBUG_HOSTS',
37
+ description: 'The RPC Url of the ethereum debug host for trace and debug methods.',
38
+ parseEnv: (val: string) => val.split(',').map(url => url.trim()),
39
+ defaultValue: [],
40
+ },
33
41
  viemPollingIntervalMS: {
34
42
  env: 'L1_READER_VIEM_POLLING_INTERVAL_MS',
35
43
  description: 'The polling interval viem uses in ms',
@@ -29,9 +29,9 @@ export interface L1TxUtilsConfig {
29
29
  */
30
30
  priorityFeeRetryBumpPercentage?: number;
31
31
  /**
32
- * Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage config
32
+ * Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee.
33
33
  */
34
- fixedPriorityFeePerGas?: number;
34
+ minimumPriorityFeePerGas?: number;
35
35
  /**
36
36
  * Maximum number of speed-up attempts
37
37
  */
@@ -90,10 +90,21 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
90
90
  env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
91
91
  ...numberConfigHelper(50),
92
92
  },
93
- fixedPriorityFeePerGas: {
94
- description: 'Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage',
95
- env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
96
- fallback: ['L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'],
93
+ minimumPriorityFeePerGas: {
94
+ description:
95
+ 'Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee. If network conditions require a higher fee, the higher fee will be used.',
96
+ env: 'L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI',
97
+ fallback: ['L1_FIXED_PRIORITY_FEE_PER_GAS', 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'],
98
+ deprecatedFallback: [
99
+ {
100
+ env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
101
+ message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS'),
102
+ },
103
+ {
104
+ env: 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI',
105
+ message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'),
106
+ },
107
+ ],
97
108
  ...floatConfigHelper(0),
98
109
  },
99
110
  maxSpeedUpAttempts: {
@@ -141,3 +152,10 @@ export const defaultL1TxUtilsConfig = getDefaultConfig<L1TxUtilsConfig>(
141
152
  export function getL1TxUtilsConfigEnvVars(): L1TxUtilsConfig {
142
153
  return getConfigFromMappings(l1TxUtilsConfigMappings);
143
154
  }
155
+
156
+ function deprecatedFixedFeeMessage(envVar: string): string {
157
+ return (
158
+ `Environment variable ${envVar} is deprecated. It is now used as a MINIMUM priority fee rather than a fixed value. ` +
159
+ 'Please use L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI instead. If network conditions require a higher fee, the higher fee will be used.'
160
+ );
161
+ }
@@ -0,0 +1,119 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import type { Logger } from '@aztec/foundation/log';
3
+ import type { DateProvider } from '@aztec/foundation/timer';
4
+
5
+ import { type Hex, encodeFunctionData } from 'viem';
6
+
7
+ import type { EthSigner } from '../eth-signer/eth-signer.js';
8
+ import { FORWARDER_ABI } from '../forwarder_proxy.js';
9
+ import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
10
+ import type { L1TxUtilsConfig } from './config.js';
11
+ import type { IL1TxMetrics, IL1TxStore } from './interfaces.js';
12
+ import { L1TxUtilsWithBlobs } from './l1_tx_utils_with_blobs.js';
13
+ import { createViemSigner } from './signer.js';
14
+ import type { L1BlobInputs, L1TxConfig, L1TxRequest, SigningCallback } from './types.js';
15
+
16
+ /**
17
+ * Extends L1TxUtilsWithBlobs to wrap all transactions through a forwarder contract.
18
+ * This is mainly used for testing the archiver's ability to decode transactions that go through proxies.
19
+ */
20
+ export class ForwarderL1TxUtils extends L1TxUtilsWithBlobs {
21
+ constructor(
22
+ client: ViemClient | ExtendedViemWalletClient,
23
+ senderAddress: EthAddress,
24
+ signingCallback: SigningCallback,
25
+ logger: Logger | undefined,
26
+ dateProvider: DateProvider | undefined,
27
+ config: Partial<L1TxUtilsConfig>,
28
+ debugMaxGasLimit: boolean,
29
+ store: IL1TxStore | undefined,
30
+ metrics: IL1TxMetrics | undefined,
31
+ private readonly forwarderAddress: EthAddress,
32
+ ) {
33
+ super(client, senderAddress, signingCallback, logger, dateProvider, config, debugMaxGasLimit, store, metrics);
34
+ }
35
+
36
+ /**
37
+ * Wraps the transaction request in a call to the forwarder contract.
38
+ */
39
+ private wrapInForwarder(request: L1TxRequest): L1TxRequest {
40
+ const forwarderCalldata = encodeFunctionData({
41
+ abi: FORWARDER_ABI,
42
+ functionName: 'forward',
43
+ args: [request.to as Hex, request.data as Hex],
44
+ });
45
+
46
+ return {
47
+ to: this.forwarderAddress.toString() as Hex,
48
+ data: forwarderCalldata,
49
+ value: request.value,
50
+ abi: request.abi, // Preserve the original ABI for error decoding
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Override sendAndMonitorTransaction to wrap the request in a forwarder call.
56
+ */
57
+ public override sendAndMonitorTransaction(request: L1TxRequest, gasConfig?: L1TxConfig, blobInputs?: L1BlobInputs) {
58
+ this.logger.debug(`Wrapping transaction to ${request.to} in forwarder at ${this.forwarderAddress.toString()}`);
59
+ const wrappedRequest = this.wrapInForwarder(request);
60
+ return super.sendAndMonitorTransaction(wrappedRequest, gasConfig, blobInputs);
61
+ }
62
+ }
63
+
64
+ export function createForwarderL1TxUtilsFromViemWallet(
65
+ client: ExtendedViemWalletClient,
66
+ forwarderAddress: EthAddress,
67
+ deps: {
68
+ logger?: Logger;
69
+ dateProvider?: DateProvider;
70
+ store?: IL1TxStore;
71
+ metrics?: IL1TxMetrics;
72
+ } = {},
73
+ config: Partial<L1TxUtilsConfig> = {},
74
+ debugMaxGasLimit: boolean = false,
75
+ ) {
76
+ return new ForwarderL1TxUtils(
77
+ client,
78
+ EthAddress.fromString(client.account.address),
79
+ createViemSigner(client),
80
+ deps.logger,
81
+ deps.dateProvider,
82
+ config,
83
+ debugMaxGasLimit,
84
+ deps.store,
85
+ deps.metrics,
86
+ forwarderAddress,
87
+ );
88
+ }
89
+
90
+ export function createForwarderL1TxUtilsFromEthSigner(
91
+ client: ViemClient,
92
+ signer: EthSigner,
93
+ forwarderAddress: EthAddress,
94
+ deps: {
95
+ logger?: Logger;
96
+ dateProvider?: DateProvider;
97
+ store?: IL1TxStore;
98
+ metrics?: IL1TxMetrics;
99
+ } = {},
100
+ config: Partial<L1TxUtilsConfig> = {},
101
+ debugMaxGasLimit: boolean = false,
102
+ ) {
103
+ const callback: SigningCallback = async (transaction, _signingAddress) => {
104
+ return (await signer.signTransaction(transaction)).toViemTransactionSignature();
105
+ };
106
+
107
+ return new ForwarderL1TxUtils(
108
+ client,
109
+ signer.address,
110
+ callback,
111
+ deps.logger,
112
+ deps.dateProvider,
113
+ config,
114
+ debugMaxGasLimit,
115
+ deps.store,
116
+ deps.metrics,
117
+ forwarderAddress,
118
+ );
119
+ }
@@ -0,0 +1,2 @@
1
+ export * from './forwarder_l1_tx_utils.js';
2
+ export * from './l1_tx_utils_with_blobs.js';
@@ -46,7 +46,7 @@ export interface IL1TxStore {
46
46
  * @param account - The sender account address
47
47
  * @param stateId - The state ID to delete
48
48
  */
49
- deleteState(account: string, stateId: number): Promise<void>;
49
+ deleteState(account: string, ...stateId: number[]): Promise<void>;
50
50
 
51
51
  /**
52
52
  * Clears all transaction states for a specific account.
@@ -130,12 +130,32 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
130
130
  return;
131
131
  }
132
132
 
133
- // Convert loaded states (which have id) to the txs format
134
- this.txs = loadedStates;
135
- this.logger.info(`Rehydrated ${loadedStates.length} tx states for account ${account}`);
133
+ // Clean up excess states if we have more than MAX_L1_TX_STATES
134
+ if (loadedStates.length > MAX_L1_TX_STATES) {
135
+ this.logger.warn(
136
+ `Found ${loadedStates.length} tx states for account ${account}, pruning to most recent ${MAX_L1_TX_STATES}`,
137
+ );
138
+
139
+ // Keep only the most recent MAX_L1_TX_STATES
140
+ const statesToKeep = loadedStates.slice(-MAX_L1_TX_STATES);
141
+ const statesToDelete = loadedStates.slice(0, -MAX_L1_TX_STATES);
142
+
143
+ // Batch delete old states in a transaction for efficiency
144
+ const idsToDelete = statesToDelete.map(s => s.id);
145
+ await this.store.deleteState(account, ...idsToDelete);
146
+
147
+ this.txs = statesToKeep;
148
+ this.logger.info(
149
+ `Cleaned up ${statesToDelete.length} old tx states, kept ${statesToKeep.length} for account ${account}`,
150
+ );
151
+ } else {
152
+ // Convert loaded states (which have id) to the txs format
153
+ this.txs = loadedStates;
154
+ this.logger.info(`Rehydrated ${loadedStates.length} tx states for account ${account}`);
155
+ }
136
156
 
137
157
  // Find all pending states and resume monitoring
138
- const pendingStates = loadedStates.filter(state => !TerminalTxUtilsState.includes(state.status));
158
+ const pendingStates = this.txs.filter(state => !TerminalTxUtilsState.includes(state.status));
139
159
  if (pendingStates.length === 0) {
140
160
  return;
141
161
  }
@@ -199,21 +199,18 @@ export class ReadOnlyL1TxUtils {
199
199
  () => this.client.getBlock({ blockTag: 'latest' }),
200
200
  'Getting latest block',
201
201
  );
202
- const networkEstimatePromise = gasConfig.fixedPriorityFeePerGas
203
- ? null
204
- : this.tryTwice(() => this.client.estimateMaxPriorityFeePerGas(), 'Estimating max priority fee per gas');
205
- const pendingBlockPromise = gasConfig.fixedPriorityFeePerGas
206
- ? null
207
- : this.tryTwice(
208
- () => this.client.getBlock({ blockTag: 'pending', includeTransactions: true }),
209
- 'Getting pending block',
210
- );
211
- const feeHistoryPromise = gasConfig.fixedPriorityFeePerGas
212
- ? null
213
- : this.tryTwice(
214
- () => this.client.getFeeHistory({ blockCount: HISTORICAL_BLOCK_COUNT, rewardPercentiles: [75] }),
215
- 'Getting fee history',
216
- );
202
+ const networkEstimatePromise = this.tryTwice(
203
+ () => this.client.estimateMaxPriorityFeePerGas(),
204
+ 'Estimating max priority fee per gas',
205
+ );
206
+ const pendingBlockPromise = this.tryTwice(
207
+ () => this.client.getBlock({ blockTag: 'pending', includeTransactions: true }),
208
+ 'Getting pending block',
209
+ );
210
+ const feeHistoryPromise = this.tryTwice(
211
+ () => this.client.getFeeHistory({ blockCount: HISTORICAL_BLOCK_COUNT, rewardPercentiles: [75] }),
212
+ 'Getting fee history',
213
+ );
217
214
  const blobBaseFeePromise = isBlobTx
218
215
  ? this.tryTwice(() => this.client.getBlobBaseFee(), 'Getting blob base fee')
219
216
  : null;
@@ -221,9 +218,9 @@ export class ReadOnlyL1TxUtils {
221
218
  const [latestBlockResult, networkEstimateResult, pendingBlockResult, feeHistoryResult, blobBaseFeeResult] =
222
219
  await Promise.allSettled([
223
220
  latestBlockPromise,
224
- networkEstimatePromise ?? Promise.resolve(0n),
225
- pendingBlockPromise ?? Promise.resolve(null),
226
- feeHistoryPromise ?? Promise.resolve(null),
221
+ networkEstimatePromise,
222
+ pendingBlockPromise,
223
+ feeHistoryPromise,
227
224
  blobBaseFeePromise ?? Promise.resolve(0n),
228
225
  ]);
229
226
 
@@ -243,15 +240,24 @@ export class ReadOnlyL1TxUtils {
243
240
  this.logger?.warn('Failed to get L1 blob base fee', attempt);
244
241
  }
245
242
 
246
- let priorityFee: bigint;
247
- if (gasConfig.fixedPriorityFeePerGas) {
248
- this.logger?.debug('Using fixed priority fee per L1 gas', {
249
- fixedPriorityFeePerGas: gasConfig.fixedPriorityFeePerGas,
250
- });
251
- priorityFee = BigInt(Math.trunc(gasConfig.fixedPriorityFeePerGas * Number(WEI_CONST)));
252
- } else {
253
- // Get competitive priority fee (includes network estimate + analysis)
254
- priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
243
+ // Get competitive priority fee
244
+ let priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
245
+
246
+ // Apply minimum priority fee as a floor if configured
247
+ if (gasConfig.minimumPriorityFeePerGas) {
248
+ const minimumFee = BigInt(Math.trunc(gasConfig.minimumPriorityFeePerGas * Number(WEI_CONST)));
249
+ if (minimumFee > priorityFee) {
250
+ this.logger?.debug('Using minimum priority fee as floor', {
251
+ minimumPriorityFeePerGas: formatGwei(minimumFee),
252
+ competitiveFee: formatGwei(priorityFee),
253
+ });
254
+ priorityFee = minimumFee;
255
+ } else {
256
+ this.logger?.debug('Competitive fee exceeds minimum, using competitive fee', {
257
+ minimumPriorityFeePerGas: formatGwei(minimumFee),
258
+ competitiveFee: formatGwei(priorityFee),
259
+ });
260
+ }
255
261
  }
256
262
  let maxFeePerGas = baseFee;
257
263
 
@@ -280,18 +286,15 @@ export class ReadOnlyL1TxUtils {
280
286
  (previousGasPrice!.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00))) / 100_00n;
281
287
  const minMaxFee = (previousGasPrice!.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00))) / 100_00n;
282
288
 
283
- let competitivePriorityFee = priorityFee;
284
- if (!gasConfig.fixedPriorityFeePerGas) {
285
- // Apply bump percentage to competitive fee
286
- competitivePriorityFee = (priorityFee * (100_00n + BigInt(configBump * 1_00))) / 100_00n;
289
+ // Apply bump percentage to competitive fee
290
+ const competitivePriorityFee = (priorityFee * (100_00n + BigInt(configBump * 1_00))) / 100_00n;
287
291
 
288
- this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
289
- networkEstimate: formatGwei(priorityFee),
290
- competitiveFee: formatGwei(competitivePriorityFee),
291
- minRequired: formatGwei(minPriorityFee),
292
- bumpPercentage: configBump,
293
- });
294
- }
292
+ this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
293
+ networkEstimate: formatGwei(priorityFee),
294
+ competitiveFee: formatGwei(competitivePriorityFee),
295
+ minRequired: formatGwei(minPriorityFee),
296
+ bumpPercentage: configBump,
297
+ });
295
298
 
296
299
  // Use maximum between competitive fee and minimum required bump
297
300
  const finalPriorityFee = competitivePriorityFee > minPriorityFee ? competitivePriorityFee : minPriorityFee;
@@ -302,20 +305,16 @@ export class ReadOnlyL1TxUtils {
302
305
  maxFeePerGas += finalPriorityFee;
303
306
  maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
304
307
 
305
- if (!gasConfig.fixedPriorityFeePerGas) {
306
- this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
307
- finalPriorityFee: formatGwei(finalPriorityFee),
308
- });
309
- }
308
+ this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
309
+ finalPriorityFee: formatGwei(finalPriorityFee),
310
+ });
310
311
  } else {
311
312
  // First attempt: apply configured bump percentage to competitive fee
312
313
  // multiply by 100 & divide by 100 to maintain some precision
313
- if (!gasConfig.fixedPriorityFeePerGas) {
314
- priorityFee = (priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00))) / 100_00n;
315
- this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
316
- networkEstimate: formatGwei(priorityFee),
317
- });
318
- }
314
+ priorityFee = (priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00))) / 100_00n;
315
+ this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
316
+ networkEstimate: formatGwei(priorityFee),
317
+ });
319
318
  maxFeePerGas += priorityFee;
320
319
  }
321
320
 
package/src/types.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  Client,
6
6
  FallbackTransport,
7
7
  GetContractReturnType,
8
+ Hex,
8
9
  HttpTransport,
9
10
  PublicActions,
10
11
  PublicClient,
@@ -16,6 +17,67 @@ import type {
16
17
  /** Type for a viem public client */
17
18
  export type ViemPublicClient = PublicClient<FallbackTransport<HttpTransport[]>, Chain>;
18
19
 
20
+ export type PublicRpcDebugSchema = [
21
+ {
22
+ Method: 'debug_traceTransaction';
23
+ Parameters: [txHash: `0x${string}`, options: { tracer: 'callTracer' }];
24
+ ReturnType: DebugCallTrace;
25
+ },
26
+ {
27
+ Method: 'trace_transaction';
28
+ Parameters: [txHash: `0x${string}`];
29
+ ReturnType: TraceTransactionResponse[];
30
+ },
31
+ ];
32
+
33
+ /** Return type for a debug_traceTransaction call */
34
+ export type DebugCallTrace = {
35
+ from: Hex;
36
+ to?: Hex;
37
+ type: string;
38
+ input?: Hex;
39
+ output?: Hex;
40
+ gas?: Hex;
41
+ gasUsed?: Hex;
42
+ value?: Hex;
43
+ error?: string;
44
+ calls?: DebugCallTrace[];
45
+ };
46
+
47
+ /** Action object for a trace_transaction call */
48
+ export type TraceAction = {
49
+ from: Hex;
50
+ to?: Hex;
51
+ callType: string;
52
+ gas?: Hex;
53
+ input?: Hex;
54
+ value?: Hex;
55
+ };
56
+
57
+ /** Result object for a trace_transaction call */
58
+ export type TraceResult = {
59
+ gasUsed?: Hex;
60
+ output?: Hex;
61
+ };
62
+
63
+ /** Return type for a single trace in trace_transaction response */
64
+ export type TraceTransactionResponse = {
65
+ action: TraceAction;
66
+ result?: TraceResult;
67
+ error?: string;
68
+ subtraces: number;
69
+ traceAddress: number[];
70
+ type: string;
71
+ };
72
+
73
+ /** Type for a viem public client with support for debug methods */
74
+ export type ViemPublicDebugClient = PublicClient<
75
+ FallbackTransport<HttpTransport[]>,
76
+ Chain,
77
+ undefined,
78
+ [...PublicRpcSchema, ...PublicRpcDebugSchema]
79
+ >;
80
+
19
81
  export type ExtendedViemWalletClient = Client<
20
82
  FallbackTransport<readonly HttpTransport[]>,
21
83
  Chain,