@atomiqlabs/chain-evm 2.1.12 → 2.1.14
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 +57 -2
- package/dist/evm/chain/EVMChainInterface.js +7 -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 +20 -2
- package/dist/evm/chain/modules/EVMTransactions.js +11 -8
- 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 +4 -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 +66 -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 +27 -8
- 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
|
@@ -3,7 +3,12 @@ import {EVMBtcHeader, EVMBtcHeaderType} from "./EVMBtcHeader";
|
|
|
3
3
|
import {Buffer} from "buffer";
|
|
4
4
|
import {keccak256} from "ethers";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Constructor payload for a stored bitcoin header committed in EVM BTC relay contract state.
|
|
8
|
+
*
|
|
9
|
+
* @category BTC Relay
|
|
10
|
+
*/
|
|
11
|
+
export type EVMBtcStoredHeaderType = {
|
|
7
12
|
blockheader: EVMBtcHeader | EVMBtcHeaderType,
|
|
8
13
|
blockHash: Buffer,
|
|
9
14
|
chainWork: bigint,
|
|
@@ -13,18 +18,23 @@ export type StarknetBtcStoredHeaderType = {
|
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
/**
|
|
21
|
+
* Represents a bitcoin header already committed inside EVM BTC relay contract state.
|
|
22
|
+
*
|
|
16
23
|
* @category BTC Relay
|
|
17
24
|
*/
|
|
18
25
|
export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
19
26
|
|
|
20
|
-
blockheader: EVMBtcHeader;
|
|
21
|
-
blockHash: Buffer;
|
|
22
|
-
chainWork: bigint;
|
|
23
|
-
blockHeight: number;
|
|
24
|
-
lastDiffAdjustment: number;
|
|
25
|
-
prevBlockTimestamps: number[];
|
|
27
|
+
private readonly blockheader: EVMBtcHeader;
|
|
28
|
+
private readonly blockHash: Buffer;
|
|
29
|
+
private readonly chainWork: bigint;
|
|
30
|
+
private readonly blockHeight: number;
|
|
31
|
+
private readonly lastDiffAdjustment: number;
|
|
32
|
+
private readonly prevBlockTimestamps: number[];
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
constructor(obj: EVMBtcStoredHeaderType) {
|
|
28
38
|
this.blockheader = obj.blockheader instanceof EVMBtcHeader ? obj.blockheader : new EVMBtcHeader(obj.blockheader);
|
|
29
39
|
this.blockHash = obj.blockHash;
|
|
30
40
|
this.chainWork = obj.chainWork;
|
|
@@ -33,26 +43,44 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
33
43
|
this.prevBlockTimestamps = obj.prevBlockTimestamps;
|
|
34
44
|
}
|
|
35
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @inheritDoc
|
|
48
|
+
*/
|
|
36
49
|
getBlockheight(): number {
|
|
37
50
|
return this.blockHeight;
|
|
38
51
|
}
|
|
39
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @inheritDoc
|
|
55
|
+
*/
|
|
40
56
|
getChainWork(): Buffer {
|
|
41
57
|
return Buffer.from(this.chainWork.toString(16).padStart(64, "0"), "hex");
|
|
42
58
|
}
|
|
43
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @inheritDoc
|
|
62
|
+
*/
|
|
44
63
|
getHeader(): EVMBtcHeader {
|
|
45
64
|
return this.blockheader;
|
|
46
65
|
}
|
|
47
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @inheritDoc
|
|
69
|
+
*/
|
|
48
70
|
getLastDiffAdjustment(): number {
|
|
49
71
|
return this.lastDiffAdjustment;
|
|
50
72
|
}
|
|
51
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @inheritDoc
|
|
76
|
+
*/
|
|
52
77
|
getPrevBlockTimestamps(): number[] {
|
|
53
78
|
return this.prevBlockTimestamps;
|
|
54
79
|
}
|
|
55
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @inheritDoc
|
|
83
|
+
*/
|
|
56
84
|
getBlockHash(): Buffer {
|
|
57
85
|
return Buffer.from([...this.blockHash]).reverse();
|
|
58
86
|
}
|
|
@@ -99,8 +127,11 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
99
127
|
return lastDiffAdjustment;
|
|
100
128
|
}
|
|
101
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @inheritDoc
|
|
132
|
+
*/
|
|
102
133
|
computeNext(header: EVMBtcHeader): EVMBtcStoredHeader {
|
|
103
|
-
header.
|
|
134
|
+
header._previousBlockhash = this.blockHash;
|
|
104
135
|
return new EVMBtcStoredHeader({
|
|
105
136
|
chainWork: this.computeNextChainWork(header.getNbits()),
|
|
106
137
|
prevBlockTimestamps: this.computeNextBlockTimestamps(),
|
|
@@ -111,10 +142,16 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
111
142
|
});
|
|
112
143
|
}
|
|
113
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Returns the commitment of this stored head (keccak256 hash), this is what's actually stored on-chain
|
|
147
|
+
*/
|
|
114
148
|
getCommitHash(): string {
|
|
115
149
|
return keccak256(this.serialize());
|
|
116
150
|
}
|
|
117
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Serializes the stored blockheader into the 160-byte binary layout used by the EVM contracts.
|
|
154
|
+
*/
|
|
118
155
|
serialize(): Buffer {
|
|
119
156
|
const buffer = Buffer.alloc(160);
|
|
120
157
|
this.blockheader.serialize().copy(buffer, 0, 0, 80);
|
|
@@ -127,6 +164,9 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
127
164
|
return buffer;
|
|
128
165
|
}
|
|
129
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Serializes the stored blockheader into the contract tuple form (`bytes32[5]` payload).
|
|
169
|
+
*/
|
|
130
170
|
serializeToStruct(): {data: [string, string, string, string, string]} {
|
|
131
171
|
const buffer = this.serialize();
|
|
132
172
|
const result: string[] = [];
|
|
@@ -136,6 +176,11 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
136
176
|
return {data: result as any};
|
|
137
177
|
}
|
|
138
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Deserializes a stored blockheader from the 160-byte binary representation.
|
|
181
|
+
*
|
|
182
|
+
* @param data Serialized stored blockheader bytes
|
|
183
|
+
*/
|
|
139
184
|
static deserialize(data: Buffer): EVMBtcStoredHeader {
|
|
140
185
|
if(data.length!==160) throw new Error(`Invalid size Expected 160, got: ${data.length}!`);
|
|
141
186
|
const blockheader = EVMBtcHeader.deserialize(data.subarray(0, 80));
|
|
@@ -153,4 +198,4 @@ export class EVMBtcStoredHeader implements BtcStoredHeader<EVMBtcHeader> {
|
|
|
153
198
|
});
|
|
154
199
|
}
|
|
155
200
|
|
|
156
|
-
}
|
|
201
|
+
}
|
|
@@ -25,8 +25,17 @@ import {EVMBrowserSigner} from "../wallet/EVMBrowserSigner";
|
|
|
25
25
|
* @category Chain Interface
|
|
26
26
|
*/
|
|
27
27
|
export type EVMRetryPolicy = {
|
|
28
|
+
/**
|
|
29
|
+
* Maximum retries to be attempted
|
|
30
|
+
*/
|
|
28
31
|
maxRetries?: number,
|
|
32
|
+
/**
|
|
33
|
+
* Default delay between retries
|
|
34
|
+
*/
|
|
29
35
|
delay?: number,
|
|
36
|
+
/**
|
|
37
|
+
* Whether the delays should scale exponentially, i.e. 1 second, 2 seconds, 4 seconds, 8 seconds
|
|
38
|
+
*/
|
|
30
39
|
exponential?: boolean
|
|
31
40
|
}
|
|
32
41
|
|
|
@@ -35,18 +44,55 @@ export type EVMRetryPolicy = {
|
|
|
35
44
|
* @category Chain Interface
|
|
36
45
|
*/
|
|
37
46
|
export type EVMConfiguration = {
|
|
47
|
+
/**
|
|
48
|
+
* EVM Block tag to be considered safe for financial application, i.e. sending assets on different blockchains
|
|
49
|
+
*/
|
|
38
50
|
safeBlockTag: EVMBlockTag,
|
|
51
|
+
/**
|
|
52
|
+
* EVM Block tag to be considered finalized, i.e. the state definitely cannot revert after the blocks gets
|
|
53
|
+
* this level of finality
|
|
54
|
+
*/
|
|
39
55
|
finalizedBlockTag: EVMBlockTag,
|
|
56
|
+
/**
|
|
57
|
+
* Maximum range of blocks to query when querying `ethereum_getLogs` RPC endpoint.
|
|
58
|
+
*/
|
|
40
59
|
maxLogsBlockRange: number,
|
|
60
|
+
/**
|
|
61
|
+
* Maximum number of `ethereum_getLogs` RPC calls to be executed in parallel
|
|
62
|
+
*/
|
|
41
63
|
maxParallelLogRequests: number,
|
|
64
|
+
/**
|
|
65
|
+
* Maximum number of parallel contract calls to execute in batch functions
|
|
66
|
+
*/
|
|
42
67
|
maxParallelCalls: number,
|
|
68
|
+
/**
|
|
69
|
+
* Maximum number of topics specified in the `ethereum_getLogs` RPC call
|
|
70
|
+
*/
|
|
43
71
|
maxLogTopics: number,
|
|
44
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Whether to use EIP-2930 access lists for transactions, if set to `true` the transaction is simulated before
|
|
75
|
+
* sending and the access list is populated for the transaction
|
|
76
|
+
*/
|
|
45
77
|
useAccessLists?: boolean,
|
|
78
|
+
/**
|
|
79
|
+
* Default EIP-2930 addresses to add when simulating the transaction initially
|
|
80
|
+
*/
|
|
46
81
|
defaultAccessListAddresses?: string[],
|
|
47
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Strategy for checking finality of transactions or events
|
|
85
|
+
*/
|
|
48
86
|
finalityCheckStrategy?: {
|
|
87
|
+
/**
|
|
88
|
+
* Type of the finality checking strategy:
|
|
89
|
+
* - `"timer"` - periodically checks for the finality status, set the interval period `delayMs`
|
|
90
|
+
* - `"blocks"` - check for the finality when new block is created
|
|
91
|
+
*/
|
|
49
92
|
type: "timer" | "blocks"
|
|
93
|
+
/**
|
|
94
|
+
* Interval in milliseconds to use for the `"timer"` type of finality checking strategy
|
|
95
|
+
*/
|
|
50
96
|
delayMs?: number
|
|
51
97
|
}
|
|
52
98
|
};
|
|
@@ -57,14 +103,18 @@ export type EVMConfiguration = {
|
|
|
57
103
|
*/
|
|
58
104
|
export class EVMChainInterface<ChainId extends string = string> implements ChainInterface<EVMTx, SignedEVMTx, EVMSigner, ChainId, Signer> {
|
|
59
105
|
|
|
60
|
-
readonly chainId: ChainId;
|
|
61
|
-
|
|
62
|
-
readonly provider: JsonRpcApiProvider;
|
|
63
|
-
readonly retryPolicy?: EVMRetryPolicy;
|
|
64
|
-
|
|
106
|
+
public readonly chainId: ChainId;
|
|
107
|
+
public readonly provider: JsonRpcApiProvider;
|
|
65
108
|
public readonly evmChainId: number;
|
|
66
109
|
|
|
67
|
-
|
|
110
|
+
/**
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
readonly _retryPolicy?: EVMRetryPolicy;
|
|
114
|
+
/**
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
readonly _config: EVMConfiguration;
|
|
68
118
|
|
|
69
119
|
public Fees: EVMFees;
|
|
70
120
|
public Tokens: EVMTokens;
|
|
@@ -73,6 +123,9 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
73
123
|
public Events: EVMEvents;
|
|
74
124
|
public Blocks: EVMBlocks;
|
|
75
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
76
129
|
protected logger: LoggerType;
|
|
77
130
|
|
|
78
131
|
constructor(
|
|
@@ -86,12 +139,12 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
86
139
|
this.chainId = chainId;
|
|
87
140
|
this.evmChainId = evmChainId;
|
|
88
141
|
this.provider = provider;
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
142
|
+
this._retryPolicy = retryPolicy;
|
|
143
|
+
this._config = config;
|
|
144
|
+
this._config.safeBlockTag ??= "safe";
|
|
145
|
+
this._config.finalizedBlockTag ??= "finalized";
|
|
146
|
+
this._config.finalityCheckStrategy ??= {type: "timer"};
|
|
147
|
+
this._config.finalityCheckStrategy.delayMs ??= 1000;
|
|
95
148
|
|
|
96
149
|
this.logger = getLogger("EVMChainInterface("+this.evmChainId+"): ");
|
|
97
150
|
|
|
@@ -103,7 +156,6 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
103
156
|
this.Blocks = new EVMBlocks(this);
|
|
104
157
|
}
|
|
105
158
|
|
|
106
|
-
|
|
107
159
|
/**
|
|
108
160
|
* @inheritDoc
|
|
109
161
|
*/
|
|
@@ -258,7 +310,7 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
258
310
|
* @inheritDoc
|
|
259
311
|
*/
|
|
260
312
|
async getFinalizedBlock(): Promise<{ height: number; blockHash: string }> {
|
|
261
|
-
const block = await this.Blocks.getBlock(this.
|
|
313
|
+
const block = await this.Blocks.getBlock(this._config.finalizedBlockTag);
|
|
262
314
|
return {
|
|
263
315
|
height: block.number,
|
|
264
316
|
blockHash: block.hash!
|
|
@@ -2,6 +2,11 @@ import {getLogger} from "../../utils/Utils";
|
|
|
2
2
|
import {JsonRpcApiProvider} from "ethers";
|
|
3
3
|
import {EVMChainInterface, EVMRetryPolicy} from "./EVMChainInterface";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Base module class shared by EVM chain submodules.
|
|
7
|
+
*
|
|
8
|
+
* @category Internal/Chain
|
|
9
|
+
*/
|
|
5
10
|
export class EVMModule<ChainId extends string = string> {
|
|
6
11
|
|
|
7
12
|
protected readonly provider: JsonRpcApiProvider;
|
|
@@ -14,7 +19,7 @@ export class EVMModule<ChainId extends string = string> {
|
|
|
14
19
|
root: EVMChainInterface<ChainId>
|
|
15
20
|
) {
|
|
16
21
|
this.provider = root.provider;
|
|
17
|
-
this.retryPolicy = root.
|
|
22
|
+
this.retryPolicy = root._retryPolicy;
|
|
18
23
|
this.root = root;
|
|
19
24
|
}
|
|
20
25
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import {EVMModule} from "../EVMModule";
|
|
2
2
|
import {Block} from "ethers";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Supported EVM block tags used for safety/finality aware reads.
|
|
6
|
+
*
|
|
7
|
+
* @category Chain Interface
|
|
8
|
+
*/
|
|
4
9
|
export type EVMBlockTag = "safe" | "pending" | "latest" | "finalized";
|
|
5
10
|
|
|
6
11
|
/**
|
|
12
|
+
* Cached block lookup helper for block and timestamp access.
|
|
13
|
+
*
|
|
7
14
|
* @category Internal/Chain
|
|
8
15
|
*/
|
|
9
16
|
export class EVMBlocks extends EVMModule<any> {
|
|
@@ -68,24 +68,24 @@ export class EVMEvents extends EVMModule<any> {
|
|
|
68
68
|
events = await this.root.provider.getLogs({
|
|
69
69
|
address: contract,
|
|
70
70
|
fromBlock: startBlock,
|
|
71
|
-
toBlock: endBlock==null ? this.root.
|
|
71
|
+
toBlock: endBlock==null ? this.root._config.safeBlockTag : endBlock,
|
|
72
72
|
topics
|
|
73
73
|
});
|
|
74
74
|
} else if(endBlock==null) {
|
|
75
|
-
const safeBlock = await this.root.provider.getBlock(this.root.
|
|
76
|
-
if(safeBlock==null) throw new Error(`Cannot retrieve '${this.root.
|
|
77
|
-
if(safeBlock.number - startBlock > this.root.
|
|
78
|
-
for(let i = startBlock + this.root.
|
|
79
|
-
events.push(...await this.getLogs(contract, topics, i - this.root.
|
|
75
|
+
const safeBlock = await this.root.provider.getBlock(this.root._config.safeBlockTag);
|
|
76
|
+
if(safeBlock==null) throw new Error(`Cannot retrieve '${this.root._config.safeBlockTag}' block`);
|
|
77
|
+
if(safeBlock.number - startBlock > this.root._config.maxLogsBlockRange) {
|
|
78
|
+
for(let i = startBlock + this.root._config.maxLogsBlockRange; i < safeBlock.number; i += this.root._config.maxLogsBlockRange) {
|
|
79
|
+
events.push(...await this.getLogs(contract, topics, i - this.root._config.maxLogsBlockRange, i));
|
|
80
80
|
startBlock = i;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
events.push(...await this.getLogs(contract, topics, startBlock, safeBlock.number));
|
|
84
84
|
} else {
|
|
85
85
|
//Both numeric
|
|
86
|
-
if(endBlock - startBlock > this.root.
|
|
87
|
-
for(let i = startBlock + this.root.
|
|
88
|
-
events.push(...await this.getLogs(contract, topics, i - this.root.
|
|
86
|
+
if(endBlock - startBlock > this.root._config.maxLogsBlockRange) {
|
|
87
|
+
for(let i = startBlock + this.root._config.maxLogsBlockRange; i < endBlock; i += this.root._config.maxLogsBlockRange) {
|
|
88
|
+
events.push(...await this.getLogs(contract, topics, i - this.root._config.maxLogsBlockRange, i));
|
|
89
89
|
startBlock = i;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -111,19 +111,19 @@ export class EVMEvents extends EVMModule<any> {
|
|
|
111
111
|
abortSignal?: AbortSignal,
|
|
112
112
|
genesisHeight?: number
|
|
113
113
|
): Promise<T | null> {
|
|
114
|
-
const latestBlock = await this.provider.getBlock(this.root.
|
|
115
|
-
if(latestBlock==null) throw new Error(`Cannot find block ${this.root.
|
|
114
|
+
const latestBlock = await this.provider.getBlock(this.root._config.safeBlockTag);
|
|
115
|
+
if(latestBlock==null) throw new Error(`Cannot find block ${this.root._config.safeBlockTag}`);
|
|
116
116
|
|
|
117
117
|
let promises: Promise<Log[]>[] = [];
|
|
118
|
-
for(let blockNumber = latestBlock.number; blockNumber >= (genesisHeight ?? 0); blockNumber-=this.root.
|
|
118
|
+
for(let blockNumber = latestBlock.number; blockNumber >= (genesisHeight ?? 0); blockNumber-=this.root._config.maxLogsBlockRange) {
|
|
119
119
|
promises.push(this.getLogs(
|
|
120
120
|
contract,
|
|
121
121
|
topics,
|
|
122
|
-
Math.max(blockNumber-this.root.
|
|
122
|
+
Math.max(blockNumber-this.root._config.maxLogsBlockRange, 0),
|
|
123
123
|
blockNumber
|
|
124
124
|
));
|
|
125
125
|
|
|
126
|
-
if(promises.length>=this.root.
|
|
126
|
+
if(promises.length>=this.root._config.maxParallelLogRequests) {
|
|
127
127
|
const eventsResult = (await Promise.all(promises)).map(
|
|
128
128
|
arr => arr.reverse() //Oldest events first
|
|
129
129
|
).flat();
|
|
@@ -162,18 +162,18 @@ export class EVMEvents extends EVMModule<any> {
|
|
|
162
162
|
abortSignal?: AbortSignal,
|
|
163
163
|
startHeight?: number
|
|
164
164
|
): Promise<T | null> {
|
|
165
|
-
const latestBlock = await this.provider.getBlock(this.root.
|
|
166
|
-
if(latestBlock==null) throw new Error(`Cannot find block ${this.root.
|
|
165
|
+
const latestBlock = await this.provider.getBlock(this.root._config.safeBlockTag);
|
|
166
|
+
if(latestBlock==null) throw new Error(`Cannot find block ${this.root._config.safeBlockTag}`);
|
|
167
167
|
|
|
168
168
|
let promises: Promise<Log[]>[] = [];
|
|
169
|
-
for(let blockNumber = startHeight ?? 0; blockNumber < latestBlock.number; blockNumber += this.root.
|
|
169
|
+
for(let blockNumber = startHeight ?? 0; blockNumber < latestBlock.number; blockNumber += this.root._config.maxLogsBlockRange) {
|
|
170
170
|
promises.push(this.getLogs(
|
|
171
171
|
contract,
|
|
172
172
|
topics,
|
|
173
173
|
blockNumber,
|
|
174
|
-
Math.min(blockNumber + this.root.
|
|
174
|
+
Math.min(blockNumber + this.root._config.maxLogsBlockRange, latestBlock.number)
|
|
175
175
|
));
|
|
176
|
-
if(promises.length>=this.root.
|
|
176
|
+
if(promises.length>=this.root._config.maxParallelLogRequests) {
|
|
177
177
|
const eventsResult = (await Promise.all(promises)).flat();
|
|
178
178
|
promises = [];
|
|
179
179
|
if(abortSignal!=null) abortSignal.throwIfAborted();
|
|
@@ -1,23 +1,48 @@
|
|
|
1
1
|
import { getLogger } from "../../../utils/Utils";
|
|
2
2
|
import {JsonRpcApiProvider, TransactionRequest} from "ethers";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Parsed EIP-1559 fee rate components.
|
|
6
|
+
*
|
|
7
|
+
* @category Chain Interface
|
|
8
|
+
*/
|
|
4
9
|
export type EVMFeeRate = {
|
|
5
10
|
maxFeePerGas: bigint;
|
|
6
11
|
maxPriorityFee: bigint;
|
|
7
12
|
};
|
|
8
13
|
|
|
9
14
|
/**
|
|
15
|
+
* Fee estimation service for EVM chains.
|
|
16
|
+
*
|
|
10
17
|
* @category Chain Interface
|
|
11
18
|
*/
|
|
12
19
|
export class EVMFees {
|
|
20
|
+
/**
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
13
23
|
protected MAX_FEE_AGE = 5000;
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
15
28
|
protected readonly logger = getLogger("EVMFees: ");
|
|
16
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
17
33
|
protected readonly provider: JsonRpcApiProvider;
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
18
37
|
protected readonly maxFeeRatePerGas: bigint;
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
19
41
|
protected readonly priorityFee: bigint;
|
|
20
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
21
46
|
protected readonly feeMultiplierPPM: bigint;
|
|
22
47
|
|
|
23
48
|
private blockFeeCache?: {
|
|
@@ -25,6 +50,12 @@ export class EVMFees {
|
|
|
25
50
|
feeRate: Promise<bigint>
|
|
26
51
|
};
|
|
27
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param provider Underlying RPC provider providing read access to the EVM network
|
|
55
|
+
* @param maxFeeRatePerGas Maximum fee rate for a transaction, default to 500 GWei
|
|
56
|
+
* @param priorityFee Priority fee (or tip) to add to the transactions, default to 1 GWei
|
|
57
|
+
* @param feeMultiplier Fee multiplier to multiply the RPC-returned fee rate with
|
|
58
|
+
*/
|
|
28
59
|
constructor(
|
|
29
60
|
provider: JsonRpcApiProvider,
|
|
30
61
|
maxFeeRatePerGas: bigint = 500n * 1_000_000_000n,
|
|
@@ -55,9 +86,7 @@ export class EVMFees {
|
|
|
55
86
|
}
|
|
56
87
|
|
|
57
88
|
/**
|
|
58
|
-
* Gets the gas price with caching, format:
|
|
59
|
-
*
|
|
60
|
-
* @private
|
|
89
|
+
* Gets the gas price with caching, format: `<base fee Wei>,<priority fee Wei>`
|
|
61
90
|
*/
|
|
62
91
|
public async getFeeRate(): Promise<string> {
|
|
63
92
|
if(this.blockFeeCache==null || Date.now() - this.blockFeeCache.timestamp > this.MAX_FEE_AGE) {
|
|
@@ -87,8 +116,8 @@ export class EVMFees {
|
|
|
87
116
|
/**
|
|
88
117
|
* Calculates the total gas fee paid for a given gas limit at a given fee rate
|
|
89
118
|
*
|
|
90
|
-
* @param gas
|
|
91
|
-
* @param feeRate
|
|
119
|
+
* @param gas Gas limit to add to the transaction
|
|
120
|
+
* @param feeRate Serialized fee rate to add to the transaction, in format: `<baseFee>,<priorityFee>`
|
|
92
121
|
*/
|
|
93
122
|
public static getGasFee(gas: number, feeRate: string): bigint {
|
|
94
123
|
if(feeRate==null) return 0n;
|
|
@@ -98,6 +127,13 @@ export class EVMFees {
|
|
|
98
127
|
return BigInt(gas) * (BigInt(baseFee) + BigInt(priorityFee));
|
|
99
128
|
}
|
|
100
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Applies the gas limit and fee rate to a transaction
|
|
132
|
+
*
|
|
133
|
+
* @param tx EVM Transaction to apply the fee rate to
|
|
134
|
+
* @param gas Gas limit to add to the transaction
|
|
135
|
+
* @param feeRate Serialized fee rate to add to the transaction, in format: `<baseFee>,<priorityFee>`
|
|
136
|
+
*/
|
|
101
137
|
public static applyFeeRate(tx: TransactionRequest, gas: number | null, feeRate: string): void {
|
|
102
138
|
if(feeRate==null) return;
|
|
103
139
|
|
|
@@ -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,7 +158,8 @@ 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
164
|
* @param signer
|
|
146
165
|
* @param txs
|
|
@@ -227,7 +246,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
227
246
|
abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>,
|
|
228
247
|
useAccessLists?: boolean
|
|
229
248
|
): Promise<string[]> {
|
|
230
|
-
await this.prepareTransactions(signer, txs, useAccessLists ?? this.root.
|
|
249
|
+
await this.prepareTransactions(signer, txs, useAccessLists ?? this.root._config.useAccessLists);
|
|
231
250
|
const signedTxs: Transaction[] = [];
|
|
232
251
|
|
|
233
252
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
@@ -415,7 +434,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
415
434
|
}
|
|
416
435
|
|
|
417
436
|
/**
|
|
418
|
-
* Gets the status of
|
|
437
|
+
* Gets the status of a raw signed EVM transaction.
|
|
419
438
|
*
|
|
420
439
|
* @param tx
|
|
421
440
|
*/
|
|
@@ -435,9 +454,9 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
435
454
|
if(txResponse.blockHash==null) return "pending";
|
|
436
455
|
|
|
437
456
|
const [safeBlockNumber, txReceipt] = await Promise.all([
|
|
438
|
-
this.root.
|
|
457
|
+
this.root._config.safeBlockTag==="latest"
|
|
439
458
|
? Promise.resolve(null)
|
|
440
|
-
: this.provider.getBlock(this.root.
|
|
459
|
+
: this.provider.getBlock(this.root._config.safeBlockTag).then(res => res?.number ?? 0),
|
|
441
460
|
this.provider.getTransactionReceipt(txId)
|
|
442
461
|
]);
|
|
443
462
|
|