@atomiqlabs/chain-evm 2.1.12 → 2.2.0
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/README.md +75 -0
- package/dist/chains/EVMOptions.d.ts +66 -0
- package/dist/chains/EVMOptions.js +2 -0
- package/dist/chains/alpen/AlpenInitializer.d.ts +3 -30
- package/dist/chains/alpen/AlpenInitializer.js +3 -3
- package/dist/chains/botanix/BotanixInitializer.d.ts +3 -30
- package/dist/chains/botanix/BotanixInitializer.js +3 -3
- package/dist/chains/citrea/CitreaBtcRelay.d.ts +5 -0
- package/dist/chains/citrea/CitreaBtcRelay.js +7 -2
- package/dist/chains/citrea/CitreaFees.d.ts +3 -5
- package/dist/chains/citrea/CitreaFees.js +3 -5
- package/dist/chains/citrea/CitreaInitializer.d.ts +3 -29
- package/dist/chains/citrea/CitreaInitializer.js +3 -3
- package/dist/chains/citrea/CitreaSpvVaultContract.d.ts +5 -0
- package/dist/chains/citrea/CitreaSpvVaultContract.js +7 -2
- package/dist/chains/citrea/CitreaSwapContract.d.ts +7 -2
- package/dist/chains/citrea/CitreaSwapContract.js +10 -5
- package/dist/chains/citrea/CitreaTokens.d.ts +5 -0
- package/dist/chains/citrea/CitreaTokens.js +5 -0
- package/dist/chains/goat/GoatInitializer.d.ts +3 -30
- package/dist/chains/goat/GoatInitializer.js +3 -3
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +41 -10
- package/dist/evm/btcrelay/EVMBtcRelay.js +50 -18
- package/dist/evm/btcrelay/headers/EVMBtcHeader.d.ts +53 -7
- package/dist/evm/btcrelay/headers/EVMBtcHeader.js +43 -5
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.d.ts +53 -8
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.js +41 -1
- package/dist/evm/chain/EVMChainInterface.d.ts +61 -2
- package/dist/evm/chain/EVMChainInterface.js +14 -7
- package/dist/evm/chain/EVMModule.d.ts +5 -0
- package/dist/evm/chain/EVMModule.js +6 -1
- package/dist/evm/chain/modules/EVMBlocks.d.ts +7 -0
- package/dist/evm/chain/modules/EVMBlocks.js +2 -0
- package/dist/evm/chain/modules/EVMEvents.js +19 -19
- package/dist/evm/chain/modules/EVMFees.d.ts +41 -5
- package/dist/evm/chain/modules/EVMFees.js +24 -5
- package/dist/evm/chain/modules/EVMTokens.d.ts +1 -1
- package/dist/evm/chain/modules/EVMTokens.js +1 -1
- package/dist/evm/chain/modules/EVMTransactions.d.ts +22 -5
- package/dist/evm/chain/modules/EVMTransactions.js +31 -22
- package/dist/evm/contract/EVMContractBase.d.ts +28 -10
- package/dist/evm/contract/EVMContractBase.js +9 -18
- package/dist/evm/contract/EVMContractModule.d.ts +5 -0
- package/dist/evm/contract/EVMContractModule.js +5 -0
- package/dist/evm/contract/modules/EVMContractEvents.d.ts +7 -1
- package/dist/evm/contract/modules/EVMContractEvents.js +23 -3
- package/dist/evm/events/EVMChainEvents.d.ts +8 -0
- package/dist/evm/events/EVMChainEvents.js +8 -0
- package/dist/evm/events/EVMChainEventsBrowser.d.ts +87 -19
- package/dist/evm/events/EVMChainEventsBrowser.js +53 -18
- package/dist/evm/providers/JsonRpcProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/JsonRpcProviderWithRetries.js +9 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.d.ts +5 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.js +5 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.js +9 -0
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +46 -21
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +61 -23
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +57 -2
- package/dist/evm/spv_swap/EVMSpvVaultData.js +57 -2
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.d.ts +12 -0
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.js +12 -0
- package/dist/evm/swaps/EVMSwapContract.d.ts +58 -13
- package/dist/evm/swaps/EVMSwapContract.js +81 -54
- package/dist/evm/swaps/EVMSwapData.d.ts +27 -6
- package/dist/evm/swaps/EVMSwapData.js +26 -0
- package/dist/evm/swaps/EVMSwapModule.d.ts +5 -0
- package/dist/evm/swaps/EVMSwapModule.js +5 -0
- package/dist/evm/swaps/handlers/IHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.js +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +10 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +7 -2
- package/dist/evm/swaps/modules/EVMLpVault.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMLpVault.js +9 -4
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +7 -2
- package/dist/evm/swaps/modules/EVMSwapClaim.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +10 -0
- package/dist/evm/swaps/modules/EVMSwapInit.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMSwapRefund.js +9 -4
- package/dist/evm/wallet/EVMBrowserSigner.d.ts +22 -2
- package/dist/evm/wallet/EVMBrowserSigner.js +40 -2
- package/dist/evm/wallet/EVMPersistentSigner.d.ts +13 -2
- package/dist/evm/wallet/EVMPersistentSigner.js +13 -1
- package/dist/evm/wallet/EVMSigner.d.ts +30 -1
- package/dist/evm/wallet/EVMSigner.js +34 -1
- package/dist/index.d.ts +71 -0
- package/dist/index.js +70 -0
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +15 -0
- package/dist/utils/Utils.d.ts +50 -0
- package/dist/utils/Utils.js +45 -0
- package/node/index.d.ts +1 -0
- package/node/index.js +3 -0
- package/package.json +5 -3
- package/src/chains/EVMOptions.ts +70 -0
- package/src/chains/alpen/AlpenInitializer.ts +5 -27
- package/src/chains/botanix/BotanixChainType.ts +5 -5
- package/src/chains/botanix/BotanixInitializer.ts +5 -27
- package/src/chains/citrea/CitreaBtcRelay.ts +8 -3
- package/src/chains/citrea/CitreaFees.ts +3 -6
- package/src/chains/citrea/CitreaInitializer.ts +5 -27
- package/src/chains/citrea/CitreaSpvVaultContract.ts +7 -2
- package/src/chains/citrea/CitreaSwapContract.ts +11 -6
- package/src/chains/citrea/CitreaTokens.ts +6 -1
- package/src/chains/goat/GoatChainType.ts +5 -5
- package/src/chains/goat/GoatInitializer.ts +3 -25
- package/src/evm/btcrelay/EVMBtcRelay.ts +54 -22
- package/src/evm/btcrelay/headers/EVMBtcHeader.ts +60 -13
- package/src/evm/btcrelay/headers/EVMBtcStoredHeader.ts +55 -10
- package/src/evm/chain/EVMChainInterface.ts +74 -14
- package/src/evm/chain/EVMModule.ts +6 -1
- package/src/evm/chain/modules/EVMBlocks.ts +7 -0
- package/src/evm/chain/modules/EVMEvents.ts +19 -19
- package/src/evm/chain/modules/EVMFees.ts +41 -5
- package/src/evm/chain/modules/EVMTokens.ts +1 -1
- package/src/evm/chain/modules/EVMTransactions.ts +40 -17
- package/src/evm/contract/EVMContractBase.ts +29 -24
- package/src/evm/contract/EVMContractModule.ts +5 -0
- package/src/evm/contract/modules/EVMContractEvents.ts +27 -8
- package/src/evm/events/EVMChainEvents.ts +8 -0
- package/src/evm/events/EVMChainEventsBrowser.ts +103 -29
- package/src/evm/providers/JsonRpcProviderWithRetries.ts +10 -1
- package/src/evm/providers/ReconnectingWebSocketProvider.ts +6 -1
- package/src/evm/providers/WebSocketProviderWithRetries.ts +10 -1
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +72 -32
- package/src/evm/spv_swap/EVMSpvVaultData.ts +57 -2
- package/src/evm/spv_swap/EVMSpvWithdrawalData.ts +12 -0
- package/src/evm/swaps/EVMSwapContract.ts +108 -63
- package/src/evm/swaps/EVMSwapData.ts +27 -1
- package/src/evm/swaps/EVMSwapModule.ts +5 -0
- package/src/evm/swaps/handlers/IHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/ClaimHandlers.ts +15 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +10 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +17 -2
- package/src/evm/swaps/modules/EVMLpVault.ts +10 -5
- package/src/evm/swaps/modules/EVMSwapClaim.ts +12 -7
- package/src/evm/swaps/modules/EVMSwapInit.ts +17 -7
- package/src/evm/swaps/modules/EVMSwapRefund.ts +9 -4
- package/src/evm/wallet/EVMBrowserSigner.ts +44 -5
- package/src/evm/wallet/EVMPersistentSigner.ts +14 -2
- package/src/evm/wallet/EVMSigner.ts +37 -1
- package/src/index.ts +72 -0
- package/src/node/index.ts +10 -0
- package/src/utils/Utils.ts +50 -1
|
@@ -10,9 +10,25 @@ import {timeoutPromise} from "../../../utils/Utils";
|
|
|
10
10
|
import {EVMSigner} from "../../wallet/EVMSigner";
|
|
11
11
|
import {TransactionRevertedError} from "@atomiqlabs/base";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Unsigned EVM transaction type used by chain modules.
|
|
15
|
+
*
|
|
16
|
+
* @category Chain Interface
|
|
17
|
+
*/
|
|
13
18
|
export type EVMTx = TransactionRequest;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Signed EVM transaction type as produced by ethers.
|
|
22
|
+
*
|
|
23
|
+
* @category Chain Interface
|
|
24
|
+
*/
|
|
14
25
|
export type SignedEVMTx = Transaction;
|
|
15
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Simplified call-trace structure returned by `debug_traceTransaction` with `callTracer`.
|
|
29
|
+
*
|
|
30
|
+
* @category Internal/Chain
|
|
31
|
+
*/
|
|
16
32
|
export type EVMTxTrace = {
|
|
17
33
|
from: string,
|
|
18
34
|
gas: string,
|
|
@@ -29,6 +45,8 @@ export type EVMTxTrace = {
|
|
|
29
45
|
const MAX_UNCONFIRMED_TXNS = 10;
|
|
30
46
|
|
|
31
47
|
/**
|
|
48
|
+
* Transaction service for preparing, signing, broadcasting and confirming EVM transactions.
|
|
49
|
+
*
|
|
32
50
|
* @category Internal/Chain
|
|
33
51
|
*/
|
|
34
52
|
export class EVMTransactions extends EVMModule<any> {
|
|
@@ -84,7 +102,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
84
102
|
}
|
|
85
103
|
this.logger.warn("confirmTransaction(): All transactions not found, fetching the latest account nonce...");
|
|
86
104
|
const _latestConfirmedNonce = this.latestConfirmedNonces[tx.from!];
|
|
87
|
-
const currentLatestNonce = await this.provider.getTransactionCount(tx.from!, this.root.
|
|
105
|
+
const currentLatestNonce = await this.provider.getTransactionCount(tx.from!, this.root._config.safeBlockTag);
|
|
88
106
|
if(_latestConfirmedNonce==null || _latestConfirmedNonce < currentLatestNonce) {
|
|
89
107
|
this.latestConfirmedNonces[tx.from!] = currentLatestNonce;
|
|
90
108
|
}
|
|
@@ -126,9 +144,9 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
126
144
|
value: toBeHex(tx.value ?? 0n),
|
|
127
145
|
input: tx.data,
|
|
128
146
|
data: tx.data,
|
|
129
|
-
accessList: this.root.
|
|
147
|
+
accessList: this.root._config.defaultAccessListAddresses==null
|
|
130
148
|
? undefined
|
|
131
|
-
: this.root.
|
|
149
|
+
: this.root._config.defaultAccessListAddresses.map(val => ({address: val, storageKeys: []}))
|
|
132
150
|
}, "pending"]);
|
|
133
151
|
} catch (e: any) {
|
|
134
152
|
//Unable to create access list, fuck it
|
|
@@ -140,22 +158,27 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
140
158
|
}
|
|
141
159
|
|
|
142
160
|
/**
|
|
143
|
-
* Prepares
|
|
161
|
+
* Prepares EVM transactions, assigns nonces when needed, and optionally applies access lists
|
|
162
|
+
* before signing.
|
|
144
163
|
*
|
|
145
|
-
* @param signer
|
|
146
164
|
* @param txs
|
|
165
|
+
* @param signer
|
|
147
166
|
* @param useAccessList Whether to use access lists for sending txns
|
|
148
|
-
* @private
|
|
149
167
|
*/
|
|
150
|
-
|
|
168
|
+
public async prepareTransactions(txs: TransactionRequest[], signer?: EVMSigner, useAccessList?: boolean): Promise<void> {
|
|
169
|
+
if(txs.length===0) return;
|
|
170
|
+
const signerAddress = signer?.getAddress()
|
|
171
|
+
?? (txs[0].from==null ? null : await resolveAddress(txs[0].from, this.provider));
|
|
172
|
+
if(signerAddress==null) throw new Error("Cannot get tx sender address!");
|
|
173
|
+
|
|
151
174
|
for(let tx of txs) {
|
|
152
175
|
tx.chainId = this.root.evmChainId;
|
|
153
|
-
tx.from =
|
|
176
|
+
tx.from = signerAddress;
|
|
154
177
|
}
|
|
155
178
|
|
|
156
|
-
if(!signer.isManagingNoncesInternally) {
|
|
157
|
-
let nonce: number = await this.root.provider.getTransactionCount(
|
|
158
|
-
const latestKnownNonce = this.latestPendingNonces[
|
|
179
|
+
if(signer==null || !signer.isManagingNoncesInternally) {
|
|
180
|
+
let nonce: number = await this.root.provider.getTransactionCount(signerAddress, "pending");
|
|
181
|
+
const latestKnownNonce = this.latestPendingNonces[signerAddress];
|
|
159
182
|
if(latestKnownNonce!=null && latestKnownNonce > nonce) {
|
|
160
183
|
this.logger.debug("prepareTransactions(): Using nonce from local cache!");
|
|
161
184
|
nonce = latestKnownNonce;
|
|
@@ -164,7 +187,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
164
187
|
for(let i=0;i<txs.length;i++) {
|
|
165
188
|
const tx = txs[i];
|
|
166
189
|
if(tx.nonce!=null) nonce = tx.nonce; //Take the nonce from last tx
|
|
167
|
-
if(nonce==null) nonce = await this.root.provider.getTransactionCount(
|
|
190
|
+
if(nonce==null) nonce = await this.root.provider.getTransactionCount(signerAddress, "pending"); //Fetch the nonce
|
|
168
191
|
if(tx.nonce==null) tx.nonce = nonce;
|
|
169
192
|
|
|
170
193
|
this.logger.debug("sendAndConfirm(): transaction prepared ("+(i+1)+"/"+txs.length+"), nonce: "+tx.nonce);
|
|
@@ -173,7 +196,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
173
196
|
}
|
|
174
197
|
}
|
|
175
198
|
|
|
176
|
-
for(let tx of txs) {
|
|
199
|
+
if(signer!=null) for(let tx of txs) {
|
|
177
200
|
if(useAccessList) await this.applyAccessList(tx);
|
|
178
201
|
for(let callback of this.cbksBeforeTxSigned) {
|
|
179
202
|
await callback(tx);
|
|
@@ -227,7 +250,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
227
250
|
abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>,
|
|
228
251
|
useAccessLists?: boolean
|
|
229
252
|
): Promise<string[]> {
|
|
230
|
-
await this.prepareTransactions(
|
|
253
|
+
await this.prepareTransactions(txs, signer, useAccessLists ?? this.root._config.useAccessLists);
|
|
231
254
|
const signedTxs: Transaction[] = [];
|
|
232
255
|
|
|
233
256
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
@@ -415,7 +438,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
415
438
|
}
|
|
416
439
|
|
|
417
440
|
/**
|
|
418
|
-
* Gets the status of
|
|
441
|
+
* Gets the status of a raw signed EVM transaction.
|
|
419
442
|
*
|
|
420
443
|
* @param tx
|
|
421
444
|
*/
|
|
@@ -435,9 +458,9 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
435
458
|
if(txResponse.blockHash==null) return "pending";
|
|
436
459
|
|
|
437
460
|
const [safeBlockNumber, txReceipt] = await Promise.all([
|
|
438
|
-
this.root.
|
|
461
|
+
this.root._config.safeBlockTag==="latest"
|
|
439
462
|
? Promise.resolve(null)
|
|
440
|
-
: this.provider.getBlock(this.root.
|
|
463
|
+
: this.provider.getBlock(this.root._config.safeBlockTag).then(res => res?.number ?? 0),
|
|
441
464
|
this.provider.getTransactionReceipt(txId)
|
|
442
465
|
]);
|
|
443
466
|
|
|
@@ -13,23 +13,39 @@ type KeysOfType<T, ValueType> = keyof {
|
|
|
13
13
|
[K in keyof T]: T[K] extends ValueType ? K : never;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Typed transaction call decoded from calldata for a specific contract method.
|
|
18
|
+
*
|
|
19
|
+
* @category Internal/Contracts
|
|
20
|
+
*/
|
|
16
21
|
export interface TypedFunctionCall<TCMethod extends TypedContractMethod>
|
|
17
22
|
extends Omit<TransactionDescription, "args"> {
|
|
18
23
|
args: __TypechainOutputObject<TCMethod>;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
|
-
* Base
|
|
27
|
+
* Base contract wrapper providing typed event and calldata parsing helpers.
|
|
28
|
+
*
|
|
29
|
+
* @category Internal/Contracts
|
|
23
30
|
*/
|
|
24
31
|
export class EVMContractBase<T extends BaseContract> {
|
|
25
32
|
|
|
26
|
-
contract: T;
|
|
33
|
+
readonly contract: T;
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
readonly _Events: EVMContractEvents<T>;
|
|
39
|
+
protected readonly Chain: EVMChainInterface<any>;
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
/**
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
readonly _contractAddress: string;
|
|
45
|
+
/**
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
readonly _contractDeploymentHeight?: number;
|
|
33
49
|
|
|
34
50
|
constructor(
|
|
35
51
|
chainInterface: EVMChainInterface<any>,
|
|
@@ -39,26 +55,15 @@ export class EVMContractBase<T extends BaseContract> {
|
|
|
39
55
|
) {
|
|
40
56
|
this.Chain = chainInterface;
|
|
41
57
|
this.contract = new Contract(contractAddress, contractAbi, chainInterface.provider) as unknown as T;
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
toTypedEvent<TEventName extends keyof T["filters"] = keyof T["filters"]>(log: Log): TypedEventLog<T["filters"][TEventName]> | null {
|
|
48
|
-
let foundFragment: EventFragment | null = null;
|
|
49
|
-
try {
|
|
50
|
-
foundFragment = this.contract.interface.getEvent(log.topics[0]);
|
|
51
|
-
} catch (error) { }
|
|
52
|
-
if(!foundFragment) return null;
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
return new EventLog(log, this.contract.interface, foundFragment) as unknown as TypedEventLog<T["filters"][TEventName]>;
|
|
56
|
-
} catch (error: any) { }
|
|
57
|
-
|
|
58
|
-
return null;
|
|
58
|
+
this._Events = new EVMContractEvents<T>(chainInterface, this);
|
|
59
|
+
this._contractAddress = contractAddress;
|
|
60
|
+
this._contractDeploymentHeight = contractDeploymentHeight;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
protected parseCalldata<TMethod extends TypedContractMethod>(calldata: string): TypedFunctionCall<TMethod> {
|
|
62
67
|
return this.contract.interface.parseTransaction({data: calldata}) as unknown as TypedFunctionCall<TMethod>;
|
|
63
68
|
}
|
|
64
69
|
|
|
@@ -4,6 +4,11 @@ import {EVMChainInterface} from "../chain/EVMChainInterface";
|
|
|
4
4
|
import {EVMContractBase} from "./EVMContractBase";
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Base module class for EVM components tied to a specific contract wrapper.
|
|
9
|
+
*
|
|
10
|
+
* @category Internal/Contracts
|
|
11
|
+
*/
|
|
7
12
|
export class EVMContractModule<T extends BaseContract, C extends EVMContractBase<T> = EVMContractBase<T>> extends EVMModule<any> {
|
|
8
13
|
|
|
9
14
|
readonly contract: C;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {BaseContract, Log} from "ethers";
|
|
1
|
+
import {BaseContract, EventFragment, EventLog, Log} from "ethers";
|
|
2
2
|
import {EVMEvents} from "../../chain/modules/EVMEvents";
|
|
3
|
-
import {EVMContractBase} from "../EVMContractBase";
|
|
3
|
+
import {EVMContractBase, TypedFunctionCall} from "../EVMContractBase";
|
|
4
4
|
import {EVMChainInterface} from "../../chain/EVMChainInterface";
|
|
5
|
-
import {TypedEventLog} from "../../typechain/common";
|
|
5
|
+
import {TypedContractMethod, TypedEventLog} from "../../typechain/common";
|
|
6
6
|
|
|
7
7
|
function normalizeTopic(topic: string) {
|
|
8
8
|
if(topic.length!==66) {
|
|
@@ -12,9 +12,14 @@ function normalizeTopic(topic: string) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Typed contract event utilities built on top of generic EVM log querying helpers.
|
|
17
|
+
*
|
|
18
|
+
* @category Internal/Contracts
|
|
19
|
+
*/
|
|
15
20
|
export class EVMContractEvents<T extends BaseContract> extends EVMEvents {
|
|
16
21
|
|
|
17
|
-
readonly contract: EVMContractBase<T>;
|
|
22
|
+
private readonly contract: EVMContractBase<T>;
|
|
18
23
|
readonly baseContract: T;
|
|
19
24
|
|
|
20
25
|
constructor(chainInterface: EVMChainInterface<any>, contract: EVMContractBase<T>) {
|
|
@@ -23,8 +28,22 @@ export class EVMContractEvents<T extends BaseContract> extends EVMEvents {
|
|
|
23
28
|
this.baseContract = contract.contract;
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
private toTypedEvent<TEventName extends keyof T["filters"] = keyof T["filters"]>(log: Log): TypedEventLog<T["filters"][TEventName]> | null {
|
|
32
|
+
let foundFragment: EventFragment | null = null;
|
|
33
|
+
try {
|
|
34
|
+
foundFragment = this.baseContract.interface.getEvent(log.topics[0]);
|
|
35
|
+
} catch (error) { }
|
|
36
|
+
if(!foundFragment) return null;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
return new EventLog(log, this.baseContract.interface, foundFragment) as unknown as TypedEventLog<T["filters"][TEventName]>;
|
|
40
|
+
} catch (error: any) { }
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toTypedEvents<TEventName extends keyof T["filters"]>(blockEvents: Log[]): (TypedEventLog<T["filters"][TEventName]> | null)[] {
|
|
46
|
+
return blockEvents.map(log => this.toTypedEvent<TEventName>(log));
|
|
28
47
|
}
|
|
29
48
|
|
|
30
49
|
private toFilter<TEventName extends keyof T["filters"]>(
|
|
@@ -83,7 +102,7 @@ export class EVMContractEvents<T extends BaseContract> extends EVMEvents {
|
|
|
83
102
|
if(result!=null) return result;
|
|
84
103
|
}
|
|
85
104
|
return null;
|
|
86
|
-
}, abortSignal, this.contract.
|
|
105
|
+
}, abortSignal, this.contract._contractDeploymentHeight);
|
|
87
106
|
}
|
|
88
107
|
|
|
89
108
|
/**
|
|
@@ -111,7 +130,7 @@ export class EVMContractEvents<T extends BaseContract> extends EVMEvents {
|
|
|
111
130
|
if(result!=null) return result;
|
|
112
131
|
}
|
|
113
132
|
return null;
|
|
114
|
-
}, abortSignal, Math.max(this.contract.
|
|
133
|
+
}, abortSignal, Math.max(this.contract._contractDeploymentHeight ?? 0, startHeight ?? 0));
|
|
115
134
|
}
|
|
116
135
|
|
|
117
136
|
}
|
|
@@ -6,6 +6,11 @@ import {EVMSwapContract} from "../swaps/EVMSwapContract";
|
|
|
6
6
|
import {EVMSpvVaultContract} from "../spv_swap/EVMSpvVaultContract";
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Backend event listener with persisted polling cursor stored on filesystem.
|
|
11
|
+
*
|
|
12
|
+
* @category Events
|
|
13
|
+
*/
|
|
9
14
|
export class EVMChainEvents extends EVMChainEventsBrowser {
|
|
10
15
|
|
|
11
16
|
private readonly directory: string;
|
|
@@ -77,6 +82,9 @@ export class EVMChainEvents extends EVMChainEventsBrowser {
|
|
|
77
82
|
}).join(";"));
|
|
78
83
|
}
|
|
79
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @inheritDoc
|
|
87
|
+
*/
|
|
80
88
|
async init(noAutomaticPoll?: boolean): Promise<void> {
|
|
81
89
|
if(noAutomaticPoll) return Promise.resolve();
|
|
82
90
|
this.stopped = false;
|
|
@@ -24,6 +24,12 @@ const LOGS_SLIDING_WINDOW_LENGTH = 60;
|
|
|
24
24
|
|
|
25
25
|
const PROCESSED_EVENTS_BACKLOG = 1000;
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Current state of the EVM event listener, containing the last processed block number
|
|
29
|
+
* and event position.
|
|
30
|
+
*
|
|
31
|
+
* @category Events
|
|
32
|
+
*/
|
|
27
33
|
export type EVMEventListenerState = {lastBlockNumber: number, lastEvent?: {blockHash: string, logIndex: number}} | null;
|
|
28
34
|
|
|
29
35
|
type AtomiqTypedEvent = (
|
|
@@ -35,6 +41,8 @@ type AtomiqTypedEvent = (
|
|
|
35
41
|
* EVM on-chain event handler for front-end systems without access to fs, uses WS or long-polling to subscribe, might lose
|
|
36
42
|
* out on some events if the network is unreliable, front-end systems should take this into consideration and not
|
|
37
43
|
* rely purely on events
|
|
44
|
+
*
|
|
45
|
+
* @category Events
|
|
38
46
|
*/
|
|
39
47
|
export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventListenerState[]> {
|
|
40
48
|
|
|
@@ -44,23 +52,59 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
44
52
|
private processedEvents: string[] = [];
|
|
45
53
|
private processedEventsIndex: number = 0;
|
|
46
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
47
58
|
protected readonly listeners: EventListener<EVMSwapData>[] = [];
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
48
62
|
protected readonly provider: JsonRpcApiProvider;
|
|
63
|
+
/**
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
49
66
|
protected readonly chainInterface: EVMChainInterface;
|
|
67
|
+
/**
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
50
70
|
protected readonly evmSwapContract: EVMSwapContract;
|
|
71
|
+
/**
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
51
74
|
protected readonly evmSpvVaultContract: EVMSpvVaultContract<any>;
|
|
75
|
+
/**
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
52
78
|
protected readonly logger = getLogger("EVMChainEventsBrowser: ");
|
|
53
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
54
83
|
protected stopped: boolean = true;
|
|
84
|
+
/**
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
55
87
|
protected pollIntervalSeconds: number;
|
|
56
88
|
|
|
57
89
|
private timeout?: any;
|
|
58
90
|
|
|
59
91
|
//Websocket
|
|
92
|
+
/**
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
60
95
|
protected readonly spvVaultContractLogFilter: EventFilter;
|
|
96
|
+
/**
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
61
99
|
protected readonly swapContractLogFilter: EventFilter;
|
|
62
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
63
104
|
protected unconfirmedEventQueue: AtomiqTypedEvent[] = [];
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
64
108
|
protected confirmedEventQueue: {event: AtomiqTypedEvent, block: Block}[] = [];
|
|
65
109
|
|
|
66
110
|
constructor(
|
|
@@ -76,10 +120,10 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
76
120
|
this.pollIntervalSeconds = pollIntervalSeconds;
|
|
77
121
|
|
|
78
122
|
this.spvVaultContractLogFilter = {
|
|
79
|
-
address: this.evmSpvVaultContract.
|
|
123
|
+
address: this.evmSpvVaultContract._contractAddress
|
|
80
124
|
};
|
|
81
125
|
this.swapContractLogFilter = {
|
|
82
|
-
address: this.evmSwapContract.
|
|
126
|
+
address: this.evmSwapContract._contractAddress
|
|
83
127
|
};
|
|
84
128
|
}
|
|
85
129
|
|
|
@@ -112,12 +156,12 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
112
156
|
}
|
|
113
157
|
}
|
|
114
158
|
|
|
115
|
-
|
|
159
|
+
private parseInitializeEvent(
|
|
116
160
|
event: TypedEventLog<EscrowManager["filters"]["Initialize"]>
|
|
117
161
|
): InitializeEvent<EVMSwapData> | null {
|
|
118
162
|
const escrowHash = event.args.escrowHash.substring(2);
|
|
119
163
|
const claimHandlerHex = event.args.claimHandler;
|
|
120
|
-
const claimHandler = this.evmSwapContract.
|
|
164
|
+
const claimHandler = this.evmSwapContract._claimHandlersByAddress[claimHandlerHex.toLowerCase()];
|
|
121
165
|
if(claimHandler==null) {
|
|
122
166
|
this.logger.warn("parseInitializeEvent("+escrowHash+"): Unknown claim handler with claim: "+claimHandlerHex);
|
|
123
167
|
return null;
|
|
@@ -132,7 +176,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
132
176
|
);
|
|
133
177
|
}
|
|
134
178
|
|
|
135
|
-
|
|
179
|
+
private parseRefundEvent(
|
|
136
180
|
event: TypedEventLog<EscrowManager["filters"]["Refund"]>
|
|
137
181
|
): RefundEvent<EVMSwapData> {
|
|
138
182
|
const escrowHash = event.args.escrowHash.substring(2);
|
|
@@ -140,12 +184,12 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
140
184
|
return new RefundEvent<EVMSwapData>(escrowHash);
|
|
141
185
|
}
|
|
142
186
|
|
|
143
|
-
|
|
187
|
+
private parseClaimEvent(
|
|
144
188
|
event: TypedEventLog<EscrowManager["filters"]["Claim"]>
|
|
145
189
|
): ClaimEvent<EVMSwapData> | null {
|
|
146
190
|
const escrowHash = event.args.escrowHash.substring(2);
|
|
147
191
|
const claimHandlerHex = event.args.claimHandler;
|
|
148
|
-
const claimHandler = this.evmSwapContract.
|
|
192
|
+
const claimHandler = this.evmSwapContract._claimHandlersByAddress[claimHandlerHex.toLowerCase()];
|
|
149
193
|
if(claimHandler==null) {
|
|
150
194
|
this.logger.warn("parseClaimEvent("+escrowHash+"): Unknown claim handler with claim: "+claimHandlerHex);
|
|
151
195
|
return null;
|
|
@@ -155,7 +199,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
155
199
|
return new ClaimEvent<EVMSwapData>(escrowHash, witnessResult);
|
|
156
200
|
}
|
|
157
201
|
|
|
158
|
-
|
|
202
|
+
private parseSpvOpenEvent(
|
|
159
203
|
event: TypedEventLog<SpvVaultManager["filters"]["Opened"]>
|
|
160
204
|
): SpvVaultOpenEvent {
|
|
161
205
|
const owner = event.args.owner;
|
|
@@ -167,7 +211,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
167
211
|
return new SpvVaultOpenEvent(owner, vaultId, btcTxId, vout);
|
|
168
212
|
}
|
|
169
213
|
|
|
170
|
-
|
|
214
|
+
private parseSpvDepositEvent(
|
|
171
215
|
event: TypedEventLog<SpvVaultManager["filters"]["Deposited"]>
|
|
172
216
|
): SpvVaultDepositEvent {
|
|
173
217
|
const [owner, vaultId] = unpackOwnerAndVaultId(event.args.ownerAndVaultId);
|
|
@@ -178,7 +222,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
178
222
|
return new SpvVaultDepositEvent(owner, vaultId, amounts, depositCount);
|
|
179
223
|
}
|
|
180
224
|
|
|
181
|
-
|
|
225
|
+
private parseSpvFrontEvent(
|
|
182
226
|
event: TypedEventLog<SpvVaultManager["filters"]["Fronted"]>
|
|
183
227
|
): SpvVaultFrontEvent {
|
|
184
228
|
const [owner, vaultId] = unpackOwnerAndVaultId(event.args.ownerAndVaultId);
|
|
@@ -193,7 +237,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
193
237
|
return new SpvVaultFrontEvent(owner, vaultId, btcTxId, recipient, executionHash, amounts, frontingAddress);
|
|
194
238
|
}
|
|
195
239
|
|
|
196
|
-
|
|
240
|
+
private parseSpvClaimEvent(
|
|
197
241
|
event: TypedEventLog<SpvVaultManager["filters"]["Claimed"]>
|
|
198
242
|
): SpvVaultClaimEvent {
|
|
199
243
|
const [owner, vaultId] = unpackOwnerAndVaultId(event.args.ownerAndVaultId);
|
|
@@ -211,7 +255,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
211
255
|
return new SpvVaultClaimEvent(owner, vaultId, btcTxId, recipient, executionHash, amounts, caller, frontingAddress, withdrawCount);
|
|
212
256
|
}
|
|
213
257
|
|
|
214
|
-
|
|
258
|
+
private parseSpvCloseEvent(
|
|
215
259
|
event: TypedEventLog<SpvVaultManager["filters"]["Closed"]>
|
|
216
260
|
): SpvVaultCloseEvent {
|
|
217
261
|
const btcTxId = Buffer.from(event.args.btcTxHash.substring(2), "hex").reverse().toString("hex");
|
|
@@ -226,7 +270,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
226
270
|
* @param currentBlock
|
|
227
271
|
* @protected
|
|
228
272
|
*/
|
|
229
|
-
|
|
273
|
+
private async processEvents(
|
|
230
274
|
events : (
|
|
231
275
|
TypedEventLog<EscrowManager["filters"]["Initialize" | "Refund" | "Claim"]> |
|
|
232
276
|
TypedEventLog<SpvVaultManager["filters"]["Opened" | "Deposited" | "Fronted" | "Claimed" | "Closed"]>
|
|
@@ -300,7 +344,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
300
344
|
}
|
|
301
345
|
}
|
|
302
346
|
|
|
303
|
-
|
|
347
|
+
private async checkEventsEcrowManager(
|
|
304
348
|
currentBlock: Block,
|
|
305
349
|
lastEvent?: {blockHash: string, logIndex: number},
|
|
306
350
|
lastBlockNumber?: number
|
|
@@ -311,7 +355,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
311
355
|
return {lastEvent, lastBlockNumber};
|
|
312
356
|
}
|
|
313
357
|
// this.logger.debug(`checkEvents(EscrowManager): Requesting logs: ${lastBlockNumber}...${currentBlock.number}`);
|
|
314
|
-
let events = await this.evmSwapContract.
|
|
358
|
+
let events = await this.evmSwapContract._Events.getContractBlockEvents(
|
|
315
359
|
["Initialize", "Claim", "Refund"],
|
|
316
360
|
[],
|
|
317
361
|
lastBlockNumber,
|
|
@@ -341,7 +385,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
341
385
|
return {lastEvent, lastBlockNumber};
|
|
342
386
|
}
|
|
343
387
|
|
|
344
|
-
|
|
388
|
+
private async checkEventsSpvVaults(
|
|
345
389
|
currentBlock: Block,
|
|
346
390
|
lastEvent?: {blockHash: string, logIndex: number},
|
|
347
391
|
lastBlockNumber?: number
|
|
@@ -352,7 +396,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
352
396
|
return {lastEvent, lastBlockNumber};
|
|
353
397
|
}
|
|
354
398
|
// this.logger.debug(`checkEvents(SpvVaults): Requesting logs: ${lastBlockNumber}...${currentBlock.number}`);
|
|
355
|
-
let events = await this.evmSpvVaultContract.
|
|
399
|
+
let events = await this.evmSpvVaultContract._Events.getContractBlockEvents(
|
|
356
400
|
["Opened", "Deposited", "Closed", "Fronted", "Claimed"],
|
|
357
401
|
[],
|
|
358
402
|
lastBlockNumber,
|
|
@@ -388,8 +432,8 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
388
432
|
async poll(lastState?: EVMEventListenerState[]): Promise<EVMEventListenerState[]> {
|
|
389
433
|
lastState ??= [];
|
|
390
434
|
|
|
391
|
-
const currentBlock = await this.provider.getBlock(this.chainInterface.
|
|
392
|
-
if(currentBlock==null) throw new Error(`Cannot fetch '${this.chainInterface.
|
|
435
|
+
const currentBlock = await this.provider.getBlock(this.chainInterface._config.safeBlockTag, false);
|
|
436
|
+
if(currentBlock==null) throw new Error(`Cannot fetch '${this.chainInterface._config.safeBlockTag}' block!`);
|
|
393
437
|
|
|
394
438
|
const resultEscrow = await this.checkEventsEcrowManager(currentBlock, lastState?.[0]?.lastEvent, lastState?.[0]?.lastBlockNumber);
|
|
395
439
|
const resultSpvVault = await this.checkEventsSpvVaults(currentBlock, lastState?.[1]?.lastEvent, lastState?.[1]?.lastBlockNumber);
|
|
@@ -405,7 +449,7 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
405
449
|
/**
|
|
406
450
|
* Sets up event handlers listening for swap events over websocket
|
|
407
451
|
*
|
|
408
|
-
* @
|
|
452
|
+
* @internal
|
|
409
453
|
*/
|
|
410
454
|
protected async setupPoll(
|
|
411
455
|
lastState?: EVMEventListenerState[],
|
|
@@ -428,26 +472,47 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
428
472
|
|
|
429
473
|
//Websocket
|
|
430
474
|
|
|
475
|
+
/**
|
|
476
|
+
* @internal
|
|
477
|
+
*/
|
|
431
478
|
protected handleWsEvent(
|
|
432
479
|
event: AtomiqTypedEvent
|
|
433
480
|
): Promise<void> {
|
|
434
|
-
if(this.chainInterface.
|
|
481
|
+
if(this.chainInterface._config.safeBlockTag==="latest" || this.chainInterface._config.safeBlockTag==="pending") {
|
|
435
482
|
return this.processEvents([event]);
|
|
436
483
|
}
|
|
437
484
|
this.unconfirmedEventQueue.push(event);
|
|
438
485
|
return this.addOrRemoveBlockListener();
|
|
439
486
|
}
|
|
440
487
|
|
|
488
|
+
/**
|
|
489
|
+
* @internal
|
|
490
|
+
*/
|
|
441
491
|
protected spvVaultContractListener?: (log: Log) => void;
|
|
492
|
+
/**
|
|
493
|
+
* @internal
|
|
494
|
+
*/
|
|
442
495
|
protected swapContractListener?: (log: Log) => void;
|
|
496
|
+
/**
|
|
497
|
+
* @internal
|
|
498
|
+
*/
|
|
443
499
|
protected blockListener?: (blockNumber: number) => Promise<void>;
|
|
500
|
+
/**
|
|
501
|
+
* @internal
|
|
502
|
+
*/
|
|
444
503
|
protected finalityCheckTimer: any;
|
|
504
|
+
/**
|
|
505
|
+
* @internal
|
|
506
|
+
*/
|
|
445
507
|
protected wsStarted: boolean = false;
|
|
446
508
|
|
|
509
|
+
/**
|
|
510
|
+
* @internal
|
|
511
|
+
*/
|
|
447
512
|
protected async checkUnconfirmedEventsFinality() {
|
|
448
513
|
if(this.unconfirmedEventQueue.length>0) {
|
|
449
|
-
const latestSafeBlock = await this.provider.getBlock(this.chainInterface.
|
|
450
|
-
if(latestSafeBlock==null) throw new Error(`Failed to fetch '${this.chainInterface.
|
|
514
|
+
const latestSafeBlock = await this.provider.getBlock(this.chainInterface._config.safeBlockTag);
|
|
515
|
+
if(latestSafeBlock==null) throw new Error(`Failed to fetch '${this.chainInterface._config.safeBlockTag}' block!`);
|
|
451
516
|
|
|
452
517
|
const events = this.unconfirmedEventQueue.filter(event => {
|
|
453
518
|
return event.blockNumber <= latestSafeBlock.number;
|
|
@@ -473,8 +538,11 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
473
538
|
}
|
|
474
539
|
}
|
|
475
540
|
|
|
541
|
+
/**
|
|
542
|
+
* @internal
|
|
543
|
+
*/
|
|
476
544
|
protected async addOrRemoveBlockListener() {
|
|
477
|
-
if(this.chainInterface.
|
|
545
|
+
if(this.chainInterface._config.finalityCheckStrategy?.type!=="blocks") return;
|
|
478
546
|
if(this.unconfirmedEventQueue.length>0 || this.confirmedEventQueue.length>0) {
|
|
479
547
|
this.logger.debug(`addOrRemoveBlockListener(): Adding block listener, unconfirmed/confirmed event count: ${this.unconfirmedEventQueue.length + this.confirmedEventQueue.length}`);
|
|
480
548
|
await this.provider.on("block", this.blockListener!);
|
|
@@ -484,6 +552,9 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
484
552
|
}
|
|
485
553
|
}
|
|
486
554
|
|
|
555
|
+
/**
|
|
556
|
+
* @internal
|
|
557
|
+
*/
|
|
487
558
|
protected async startFinalityCheckTimer() {
|
|
488
559
|
let check: () => Promise<void>;
|
|
489
560
|
check = async () => {
|
|
@@ -496,11 +567,14 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
496
567
|
}
|
|
497
568
|
}
|
|
498
569
|
if(!this.wsStarted) return;
|
|
499
|
-
this.finalityCheckTimer = setTimeout(check, this.chainInterface.
|
|
570
|
+
this.finalityCheckTimer = setTimeout(check, this.chainInterface._config.finalityCheckStrategy?.delayMs ?? 5*1000);
|
|
500
571
|
};
|
|
501
572
|
await check();
|
|
502
573
|
}
|
|
503
574
|
|
|
575
|
+
/**
|
|
576
|
+
* @internal
|
|
577
|
+
*/
|
|
504
578
|
protected async setupWebsocket() {
|
|
505
579
|
this.wsStarted = true;
|
|
506
580
|
|
|
@@ -518,18 +592,18 @@ export class EVMChainEventsBrowser implements ChainEvents<EVMSwapData, EVMEventL
|
|
|
518
592
|
await this.addOrRemoveBlockListener();
|
|
519
593
|
}
|
|
520
594
|
|
|
521
|
-
if(this.chainInterface.
|
|
522
|
-
if(this.chainInterface.
|
|
595
|
+
if(this.chainInterface._config.safeBlockTag==="safe" || this.chainInterface._config.safeBlockTag==="finalized") {
|
|
596
|
+
if(this.chainInterface._config.finalityCheckStrategy?.type==="timer") this.startFinalityCheckTimer();
|
|
523
597
|
}
|
|
524
598
|
|
|
525
599
|
await this.provider.on(this.spvVaultContractLogFilter, this.spvVaultContractListener = (log) => {
|
|
526
|
-
let [event] = this.evmSpvVaultContract.
|
|
600
|
+
let [event] = this.evmSpvVaultContract._Events.toTypedEvents([log]);
|
|
527
601
|
if(event==null || event.removed) return;
|
|
528
602
|
this.handleWsEvent(event);
|
|
529
603
|
});
|
|
530
604
|
|
|
531
605
|
await this.provider.on(this.swapContractLogFilter, this.swapContractListener = (log) => {
|
|
532
|
-
let [event] = this.evmSwapContract.
|
|
606
|
+
let [event] = this.evmSwapContract._Events.toTypedEvents([log]);
|
|
533
607
|
if(event==null || event.removed) return;
|
|
534
608
|
if(event.eventName!=="Initialize" && event.eventName!=="Refund" && event.eventName!=="Claim") return;
|
|
535
609
|
this.handleWsEvent(event);
|