import { Provider } from "starknet" ; import { BackupWallet } from "../shared/backup.model" ; import { getProvider } from "../shared/networks" ; import { TransactionMeta , TransactionStatus , } from "../shared/transactions.model" ; interface TransactionStatusWithProvider extends TransactionStatus { provider : Provider ; } type FetchedTransactionStatus = Omit < TransactionStatus , "walletAddress" | "meta" > ; type Listener = ( transactions : TransactionStatus [ ] ) => void ; export async function getTransactionStatus ( provider , hash ) { const { tx_status } = await provider . getTransactionStatus ( hash ) ; return { hash , status : tx_status } ; } export class TransactionTracker { private transactions : TransactionStatusWithProvider [ ] = [ ] ; private listeners : Listener [ ] = [ ] ; private interval : NodeJS . Timeout ; constructor ( listener , interval = 30 * 1000 ) { this . listeners = [ listener ] ; this . interval = setInterval ( ( ) => this . checkTransactions ( ) , interval ) ; } public async trackTransaction ( transactionHash , wallet , meta = { title : "Contract interaction" , } ) { const provider = getProvider ( wallet . network ) ; this . transactions . push ( { hash : transactionHash , provider , walletAddress : wallet . address , status : "RECEIVED" , meta , } ) ; this . listeners . forEach ( ( listener ) => { listener ( this . transactions ) ; } ) ; } public getAllTransactions ( byWalletAddress ? ) { return this . transactions . filter ( ( transaction ) => ! byWalletAddress || transaction . walletAddress === byWalletAddress ) . map ( ( { hash , walletAddress , meta } ) => ( { hash , walletAddress , status : this . getTransactionStatus ( hash ) ?. status || "NOT_RECEIVED" , meta , } ) ) ; } public getTransactionStatus ( hash ) { return this . transactions . find ( ( { hash : txHash } ) => txHash === hash ) ; } private async checkTransactions ( ) { const transactionStatus = await Promise . all ( this . transactions . map ( async ( { hash , provider , walletAddress , meta } ) => { return getTransactionStatus ( provider , hash ) . then ( ( status ) => ( { ... status , walletAddress , provider , meta , } ) ) ; } ) ) ; if ( transactionStatus . length > 0 ) { this . transactions = transactionStatus ; this . listeners . forEach ( ( listener ) => { listener ( transactionStatus ) ; } ) ; } } public addListener ( listener ) { this . listeners . push ( listener ) ; } public removeListener ( listener ) { this . listeners = this . listeners . filter ( ( l ) => l !== listener ) ; } public async stop ( ) { clearInterval ( this . interval ) ; } }