@atomiqlabs/chain-evm 1.0.0-dev.22
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/LICENSE +201 -0
- package/dist/chains/citrea/CitreaChainType.d.ts +13 -0
- package/dist/chains/citrea/CitreaChainType.js +2 -0
- package/dist/chains/citrea/CitreaInitializer.d.ts +30 -0
- package/dist/chains/citrea/CitreaInitializer.js +120 -0
- package/dist/evm/btcrelay/BtcRelayAbi.d.ts +198 -0
- package/dist/evm/btcrelay/BtcRelayAbi.js +261 -0
- package/dist/evm/btcrelay/BtcRelayTypechain.d.ts +172 -0
- package/dist/evm/btcrelay/BtcRelayTypechain.js +2 -0
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +188 -0
- package/dist/evm/btcrelay/EVMBtcRelay.js +419 -0
- package/dist/evm/btcrelay/headers/EVMBtcHeader.d.ts +33 -0
- package/dist/evm/btcrelay/headers/EVMBtcHeader.js +84 -0
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.d.ts +56 -0
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.js +123 -0
- package/dist/evm/chain/EVMChainInterface.d.ts +51 -0
- package/dist/evm/chain/EVMChainInterface.js +90 -0
- package/dist/evm/chain/EVMModule.d.ts +9 -0
- package/dist/evm/chain/EVMModule.js +13 -0
- package/dist/evm/chain/modules/ERC20Abi.d.ts +168 -0
- package/dist/evm/chain/modules/ERC20Abi.js +225 -0
- package/dist/evm/chain/modules/EVMAddresses.d.ts +9 -0
- package/dist/evm/chain/modules/EVMAddresses.js +26 -0
- package/dist/evm/chain/modules/EVMBlocks.d.ts +20 -0
- package/dist/evm/chain/modules/EVMBlocks.js +64 -0
- package/dist/evm/chain/modules/EVMEvents.d.ts +36 -0
- package/dist/evm/chain/modules/EVMEvents.js +122 -0
- package/dist/evm/chain/modules/EVMFees.d.ts +35 -0
- package/dist/evm/chain/modules/EVMFees.js +73 -0
- package/dist/evm/chain/modules/EVMSignatures.d.ts +29 -0
- package/dist/evm/chain/modules/EVMSignatures.js +68 -0
- package/dist/evm/chain/modules/EVMTokens.d.ts +49 -0
- package/dist/evm/chain/modules/EVMTokens.js +105 -0
- package/dist/evm/chain/modules/EVMTransactions.d.ts +89 -0
- package/dist/evm/chain/modules/EVMTransactions.js +216 -0
- package/dist/evm/contract/EVMContractBase.d.ts +22 -0
- package/dist/evm/contract/EVMContractBase.js +34 -0
- package/dist/evm/contract/EVMContractModule.d.ts +8 -0
- package/dist/evm/contract/EVMContractModule.js +11 -0
- package/dist/evm/contract/modules/EVMContractEvents.d.ts +42 -0
- package/dist/evm/contract/modules/EVMContractEvents.js +75 -0
- package/dist/evm/events/EVMChainEvents.d.ts +22 -0
- package/dist/evm/events/EVMChainEvents.js +67 -0
- package/dist/evm/events/EVMChainEventsBrowser.d.ts +86 -0
- package/dist/evm/events/EVMChainEventsBrowser.js +294 -0
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +64 -0
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +410 -0
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +38 -0
- package/dist/evm/spv_swap/EVMSpvVaultData.js +159 -0
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.d.ts +19 -0
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.js +55 -0
- package/dist/evm/spv_swap/SpvVaultContractAbi.d.ts +91 -0
- package/dist/evm/spv_swap/SpvVaultContractAbi.js +849 -0
- package/dist/evm/spv_swap/SpvVaultContractTypechain.d.ts +450 -0
- package/dist/evm/spv_swap/SpvVaultContractTypechain.js +2 -0
- package/dist/evm/swaps/EVMSwapContract.d.ts +192 -0
- package/dist/evm/swaps/EVMSwapContract.js +373 -0
- package/dist/evm/swaps/EVMSwapData.d.ts +64 -0
- package/dist/evm/swaps/EVMSwapData.js +254 -0
- package/dist/evm/swaps/EVMSwapModule.d.ts +9 -0
- package/dist/evm/swaps/EVMSwapModule.js +11 -0
- package/dist/evm/swaps/EscrowManagerAbi.d.ts +120 -0
- package/dist/evm/swaps/EscrowManagerAbi.js +985 -0
- package/dist/evm/swaps/EscrowManagerTypechain.d.ts +475 -0
- package/dist/evm/swaps/EscrowManagerTypechain.js +2 -0
- package/dist/evm/swaps/handlers/IHandler.d.ts +13 -0
- package/dist/evm/swaps/handlers/IHandler.js +2 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.d.ts +10 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.js +13 -0
- package/dist/evm/swaps/handlers/claim/HashlockClaimHandler.d.ts +20 -0
- package/dist/evm/swaps/handlers/claim/HashlockClaimHandler.js +39 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +24 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +59 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +25 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +51 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +21 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +28 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +48 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +63 -0
- package/dist/evm/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -0
- package/dist/evm/swaps/handlers/refund/TimelockRefundHandler.js +28 -0
- package/dist/evm/swaps/modules/EVMLpVault.d.ts +69 -0
- package/dist/evm/swaps/modules/EVMLpVault.js +131 -0
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +53 -0
- package/dist/evm/swaps/modules/EVMSwapClaim.js +101 -0
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +88 -0
- package/dist/evm/swaps/modules/EVMSwapInit.js +241 -0
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +62 -0
- package/dist/evm/swaps/modules/EVMSwapRefund.js +132 -0
- package/dist/evm/typechain/common.d.ts +50 -0
- package/dist/evm/typechain/common.js +2 -0
- package/dist/evm/wallet/EVMSigner.d.ts +9 -0
- package/dist/evm/wallet/EVMSigner.js +16 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +53 -0
- package/dist/utils/Utils.d.ts +15 -0
- package/dist/utils/Utils.js +71 -0
- package/package.json +37 -0
- package/src/chains/citrea/CitreaChainType.ts +28 -0
- package/src/chains/citrea/CitreaInitializer.ts +167 -0
- package/src/evm/btcrelay/BtcRelayAbi.ts +258 -0
- package/src/evm/btcrelay/BtcRelayTypechain.ts +371 -0
- package/src/evm/btcrelay/EVMBtcRelay.ts +517 -0
- package/src/evm/btcrelay/headers/EVMBtcHeader.ts +110 -0
- package/src/evm/btcrelay/headers/EVMBtcStoredHeader.ts +153 -0
- package/src/evm/chain/EVMChainInterface.ts +157 -0
- package/src/evm/chain/EVMModule.ts +21 -0
- package/src/evm/chain/modules/ERC20Abi.ts +222 -0
- package/src/evm/chain/modules/EVMAddresses.ts +24 -0
- package/src/evm/chain/modules/EVMBlocks.ts +75 -0
- package/src/evm/chain/modules/EVMEvents.ts +139 -0
- package/src/evm/chain/modules/EVMFees.ts +105 -0
- package/src/evm/chain/modules/EVMSignatures.ts +76 -0
- package/src/evm/chain/modules/EVMTokens.ts +115 -0
- package/src/evm/chain/modules/EVMTransactions.ts +246 -0
- package/src/evm/contract/EVMContractBase.ts +63 -0
- package/src/evm/contract/EVMContractModule.ts +16 -0
- package/src/evm/contract/modules/EVMContractEvents.ts +102 -0
- package/src/evm/events/EVMChainEvents.ts +81 -0
- package/src/evm/events/EVMChainEventsBrowser.ts +390 -0
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +533 -0
- package/src/evm/spv_swap/EVMSpvVaultData.ts +201 -0
- package/src/evm/spv_swap/EVMSpvWithdrawalData.ts +70 -0
- package/src/evm/spv_swap/SpvVaultContractAbi.ts +846 -0
- package/src/evm/spv_swap/SpvVaultContractTypechain.ts +685 -0
- package/src/evm/swaps/EVMSwapContract.ts +590 -0
- package/src/evm/swaps/EVMSwapData.ts +367 -0
- package/src/evm/swaps/EVMSwapModule.ts +16 -0
- package/src/evm/swaps/EscrowManagerAbi.ts +982 -0
- package/src/evm/swaps/EscrowManagerTypechain.ts +723 -0
- package/src/evm/swaps/handlers/IHandler.ts +17 -0
- package/src/evm/swaps/handlers/claim/ClaimHandlers.ts +20 -0
- package/src/evm/swaps/handlers/claim/HashlockClaimHandler.ts +47 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +82 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +76 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +46 -0
- package/src/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +115 -0
- package/src/evm/swaps/handlers/refund/TimelockRefundHandler.ts +38 -0
- package/src/evm/swaps/modules/EVMLpVault.ts +153 -0
- package/src/evm/swaps/modules/EVMSwapClaim.ts +141 -0
- package/src/evm/swaps/modules/EVMSwapInit.ts +292 -0
- package/src/evm/swaps/modules/EVMSwapRefund.ts +198 -0
- package/src/evm/typechain/common.ts +131 -0
- package/src/evm/wallet/EVMSigner.ts +23 -0
- package/src/index.ts +44 -0
- package/src/utils/Utils.ts +81 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMAddresses = void 0;
|
|
4
|
+
const EVMModule_1 = require("../EVMModule");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
class EVMAddresses extends EVMModule_1.EVMModule {
|
|
7
|
+
///////////////////
|
|
8
|
+
//// Address utils
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether an address is a valid EVM address
|
|
11
|
+
*
|
|
12
|
+
* @param value
|
|
13
|
+
*/
|
|
14
|
+
static isValidAddress(value) {
|
|
15
|
+
if (value.length !== 42)
|
|
16
|
+
return false;
|
|
17
|
+
try {
|
|
18
|
+
(0, ethers_1.isAddress)(value);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.EVMAddresses = EVMAddresses;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EVMModule } from "../EVMModule";
|
|
2
|
+
export type EVMBlockTag = "safe" | "pending" | "latest" | "finalized";
|
|
3
|
+
export declare class EVMBlocks extends EVMModule<any> {
|
|
4
|
+
private BLOCK_CACHE_TIME;
|
|
5
|
+
private blockCache;
|
|
6
|
+
/**
|
|
7
|
+
* Initiates fetch of a given block & saves it to cache
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
* @param blockTag
|
|
11
|
+
*/
|
|
12
|
+
private fetchAndSaveBlockTime;
|
|
13
|
+
private cleanupBlocks;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the block for a given blocktag, with caching
|
|
16
|
+
*
|
|
17
|
+
* @param blockTag
|
|
18
|
+
*/
|
|
19
|
+
getBlockTime(blockTag: EVMBlockTag | number): Promise<number>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMBlocks = void 0;
|
|
4
|
+
const EVMModule_1 = require("../EVMModule");
|
|
5
|
+
class EVMBlocks extends EVMModule_1.EVMModule {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.BLOCK_CACHE_TIME = 5 * 1000;
|
|
9
|
+
this.blockCache = {};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Initiates fetch of a given block & saves it to cache
|
|
13
|
+
*
|
|
14
|
+
* @private
|
|
15
|
+
* @param blockTag
|
|
16
|
+
*/
|
|
17
|
+
fetchAndSaveBlockTime(blockTag) {
|
|
18
|
+
const blockTagStr = blockTag.toString(10);
|
|
19
|
+
const blockTimePromise = this.provider.getBlock(blockTag, false).then(result => result.timestamp);
|
|
20
|
+
const timestamp = Date.now();
|
|
21
|
+
this.blockCache[blockTagStr] = {
|
|
22
|
+
blockTime: blockTimePromise,
|
|
23
|
+
timestamp
|
|
24
|
+
};
|
|
25
|
+
blockTimePromise.catch(e => {
|
|
26
|
+
if (this.blockCache[blockTagStr] != null && this.blockCache[blockTagStr].blockTime === blockTimePromise)
|
|
27
|
+
delete this.blockCache[blockTagStr];
|
|
28
|
+
throw e;
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
blockTime: blockTimePromise,
|
|
32
|
+
timestamp
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
cleanupBlocks() {
|
|
36
|
+
const currentTime = Date.now();
|
|
37
|
+
//Keys are in order that they were added, so we can stop at the first non-expired block
|
|
38
|
+
for (let key in this.blockCache) {
|
|
39
|
+
const block = this.blockCache[key];
|
|
40
|
+
if (currentTime - block.timestamp > this.BLOCK_CACHE_TIME) {
|
|
41
|
+
delete this.blockCache[key];
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
///////////////////
|
|
49
|
+
//// Blocks
|
|
50
|
+
/**
|
|
51
|
+
* Gets the block for a given blocktag, with caching
|
|
52
|
+
*
|
|
53
|
+
* @param blockTag
|
|
54
|
+
*/
|
|
55
|
+
getBlockTime(blockTag) {
|
|
56
|
+
this.cleanupBlocks();
|
|
57
|
+
let cachedBlockData = this.blockCache[blockTag.toString(10)];
|
|
58
|
+
if (cachedBlockData == null || Date.now() - cachedBlockData.timestamp > this.BLOCK_CACHE_TIME) {
|
|
59
|
+
cachedBlockData = this.fetchAndSaveBlockTime(blockTag);
|
|
60
|
+
}
|
|
61
|
+
return cachedBlockData.blockTime;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.EVMBlocks = EVMBlocks;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { EVMModule } from "../EVMModule";
|
|
2
|
+
import { Log } from "ethers";
|
|
3
|
+
export declare class EVMEvents extends EVMModule<any> {
|
|
4
|
+
/**
|
|
5
|
+
* Returns the all the events occuring in a block range as identified by the contract and keys
|
|
6
|
+
*
|
|
7
|
+
* @param contract
|
|
8
|
+
* @param topics
|
|
9
|
+
* @param startBlock
|
|
10
|
+
* @param endBlock
|
|
11
|
+
* @param abortSignal
|
|
12
|
+
*/
|
|
13
|
+
getBlockEvents(contract: string, topics: (string[] | string | null)[], startBlock?: number, endBlock?: number, abortSignal?: AbortSignal): Promise<Log[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Runs a search backwards in time, processing events from a specific contract and keys
|
|
16
|
+
*
|
|
17
|
+
* @param contract
|
|
18
|
+
* @param topics
|
|
19
|
+
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
20
|
+
* was found, or null if the search should continue
|
|
21
|
+
* @param abortSignal
|
|
22
|
+
* @param genesisHeight Height when the contract was deployed
|
|
23
|
+
*/
|
|
24
|
+
findInEvents<T>(contract: string, topics: (string[] | string | null)[], processor: (signatures: Log[]) => Promise<T>, abortSignal?: AbortSignal, genesisHeight?: number): Promise<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Runs a search forwards in time, processing events from a specific contract and keys
|
|
27
|
+
*
|
|
28
|
+
* @param contract
|
|
29
|
+
* @param topics
|
|
30
|
+
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
31
|
+
* was found, or null if the search should continue
|
|
32
|
+
* @param abortSignal
|
|
33
|
+
* @param startHeight Blockheight at which to start
|
|
34
|
+
*/
|
|
35
|
+
findInEventsForward<T>(contract: string, topics: (string[] | string | null)[], processor: (signatures: Log[]) => Promise<T>, abortSignal?: AbortSignal, startHeight?: number): Promise<T>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMEvents = void 0;
|
|
4
|
+
const EVMModule_1 = require("../EVMModule");
|
|
5
|
+
class EVMEvents extends EVMModule_1.EVMModule {
|
|
6
|
+
/**
|
|
7
|
+
* Returns the all the events occuring in a block range as identified by the contract and keys
|
|
8
|
+
*
|
|
9
|
+
* @param contract
|
|
10
|
+
* @param topics
|
|
11
|
+
* @param startBlock
|
|
12
|
+
* @param endBlock
|
|
13
|
+
* @param abortSignal
|
|
14
|
+
*/
|
|
15
|
+
async getBlockEvents(contract, topics, startBlock, endBlock = startBlock, abortSignal) {
|
|
16
|
+
let events = [];
|
|
17
|
+
if (startBlock === endBlock) {
|
|
18
|
+
events = await this.root.provider.getLogs({
|
|
19
|
+
address: contract,
|
|
20
|
+
fromBlock: startBlock == null ? this.root.config.safeBlockTag : startBlock,
|
|
21
|
+
toBlock: endBlock == null ? this.root.config.safeBlockTag : endBlock,
|
|
22
|
+
topics
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else if (endBlock == null) {
|
|
26
|
+
const safeBlock = await this.root.provider.getBlock(this.root.config.safeBlockTag);
|
|
27
|
+
if (safeBlock.number - startBlock > this.root.config.maxLogsBlockRange) {
|
|
28
|
+
for (let i = startBlock + this.root.config.maxLogsBlockRange; i < safeBlock.number; i += this.root.config.maxLogsBlockRange) {
|
|
29
|
+
events.push(...await this.root.provider.getLogs({
|
|
30
|
+
address: contract,
|
|
31
|
+
fromBlock: i - this.root.config.maxLogsBlockRange,
|
|
32
|
+
toBlock: i,
|
|
33
|
+
topics
|
|
34
|
+
}));
|
|
35
|
+
startBlock = i;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
events.push(...await this.root.provider.getLogs({
|
|
39
|
+
address: contract,
|
|
40
|
+
fromBlock: startBlock == null ? this.root.config.safeBlockTag : startBlock,
|
|
41
|
+
toBlock: endBlock == null ? this.root.config.safeBlockTag : endBlock,
|
|
42
|
+
topics
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
//Both numeric
|
|
47
|
+
if (endBlock - startBlock > this.root.config.maxLogsBlockRange) {
|
|
48
|
+
for (let i = startBlock + this.root.config.maxLogsBlockRange; i < endBlock; i += this.root.config.maxLogsBlockRange) {
|
|
49
|
+
events.push(...await this.root.provider.getLogs({
|
|
50
|
+
address: contract,
|
|
51
|
+
fromBlock: i - this.root.config.maxLogsBlockRange,
|
|
52
|
+
toBlock: i,
|
|
53
|
+
topics
|
|
54
|
+
}));
|
|
55
|
+
startBlock = i;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
events.push(...await this.root.provider.getLogs({
|
|
59
|
+
address: contract,
|
|
60
|
+
fromBlock: startBlock,
|
|
61
|
+
toBlock: endBlock,
|
|
62
|
+
topics
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
return events.filter(val => !val.removed);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Runs a search backwards in time, processing events from a specific contract and keys
|
|
69
|
+
*
|
|
70
|
+
* @param contract
|
|
71
|
+
* @param topics
|
|
72
|
+
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
73
|
+
* was found, or null if the search should continue
|
|
74
|
+
* @param abortSignal
|
|
75
|
+
* @param genesisHeight Height when the contract was deployed
|
|
76
|
+
*/
|
|
77
|
+
async findInEvents(contract, topics, processor, abortSignal, genesisHeight) {
|
|
78
|
+
const { number: latestBlockNumber } = await this.provider.getBlock(this.root.config.safeBlockTag);
|
|
79
|
+
for (let blockNumber = latestBlockNumber; blockNumber >= (genesisHeight ?? 0); blockNumber -= this.root.config.maxLogsBlockRange) {
|
|
80
|
+
const eventsResult = await this.provider.getLogs({
|
|
81
|
+
address: contract,
|
|
82
|
+
topics,
|
|
83
|
+
fromBlock: Math.max(blockNumber - this.root.config.maxLogsBlockRange, 0),
|
|
84
|
+
toBlock: blockNumber === latestBlockNumber ? this.root.config.safeBlockTag : blockNumber
|
|
85
|
+
});
|
|
86
|
+
if (abortSignal != null)
|
|
87
|
+
abortSignal.throwIfAborted();
|
|
88
|
+
const result = await processor(eventsResult.reverse()); //Newest events first
|
|
89
|
+
if (result != null)
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Runs a search forwards in time, processing events from a specific contract and keys
|
|
96
|
+
*
|
|
97
|
+
* @param contract
|
|
98
|
+
* @param topics
|
|
99
|
+
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
100
|
+
* was found, or null if the search should continue
|
|
101
|
+
* @param abortSignal
|
|
102
|
+
* @param startHeight Blockheight at which to start
|
|
103
|
+
*/
|
|
104
|
+
async findInEventsForward(contract, topics, processor, abortSignal, startHeight) {
|
|
105
|
+
const { number: latestBlockNumber } = await this.provider.getBlock(this.root.config.safeBlockTag);
|
|
106
|
+
for (let blockNumber = startHeight ?? 0; blockNumber < latestBlockNumber; blockNumber += this.root.config.maxLogsBlockRange) {
|
|
107
|
+
const eventsResult = await this.provider.getLogs({
|
|
108
|
+
address: contract,
|
|
109
|
+
topics,
|
|
110
|
+
fromBlock: blockNumber,
|
|
111
|
+
toBlock: (blockNumber + this.root.config.maxLogsBlockRange) > latestBlockNumber ? this.root.config.safeBlockTag : blockNumber + this.root.config.maxLogsBlockRange
|
|
112
|
+
});
|
|
113
|
+
if (abortSignal != null)
|
|
114
|
+
abortSignal.throwIfAborted();
|
|
115
|
+
const result = await processor(eventsResult); //Oldest events first
|
|
116
|
+
if (result != null)
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.EVMEvents = EVMEvents;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Provider, TransactionRequest } from "ethers";
|
|
2
|
+
export type EVMFeeRate = {
|
|
3
|
+
maxFeePerGas: bigint;
|
|
4
|
+
maxPriorityFee: bigint;
|
|
5
|
+
};
|
|
6
|
+
export declare class EVMFees {
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private readonly provider;
|
|
9
|
+
private readonly maxFeeRatePerGas;
|
|
10
|
+
private readonly priorityFee;
|
|
11
|
+
private readonly feeMultiplierPPM;
|
|
12
|
+
private blockFeeCache;
|
|
13
|
+
constructor(provider: Provider, maxFeeRatePerGas?: bigint, priorityFee?: bigint, feeMultiplier?: number);
|
|
14
|
+
/**
|
|
15
|
+
* Gets evm fee rate
|
|
16
|
+
*
|
|
17
|
+
* @private
|
|
18
|
+
* @returns {Promise<bigint>} L1 gas price denominated in Wei
|
|
19
|
+
*/
|
|
20
|
+
private _getFeeRate;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the gas price with caching, format: <gas price in Wei>;<transaction version: v1/v3>
|
|
23
|
+
*
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
getFeeRate(): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Calculates the total gas fee paid for a given gas limit at a given fee rate
|
|
29
|
+
*
|
|
30
|
+
* @param gas
|
|
31
|
+
* @param feeRate
|
|
32
|
+
*/
|
|
33
|
+
static getGasFee(gas: number, feeRate: string): bigint;
|
|
34
|
+
static applyFeeRate(tx: TransactionRequest, gas: number, feeRate: string): any;
|
|
35
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMFees = void 0;
|
|
4
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
5
|
+
const MAX_FEE_AGE = 5000;
|
|
6
|
+
class EVMFees {
|
|
7
|
+
constructor(provider, maxFeeRatePerGas = 500n * 1000000000n, priorityFee = 1n * 1000000000n, feeMultiplier = 1.25) {
|
|
8
|
+
this.logger = (0, Utils_1.getLogger)("EVMFees: ");
|
|
9
|
+
this.blockFeeCache = null;
|
|
10
|
+
this.provider = provider;
|
|
11
|
+
this.maxFeeRatePerGas = maxFeeRatePerGas;
|
|
12
|
+
this.priorityFee = priorityFee;
|
|
13
|
+
this.feeMultiplierPPM = BigInt(Math.floor(feeMultiplier * 1000000));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Gets evm fee rate
|
|
17
|
+
*
|
|
18
|
+
* @private
|
|
19
|
+
* @returns {Promise<bigint>} L1 gas price denominated in Wei
|
|
20
|
+
*/
|
|
21
|
+
async _getFeeRate() {
|
|
22
|
+
const block = await this.provider.getBlock("latest");
|
|
23
|
+
const baseFee = block.baseFeePerGas * this.feeMultiplierPPM / 1000000n;
|
|
24
|
+
this.logger.debug("_getFeeRate(): Base fee rate: " + baseFee.toString(10));
|
|
25
|
+
return baseFee;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the gas price with caching, format: <gas price in Wei>;<transaction version: v1/v3>
|
|
29
|
+
*
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
async getFeeRate() {
|
|
33
|
+
if (this.blockFeeCache == null || Date.now() - this.blockFeeCache.timestamp > MAX_FEE_AGE) {
|
|
34
|
+
let obj = {
|
|
35
|
+
timestamp: Date.now(),
|
|
36
|
+
feeRate: null
|
|
37
|
+
};
|
|
38
|
+
obj.feeRate = this._getFeeRate().catch(e => {
|
|
39
|
+
if (this.blockFeeCache === obj)
|
|
40
|
+
this.blockFeeCache = null;
|
|
41
|
+
throw e;
|
|
42
|
+
});
|
|
43
|
+
this.blockFeeCache = obj;
|
|
44
|
+
}
|
|
45
|
+
let baseFee = await this.blockFeeCache.feeRate;
|
|
46
|
+
if (baseFee > this.maxFeeRatePerGas)
|
|
47
|
+
baseFee = this.maxFeeRatePerGas;
|
|
48
|
+
const fee = baseFee.toString(10) + "," + this.priorityFee.toString(10);
|
|
49
|
+
this.logger.debug("getFeeRate(): calculated fee: " + fee);
|
|
50
|
+
return fee;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Calculates the total gas fee paid for a given gas limit at a given fee rate
|
|
54
|
+
*
|
|
55
|
+
* @param gas
|
|
56
|
+
* @param feeRate
|
|
57
|
+
*/
|
|
58
|
+
static getGasFee(gas, feeRate) {
|
|
59
|
+
if (feeRate == null)
|
|
60
|
+
return 0n;
|
|
61
|
+
const [baseFee, priorityFee] = feeRate.split(",");
|
|
62
|
+
return BigInt(gas) * (BigInt(baseFee) + BigInt(priorityFee));
|
|
63
|
+
}
|
|
64
|
+
static applyFeeRate(tx, gas, feeRate) {
|
|
65
|
+
if (feeRate == null)
|
|
66
|
+
return null;
|
|
67
|
+
const [baseFee, priorityFee] = feeRate.split(",");
|
|
68
|
+
tx.maxFeePerGas = BigInt(baseFee) + BigInt(priorityFee);
|
|
69
|
+
tx.maxPriorityFeePerGas = BigInt(priorityFee);
|
|
70
|
+
tx.gasLimit = BigInt(gas) + 21000n;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.EVMFees = EVMFees;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { EVMSigner } from "../../wallet/EVMSigner";
|
|
4
|
+
import { EVMModule } from "../EVMModule";
|
|
5
|
+
import { EVMChainInterface } from "../EVMChainInterface";
|
|
6
|
+
import { TypedDataField } from "ethers";
|
|
7
|
+
export declare class EVMSignatures extends EVMModule<any> {
|
|
8
|
+
private readonly domainName;
|
|
9
|
+
constructor(root: EVMChainInterface<any>, domainName?: string);
|
|
10
|
+
signTypedMessage(contract: string, signer: EVMSigner, type: TypedDataField[], typeName: string, message: object): Promise<string>;
|
|
11
|
+
isValidSignature(contract: string, signature: string, address: string, type: TypedDataField[], typeName: string, message: object): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Produces a signature over the sha256 of a specified data Buffer, only works with providers which
|
|
14
|
+
* expose their private key (i.e. backend based, not browser wallet based)
|
|
15
|
+
*
|
|
16
|
+
* @param signer
|
|
17
|
+
* @param data data to sign
|
|
18
|
+
*/
|
|
19
|
+
getDataSignature(signer: EVMSigner, data: Buffer): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Checks whether a signature is a valid signature produced by the account over a data message (computes
|
|
22
|
+
* sha256 hash of the message)
|
|
23
|
+
*
|
|
24
|
+
* @param data signed data
|
|
25
|
+
* @param signature data signature
|
|
26
|
+
* @param address public key of the signer
|
|
27
|
+
*/
|
|
28
|
+
isValidDataSignature(data: Buffer, signature: string, address: string): Promise<boolean>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMSignatures = void 0;
|
|
4
|
+
const EVMModule_1 = require("../EVMModule");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const DataHash = [
|
|
7
|
+
{ name: "dataHash", type: "bytes32" }
|
|
8
|
+
];
|
|
9
|
+
class EVMSignatures extends EVMModule_1.EVMModule {
|
|
10
|
+
constructor(root, domainName = "atomiq.exchange") {
|
|
11
|
+
super(root);
|
|
12
|
+
this.domainName = domainName;
|
|
13
|
+
}
|
|
14
|
+
async signTypedMessage(contract, signer, type, typeName, message) {
|
|
15
|
+
return signer.account.signTypedData({
|
|
16
|
+
name: this.domainName,
|
|
17
|
+
version: "1",
|
|
18
|
+
chainId: BigInt(this.root.evmChainId),
|
|
19
|
+
verifyingContract: contract
|
|
20
|
+
}, { [typeName]: type }, message);
|
|
21
|
+
}
|
|
22
|
+
async isValidSignature(contract, signature, address, type, typeName, message) {
|
|
23
|
+
return Promise.resolve(address === (0, ethers_1.verifyTypedData)({
|
|
24
|
+
name: this.domainName,
|
|
25
|
+
version: "1",
|
|
26
|
+
chainId: BigInt(this.root.evmChainId),
|
|
27
|
+
verifyingContract: contract
|
|
28
|
+
}, { [typeName]: type }, message, signature));
|
|
29
|
+
}
|
|
30
|
+
///////////////////
|
|
31
|
+
//// Data signatures
|
|
32
|
+
/**
|
|
33
|
+
* Produces a signature over the sha256 of a specified data Buffer, only works with providers which
|
|
34
|
+
* expose their private key (i.e. backend based, not browser wallet based)
|
|
35
|
+
*
|
|
36
|
+
* @param signer
|
|
37
|
+
* @param data data to sign
|
|
38
|
+
*/
|
|
39
|
+
getDataSignature(signer, data) {
|
|
40
|
+
return signer.account.signTypedData({
|
|
41
|
+
name: this.domainName,
|
|
42
|
+
version: "1",
|
|
43
|
+
chainId: BigInt(this.root.evmChainId),
|
|
44
|
+
verifyingContract: "0x0000000000000000000000000000000000000000"
|
|
45
|
+
}, { DataHash }, {
|
|
46
|
+
dataHash: (0, ethers_1.sha256)(data)
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Checks whether a signature is a valid signature produced by the account over a data message (computes
|
|
51
|
+
* sha256 hash of the message)
|
|
52
|
+
*
|
|
53
|
+
* @param data signed data
|
|
54
|
+
* @param signature data signature
|
|
55
|
+
* @param address public key of the signer
|
|
56
|
+
*/
|
|
57
|
+
isValidDataSignature(data, signature, address) {
|
|
58
|
+
return Promise.resolve(address === (0, ethers_1.verifyTypedData)({
|
|
59
|
+
name: this.domainName,
|
|
60
|
+
version: "1",
|
|
61
|
+
chainId: BigInt(this.root.evmChainId),
|
|
62
|
+
verifyingContract: "0x0000000000000000000000000000000000000000"
|
|
63
|
+
}, { DataHash }, {
|
|
64
|
+
dataHash: (0, ethers_1.sha256)(data)
|
|
65
|
+
}, signature));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.EVMSignatures = EVMSignatures;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { EVMModule } from "../EVMModule";
|
|
2
|
+
import { TransactionRequest } from "ethers";
|
|
3
|
+
export declare class EVMTokens extends EVMModule<any> {
|
|
4
|
+
static readonly ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
5
|
+
static readonly GasCosts: {
|
|
6
|
+
TRANSFER: number;
|
|
7
|
+
APPROVE: number;
|
|
8
|
+
};
|
|
9
|
+
private getContract;
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the provided string is a valid starknet token
|
|
12
|
+
*
|
|
13
|
+
* @param token
|
|
14
|
+
*/
|
|
15
|
+
isValidToken(token: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the token balance of the address
|
|
18
|
+
*
|
|
19
|
+
* @param address
|
|
20
|
+
* @param token
|
|
21
|
+
*/
|
|
22
|
+
getTokenBalance(address: string, token: string): Promise<bigint>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the native currency address
|
|
25
|
+
*/
|
|
26
|
+
getNativeCurrencyAddress(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Creates transactions for sending the over the tokens
|
|
29
|
+
*
|
|
30
|
+
* @param signer
|
|
31
|
+
* @param token token to send
|
|
32
|
+
* @param amount amount of the token to send
|
|
33
|
+
* @param recipient recipient's address
|
|
34
|
+
* @param feeRate fee rate to use for the transactions
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
Transfer(signer: string, token: string, amount: bigint, recipient: string, feeRate?: string): Promise<TransactionRequest>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates transactions for approving spending of tokens
|
|
40
|
+
*
|
|
41
|
+
* @param signer
|
|
42
|
+
* @param token token to send
|
|
43
|
+
* @param amount amount of the token to send
|
|
44
|
+
* @param spender recipient's address
|
|
45
|
+
* @param feeRate fee rate to use for the transactions
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
Approve(signer: string, token: string, amount: bigint, spender: string, feeRate?: string): Promise<TransactionRequest>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVMTokens = void 0;
|
|
4
|
+
const EVMModule_1 = require("../EVMModule");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const ERC20Abi_1 = require("./ERC20Abi");
|
|
7
|
+
const EVMAddresses_1 = require("./EVMAddresses");
|
|
8
|
+
const EVMFees_1 = require("./EVMFees");
|
|
9
|
+
class EVMTokens extends EVMModule_1.EVMModule {
|
|
10
|
+
getContract(address) {
|
|
11
|
+
return new ethers_1.Contract(address, ERC20Abi_1.ERC20Abi, this.root.provider);
|
|
12
|
+
}
|
|
13
|
+
///////////////////
|
|
14
|
+
//// Tokens
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the provided string is a valid starknet token
|
|
17
|
+
*
|
|
18
|
+
* @param token
|
|
19
|
+
*/
|
|
20
|
+
isValidToken(token) {
|
|
21
|
+
return EVMAddresses_1.EVMAddresses.isValidAddress(token);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the token balance of the address
|
|
25
|
+
*
|
|
26
|
+
* @param address
|
|
27
|
+
* @param token
|
|
28
|
+
*/
|
|
29
|
+
async getTokenBalance(address, token) {
|
|
30
|
+
let balance;
|
|
31
|
+
if (token === "0x0000000000000000000000000000000000000000") {
|
|
32
|
+
balance = await this.provider.getBalance(address);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const erc20 = this.getContract(token);
|
|
36
|
+
balance = await erc20.balanceOf(address);
|
|
37
|
+
}
|
|
38
|
+
this.logger.debug("getTokenBalance(): token balance fetched, token: " + token +
|
|
39
|
+
" address: " + address + " amount: " + balance.toString(10));
|
|
40
|
+
return balance;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns the native currency address
|
|
44
|
+
*/
|
|
45
|
+
getNativeCurrencyAddress() {
|
|
46
|
+
return "0x0000000000000000000000000000000000000000";
|
|
47
|
+
}
|
|
48
|
+
///////////////////
|
|
49
|
+
//// Transfers
|
|
50
|
+
/**
|
|
51
|
+
* Creates transactions for sending the over the tokens
|
|
52
|
+
*
|
|
53
|
+
* @param signer
|
|
54
|
+
* @param token token to send
|
|
55
|
+
* @param amount amount of the token to send
|
|
56
|
+
* @param recipient recipient's address
|
|
57
|
+
* @param feeRate fee rate to use for the transactions
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
async Transfer(signer, token, amount, recipient, feeRate) {
|
|
61
|
+
let tx;
|
|
62
|
+
if (token === this.getNativeCurrencyAddress()) {
|
|
63
|
+
tx = {
|
|
64
|
+
to: recipient,
|
|
65
|
+
value: amount
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
tx = await this.getContract(token).transfer.populateTransaction(recipient, amount);
|
|
70
|
+
}
|
|
71
|
+
tx.from = signer;
|
|
72
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, EVMTokens.GasCosts.TRANSFER, feeRate ?? await this.root.Fees.getFeeRate());
|
|
73
|
+
this.logger.debug("txsTransfer(): transfer TX created, recipient: " + recipient.toString() +
|
|
74
|
+
" token: " + token.toString() + " amount: " + amount.toString(10));
|
|
75
|
+
return tx;
|
|
76
|
+
}
|
|
77
|
+
///////////////////
|
|
78
|
+
//// Approval
|
|
79
|
+
/**
|
|
80
|
+
* Creates transactions for approving spending of tokens
|
|
81
|
+
*
|
|
82
|
+
* @param signer
|
|
83
|
+
* @param token token to send
|
|
84
|
+
* @param amount amount of the token to send
|
|
85
|
+
* @param spender recipient's address
|
|
86
|
+
* @param feeRate fee rate to use for the transactions
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
async Approve(signer, token, amount, spender, feeRate) {
|
|
90
|
+
if (token === this.getNativeCurrencyAddress())
|
|
91
|
+
return null;
|
|
92
|
+
const tx = await this.getContract(token).approve.populateTransaction(spender, amount);
|
|
93
|
+
tx.from = signer;
|
|
94
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, EVMTokens.GasCosts.APPROVE, feeRate ?? await this.root.Fees.getFeeRate());
|
|
95
|
+
this.logger.debug("txsTransfer(): approve TX created, spender: " + spender.toString() +
|
|
96
|
+
" token: " + token.toString() + " amount: " + amount.toString(10));
|
|
97
|
+
return tx;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.EVMTokens = EVMTokens;
|
|
101
|
+
EVMTokens.ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
102
|
+
EVMTokens.GasCosts = {
|
|
103
|
+
TRANSFER: 80000,
|
|
104
|
+
APPROVE: 80000
|
|
105
|
+
};
|