@aztec/ethereum 3.0.0-nightly.20250925 → 3.0.0-nightly.20250927
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.
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +1 -1
- package/dest/contracts/empire_base.d.ts +1 -1
- package/dest/contracts/empire_base.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/fee_asset_handler.d.ts +3 -3
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/governance.js +1 -1
- package/dest/contracts/governance_proposer.d.ts +1 -1
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/multicall.d.ts +4 -4
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/rollup.d.ts +3 -3
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.d.ts +1 -1
- package/dest/deploy_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.js +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/l1_artifacts.d.ts +978 -2218
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_tx_utils/config.d.ts +56 -0
- package/dest/l1_tx_utils/config.d.ts.map +1 -0
- package/dest/l1_tx_utils/config.js +67 -0
- package/dest/l1_tx_utils/constants.d.ts +6 -0
- package/dest/l1_tx_utils/constants.d.ts.map +1 -0
- package/dest/l1_tx_utils/constants.js +14 -0
- package/dest/l1_tx_utils/factory.d.ts +9 -0
- package/dest/l1_tx_utils/factory.d.ts.map +1 -0
- package/dest/l1_tx_utils/factory.js +14 -0
- package/dest/l1_tx_utils/index.d.ts +9 -0
- package/dest/l1_tx_utils/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/index.js +9 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +80 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
- package/dest/{l1_tx_utils.js → l1_tx_utils/l1_tx_utils.js} +14 -433
- package/dest/{l1_tx_utils_with_blobs.d.ts → l1_tx_utils/l1_tx_utils_with_blobs.d.ts} +6 -4
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
- package/dest/{l1_tx_utils_with_blobs.js → l1_tx_utils/l1_tx_utils_with_blobs.js} +2 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +81 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +304 -0
- package/dest/l1_tx_utils/signer.d.ts +4 -0
- package/dest/l1_tx_utils/signer.d.ts.map +1 -0
- package/dest/l1_tx_utils/signer.js +16 -0
- package/dest/l1_tx_utils/types.d.ts +44 -0
- package/dest/l1_tx_utils/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/types.js +9 -0
- package/dest/l1_tx_utils/utils.d.ts +4 -0
- package/dest/l1_tx_utils/utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/utils.js +14 -0
- package/dest/publisher_manager.d.ts +1 -1
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +1 -1
- package/dest/test/delayed_tx_utils.d.ts +2 -2
- package/dest/test/delayed_tx_utils.d.ts.map +1 -1
- package/dest/test/delayed_tx_utils.js +2 -2
- package/dest/test/upgrade_utils.js +1 -1
- package/package.json +6 -6
- package/src/config.ts +1 -1
- package/src/contracts/empire_base.ts +1 -1
- package/src/contracts/empire_slashing_proposer.ts +1 -1
- package/src/contracts/fee_asset_handler.ts +1 -1
- package/src/contracts/governance.ts +1 -1
- package/src/contracts/governance_proposer.ts +1 -1
- package/src/contracts/multicall.ts +1 -1
- package/src/contracts/rollup.ts +1 -1
- package/src/deploy_l1_contracts.ts +1 -1
- package/src/index.ts +1 -1
- package/src/l1_tx_utils/config.ts +129 -0
- package/src/l1_tx_utils/constants.ts +18 -0
- package/src/l1_tx_utils/factory.ts +44 -0
- package/src/l1_tx_utils/index.ts +11 -0
- package/src/l1_tx_utils/l1_tx_utils.ts +527 -0
- package/src/{l1_tx_utils_with_blobs.ts → l1_tx_utils/l1_tx_utils_with_blobs.ts} +7 -10
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +368 -0
- package/src/l1_tx_utils/signer.ts +28 -0
- package/src/l1_tx_utils/types.ts +52 -0
- package/src/l1_tx_utils/utils.ts +16 -0
- package/src/publisher_manager.ts +1 -1
- package/src/test/delayed_tx_utils.ts +2 -2
- package/src/test/upgrade_utils.ts +1 -1
- package/dest/l1_tx_utils.d.ts +0 -252
- package/dest/l1_tx_utils.d.ts.map +0 -1
- package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
- package/src/l1_tx_utils.ts +0 -1125
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
|
+
import { type Abi, type BlockOverrides, type Hex, type PrepareTransactionRequestRequest, type StateOverride, type TransactionReceipt } from 'viem';
|
|
5
|
+
import type { ViemClient } from '../types.js';
|
|
6
|
+
import { type L1TxUtilsConfig } from './config.js';
|
|
7
|
+
import { ReadOnlyL1TxUtils } from './readonly_l1_tx_utils.js';
|
|
8
|
+
import { type GasPrice, type L1BlobInputs, type L1GasConfig, type L1TxRequest, type SigningCallback, TxUtilsState } from './types.js';
|
|
9
|
+
export declare class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
10
|
+
client: ViemClient;
|
|
11
|
+
address: EthAddress;
|
|
12
|
+
protected signer: SigningCallback;
|
|
13
|
+
protected logger: Logger;
|
|
14
|
+
private txUtilsState;
|
|
15
|
+
private lastMinedBlockNumber;
|
|
16
|
+
private nonceManager;
|
|
17
|
+
constructor(client: ViemClient, address: EthAddress, signer: SigningCallback, logger?: Logger, dateProvider?: DateProvider, config?: Partial<L1TxUtilsConfig>, debugMaxGasLimit?: boolean);
|
|
18
|
+
get state(): TxUtilsState;
|
|
19
|
+
get lastMinedAtBlockNumber(): bigint | undefined;
|
|
20
|
+
private set lastMinedAtBlockNumber(value);
|
|
21
|
+
private set state(value);
|
|
22
|
+
getSenderAddress(): EthAddress;
|
|
23
|
+
getSenderBalance(): Promise<bigint>;
|
|
24
|
+
private signTransaction;
|
|
25
|
+
protected prepareSignedTransaction(txData: PrepareTransactionRequestRequest): Promise<`0x${string}`>;
|
|
26
|
+
/**
|
|
27
|
+
* Sends a transaction with gas estimation and pricing
|
|
28
|
+
* @param request - The transaction request (to, data, value)
|
|
29
|
+
* @param gasConfig - Optional gas configuration
|
|
30
|
+
* @returns The transaction hash and parameters used
|
|
31
|
+
*/
|
|
32
|
+
sendTransaction(request: L1TxRequest, _gasConfig?: L1GasConfig, blobInputs?: L1BlobInputs, stateChange?: TxUtilsState): Promise<{
|
|
33
|
+
txHash: Hex;
|
|
34
|
+
gasLimit: bigint;
|
|
35
|
+
gasPrice: GasPrice;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Monitors a transaction until completion, handling speed-ups if needed
|
|
39
|
+
* @param request - Original transaction request (needed for speed-ups)
|
|
40
|
+
* @param initialTxHash - Hash of the initial transaction
|
|
41
|
+
* @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
|
|
42
|
+
* @param params - Parameters used in the initial transaction
|
|
43
|
+
* @param gasConfig - Optional gas configuration
|
|
44
|
+
*/
|
|
45
|
+
monitorTransaction(request: L1TxRequest, initialTxHash: Hex, allVersions: Set<Hex>, params: {
|
|
46
|
+
gasLimit: bigint;
|
|
47
|
+
}, _gasConfig?: Partial<L1TxUtilsConfig> & {
|
|
48
|
+
txTimeoutAt?: Date;
|
|
49
|
+
}, _blobInputs?: L1BlobInputs, isCancelTx?: boolean): Promise<TransactionReceipt>;
|
|
50
|
+
/**
|
|
51
|
+
* Sends a transaction and monitors it until completion
|
|
52
|
+
* @param request - The transaction request (to, data, value)
|
|
53
|
+
* @param gasConfig - Optional gas configuration
|
|
54
|
+
* @returns The receipt of the successful transaction
|
|
55
|
+
*/
|
|
56
|
+
sendAndMonitorTransaction(request: L1TxRequest, gasConfig?: L1GasConfig, blobInputs?: L1BlobInputs): Promise<{
|
|
57
|
+
receipt: TransactionReceipt;
|
|
58
|
+
gasPrice: GasPrice;
|
|
59
|
+
}>;
|
|
60
|
+
simulate(request: L1TxRequest & {
|
|
61
|
+
gas?: bigint;
|
|
62
|
+
from?: Hex;
|
|
63
|
+
}, _blockOverrides?: BlockOverrides<bigint, number>, stateOverrides?: StateOverride, abi?: Abi, _gasConfig?: L1TxUtilsConfig & {
|
|
64
|
+
fallbackGasEstimate?: bigint;
|
|
65
|
+
ignoreBlockGasLimit?: boolean;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
gasUsed: bigint;
|
|
68
|
+
result: `0x${string}`;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
|
|
72
|
+
* @param nonce - The nonce of the transaction to cancel
|
|
73
|
+
* @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
|
|
74
|
+
* @param previousGasPrice - The gas price of the previous transaction
|
|
75
|
+
* @param attempts - The number of attempts to cancel the transaction
|
|
76
|
+
* @returns The hash of the cancellation transaction
|
|
77
|
+
*/
|
|
78
|
+
protected attemptTxCancellation(currentTxHash: Hex, nonce: number, allVersions: Set<Hex>, isBlobTx?: boolean, previousGasPrice?: GasPrice, attempts?: number): Promise<`0x${string}`>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=l1_tx_utils.d.ts.map
|
|
@@ -0,0 +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,400 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { bigintConfigHelper, booleanConfigHelper, getConfigFromMappings, getDefaultConfig, numberConfigHelper } from '@aztec/foundation/config';
|
|
1
|
+
import { times } from '@aztec/foundation/collection';
|
|
3
2
|
import { TimeoutError } from '@aztec/foundation/error';
|
|
4
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
4
|
import { makeBackoff, retry } from '@aztec/foundation/retry';
|
|
7
5
|
import { sleep } from '@aztec/foundation/sleep';
|
|
8
6
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
9
7
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
10
8
|
import pickBy from 'lodash.pickby';
|
|
11
|
-
import {
|
|
9
|
+
import { createNonceManager, formatGwei, serializeTransaction } from 'viem';
|
|
12
10
|
import { jsonRpc } from 'viem/nonce';
|
|
13
|
-
import { formatViemError } from '
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// @note using this large gas limit to avoid the issue of `gas limit too low` when estimating gas in reth
|
|
19
|
-
const LARGE_GAS_LIMIT = 12_000_000n;
|
|
20
|
-
// setting a minimum bump percentage to 10% due to geth's implementation
|
|
21
|
-
// https://github.com/ethereum/go-ethereum/blob/e3d61e6db028c412f74bc4d4c7e117a9e29d0de0/core/txpool/legacypool/list.go#L298
|
|
22
|
-
const MIN_REPLACEMENT_BUMP_PERCENTAGE = 10;
|
|
23
|
-
// setting a minimum bump percentage to 100% due to geth's implementation
|
|
24
|
-
// https://github.com/ethereum/go-ethereum/blob/e3d61e6db028c412f74bc4d4c7e117a9e29d0de0/core/txpool/blobpool/config.go#L34
|
|
25
|
-
const MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE = 100;
|
|
26
|
-
// Avg ethereum block time is ~12s
|
|
27
|
-
const BLOCK_TIME_MS = 12_000;
|
|
28
|
-
export const l1TxUtilsConfigMappings = {
|
|
29
|
-
gasLimitBufferPercentage: {
|
|
30
|
-
description: 'How much to increase calculated gas limit by (percentage)',
|
|
31
|
-
env: 'L1_GAS_LIMIT_BUFFER_PERCENTAGE',
|
|
32
|
-
...numberConfigHelper(20)
|
|
33
|
-
},
|
|
34
|
-
maxGwei: {
|
|
35
|
-
description: 'Maximum gas price in gwei',
|
|
36
|
-
env: 'L1_GAS_PRICE_MAX',
|
|
37
|
-
...bigintConfigHelper(500n)
|
|
38
|
-
},
|
|
39
|
-
maxBlobGwei: {
|
|
40
|
-
description: 'Maximum blob fee per gas in gwei',
|
|
41
|
-
env: 'L1_BLOB_FEE_PER_GAS_MAX',
|
|
42
|
-
...bigintConfigHelper(1_500n)
|
|
43
|
-
},
|
|
44
|
-
priorityFeeBumpPercentage: {
|
|
45
|
-
description: 'How much to increase priority fee by each attempt (percentage)',
|
|
46
|
-
env: 'L1_PRIORITY_FEE_BUMP_PERCENTAGE',
|
|
47
|
-
...numberConfigHelper(20)
|
|
48
|
-
},
|
|
49
|
-
priorityFeeRetryBumpPercentage: {
|
|
50
|
-
description: 'How much to increase priority fee by each retry attempt (percentage)',
|
|
51
|
-
env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
|
|
52
|
-
...numberConfigHelper(50)
|
|
53
|
-
},
|
|
54
|
-
fixedPriorityFeePerGas: {
|
|
55
|
-
description: 'Fixed priority fee per gas in Gwei. Overrides any priority fee bump percentage',
|
|
56
|
-
env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
|
|
57
|
-
...numberConfigHelper(0)
|
|
58
|
-
},
|
|
59
|
-
maxAttempts: {
|
|
60
|
-
description: 'Maximum number of speed-up attempts',
|
|
61
|
-
env: 'L1_TX_MONITOR_MAX_ATTEMPTS',
|
|
62
|
-
...numberConfigHelper(3)
|
|
63
|
-
},
|
|
64
|
-
checkIntervalMs: {
|
|
65
|
-
description: 'How often to check tx status',
|
|
66
|
-
env: 'L1_TX_MONITOR_CHECK_INTERVAL_MS',
|
|
67
|
-
...numberConfigHelper(1_000)
|
|
68
|
-
},
|
|
69
|
-
stallTimeMs: {
|
|
70
|
-
description: 'How long before considering tx stalled',
|
|
71
|
-
env: 'L1_TX_MONITOR_STALL_TIME_MS',
|
|
72
|
-
...numberConfigHelper(24_000)
|
|
73
|
-
},
|
|
74
|
-
txTimeoutMs: {
|
|
75
|
-
description: 'How long to wait for a tx to be mined before giving up. Set to 0 to disable.',
|
|
76
|
-
env: 'L1_TX_MONITOR_TX_TIMEOUT_MS',
|
|
77
|
-
...numberConfigHelper(120_000)
|
|
78
|
-
},
|
|
79
|
-
txPropagationMaxQueryAttempts: {
|
|
80
|
-
description: 'How many attempts will be done to get a tx after it was sent',
|
|
81
|
-
env: 'L1_TX_PROPAGATION_MAX_QUERY_ATTEMPTS',
|
|
82
|
-
...numberConfigHelper(3)
|
|
83
|
-
},
|
|
84
|
-
cancelTxOnTimeout: {
|
|
85
|
-
description: "Whether to attempt to cancel a tx if it's not mined after txTimeoutMs",
|
|
86
|
-
env: 'L1_TX_MONITOR_CANCEL_TX_ON_TIMEOUT',
|
|
87
|
-
...booleanConfigHelper(true)
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
export const defaultL1TxUtilsConfig = getDefaultConfig(l1TxUtilsConfigMappings);
|
|
91
|
-
export function getL1TxUtilsConfigEnvVars() {
|
|
92
|
-
return getConfigFromMappings(l1TxUtilsConfigMappings);
|
|
93
|
-
}
|
|
94
|
-
export var TxUtilsState = /*#__PURE__*/ function(TxUtilsState) {
|
|
95
|
-
TxUtilsState[TxUtilsState["IDLE"] = 0] = "IDLE";
|
|
96
|
-
TxUtilsState[TxUtilsState["SENT"] = 1] = "SENT";
|
|
97
|
-
TxUtilsState[TxUtilsState["SPEED_UP"] = 2] = "SPEED_UP";
|
|
98
|
-
TxUtilsState[TxUtilsState["CANCELLED"] = 3] = "CANCELLED";
|
|
99
|
-
TxUtilsState[TxUtilsState["NOT_MINED"] = 4] = "NOT_MINED";
|
|
100
|
-
TxUtilsState[TxUtilsState["MINED"] = 5] = "MINED";
|
|
101
|
-
return TxUtilsState;
|
|
102
|
-
}({});
|
|
103
|
-
export class ReadOnlyL1TxUtils {
|
|
104
|
-
client;
|
|
105
|
-
logger;
|
|
106
|
-
dateProvider;
|
|
107
|
-
debugMaxGasLimit;
|
|
108
|
-
config;
|
|
109
|
-
interrupted;
|
|
110
|
-
constructor(client, logger = createLogger('ReadOnlyL1TxUtils'), dateProvider, config, debugMaxGasLimit = false){
|
|
111
|
-
this.client = client;
|
|
112
|
-
this.logger = logger;
|
|
113
|
-
this.dateProvider = dateProvider;
|
|
114
|
-
this.debugMaxGasLimit = debugMaxGasLimit;
|
|
115
|
-
this.interrupted = false;
|
|
116
|
-
this.config = {
|
|
117
|
-
...defaultL1TxUtilsConfig,
|
|
118
|
-
...config || {}
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
interrupt() {
|
|
122
|
-
this.interrupted = true;
|
|
123
|
-
}
|
|
124
|
-
restart() {
|
|
125
|
-
this.interrupted = false;
|
|
126
|
-
}
|
|
127
|
-
getBlock() {
|
|
128
|
-
return this.client.getBlock();
|
|
129
|
-
}
|
|
130
|
-
getBlockNumber() {
|
|
131
|
-
return this.client.getBlockNumber();
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Gets the current gas price with bounds checking
|
|
135
|
-
*/ async getGasPrice(_gasConfig, isBlobTx = false, attempt = 0, previousGasPrice) {
|
|
136
|
-
const gasConfig = {
|
|
137
|
-
...this.config,
|
|
138
|
-
..._gasConfig
|
|
139
|
-
};
|
|
140
|
-
const block = await this.client.getBlock({
|
|
141
|
-
blockTag: 'latest'
|
|
142
|
-
});
|
|
143
|
-
const baseFee = block.baseFeePerGas ?? 0n;
|
|
144
|
-
// Get blob base fee if available
|
|
145
|
-
let blobBaseFee = 0n;
|
|
146
|
-
if (isBlobTx) {
|
|
147
|
-
try {
|
|
148
|
-
blobBaseFee = await retry(()=>this.client.getBlobBaseFee(), 'Getting L1 blob base fee', makeBackoff(times(2, ()=>1)), this.logger, true);
|
|
149
|
-
this.logger?.debug('L1 Blob base fee:', {
|
|
150
|
-
blobBaseFee: formatGwei(blobBaseFee)
|
|
151
|
-
});
|
|
152
|
-
} catch {
|
|
153
|
-
this.logger?.warn('Failed to get L1 blob base fee', attempt);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
let priorityFee;
|
|
157
|
-
if (gasConfig.fixedPriorityFeePerGas) {
|
|
158
|
-
this.logger?.debug('Using fixed priority fee per L1 gas', {
|
|
159
|
-
fixedPriorityFeePerGas: gasConfig.fixedPriorityFeePerGas
|
|
160
|
-
});
|
|
161
|
-
// try to maintain precision up to 1000000 wei
|
|
162
|
-
priorityFee = BigInt(gasConfig.fixedPriorityFeePerGas * 1_000_000) * (WEI_CONST / 1_000_000n);
|
|
163
|
-
} else {
|
|
164
|
-
// Get initial priority fee from the network
|
|
165
|
-
priorityFee = await this.client.estimateMaxPriorityFeePerGas();
|
|
166
|
-
}
|
|
167
|
-
let maxFeePerGas = baseFee;
|
|
168
|
-
let maxFeePerBlobGas = blobBaseFee;
|
|
169
|
-
// Bump base fee so it's valid for next blocks if it stalls
|
|
170
|
-
const numBlocks = Math.ceil(gasConfig.stallTimeMs / BLOCK_TIME_MS);
|
|
171
|
-
for(let i = 0; i < numBlocks; i++){
|
|
172
|
-
// each block can go up 12.5% from previous baseFee
|
|
173
|
-
maxFeePerGas = maxFeePerGas * (1_000n + 125n) / 1_000n;
|
|
174
|
-
// same for blob gas fee
|
|
175
|
-
maxFeePerBlobGas = maxFeePerBlobGas * (1_000n + 125n) / 1_000n;
|
|
176
|
-
}
|
|
177
|
-
if (attempt > 0) {
|
|
178
|
-
const configBump = gasConfig.priorityFeeRetryBumpPercentage ?? defaultL1TxUtilsConfig.priorityFeeRetryBumpPercentage;
|
|
179
|
-
// if this is a blob tx, we have to use the blob bump percentage
|
|
180
|
-
const minBumpPercentage = isBlobTx ? MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE : MIN_REPLACEMENT_BUMP_PERCENTAGE;
|
|
181
|
-
const bumpPercentage = configBump > minBumpPercentage ? configBump : minBumpPercentage;
|
|
182
|
-
// Calculate minimum required fees based on previous attempt
|
|
183
|
-
// multiply by 100 & divide by 100 to maintain some precision
|
|
184
|
-
const minPriorityFee = previousGasPrice.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
|
|
185
|
-
const minMaxFee = previousGasPrice.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
|
|
186
|
-
// Add priority fee to maxFeePerGas
|
|
187
|
-
maxFeePerGas += priorityFee;
|
|
188
|
-
// Use maximum between current network values and minimum required values
|
|
189
|
-
priorityFee = priorityFee > minPriorityFee ? priorityFee : minPriorityFee;
|
|
190
|
-
maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
|
|
191
|
-
} else {
|
|
192
|
-
// first attempt, just bump priority fee, unless it's a fixed config
|
|
193
|
-
// multiply by 100 & divide by 100 to maintain some precision
|
|
194
|
-
if (!gasConfig.fixedPriorityFeePerGas) {
|
|
195
|
-
priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
|
|
196
|
-
}
|
|
197
|
-
maxFeePerGas += priorityFee;
|
|
198
|
-
}
|
|
199
|
-
// Ensure we don't exceed maxGwei
|
|
200
|
-
const maxGweiInWei = gasConfig.maxGwei * WEI_CONST;
|
|
201
|
-
maxFeePerGas = maxFeePerGas > maxGweiInWei ? maxGweiInWei : maxFeePerGas;
|
|
202
|
-
// Ensure we don't exceed maxBlobGwei
|
|
203
|
-
if (maxFeePerBlobGas) {
|
|
204
|
-
const maxBlobGweiInWei = gasConfig.maxBlobGwei * WEI_CONST;
|
|
205
|
-
maxFeePerBlobGas = maxFeePerBlobGas > maxBlobGweiInWei ? maxBlobGweiInWei : maxFeePerBlobGas;
|
|
206
|
-
}
|
|
207
|
-
// Ensure priority fee doesn't exceed max fee
|
|
208
|
-
const maxPriorityFeePerGas = priorityFee > maxFeePerGas ? maxFeePerGas : priorityFee;
|
|
209
|
-
if (attempt > 0 && previousGasPrice?.maxFeePerBlobGas) {
|
|
210
|
-
const bumpPercentage = gasConfig.priorityFeeRetryBumpPercentage > MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE ? gasConfig.priorityFeeRetryBumpPercentage : MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE;
|
|
211
|
-
// calculate min blob fee based on previous attempt
|
|
212
|
-
const minBlobFee = previousGasPrice.maxFeePerBlobGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
|
|
213
|
-
// use max between current network values and min required values
|
|
214
|
-
maxFeePerBlobGas = maxFeePerBlobGas > minBlobFee ? maxFeePerBlobGas : minBlobFee;
|
|
215
|
-
}
|
|
216
|
-
this.logger?.debug(`Computed L1 gas price`, {
|
|
217
|
-
attempt,
|
|
218
|
-
baseFee: formatGwei(baseFee),
|
|
219
|
-
maxFeePerGas: formatGwei(maxFeePerGas),
|
|
220
|
-
maxPriorityFeePerGas: formatGwei(maxPriorityFeePerGas),
|
|
221
|
-
...maxFeePerBlobGas && {
|
|
222
|
-
maxFeePerBlobGas: formatGwei(maxFeePerBlobGas)
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
return {
|
|
226
|
-
maxFeePerGas,
|
|
227
|
-
maxPriorityFeePerGas,
|
|
228
|
-
...maxFeePerBlobGas && {
|
|
229
|
-
maxFeePerBlobGas: maxFeePerBlobGas
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Estimates gas and adds buffer
|
|
235
|
-
*/ async estimateGas(account, request, _gasConfig, _blobInputs) {
|
|
236
|
-
const gasConfig = {
|
|
237
|
-
...this.config,
|
|
238
|
-
..._gasConfig
|
|
239
|
-
};
|
|
240
|
-
let initialEstimate = 0n;
|
|
241
|
-
if (_blobInputs) {
|
|
242
|
-
// @note requests with blobs also require maxFeePerBlobGas to be set
|
|
243
|
-
const gasPrice = await this.getGasPrice(gasConfig, true, 0);
|
|
244
|
-
initialEstimate = await this.client.estimateGas({
|
|
245
|
-
account,
|
|
246
|
-
...request,
|
|
247
|
-
..._blobInputs,
|
|
248
|
-
maxFeePerBlobGas: gasPrice.maxFeePerBlobGas,
|
|
249
|
-
gas: LARGE_GAS_LIMIT
|
|
250
|
-
});
|
|
251
|
-
this.logger?.debug(`L1 gas used in estimateGas by blob tx: ${initialEstimate}`);
|
|
252
|
-
} else {
|
|
253
|
-
initialEstimate = await this.client.estimateGas({
|
|
254
|
-
account,
|
|
255
|
-
...request,
|
|
256
|
-
gas: LARGE_GAS_LIMIT
|
|
257
|
-
});
|
|
258
|
-
this.logger?.debug(`L1 gas used in estimateGas by non-blob tx: ${initialEstimate}`);
|
|
259
|
-
}
|
|
260
|
-
// Add buffer based on either fixed amount or percentage
|
|
261
|
-
const withBuffer = this.bumpGasLimit(initialEstimate, gasConfig);
|
|
262
|
-
return withBuffer;
|
|
263
|
-
}
|
|
264
|
-
async getTransactionStats(txHash) {
|
|
265
|
-
const tx = await this.client.getTransaction({
|
|
266
|
-
hash: txHash
|
|
267
|
-
});
|
|
268
|
-
if (!tx) {
|
|
269
|
-
return undefined;
|
|
270
|
-
}
|
|
271
|
-
const calldata = hexToBytes(tx.input);
|
|
272
|
-
return {
|
|
273
|
-
sender: tx.from.toString(),
|
|
274
|
-
transactionHash: tx.hash,
|
|
275
|
-
calldataSize: calldata.length,
|
|
276
|
-
calldataGas: getCalldataGasUsage(calldata)
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
async tryGetErrorFromRevertedTx(data, args, blobInputs, stateOverride = []) {
|
|
280
|
-
try {
|
|
281
|
-
await this.client.simulateContract({
|
|
282
|
-
...args,
|
|
283
|
-
account: this.client.account,
|
|
284
|
-
stateOverride
|
|
285
|
-
});
|
|
286
|
-
this.logger?.trace('Simulated blob tx', {
|
|
287
|
-
blobInputs
|
|
288
|
-
});
|
|
289
|
-
// If the above passes, we have a blob error. We cannot simulate blob txs, and failed txs no longer throw errors.
|
|
290
|
-
// Strangely, the only way to throw the revert reason as an error and provide blobs is prepareTransactionRequest.
|
|
291
|
-
// See: https://github.com/wevm/viem/issues/2075
|
|
292
|
-
// This throws a EstimateGasExecutionError with the custom error information:
|
|
293
|
-
const request = blobInputs ? {
|
|
294
|
-
account: this.client.account,
|
|
295
|
-
to: args.address,
|
|
296
|
-
data,
|
|
297
|
-
blobs: blobInputs.blobs,
|
|
298
|
-
kzg: blobInputs.kzg,
|
|
299
|
-
maxFeePerBlobGas: blobInputs.maxFeePerBlobGas
|
|
300
|
-
} : {
|
|
301
|
-
account: this.client.account,
|
|
302
|
-
to: args.address,
|
|
303
|
-
data
|
|
304
|
-
};
|
|
305
|
-
this.logger?.trace('Preparing tx', {
|
|
306
|
-
request
|
|
307
|
-
});
|
|
308
|
-
await this.client.prepareTransactionRequest(request);
|
|
309
|
-
this.logger?.trace('Prepared tx');
|
|
310
|
-
return undefined;
|
|
311
|
-
} catch (simulationErr) {
|
|
312
|
-
// If we don't have a ContractFunctionExecutionError, we have a blob related error => use getContractError to get the error msg.
|
|
313
|
-
const contractErr = simulationErr.name === 'ContractFunctionExecutionError' ? simulationErr : getContractError(simulationErr, {
|
|
314
|
-
args: [],
|
|
315
|
-
abi: args.abi,
|
|
316
|
-
functionName: args.functionName,
|
|
317
|
-
address: args.address
|
|
318
|
-
});
|
|
319
|
-
if (contractErr.name === 'ContractFunctionExecutionError') {
|
|
320
|
-
const execErr = contractErr;
|
|
321
|
-
return tryGetCustomErrorNameContractFunction(execErr);
|
|
322
|
-
}
|
|
323
|
-
this.logger?.error(`Error getting error from simulation`, simulationErr);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
async simulate(request, blockOverrides = {}, stateOverrides = [], abi = RollupAbi, _gasConfig) {
|
|
327
|
-
const gasConfig = {
|
|
328
|
-
...this.config,
|
|
329
|
-
..._gasConfig
|
|
330
|
-
};
|
|
331
|
-
const call = {
|
|
332
|
-
to: request.to,
|
|
333
|
-
data: request.data,
|
|
334
|
-
...request.from && {
|
|
335
|
-
from: request.from
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
return await this._simulate(call, blockOverrides, stateOverrides, gasConfig, abi);
|
|
339
|
-
}
|
|
340
|
-
async _simulate(call, blockOverrides = {}, stateOverrides = [], gasConfig, abi) {
|
|
341
|
-
try {
|
|
342
|
-
const result = await this.client.simulateBlocks({
|
|
343
|
-
validation: false,
|
|
344
|
-
blocks: [
|
|
345
|
-
{
|
|
346
|
-
blockOverrides,
|
|
347
|
-
stateOverrides,
|
|
348
|
-
calls: [
|
|
349
|
-
call
|
|
350
|
-
]
|
|
351
|
-
}
|
|
352
|
-
]
|
|
353
|
-
});
|
|
354
|
-
if (result[0].calls[0].status === 'failure') {
|
|
355
|
-
this.logger?.error('L1 transaction simulation failed', result[0].calls[0].error);
|
|
356
|
-
const decodedError = decodeErrorResult({
|
|
357
|
-
abi,
|
|
358
|
-
data: result[0].calls[0].data
|
|
359
|
-
});
|
|
360
|
-
throw new Error(`L1 transaction simulation failed with error ${decodedError.errorName}(${decodedError.args?.join(',')})`);
|
|
361
|
-
}
|
|
362
|
-
this.logger?.debug(`L1 transaction simulation succeeded`, {
|
|
363
|
-
...result[0].calls[0]
|
|
364
|
-
});
|
|
365
|
-
return {
|
|
366
|
-
gasUsed: result[0].gasUsed,
|
|
367
|
-
result: result[0].calls[0].data
|
|
368
|
-
};
|
|
369
|
-
} catch (err) {
|
|
370
|
-
if (err instanceof MethodNotFoundRpcError || err instanceof MethodNotSupportedRpcError) {
|
|
371
|
-
if (gasConfig.fallbackGasEstimate) {
|
|
372
|
-
this.logger?.warn(`Node does not support eth_simulateV1 API. Using fallback gas estimate: ${gasConfig.fallbackGasEstimate}`);
|
|
373
|
-
return {
|
|
374
|
-
gasUsed: gasConfig.fallbackGasEstimate,
|
|
375
|
-
result: '0x'
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
this.logger?.error('Node does not support eth_simulateV1 API');
|
|
379
|
-
}
|
|
380
|
-
throw err;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
bumpGasLimit(gasLimit, _gasConfig) {
|
|
384
|
-
const gasConfig = {
|
|
385
|
-
...this.config,
|
|
386
|
-
..._gasConfig
|
|
387
|
-
};
|
|
388
|
-
const bumpedGasLimit = gasLimit + gasLimit * BigInt((gasConfig?.gasLimitBufferPercentage || 0) * 1_00) / 100_00n;
|
|
389
|
-
const cleanGasConfig = pickBy(gasConfig, (_, key)=>key in l1TxUtilsConfigMappings);
|
|
390
|
-
this.logger?.debug('Bumping gas limit', {
|
|
391
|
-
gasLimit,
|
|
392
|
-
gasConfig: cleanGasConfig,
|
|
393
|
-
bumpedGasLimit
|
|
394
|
-
});
|
|
395
|
-
return bumpedGasLimit;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
11
|
+
import { formatViemError } from '../utils.js';
|
|
12
|
+
import { l1TxUtilsConfigMappings } from './config.js';
|
|
13
|
+
import { LARGE_GAS_LIMIT } from './constants.js';
|
|
14
|
+
import { ReadOnlyL1TxUtils } from './readonly_l1_tx_utils.js';
|
|
15
|
+
import { TxUtilsState } from './types.js';
|
|
398
16
|
export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
399
17
|
client;
|
|
400
18
|
address;
|
|
@@ -404,7 +22,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
404
22
|
lastMinedBlockNumber;
|
|
405
23
|
nonceManager;
|
|
406
24
|
constructor(client, address, signer, logger = createLogger('L1TxUtils'), dateProvider = new DateProvider(), config, debugMaxGasLimit = false){
|
|
407
|
-
super(client, logger, dateProvider, config, debugMaxGasLimit), this.client = client, this.address = address, this.signer = signer, this.logger = logger, this.txUtilsState =
|
|
25
|
+
super(client, logger, dateProvider, config, debugMaxGasLimit), this.client = client, this.address = address, this.signer = signer, this.logger = logger, this.txUtilsState = TxUtilsState.IDLE, this.lastMinedBlockNumber = undefined;
|
|
408
26
|
this.nonceManager = createNonceManager({
|
|
409
27
|
source: jsonRpc()
|
|
410
28
|
});
|
|
@@ -443,7 +61,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
443
61
|
* @param request - The transaction request (to, data, value)
|
|
444
62
|
* @param gasConfig - Optional gas configuration
|
|
445
63
|
* @returns The transaction hash and parameters used
|
|
446
|
-
*/ async sendTransaction(request, _gasConfig, blobInputs, stateChange =
|
|
64
|
+
*/ async sendTransaction(request, _gasConfig, blobInputs, stateChange = TxUtilsState.SENT) {
|
|
447
65
|
try {
|
|
448
66
|
const gasConfig = {
|
|
449
67
|
...this.config,
|
|
@@ -588,7 +206,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
588
206
|
} else {
|
|
589
207
|
this.logger?.debug(`L1 transaction ${hash} mined`);
|
|
590
208
|
}
|
|
591
|
-
this.state =
|
|
209
|
+
this.state = TxUtilsState.MINED;
|
|
592
210
|
this.lastMinedAtBlockNumber = receipt.blockNumber;
|
|
593
211
|
return receipt;
|
|
594
212
|
}
|
|
@@ -600,7 +218,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
600
218
|
}
|
|
601
219
|
// If we get here then we have checked all of our tx versions and not found anything.
|
|
602
220
|
// We should consider the nonce as MINED
|
|
603
|
-
this.state =
|
|
221
|
+
this.state = TxUtilsState.MINED;
|
|
604
222
|
throw new Error(`Nonce ${nonce} is MINED but not by one of our expected transactions`);
|
|
605
223
|
}
|
|
606
224
|
this.logger?.trace(`Tx timeout check for ${currentTxHash}: ${isTimedOut()}`, {
|
|
@@ -658,7 +276,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
658
276
|
serializedTransaction: signedRequest
|
|
659
277
|
});
|
|
660
278
|
if (!isCancelTx) {
|
|
661
|
-
this.state =
|
|
279
|
+
this.state = TxUtilsState.SPEED_UP;
|
|
662
280
|
}
|
|
663
281
|
const cleanGasConfig = pickBy(gasConfig, (_, key)=>key in l1TxUtilsConfigMappings);
|
|
664
282
|
this.logger?.verbose(`Sent L1 speed-up tx ${newHash}, replacing ${currentTxHash}`, {
|
|
@@ -689,7 +307,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
689
307
|
// The transaction has timed out. If it's a cancellation then we are giving up on it.
|
|
690
308
|
// Otherwise we may attempt to cancel it if configured to do so.
|
|
691
309
|
if (isCancelTx) {
|
|
692
|
-
this.state =
|
|
310
|
+
this.state = TxUtilsState.NOT_MINED;
|
|
693
311
|
} else if (gasConfig.cancelTxOnTimeout) {
|
|
694
312
|
// Fire cancellation without awaiting to avoid blocking the main thread
|
|
695
313
|
this.attemptTxCancellation(currentTxHash, nonce, allVersions, isBlobTx, lastGasPrice, attempts).catch((err)=>{
|
|
@@ -786,7 +404,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
786
404
|
const cancelTxHash = await this.client.sendRawTransaction({
|
|
787
405
|
serializedTransaction: signedRequest
|
|
788
406
|
});
|
|
789
|
-
this.state =
|
|
407
|
+
this.state = TxUtilsState.CANCELLED;
|
|
790
408
|
this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`, {
|
|
791
409
|
nonce
|
|
792
410
|
});
|
|
@@ -796,40 +414,3 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
796
414
|
return receipt.transactionHash;
|
|
797
415
|
}
|
|
798
416
|
}
|
|
799
|
-
export function createViemSigner(client) {
|
|
800
|
-
const signer = async (tx, _address)=>{
|
|
801
|
-
const signedTx = await client.signTransaction(tx);
|
|
802
|
-
const parsed = parseTransaction(signedTx);
|
|
803
|
-
if (!parsed.r || !parsed.s || parsed.yParity !== 0 && parsed.yParity !== 1) {
|
|
804
|
-
throw new Error('Failed to extract signature from viem signed transaction');
|
|
805
|
-
}
|
|
806
|
-
return {
|
|
807
|
-
r: parsed.r,
|
|
808
|
-
s: parsed.s,
|
|
809
|
-
yParity: parsed.yParity
|
|
810
|
-
};
|
|
811
|
-
};
|
|
812
|
-
return signer;
|
|
813
|
-
}
|
|
814
|
-
export function createL1TxUtilsFromViemWallet(client, logger = createLogger('L1TxUtils'), dateProvider = new DateProvider(), config, debugMaxGasLimit = false) {
|
|
815
|
-
return new L1TxUtils(client, EthAddress.fromString(client.account.address), createViemSigner(client), logger, dateProvider, config, debugMaxGasLimit);
|
|
816
|
-
}
|
|
817
|
-
export function createL1TxUtilsFromEthSigner(client, signer, logger = createLogger('L1TxUtils'), dateProvider = new DateProvider(), config, debugMaxGasLimit = false) {
|
|
818
|
-
const callback = async (transaction, _signingAddress)=>{
|
|
819
|
-
return (await signer.signTransaction(transaction)).toViemTransactionSignature();
|
|
820
|
-
};
|
|
821
|
-
return new L1TxUtils(client, signer.address, callback, logger, dateProvider, config, debugMaxGasLimit);
|
|
822
|
-
}
|
|
823
|
-
export function tryGetCustomErrorNameContractFunction(err) {
|
|
824
|
-
return compactArray([
|
|
825
|
-
err.shortMessage,
|
|
826
|
-
...(err.metaMessages ?? []).slice(0, 2).map((s)=>s.trim())
|
|
827
|
-
]).join(' ');
|
|
828
|
-
}
|
|
829
|
-
/*
|
|
830
|
-
* Returns cost of calldata usage in Ethereum.
|
|
831
|
-
* @param data - Calldata.
|
|
832
|
-
* @returns 4 for each zero byte, 16 for each nonzero.
|
|
833
|
-
*/ export function getCalldataGasUsage(data) {
|
|
834
|
-
return data.filter((byte)=>byte === 0).length * 4 + data.filter((byte)=>byte !== 0).length * 16;
|
|
835
|
-
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type Logger } from '@aztec/foundation/log';
|
|
2
2
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
3
3
|
import { type Hex } from 'viem';
|
|
4
|
-
import type { EthSigner } from '
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
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 { L1TxUtils } from './l1_tx_utils.js';
|
|
8
|
+
import type { GasPrice } from './types.js';
|
|
7
9
|
export declare class L1TxUtilsWithBlobs extends L1TxUtils {
|
|
8
10
|
/**
|
|
9
11
|
* Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
|
|
@@ -13,7 +15,7 @@ export declare class L1TxUtilsWithBlobs extends L1TxUtils {
|
|
|
13
15
|
* @param attempts - The number of attempts to cancel the transaction
|
|
14
16
|
* @returns The hash of the cancellation transaction
|
|
15
17
|
*/
|
|
16
|
-
attemptTxCancellation(currentTxHash: Hex, nonce: number, allVersions: Set<Hex>, isBlobTx?: boolean, previousGasPrice?: GasPrice, attempts?: number): Promise<`0x${string}`>;
|
|
18
|
+
protected attemptTxCancellation(currentTxHash: Hex, nonce: number, allVersions: Set<Hex>, isBlobTx?: boolean, previousGasPrice?: GasPrice, attempts?: number): Promise<`0x${string}`>;
|
|
17
19
|
}
|
|
18
20
|
export declare function createL1TxUtilsWithBlobsFromViemWallet(client: ExtendedViemWalletClient, logger?: Logger, dateProvider?: DateProvider, config?: Partial<L1TxUtilsConfig>, debugMaxGasLimit?: boolean): L1TxUtilsWithBlobs;
|
|
19
21
|
export declare function createL1TxUtilsWithBlobsFromEthSigner(client: ViemClient, signer: EthSigner, logger?: Logger, dateProvider?: DateProvider, config?: Partial<L1TxUtilsConfig>, debugMaxGasLimit?: boolean): L1TxUtilsWithBlobs;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"l1_tx_utils_with_blobs.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/l1_tx_utils_with_blobs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,KAAK,GAAG,EAA4C,MAAM,MAAM,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,YAAY,CAAC;AAE5D,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C;;;;;;;OAOG;cACsB,qBAAqB,CAC5C,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,EACrB,QAAQ,UAAQ,EAChB,gBAAgB,CAAC,EAAE,QAAQ,EAC3B,QAAQ,SAAI;CAoFf;AAED,wBAAgB,sCAAsC,CACpD,MAAM,EAAE,wBAAwB,EAChC,MAAM,GAAE,MAAkC,EAC1C,YAAY,GAAE,YAAiC,EAC/C,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACjC,gBAAgB,GAAE,OAAe,sBAWlC;AAED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,SAAS,EACjB,MAAM,GAAE,MAAkC,EAC1C,YAAY,GAAE,YAAiC,EAC/C,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACjC,gBAAgB,GAAE,OAAe,sBAOlC"}
|
|
@@ -3,7 +3,8 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
5
|
import { formatGwei } from 'viem';
|
|
6
|
-
import { L1TxUtils
|
|
6
|
+
import { L1TxUtils } from './l1_tx_utils.js';
|
|
7
|
+
import { createViemSigner } from './signer.js';
|
|
7
8
|
export class L1TxUtilsWithBlobs extends L1TxUtils {
|
|
8
9
|
/**
|
|
9
10
|
* Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
|