179 lines
5.3 KiB
TypeScript
179 lines
5.3 KiB
TypeScript
|
// ts-essentials
|
||
|
import { DeepRequired, Merge } from 'ts-essentials'
|
||
|
|
||
|
// Contract types
|
||
|
import { RelayerRegistry } from './deth/RelayerRegistry.js'
|
||
|
|
||
|
// Local imports
|
||
|
import { AsyncUtils, ErrorUtils } from '@tornado/sdk-utils'
|
||
|
import { Docs, Cache, Onchain, Options as DataOptions } from '@tornado/sdk-data'
|
||
|
import { Chain, Synchronizer, Options as ChainOptions, syncErrorHandler } from '@tornado/sdk-chain'
|
||
|
|
||
|
// @ts-ignore
|
||
|
import { toIndexableString } from 'pouchdb-collate'
|
||
|
import { match } from 'assert'
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECLARATIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
export namespace Options {
|
||
|
export type Cache = DataOptions.Cache
|
||
|
export type Sync = ChainOptions.Sync
|
||
|
}
|
||
|
|
||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPLEMENTATIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
export class Registrations extends Docs.Base {}
|
||
|
|
||
|
export class Stakes extends Docs.Base {}
|
||
|
|
||
|
export class Burns extends Docs.Base {}
|
||
|
|
||
|
export class RegistrationsCache extends Cache.Syncable<Registrations> {
|
||
|
// TODO: IMPLEMENT
|
||
|
buildDoc(response: any): Docs.Withdrawal {
|
||
|
return new Docs.Withdrawal(response)
|
||
|
}
|
||
|
getErrorHandlers(): Array<AsyncUtils.ErrorHandler> {
|
||
|
return [syncErrorHandler]
|
||
|
}
|
||
|
getCallbacks(registry: RelayerRegistry): Array<AsyncUtils.Callback> {
|
||
|
return [
|
||
|
(fromBlock: number, toBlock: number) => {
|
||
|
return registry.queryFilter(
|
||
|
registry.filters['RelayerRegistered(bytes32,string,address,uint256)'](null, null, null, null),
|
||
|
fromBlock,
|
||
|
toBlock
|
||
|
)
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class StakesCache extends Cache.Syncable<Stakes> {
|
||
|
// TODO: IMPLEMENT
|
||
|
buildDoc(response: any): Docs.Withdrawal {
|
||
|
return new Docs.Withdrawal(response)
|
||
|
}
|
||
|
getErrorHandlers(): Array<AsyncUtils.ErrorHandler> {
|
||
|
return [syncErrorHandler]
|
||
|
}
|
||
|
getCallbacks(registry: RelayerRegistry): Array<AsyncUtils.Callback> {
|
||
|
return [
|
||
|
(fromBlock: number, toBlock: number) => {
|
||
|
return registry.queryFilter(
|
||
|
registry.filters['StakeAddedToRelayer(address,uint256)'](null, null),
|
||
|
fromBlock,
|
||
|
toBlock
|
||
|
)
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class BurnsCache extends Cache.Syncable<Burns> {
|
||
|
// TODO: IMPLEMENT
|
||
|
buildDoc(response: any): Docs.Withdrawal {
|
||
|
return new Docs.Withdrawal(response)
|
||
|
}
|
||
|
getErrorHandlers(): Array<AsyncUtils.ErrorHandler> {
|
||
|
return [syncErrorHandler]
|
||
|
}
|
||
|
getCallbacks(registry: RelayerRegistry): Array<AsyncUtils.Callback> {
|
||
|
return [
|
||
|
(fromBlock: number, toBlock: number) => {
|
||
|
return registry.queryFilter(
|
||
|
registry.filters['StakeBurned(address,uint256)'](null, null),
|
||
|
fromBlock,
|
||
|
toBlock
|
||
|
)
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class Registry extends Synchronizer {
|
||
|
private _chain?: Chain
|
||
|
|
||
|
get chain(): Chain {
|
||
|
this._checkProvider('chain')
|
||
|
return this._chain!
|
||
|
}
|
||
|
|
||
|
constructor() {
|
||
|
super()
|
||
|
this.caches = new Map<string, Cache.Syncable<Docs.Base>>()
|
||
|
}
|
||
|
|
||
|
loadRegistrations(name: string, options?: Options.Cache): RegistrationsCache {
|
||
|
return this.loadCache<Registrations, RegistrationsCache>(name, options)
|
||
|
}
|
||
|
|
||
|
loadStakes(name: string, options?: Options.Cache): StakesCache {
|
||
|
return this.loadCache<Stakes, StakesCache>(name, options)
|
||
|
}
|
||
|
|
||
|
loadBurns(name: string, options?: Options.Cache): BurnsCache {
|
||
|
return this.loadCache<Burns, BurnsCache>(name, options)
|
||
|
}
|
||
|
|
||
|
loadCache<D extends Docs.Base, C extends Cache.Syncable<D> = Cache.Syncable<D>>(
|
||
|
name: string,
|
||
|
options?: Options.Cache
|
||
|
): C {
|
||
|
let constructor,
|
||
|
cache = super.loadCache(name)
|
||
|
|
||
|
if (!cache) {
|
||
|
const regexp = /([A-Za-z]+)([0-9]+)/
|
||
|
const matches = name.match(regexp)
|
||
|
|
||
|
if (!matches)
|
||
|
throw ErrorUtils.getError(`Registry.loadCache: name ${name} has wrong format for cache`)
|
||
|
|
||
|
// ETH net id
|
||
|
if (matches.length === 2)
|
||
|
name += "1"
|
||
|
|
||
|
if (matches[1] === 'Registrations') {
|
||
|
constructor = (name: string, options?: Options.Cache) => new RegistrationsCache(name, options)
|
||
|
} else if (matches[1] === 'Burns') {
|
||
|
constructor = (name: string, options?: Options.Cache) => new BurnsCache(name, options)
|
||
|
} else if (matches[1] === 'Stakes') {
|
||
|
constructor = (name: string, options?: Options.Cache) => new StakesCache(name, options)
|
||
|
} else throw ErrorUtils.getError(`Registry.loadCache: there exists no such event ${matches[1]}`)
|
||
|
|
||
|
cache = constructor(name, options)
|
||
|
this.caches.set(name, cache)
|
||
|
}
|
||
|
return cache as C
|
||
|
}
|
||
|
|
||
|
// TODO: FINISH
|
||
|
async _sync(
|
||
|
event: string,
|
||
|
networkId?: string,
|
||
|
options?: Merge<Options.Sync, Options.Cache>
|
||
|
): Promise<void> {
|
||
|
networkId = networkId ?? '1'
|
||
|
|
||
|
if (this.chain.id !== +networkId)
|
||
|
throw ErrorUtils.getError('Registry.syncRegistrations: provider bound to wrong chain!')
|
||
|
|
||
|
const registryAddress = await Onchain.getRegistryAddress(networkId)
|
||
|
|
||
|
options = options ?? {}
|
||
|
|
||
|
options.startBlock = options.startBlock ?? (await Onchain.getRegistryDeployBlockNum(networkId))
|
||
|
}
|
||
|
|
||
|
private _checkProvider(parentCallName: string): void {
|
||
|
if (!this._chain)
|
||
|
throw ErrorUtils.getError('Core.' + parentCallName + ': you must first connect a provider!')
|
||
|
}
|
||
|
|
||
|
protected async _populateSyncOptions(options: Options.Sync): Promise<DeepRequired<Options.Sync>> {
|
||
|
options.targetBlock = options.targetBlock ?? (await this.chain.latestBlockNum())
|
||
|
return super._populateSyncOptions(options)
|
||
|
}
|
||
|
}
|