init
This commit is contained in:
commit
44f31f8b9f
402 changed files with 47865 additions and 0 deletions
201
services/registry/index.js
Normal file
201
services/registry/index.js
Normal file
|
@ -0,0 +1,201 @@
|
|||
import namehash from 'eth-ens-namehash'
|
||||
import { BigNumber as BN } from 'bignumber.js'
|
||||
import { toChecksumAddress } from 'web3-utils'
|
||||
|
||||
import { graph } from '@/services'
|
||||
import networkConfig from '@/networkConfig'
|
||||
import { REGISTRY_DEPLOYED_BLOCK } from '@/constants'
|
||||
|
||||
import AggregatorABI from '@/abis/Aggregator.abi.json'
|
||||
import RelayerRegistryABI from '@/abis/RelayerRegistry.abi.json'
|
||||
|
||||
const MIN_STAKE_BALANCE = '0x22B1C8C1227A00000' // 40 TORN
|
||||
|
||||
const subdomains = Object.values(networkConfig).map(({ ensSubdomainKey }) => ensSubdomainKey)
|
||||
|
||||
class RelayerRegister {
|
||||
constructor(provider) {
|
||||
this.provider = provider
|
||||
this.$indexedDB = window.$nuxt.$indexedDB
|
||||
|
||||
const { registryContract, aggregatorContract } = networkConfig.netId1
|
||||
|
||||
this.aggregator = new this.provider.Contract(AggregatorABI, aggregatorContract)
|
||||
this.relayerRegistry = new this.provider.Contract(RelayerRegistryABI, registryContract)
|
||||
}
|
||||
|
||||
fetchEvents = async (fromBlock, toBlock) => {
|
||||
if (fromBlock <= toBlock) {
|
||||
try {
|
||||
const registeredEventsPart = await this.relayerRegistry.getPastEvents('RelayerRegistered', {
|
||||
fromBlock,
|
||||
toBlock
|
||||
})
|
||||
|
||||
return registeredEventsPart
|
||||
} catch (error) {
|
||||
const midBlock = (fromBlock + toBlock) >> 1
|
||||
|
||||
if (midBlock - fromBlock < 2) {
|
||||
throw new Error(`error fetching events: ${error.message}`)
|
||||
}
|
||||
|
||||
const arr1 = await this.fetchEvents(fromBlock, midBlock)
|
||||
const arr2 = await this.fetchEvents(midBlock + 1, toBlock)
|
||||
return [...arr1, ...arr2]
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
saveEvents = async ({ events, lastSyncBlock, storeName }) => {
|
||||
try {
|
||||
if (this.$indexedDB.isBlocked) {
|
||||
return
|
||||
}
|
||||
|
||||
await this.$indexedDB.putItem({
|
||||
data: {
|
||||
blockNumber: lastSyncBlock,
|
||||
name: storeName
|
||||
},
|
||||
storeName: 'lastEvents_1'
|
||||
})
|
||||
|
||||
if (events.length) {
|
||||
this.$indexedDB.createMultipleTransactions({ data: events, storeName })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`saveEvents has error: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
getCachedData = async () => {
|
||||
let blockFrom = REGISTRY_DEPLOYED_BLOCK[1]
|
||||
|
||||
try {
|
||||
const blockTo = await this.provider.getBlockNumber()
|
||||
|
||||
const cachedEvents = await this.$indexedDB.getAll({
|
||||
storeName: 'register_events'
|
||||
})
|
||||
|
||||
const lastBlock = await this.$indexedDB.getFromIndex({
|
||||
indexName: 'name',
|
||||
key: 'register_events',
|
||||
storeName: 'lastEvents_1'
|
||||
})
|
||||
|
||||
if (lastBlock) {
|
||||
blockFrom = blockTo >= lastBlock.blockNumber ? lastBlock.blockNumber + 1 : blockTo
|
||||
}
|
||||
|
||||
return { blockFrom, blockTo, cachedEvents }
|
||||
} catch {
|
||||
return { blockFrom, blockTo: 'latest', cachedEvents: [] }
|
||||
}
|
||||
}
|
||||
|
||||
fetchRelayers = async () => {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { blockFrom, blockTo, cachedEvents } = await this.getCachedData()
|
||||
let allRelayers = cachedEvents
|
||||
|
||||
if (blockFrom !== blockTo) {
|
||||
const registeredRelayersEvents = await graph.getAllRegisters(blockFrom)
|
||||
|
||||
let relayers = {
|
||||
lastSyncBlock: registeredRelayersEvents.lastSyncBlock,
|
||||
events: registeredRelayersEvents.events.map((el) => ({
|
||||
ensName: el.ensName,
|
||||
relayerAddress: toChecksumAddress(el.address)
|
||||
}))
|
||||
}
|
||||
|
||||
const isGraphLate = relayers.lastSyncBlock && blockTo > Number(relayers.lastSyncBlock)
|
||||
|
||||
if (isGraphLate) {
|
||||
blockFrom = relayers.lastSyncBlock
|
||||
}
|
||||
|
||||
if (!relayers.events.length || isGraphLate) {
|
||||
const multicallEvents = await this.fetchEvents(blockFrom, blockTo)
|
||||
const eventsRelayers = multicallEvents.map(({ returnValues }) => ({
|
||||
ensName: returnValues.ensName,
|
||||
relayerAddress: returnValues.relayerAddress
|
||||
}))
|
||||
|
||||
relayers = {
|
||||
lastSyncBlock: blockTo,
|
||||
events: relayers.events.concat(eventsRelayers)
|
||||
}
|
||||
}
|
||||
|
||||
await this.saveEvents({ storeName: 'register_events', ...relayers })
|
||||
allRelayers = allRelayers.concat(relayers.events)
|
||||
}
|
||||
|
||||
return allRelayers
|
||||
}
|
||||
|
||||
filterRelayer = (acc, curr, ensSubdomainKey, relayer) => {
|
||||
const subdomainIndex = subdomains.indexOf(ensSubdomainKey)
|
||||
|
||||
const mainnetSubdomain = curr.records[0]
|
||||
const hostname = curr.records[subdomainIndex]
|
||||
const isHostWithProtocol = hostname.includes('http')
|
||||
|
||||
const isOwner = relayer.relayerAddress === curr.owner
|
||||
const hasMinBalance = new BN(curr.balance).gte(MIN_STAKE_BALANCE)
|
||||
|
||||
if (
|
||||
hostname &&
|
||||
isOwner &&
|
||||
mainnetSubdomain &&
|
||||
curr.isRegistered &&
|
||||
hasMinBalance &&
|
||||
!isHostWithProtocol
|
||||
) {
|
||||
acc.push({
|
||||
hostname,
|
||||
ensName: relayer.ensName,
|
||||
stakeBalance: curr.balance,
|
||||
relayerAddress: relayer.relayerAddress
|
||||
})
|
||||
} else {
|
||||
console.error(`${relayer.ensName} invalid: `, {
|
||||
isOwner,
|
||||
hasTXT: Boolean(hostname),
|
||||
isHasMinBalance: hasMinBalance,
|
||||
isRegistered: curr.isRegistered,
|
||||
isHostWithoutProtocol: !isHostWithProtocol,
|
||||
isMainnetSubdomain: Boolean(mainnetSubdomain)
|
||||
})
|
||||
}
|
||||
|
||||
return acc
|
||||
}
|
||||
|
||||
getValidRelayers = async (relayers, ensSubdomainKey) => {
|
||||
const relayerNameHashes = relayers.map((r) => namehash.hash(r.ensName))
|
||||
|
||||
const relayersData = await this.aggregator.methods.relayersData(relayerNameHashes, subdomains).call()
|
||||
|
||||
const validRelayers = relayersData.reduce(
|
||||
(acc, curr, index) => this.filterRelayer(acc, curr, ensSubdomainKey, relayers[index]),
|
||||
[]
|
||||
)
|
||||
|
||||
return validRelayers
|
||||
}
|
||||
|
||||
getRelayers = async (ensSubdomainKey) => {
|
||||
const relayers = await this.fetchRelayers()
|
||||
|
||||
const validRelayers = await this.getValidRelayers(relayers, ensSubdomainKey)
|
||||
|
||||
return validRelayers
|
||||
}
|
||||
}
|
||||
|
||||
export const relayerRegisterService = (provider) => new RelayerRegister(provider.eth)
|
Loading…
Add table
Add a link
Reference in a new issue