Skip to content

Commit

Permalink
feat(orap): support provider manager
Browse files Browse the repository at this point in the history
  • Loading branch information
murongg committed Aug 8, 2024
1 parent b205cb1 commit c0a9490
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/orap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './signal'
export * from './store'
export * from './task'
export * from './orap'
export * from './types'
8 changes: 4 additions & 4 deletions packages/orap/orap.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ethers } from 'ethers'
import { EventSignal } from './signal/event'
import type { Providers } from './types'

export interface ListenOptions {
wsProvider: ethers.WebSocketProvider
httpProvider?: ethers.JsonRpcProvider
wsProvider: Providers
httpProvider?: Providers
}

export class Orap {
Expand All @@ -23,7 +23,7 @@ export class Orap {
return es
}

_listenChain(wsProvider: ethers.WebSocketProvider, httpProvider?: ethers.JsonRpcProvider) {
_listenChain(wsProvider: Providers, httpProvider?: Providers) {
this.routes.event.forEach(es => es.listen(wsProvider, httpProvider))
}

Expand Down
31 changes: 20 additions & 11 deletions packages/orap/signal/event.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { EventFragment, Log } from 'ethers'
import { ethers } from 'ethers'
import { AutoCrossChecker, ONE_MINUTE_MS } from '@ora-io/rek'
import { AutoCrossChecker, ONE_MINUTE_MS, ProviderManager } from '@ora-io/rek'
import type { AutoCrossCheckParam } from '@ora-io/rek'
import type { Providers } from '../types'
import type { Signal } from './type'

export interface EventSignalRegisterParams {
Expand All @@ -14,7 +15,7 @@ export interface EventSignalRegisterParams {
export type EventSignalCallback = ethers.Listener

export class EventSignal implements Signal {
provider?: ethers.JsonRpcProvider | ethers.WebSocketProvider
provider?: Providers
contract: ethers.Contract
esig: string
eventFragment: EventFragment
Expand Down Expand Up @@ -57,28 +58,36 @@ export class EventSignal implements Signal {

// TODO: how to integrate crosschecker
// TODO: should be wsProvider only?
listen(provider: ethers.WebSocketProvider, crosscheckProvider?: ethers.JsonRpcProvider) {
listen(provider: Providers, crosscheckProvider?: Providers) {
this.provider = provider

// start event listener
const listener = this.contract.connect(provider)
listener?.on(
this.params.eventName,
// TODO: calling this seems to be async, should we make it to sequential?
this.subscribeCallback,
)
if (provider instanceof ProviderManager) {
provider.addContract(this.params.address, this.contract)
provider.addListener(this.params.address, this.params.eventName, this.subscribeCallback)
}
else {
const listener = this.contract.connect(provider)
listener?.on(
this.params.eventName,
// TODO: calling this seems to be async, should we make it to sequential?
this.subscribeCallback,
)
}

// start cross-checker if ever set
if (this.crosscheckerOptions) {
if (!crosscheckProvider)
throw new Error('crosschecker set, please provide crosscheckProvider to listen function')
this.startCrossChecker(crosscheckProvider)
const _crosscheckProvider = crosscheckProvider instanceof ProviderManager ? crosscheckProvider.provider : crosscheckProvider
if (_crosscheckProvider)
this.startCrossChecker(_crosscheckProvider)
}

return this
}

async startCrossChecker(provider: ethers.JsonRpcProvider) {
async startCrossChecker(provider: ethers.WebSocketProvider | ethers.JsonRpcProvider) {
if (!this.crosscheckerOptions)
throw new Error('no crosscheck set, can\'t start crosschecker')
this.crosschecker = new AutoCrossChecker(provider, this.crosscheckerOptions)
Expand Down
4 changes: 4 additions & 0 deletions packages/orap/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { ProviderManager } from '@ora-io/rek'
import type { ethers } from 'ethers'

export type Providers = ethers.WebSocketProvider | ethers.JsonRpcProvider | ProviderManager
1 change: 1 addition & 0 deletions packages/rek/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './event/crosschecker/basechecker'
export * from './event/crosschecker/autochecker'
export * from './event/crosschecker/interface'
export * from './constants'
export * from './managers'
2 changes: 2 additions & 0 deletions packages/rek/managers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './contract'
export * from './provider'
21 changes: 9 additions & 12 deletions packages/rek/managers/provider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from 'node:events'
import type { Interface, InterfaceAbi } from 'ethers'
import { WebSocketProvider, ethers } from 'ethers'
import type { InterfaceAbi } from 'ethers'
import { Interface, WebSocketProvider, ethers } from 'ethers'
import type { ErrorEvent, WebSocket } from 'ws'
import { ContractManager } from './contract'

Expand Down Expand Up @@ -48,24 +48,21 @@ export class ProviderManager {
return this._contracts
}

async addContract(address: ethers.Contract): Promise<ContractManager | undefined>

async addContract(address: string, abi: Interface | InterfaceAbi): Promise<ContractManager | undefined>

async addContract(address: string | ethers.Contract, abi?: Interface | InterfaceAbi): Promise<ContractManager | undefined> {
addContract(address: string, contract: ethers.Contract): ContractManager | undefined
addContract(address: string, abi: Interface | InterfaceAbi): ContractManager | undefined
addContract(address: string, abi: Interface | InterfaceAbi | ethers.Contract): ContractManager | undefined {
if (this._provider) {
if (typeof address === 'string') {
if (abi instanceof Interface || Array.isArray(abi)) {
if (!abi)
throw new Error('ABI must be provided when address is a string')

const contract = new ContractManager(address, abi, this._provider)
this._contracts.set(address, contract)
return contract
}
else if (address instanceof ethers.Contract) {
const contractAddress = await address.getAddress()
const contract = new ContractManager(contractAddress, address.interface, this._provider)
this._contracts.set(contractAddress, contract)
else if (abi instanceof ethers.Contract) {
const contract = new ContractManager(address, abi.interface, this._provider)
this._contracts.set(address, contract)
return contract
}
else {
Expand Down

0 comments on commit c0a9490

Please sign in to comment.