@atomiqlabs/chain-evm 1.0.0-dev.92 → 1.0.0-dev.94

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.
@@ -84,11 +84,10 @@ function initializeBotanix(options, bitcoinRpc, network) {
84
84
  const Fees = options.fees ?? new EVMFees_1.EVMFees(provider, 2n * 1000000000n, 1000000n);
85
85
  const chainInterface = new EVMChainInterface_1.EVMChainInterface("BOTANIX", chainId, provider, {
86
86
  safeBlockTag: "finalized",
87
- maxLogsBlockRange: 950,
88
- maxLogTopics: 64,
89
- maxParallelLogRequests: 5,
90
- maxParallelCalls: 5,
91
- ...options?.evmConfig
87
+ maxLogsBlockRange: options?.evmConfig?.maxLogsBlockRange ?? 950,
88
+ maxLogTopics: options?.evmConfig?.maxLogTopics ?? 64,
89
+ maxParallelLogRequests: options?.evmConfig?.maxParallelLogRequests ?? 5,
90
+ maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5
92
91
  }, options.retryPolicy, Fees);
93
92
  const btcRelay = new EVMBtcRelay_1.EVMBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
94
93
  const swapContract = new EVMSwapContract_1.EVMSwapContract(chainInterface, btcRelay, options.swapContract ?? defaultContractAddresses.swapContract, {
@@ -90,11 +90,10 @@ function initializeCitrea(options, bitcoinRpc, network) {
90
90
  const Fees = options.fees ?? new CitreaFees_1.CitreaFees(provider, 2n * 1000000000n, 1000000n);
91
91
  const chainInterface = new EVMChainInterface_1.EVMChainInterface("CITREA", chainId, provider, {
92
92
  safeBlockTag: "latest",
93
- maxLogsBlockRange: 950,
94
- maxLogTopics: 64,
95
- maxParallelLogRequests: 5,
96
- maxParallelCalls: 5,
97
- ...options?.evmConfig
93
+ maxLogsBlockRange: options?.evmConfig?.maxLogsBlockRange ?? 950,
94
+ maxLogTopics: options?.evmConfig?.maxLogTopics ?? 64,
95
+ maxParallelLogRequests: options?.evmConfig?.maxParallelLogRequests ?? 5,
96
+ maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5
98
97
  }, options.retryPolicy, Fees);
99
98
  chainInterface.Tokens = new CitreaTokens_1.CitreaTokens(chainInterface); //Override with custom token module allowing l1 state diff based fee calculation
100
99
  const btcRelay = new CitreaBtcRelay_1.CitreaBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
@@ -32,15 +32,34 @@ class EVMTransactions extends EVMModule_1.EVMModule {
32
32
  this.onBeforeTxReplace(txReplaceListener);
33
33
  let state = "pending";
34
34
  let confirmedTxId = null;
35
- while (state === "pending" || state === "not_found") {
35
+ while (state === "pending") {
36
36
  await (0, Utils_1.timeoutPromise)(3000, abortSignal);
37
+ const latestConfirmedNonce = this.latestConfirmedNonces[tx.from];
38
+ const snapshot = [...checkTxns]; //Iterate over a snapshot
39
+ const totalTxnCount = snapshot.length;
40
+ let notFoundTxns = 0;
37
41
  for (let txId of checkTxns) {
38
- state = await this.getTxIdStatus(txId);
39
- if (state === "reverted" || state === "success") {
42
+ let _state = await this.getTxIdStatus(txId);
43
+ if (_state === "not_found")
44
+ notFoundTxns++;
45
+ if (_state === "reverted" || _state === "success") {
40
46
  confirmedTxId = txId;
47
+ state = _state;
41
48
  break;
42
49
  }
43
50
  }
51
+ if (notFoundTxns === totalTxnCount) { //All not found, check the latest account nonce
52
+ if (latestConfirmedNonce != null && latestConfirmedNonce > tx.nonce) {
53
+ //Confirmed nonce is already higher than the TX nonce, meaning the TX got replaced
54
+ throw new Error("Transaction failed - replaced!");
55
+ }
56
+ this.logger.warn("confirmTransaction(): All transactions not found, fetching the latest account nonce...");
57
+ const _latestConfirmedNonce = this.latestConfirmedNonces[tx.from];
58
+ const currentLatestNonce = await this.provider.getTransactionCount(tx.from, this.root.config.safeBlockTag);
59
+ if (_latestConfirmedNonce == null || _latestConfirmedNonce < currentLatestNonce) {
60
+ this.latestConfirmedNonces[tx.from] = currentLatestNonce;
61
+ }
62
+ }
44
63
  }
45
64
  this.offBeforeTxReplace(txReplaceListener);
46
65
  const nextAccountNonce = tx.nonce + 1;
@@ -160,17 +179,19 @@ class EVMTransactions extends EVMModule_1.EVMModule {
160
179
  if (currentPendingNonce == null || nextAccountNonce > currentPendingNonce) {
161
180
  this.latestPendingNonces[tx.from] = nextAccountNonce;
162
181
  }
163
- if (waitForConfirmation)
164
- promises.push(this.confirmTransaction(tx, abortSignal));
165
- txIds.push(tx.hash);
182
+ promises.push(this.confirmTransaction(tx, abortSignal));
183
+ if (!waitForConfirmation)
184
+ txIds.push(tx.hash);
166
185
  this.logger.debug("sendAndConfirm(): transaction sent (" + (i + 1) + "/" + signedTxs.length + "): " + tx.hash);
167
186
  if (promises.length >= MAX_UNCONFIRMED_TXNS) {
168
- await Promise.all(promises);
187
+ if (waitForConfirmation)
188
+ txIds.push(...await Promise.all(promises));
169
189
  promises = [];
170
190
  }
171
191
  }
172
- if (promises.length > 0)
173
- txIds = await Promise.all(promises);
192
+ if (waitForConfirmation && promises.length > 0) {
193
+ txIds.push(...await Promise.all(promises));
194
+ }
174
195
  }
175
196
  else {
176
197
  for (let i = 0; i < txs.length; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomiqlabs/chain-evm",
3
- "version": "1.0.0-dev.92",
3
+ "version": "1.0.0-dev.94",
4
4
  "description": "EVM specific base implementation",
5
5
  "main": "./dist/index.js",
6
6
  "types:": "./dist/index.d.ts",
@@ -121,11 +121,10 @@ export function initializeBotanix(
121
121
 
122
122
  const chainInterface = new EVMChainInterface("BOTANIX", chainId, provider, {
123
123
  safeBlockTag: "finalized",
124
- maxLogsBlockRange: 950,
125
- maxLogTopics: 64,
126
- maxParallelLogRequests: 5,
127
- maxParallelCalls: 5,
128
- ...options?.evmConfig
124
+ maxLogsBlockRange: options?.evmConfig?.maxLogsBlockRange ?? 950,
125
+ maxLogTopics: options?.evmConfig?.maxLogTopics ?? 64,
126
+ maxParallelLogRequests: options?.evmConfig?.maxParallelLogRequests ?? 5,
127
+ maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5
129
128
  }, options.retryPolicy, Fees);
130
129
 
131
130
  const btcRelay = new EVMBtcRelay(
@@ -127,11 +127,10 @@ export function initializeCitrea(
127
127
 
128
128
  const chainInterface = new EVMChainInterface("CITREA", chainId, provider, {
129
129
  safeBlockTag: "latest",
130
- maxLogsBlockRange: 950,
131
- maxLogTopics: 64,
132
- maxParallelLogRequests: 5,
133
- maxParallelCalls: 5,
134
- ...options?.evmConfig
130
+ maxLogsBlockRange: options?.evmConfig?.maxLogsBlockRange ?? 950,
131
+ maxLogTopics: options?.evmConfig?.maxLogTopics ?? 64,
132
+ maxParallelLogRequests: options?.evmConfig?.maxParallelLogRequests ?? 5,
133
+ maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5
135
134
  }, options.retryPolicy, Fees);
136
135
  chainInterface.Tokens = new CitreaTokens(chainInterface); //Override with custom token module allowing l1 state diff based fee calculation
137
136
 
@@ -50,15 +50,34 @@ export class EVMTransactions extends EVMModule<any> {
50
50
 
51
51
  let state = "pending";
52
52
  let confirmedTxId: string = null;
53
- while(state==="pending" || state==="not_found") {
53
+ while(state==="pending") {
54
54
  await timeoutPromise(3000, abortSignal);
55
+ const latestConfirmedNonce = this.latestConfirmedNonces[tx.from];
56
+
57
+ const snapshot = [...checkTxns]; //Iterate over a snapshot
58
+ const totalTxnCount = snapshot.length;
59
+ let notFoundTxns = 0;
55
60
  for(let txId of checkTxns) {
56
- state = await this.getTxIdStatus(txId);
57
- if(state==="reverted" || state==="success") {
61
+ let _state = await this.getTxIdStatus(txId);
62
+ if(_state==="not_found") notFoundTxns++;
63
+ if(_state==="reverted" || _state==="success") {
58
64
  confirmedTxId = txId;
65
+ state = _state;
59
66
  break;
60
67
  }
61
68
  }
69
+ if(notFoundTxns===totalTxnCount) { //All not found, check the latest account nonce
70
+ if(latestConfirmedNonce!=null && latestConfirmedNonce>tx.nonce) {
71
+ //Confirmed nonce is already higher than the TX nonce, meaning the TX got replaced
72
+ throw new Error("Transaction failed - replaced!");
73
+ }
74
+ this.logger.warn("confirmTransaction(): All transactions not found, fetching the latest account nonce...");
75
+ const _latestConfirmedNonce = this.latestConfirmedNonces[tx.from];
76
+ const currentLatestNonce = await this.provider.getTransactionCount(tx.from, this.root.config.safeBlockTag);
77
+ if(_latestConfirmedNonce==null || _latestConfirmedNonce < currentLatestNonce) {
78
+ this.latestConfirmedNonces[tx.from] = currentLatestNonce;
79
+ }
80
+ }
62
81
  }
63
82
 
64
83
  this.offBeforeTxReplace(txReplaceListener);
@@ -193,15 +212,17 @@ export class EVMTransactions extends EVMModule<any> {
193
212
  this.latestPendingNonces[tx.from] = nextAccountNonce;
194
213
  }
195
214
 
196
- if(waitForConfirmation) promises.push(this.confirmTransaction(tx, abortSignal));
197
- txIds.push(tx.hash);
215
+ promises.push(this.confirmTransaction(tx, abortSignal));
216
+ if(!waitForConfirmation) txIds.push(tx.hash);
198
217
  this.logger.debug("sendAndConfirm(): transaction sent ("+(i+1)+"/"+signedTxs.length+"): "+tx.hash);
199
218
  if(promises.length >= MAX_UNCONFIRMED_TXNS) {
200
- await Promise.all(promises);
219
+ if(waitForConfirmation) txIds.push(...await Promise.all(promises));
201
220
  promises = [];
202
221
  }
203
222
  }
204
- if(promises.length>0) txIds = await Promise.all(promises);
223
+ if(waitForConfirmation && promises.length>0) {
224
+ txIds.push(...await Promise.all(promises));
225
+ }
205
226
  } else {
206
227
  for(let i=0;i<txs.length;i++) {
207
228
  let tx: TransactionResponse | Transaction;