squid-js/src/keeper/EventHandler.ts

63 lines
1.7 KiB
TypeScript
Raw Normal View History

import { ContractEvent } from "./ContractEvent"
import ContractBase from "./contracts/ContractBase"
import { Instantiable, InstantiableConfig } from "../Instantiable.abstract"
export class EventHandler extends Instantiable {
private events = new Set<(blockNumber) => void>()
private lastBlock: number
private interval = 200
private polling: boolean = false
private lastTimeout: NodeJS.Timeout
get count() {
return this.events.size
}
constructor(config: InstantiableConfig) {
super()
this.setInstanceConfig(config)
}
private async checkBlock(isInterval?: boolean, n = 0) {
const blockNumber = await this.web3.eth.getBlockNumber()
if ((this.polling && !isInterval) || !this.count) {
return
}
this.polling = true
if (!this.lastBlock) {
this.lastBlock = blockNumber
}
if (this.lastBlock !== blockNumber) {
this.events.forEach(fn => fn(this.lastBlock + 1))
this.lastBlock = blockNumber
}
this.lastTimeout = setTimeout(() => this.checkBlock(true, n++), this.interval)
}
public subscribe(callback: (number) => void) {
this.events.add(callback)
this.checkBlock()
return {
unsubscribe: () => this.unsubscribe(callback),
}
}
public unsubscribe(callback: (number) => void) {
this.events.delete(callback)
if (!this.count) {
clearTimeout(this.lastTimeout)
delete this.lastBlock
this.polling = false
}
}
public getEvent(contract: ContractBase, eventName: string, filter: {[key: string]: any}) {
return new ContractEvent(this, contract, eventName, filter)
}
}