import { BlockExplorerERC20Transfer, BlockExplorerERC721Transfer, BlockExplorerInterface, BlockExplorerTransaction, ExplorerResultType } from "./BlockExplorerInterface"; // Designed to work for block explorers with the same API as etherscan export class EthereumBlockExplorer extends BlockExplorerInterface { constructor(blockExplorerAPIURL: string, maxCallsPerSecond: number = 1) { super(blockExplorerAPIURL); this.minInterval = 5100 / maxCallsPerSecond; } async getTransactionsForAddress(address: string): Promise { //update this endpoint to match given block explorer const type = ExplorerResultType.NormalTransactions; console.log("BlockExplorerInterface::getTransactionsForAddress::new request", this.blockExplorerAPIURL) const accountTxListUrl = `${this.blockExplorerAPIURL}?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&sort=desc`; try { return this.queue.add(async () => { const response = await fetch(accountTxListUrl); const data = await response.json(); if (data.status === "0") { return []; } return this.transformRawTransactionResponse(data.result) as BlockExplorerTransaction[]; }) as Promise; } catch (e) { console.error("BlockExplorerInterface::getTransactionsForAddress::error", e) throw new Error(e as any) } } async getERC20TransfersForAddress(address: string): Promise { //update this endpoint to match given block explorer const type = ExplorerResultType.ERC20Transfers; console.log("BlockExplorerInterface::getERC20TransfersForAddress::new request", this.blockExplorerAPIURL) const accountTxListUrl = `${this.blockExplorerAPIURL}?module=account&action=tokentx&address=${address}&startblock=0&endblock=99999999&sort=desc`; try { return this.queue.add(async () => { const response = await fetch(accountTxListUrl); const data = await response.json(); console.log("BlockExplorerInterface::getERC20TransfersForAddress::data", data) if (data.status === "0") { return []; } return data.result as BlockExplorerERC20Transfer[]; }) as Promise; } catch (e) { console.error("BlockExplorerInterface::getERC20TransfersForAddress::error", e) throw new Error(e as any) } } async getERC721TransfersForAddress(address: string): Promise { //update this endpoint to match given block explorer const type = ExplorerResultType.ERC721Transfers; console.log(type) console.log("BlockExplorerInterface::getERC721TransfersForAddress::new request", this.blockExplorerAPIURL) const accountTxListUrl = `${this.blockExplorerAPIURL}?module=account&action=tokennfttx&address=${address}&startblock=0&endblock=99999999&sort=desc`; try { return this.queue.add(async () => { const response = await fetch(accountTxListUrl); const data = await response.json(); if (data.status === "0") { throw new Error("Error::getERC721TransfersForAddress::" + data.message) } return data.result as BlockExplorerERC721Transfer[]; }) as Promise; } catch (e) { console.error("BlockExplorerInterface::getERC721TransfersForAddress::error", e) throw new Error(e as any) } } //update this to transform the raw response to the BlockExplorerTransaction interface public transformRawTransactionResponse(rawTransactions: any[]): any[] { console.log("BlockExplorerInterface::transformRawTransactionResponse::rawTransactions", rawTransactions) return rawTransactions.map((tx: any) => { return { ...tx, functionName: this.extractFunctionName(tx.functionName), } }); } }