import { ApiPromise } from '@polkadot/api' ; import { Option } from '@polkadot/types' ; import { AccountId , BlockNumber , EraIndex , Exposure , Hash , StakingLedger , ValidatorId , ValidatorPrefs , } from '@polkadot/types/interfaces' ; import { logger } from '@polkadot/util' ; import { prisma } from '../generated/prisma-client' ; import { filterEvents } from '../util/filterEvents' ; import { Cached , NomidotNominationAndValidators , Task } from './types' ; const l = logger ( 'Task: Nomination + Validators' ) ; const createNominationAndValidators = { name : 'createNominationAndValidators' , read : async ( blockHash , cached , api ) : Promise < Set < NomidotNominationAndValidators > > => { const result = new Set ( ) ; const { events , sessionIndex } = cached ; const didNewSessionStart = filterEvents ( events , 'session' , 'NewSession' ) . length > 0 ; if ( didNewSessionStart ) { const validators = await api . query . session . validators . at ( blockHash ) ; await Promise . all ( validators . map ( async ( validator ) => { const bonded = await api . query . staking . bonded . at ( blockHash , validator ) ; const ledger = await api . query . staking . ledger . at ( blockHash , validator ) ; if ( bonded . isNone && ledger . isNone ) { const result = { stakedAmount : null , session : sessionIndex , nominatorController : null , nominatorStash : null , validatorPreferences : null , validatorController : validator , validatorStash : validator , } ; return result ; } const validatorStash = bonded . isNone ? ledger . unwrap ( ) . stash : validator ; const validatorController = ledger . isSome && ledger . unwrap ( ) . stash ? validator : bonded . unwrap ( ) ; const validatorPreferences = await api . query . staking . validators . at ( blockHash , validatorStash ) ; let exposure ; if ( api . query . staking . stakers ) { exposure = await api . query . staking . stakers . at < Exposure > ( blockHash ) ; } else { const currentEra = await api . query . staking . currentEra . at ( blockHash ) ; exposure = await api . query . staking . erasStakers . at < Exposure > ( blockHash , currentEra . unwrap ( ) , validatorStash ) ; } await Promise . all ( exposure . others . map ( async ( individualExposure ) => { const { who , value } = individualExposure ; const bonded = await api . query . staking . bonded . at ( blockHash , who ) ; const ledger = await api . query . staking . ledger . at ( blockHash , who ) ; const nominatorStash = bonded . isNone ? ledger . unwrapOr ( { stash : null } ) . stash : who ; const nominatorController = ledger . isSome && ledger . unwrapOr ( { stash : null } ) . stash ? who : bonded . unwrapOr ( null ) ; result . add ( { nominatorStash , nominatorController , session : sessionIndex , stakedAmount : value , validatorController , validatorStash , validatorPreferences , } as NomidotNominationAndValidators ) ; } ) ) ; } ) ) ; } else { l . log ( 'Session did not change. Skipping....' ) ; } return result ; } , write : async ( blockNumber , values ) => { for await ( const nominationsAndValidators of values ) { const { stakedAmount , session , nominatorController , nominatorStash , validatorController , validatorStash , validatorPreferences , } = nominationsAndValidators ; await prisma . createValidator ( { session : { connect : { index : session . toNumber ( ) , } , } , controller : validatorController ? validatorController . toHex ( ) : '0x00' , stash : validatorStash ? validatorStash . toHex ( ) : '0x00' , preferences : validatorPreferences ? validatorPreferences . toHex ( ) : '0x00' , } ) ; await prisma . createNomination ( { session : { connect : { index : session . toNumber ( ) , } , } , validatorController : validatorController ? validatorController . toHex ( ) : '0x00' , validatorStash : validatorStash ? validatorStash . toHex ( ) : '0x00' , nominatorController : nominatorController ? nominatorController . toHex ( ) : '0x00' , nominatorStash : nominatorStash ? nominatorStash . toHex ( ) : '0x00' , stakedAmount : stakedAmount . toHex ( ) , } ) ; } } , } ; export default createNominationAndValidators ;