import { getAddress } from '@ethersproject/address' ; import { subgraphRequest } from '../../utils' ; export const author = 'noiach' ; export const version = '0.1.0' ; const RENVM_SUBGRAPH_URL = { '1' : 'https://api.thegraph.com/subgraphs/name/renproject/renvm' , '42' : 'https://api.thegraph.com/subgraphs/name/renproject/renvm-testnet' } ; const MONTH = 28 * 24 * 60 * 60 ; const QUERY_LIMIT = 1000 ; const RENVM_SUBGRAPH_QUERY = { darknodes : { __args : { first : QUERY_LIMIT , skip : 0 , where : { registeredAt_gt : 0 , registeredAt_lte : undefined } } , registeredAt : true , deregisteredAt : true , operator : true } } ; interface SubgraphDarknode { registeredAt : number ; deregisteredAt : number ; operator : string ; } export async function strategy ( space , network , provider , addresses , options , snapshot ) { if ( snapshot !== 'latest' ) { RENVM_SUBGRAPH_QUERY . darknodes . __args . block = { number : snapshot } ; } const timestamp = ( await provider . getBlock ( snapshot ) ) . timestamp ; RENVM_SUBGRAPH_QUERY . darknodes . __args . where . registeredAt_lte = timestamp ; let nodes = [ ] ; while ( nodes . length < 10000 ) { RENVM_SUBGRAPH_QUERY . darknodes . __args . skip = nodes . length ; const result = await subgraphRequest ( RENVM_SUBGRAPH_URL [ network ] , RENVM_SUBGRAPH_QUERY ) ; if ( result && result . darknodes ) { nodes = nodes . concat ( result . darknodes ) ; } else { break ; } if ( result . darknodes . length < QUERY_LIMIT ) { break ; } } const scores = addresses . reduce ( ( obj , address ) => ( { ... obj , [ getAddress ( address ) ] : 0 } ) , { } ) ; nodes . forEach ( ( darknode ) => { const nodeOperator = getAddress ( darknode . operator ) ; if ( scores [ nodeOperator ] === undefined ) { return ; } if ( darknode . deregisteredAt > 0 && darknode . deregisteredAt < timestamp ) { return ; } const timeRegistered = timestamp - darknode . registeredAt ; const score = Math . sqrt ( Math . ceil ( timeRegistered / MONTH ) ) ; scores [ nodeOperator ] += score ; } ) ; return scores ; }