88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
|
import { methodNameByAddressMapper } from "./mappers/methodNameByAddressMapper";
|
||
|
import { EvmBlock, EvmTransaction } from "../../entities";
|
||
|
import { EvmBlockRepository } from "../../repositories";
|
||
|
import { GetEvmOpts } from "./GetEvmLogs";
|
||
|
import winston from "winston";
|
||
|
|
||
|
export class GetEvmTransactions {
|
||
|
private readonly blockRepo: EvmBlockRepository;
|
||
|
protected readonly logger: winston.Logger;
|
||
|
|
||
|
constructor(blockRepo: EvmBlockRepository) {
|
||
|
this.logger = winston.child({ module: "GetEvmTransactions" });
|
||
|
this.blockRepo = blockRepo;
|
||
|
}
|
||
|
|
||
|
async execute(range: Range, opts: GetEvmOpts): Promise<EvmTransaction[]> {
|
||
|
const fromBlock = range.fromBlock;
|
||
|
const toBlock = range.toBlock;
|
||
|
|
||
|
if (fromBlock > toBlock) {
|
||
|
this.logger.info(`[exec] Invalid range [fromBlock: ${fromBlock} - toBlock: ${toBlock}]`);
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
let populateTransactions: EvmTransaction[] = [];
|
||
|
const environment = opts.environment;
|
||
|
const isTransactionsPresent = true;
|
||
|
const chain = opts.chain;
|
||
|
|
||
|
for (let block = fromBlock; block <= toBlock; block++) {
|
||
|
const evmBlock = await this.blockRepo.getBlock(chain, block, isTransactionsPresent);
|
||
|
const transactions = evmBlock.transactions ?? [];
|
||
|
|
||
|
// Only process transactions to the contract address
|
||
|
const transactionsFilter = transactions.filter(
|
||
|
(transaction) =>
|
||
|
opts.addresses?.includes(String(transaction.to).toLowerCase()) ||
|
||
|
opts.addresses?.includes(String(transaction.from).toLowerCase())
|
||
|
);
|
||
|
|
||
|
if (transactionsFilter.length > 0) {
|
||
|
populateTransactions = await this.populateTransaction(
|
||
|
chain,
|
||
|
environment,
|
||
|
evmBlock,
|
||
|
transactionsFilter
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.logger.info(
|
||
|
`[${chain}][exec] Got ${
|
||
|
populateTransactions?.length
|
||
|
} transactions to process for ${this.populateLog(opts, fromBlock, toBlock)}`
|
||
|
);
|
||
|
return populateTransactions;
|
||
|
}
|
||
|
|
||
|
private async populateTransaction(
|
||
|
chain: string,
|
||
|
environment: string,
|
||
|
evmBlock: EvmBlock,
|
||
|
transactionsFilter: EvmTransaction[]
|
||
|
): Promise<EvmTransaction[]> {
|
||
|
const hashNumbers = new Set(transactionsFilter.map((transaction) => transaction.hash));
|
||
|
const receiptTransaction = await this.blockRepo.getTransactionReceipt(chain, hashNumbers);
|
||
|
|
||
|
transactionsFilter.forEach((transaction) => {
|
||
|
transaction.chainId = Number(transaction.chainId);
|
||
|
transaction.timestamp = evmBlock.timestamp;
|
||
|
transaction.status = receiptTransaction[transaction.hash].status;
|
||
|
transaction.environment = environment;
|
||
|
transaction.chain = chain;
|
||
|
});
|
||
|
|
||
|
return transactionsFilter;
|
||
|
}
|
||
|
|
||
|
private populateLog(opts: GetEvmOpts, fromBlock: bigint, toBlock: bigint): string {
|
||
|
return `[addresses:${opts.addresses}][topics:${opts.topics}][blocks:${fromBlock} - ${toBlock}]`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type Range = {
|
||
|
fromBlock: bigint;
|
||
|
toBlock: bigint;
|
||
|
};
|