import { Annotated } from '.' ; import { OpticsContext } from '..' ; import { Domain } from '../../domains' ; import { Result } from '@ethersproject/abi' ; import { TypedEvent , TypedEventFilter , } from '@optics-xyz/ts-interface/dist/optics-core/commons' ; export interface TSContract < T extends Result , U > { queryFilter ( event , fromBlockOrBlockhash ? , toBlock ? ) : Promise < Array < TypedEvent < T & U > > > ; } export async function queryAnnotatedEvents < T extends Result , U > ( context , nameOrDomain , contract , filter , startBlock ? , endBlock ? ) { const events = await getEvents ( context , nameOrDomain , contract , filter , startBlock , endBlock ) ; return Annotated . fromEvents ( context . resolveDomain ( nameOrDomain ) , events ) ; } export async function getEvents < T extends Result , U > ( context , nameOrDomain , contract , filter , startBlock ? , endBlock ? ) { const domain = context . mustGetDomain ( nameOrDomain ) ; if ( domain . paginate ) { return getPaginatedEvents ( context , domain , contract , filter , startBlock , endBlock ) ; } return contract . queryFilter ( filter , startBlock , endBlock ) ; } async function getPaginatedEvents < T extends Result , U > ( context , domain , contract , filter , startBlock ? , endBlock ? ) { if ( ! domain . paginate ) { throw new Error ( 'Domain need not be paginated' ) ; } const firstBlock = startBlock ? Math . max ( startBlock , domain . paginate . from ) : domain . paginate . from ; let lastBlock ; if ( ! endBlock ) { const provider = context . mustGetProvider ( domain . id ) ; lastBlock = await provider . getBlockNumber ( ) ; } else { lastBlock = endBlock ; } const eventArrayPromises = [ ] ; for ( let from = firstBlock ; from <= lastBlock ; from += domain . paginate . blocks ) { const nextFrom = from + domain . paginate . blocks ; const to = Math . min ( nextFrom , lastBlock ) ; const eventArrayPromise = contract . queryFilter ( filter , from , to ) ; eventArrayPromises . push ( eventArrayPromise ) ; } const eventArrays = await Promise . all ( eventArrayPromises ) ; let events = [ ] ; for ( const eventArray of eventArrays ) { events = events . concat ( eventArray ) ; } return events ; }