import { ApiPromise, WsProvider } from '@polkadot/api' import { wsLocation } from '../config.json' import { memberHandle, memberIdByAccount } from './lib/getters' // types import { Api } from '../types' import { Hash } from '@polkadot/types/interfaces' import { types } from '@joystream/types' import { RewardRelationship, RewardRelationshipId, } from '@joystream/types/recurring-rewards' import { MemberId } from '@joystream/types/members' import { Stake } from '@joystream/types/stake' import { WorkerId } from '@joystream/types/working-group' import { WorkerOf } from '@joystream/types/augment-codec/all' const PRICE = 30 / 1000000 // TODO // api calls const getBlockHash = (api: Api, blockId: number) => api.rpc.chain.getBlockHash(blockId).then((array: any) => array.toHuman()) const nextWorker = (api: Api, group: string, hash: Hash) => api.query[group].nextWorkerId.at(hash) const getWorker = (api: Api, group: string, id: number) => api.query[group].workerById(id) const getStake = (api: Api, id: number) => api.query.stake.stakes(id) const getReward = (api: Api, hash: Hash, id: RewardRelationshipId) => api.query.recurringRewards.rewardRelationships.at(hash, id) const formatTokens = (amount: number) => (amount / 1000000).toFixed(1) // calculations const computeReward = async ( api: Api, blocks: number, ids: RewardRelationshipId[], hash: Hash ): Promise<[number, string]> => { let recurringRewards: RewardRelationship[] = await Promise.all( ids.map((id) => getReward(api, hash, id)) ) let report = `` let rewardPerBlock = 0 for (let recurringReward of recurringRewards) { const amount = recurringReward.amount_per_payout.toNumber() const payoutInterval = recurringReward.payout_interval.unwrapOr(null) if (amount && payoutInterval) { const amountPerBlock = amount / +payoutInterval rewardPerBlock += amountPerBlock const id: MemberId = await memberIdByAccount(api, recurringReward.account) if (!id) continue const handle = await memberHandle(api, id) const earned = amountPerBlock * blocks const dailyDollar = (14400 * amountPerBlock * PRICE).toFixed(1) const totalEarned = +recurringReward.total_reward_received const earnedDollar = (earned * PRICE).toFixed() const totalEarnedDollar = (totalEarned * PRICE).toFixed() report += workerRow( id.toNumber(), handle, amountPerBlock.toFixed(), formatTokens(earned), dailyDollar, earnedDollar, formatTokens(totalEarned), totalEarnedDollar ) } } return [rewardPerBlock * blocks, report] } export const getSalaries = async ( api: any, group: string, blocks: number, startHash: Hash, endHash: Hash ) => { const nextWorkerId = ((await nextWorker( api, group, endHash )) as WorkerId).toNumber() let ids: RewardRelationshipId[] = [] let totalStake = 0 for (let i = 0; i < nextWorkerId; ++i) { let worker = (await getWorker(api, group, i)) as WorkerOf if (worker.reward_relationship.isSome) ids.push(worker.reward_relationship.unwrap()) if (worker.role_stake_profile.isSome) { let roleStakeProfile = worker.role_stake_profile.unwrap() const id = Number(roleStakeProfile.stake_id) let stake = (await getStake(api, id)) as Stake totalStake += stake.value.toNumber() } } let [sum, report] = await computeReward(api, blocks, ids, endHash) const staked = formatTokens(totalStake) const rewards = formatTokens(sum) const stakedDollar = (totalStake * PRICE).toFixed() const rewardsDollar = (sum * PRICE).toFixed() report += `- Rewards: ${rewards} M tJOY ($${rewardsDollar})\n- Stake: ${staked} M tJOY ($${stakedDollar})` return report } // output const tableHead = (group: string, start: number, end: number) => `# Salaries ${group} from ${start} to ${end}\n| # | Member | tJOY / Block | Daily $ | M tJOY / term | $ / term | Total M tJOY | Total $ |\n|--|--|--|--|--|--|--|--|\n` const workerRow = ( id: number, handle: string, perBlock: string, earned: string, dailyDollar: string, earnedDollar: string, totalEarned: string, totalDollar: string ) => `| ${id} | ${handle} | ${perBlock} | ${earned} | ${dailyDollar} | ${earnedDollar} | ${totalEarned} | ${totalDollar} |\n` // main const main = async () => { const provider = new WsProvider(wsLocation) const api = await ApiPromise.create({ provider, types }) await api.isReady const start = 1890000 const end = (await api.derive.chain.bestNumberFinalized()).toNumber() const startHash = await getBlockHash(api, start) const endHash = await getBlockHash(api, end) const group = 'operationsWorkingGroup' const report = await getSalaries(api, group, end - start, startHash, endHash) console.log(tableHead(group, start, end) + report) } main()