|
@@ -1,125 +1,224 @@
|
|
-import { ApiPromise } from "@polkadot/api";
|
|
|
|
-import { Option, u32, Vec } from "@polkadot/types";
|
|
|
|
-import type { Codec, Observable } from "@polkadot/types/types";
|
|
|
|
|
|
+import { ApiPromise } from '@polkadot/api'
|
|
|
|
+import moment from 'moment'
|
|
|
|
+
|
|
|
|
+// types
|
|
|
|
+import { AccountBalance, ElectionInfo, Round, ProposalDetail } from './types'
|
|
|
|
+import { Option, u32, u64, Vec } from '@polkadot/types'
|
|
|
|
+import type { Codec, Observable } from '@polkadot/types/types'
|
|
import {
|
|
import {
|
|
AccountId,
|
|
AccountId,
|
|
|
|
+ AccountInfo,
|
|
|
|
+ AccountData,
|
|
Balance,
|
|
Balance,
|
|
- BalanceOf,
|
|
|
|
BlockNumber,
|
|
BlockNumber,
|
|
EraIndex,
|
|
EraIndex,
|
|
EventRecord,
|
|
EventRecord,
|
|
Hash,
|
|
Hash,
|
|
Moment,
|
|
Moment,
|
|
-} from "@polkadot/types/interfaces";
|
|
|
|
-import { SignedBlock } from "@polkadot/types/interfaces/runtime";
|
|
|
|
-
|
|
|
|
-import { PostId, ThreadId } from "@joystream/types/common";
|
|
|
|
-import { CategoryId } from "@joystream/types/forum";
|
|
|
|
-import { ElectionStake, SealedVote, Seats } from "@joystream/types/council";
|
|
|
|
-import { Mint, MintId } from "@joystream/types/mint";
|
|
|
|
-import { MemberId, Membership } from "@joystream/types/members";
|
|
|
|
-import { WorkerId } from "@joystream/types/working-group";
|
|
|
|
-import { Stake, StakeId } from "@joystream/types/stake";
|
|
|
|
|
|
+} from '@polkadot/types/interfaces'
|
|
|
|
+import { SignedBlock } from '@polkadot/types/interfaces/runtime'
|
|
|
|
+
|
|
|
|
+import { PostId, ThreadId } from '@joystream/types/common'
|
|
|
|
+import { CategoryId, Category, Thread, Post } from '@joystream/types/forum'
|
|
|
|
+import {
|
|
|
|
+ ElectionStage,
|
|
|
|
+ ElectionStake,
|
|
|
|
+ SealedVote,
|
|
|
|
+ Seats,
|
|
|
|
+} from '@joystream/types/council'
|
|
|
|
+import { Entity, EntityId } from '@joystream/types/content-directory'
|
|
|
|
+import { ContentId, DataObject } from '@joystream/types/media'
|
|
|
|
+import { MemberId, Membership } from '@joystream/types/members'
|
|
|
|
+import { Mint, MintId } from '@joystream/types/mint'
|
|
|
|
+import {
|
|
|
|
+ Proposal,
|
|
|
|
+ ProposalId,
|
|
|
|
+ ProposalDetails,
|
|
|
|
+ DiscussionPost,
|
|
|
|
+ SpendingParams,
|
|
|
|
+ VoteKind,
|
|
|
|
+} from '@joystream/types/proposals'
|
|
|
|
+import { Stake, StakeId } from '@joystream/types/stake'
|
|
import {
|
|
import {
|
|
RewardRelationship,
|
|
RewardRelationship,
|
|
RewardRelationshipId,
|
|
RewardRelationshipId,
|
|
-} from "@joystream/types/recurring-rewards";
|
|
|
|
-
|
|
|
|
-import { Entity, EntityId } from "@joystream/types/content-directory";
|
|
|
|
-import { ContentId, DataObject } from "@joystream/types/media";
|
|
|
|
-
|
|
|
|
-import { SpendingParams } from "@joystream/types/proposals";
|
|
|
|
-import { ProposalId, WorkerOf } from "@joystream/types/augment-codec/all";
|
|
|
|
-import { ProposalDetails, ProposalOf } from "@joystream/types/augment/types";
|
|
|
|
|
|
+} from '@joystream/types/recurring-rewards'
|
|
|
|
+import { WorkerId, Worker } from '@joystream/types/working-group'
|
|
|
|
|
|
// blocks
|
|
// blocks
|
|
export const getBlock = (api: ApiPromise, hash: Hash): Promise<SignedBlock> =>
|
|
export const getBlock = (api: ApiPromise, hash: Hash): Promise<SignedBlock> =>
|
|
- api.rpc.chain.getBlock(hash);
|
|
|
|
|
|
+ api.rpc.chain.getBlock(hash)
|
|
|
|
|
|
-export const getBlockHash = (api: ApiPromise, block: number): Promise<Hash> =>
|
|
|
|
- api.rpc.chain.getBlockHash(block);
|
|
|
|
|
|
+export const getBlockHash = (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ block: BlockNumber | number
|
|
|
|
+): Promise<Hash> => {
|
|
|
|
+ try {
|
|
|
|
+ return api.rpc.chain.getBlockHash(block)
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error(`BlockHash: ${block}`)
|
|
|
|
+ //const head =
|
|
|
|
+ //return api.query.system.blockHash(head)
|
|
|
|
+ //return api.query.system.parentHash()
|
|
|
|
+ return api.rpc.chain.getFinalizedHead()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
-export const getTimestamp = (api: ApiPromise, hash: Hash): Promise<Moment> =>
|
|
|
|
- api.query.timestamp.now.at(hash);
|
|
|
|
|
|
+export const getTimestamp = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash
|
|
|
|
+): Promise<number> =>
|
|
|
|
+ moment.utc((await api.query.timestamp.now.at(hash)).toNumber()).valueOf()
|
|
|
|
|
|
export const getIssuance = (api: ApiPromise, hash: Hash): Promise<Balance> =>
|
|
export const getIssuance = (api: ApiPromise, hash: Hash): Promise<Balance> =>
|
|
- api.query.balances.totalIssuance.at(hash);
|
|
|
|
|
|
+ api.query.balances.totalIssuance.at(hash)
|
|
|
|
|
|
export const getEvents = (
|
|
export const getEvents = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<Vec<EventRecord>> => api.query.system.events.at(hash);
|
|
|
|
|
|
+): Promise<Vec<EventRecord>> => api.query.system.events.at(hash)
|
|
|
|
|
|
-export const getEra = (
|
|
|
|
- api: ApiPromise,
|
|
|
|
- hash: Hash
|
|
|
|
-): Promise<Option<EraIndex>> => api.query.staking.currentEra.at(hash);
|
|
|
|
|
|
+export const getEra = async (api: ApiPromise, hash: Hash): Promise<number> =>
|
|
|
|
+ Number(api.query.staking.currentEra.at(hash))
|
|
|
|
|
|
export const getEraStake = async (
|
|
export const getEraStake = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
- era: EraIndex
|
|
|
|
|
|
+ era: EraIndex | number
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- (await api.query.staking.erasTotalStake.at(hash, era)).toNumber();
|
|
|
|
|
|
+ (await api.query.staking.erasTotalStake.at(hash, era)).toNumber()
|
|
|
|
|
|
// council
|
|
// council
|
|
export const getCouncil = (api: ApiPromise, hash: Hash): Promise<Seats> =>
|
|
export const getCouncil = (api: ApiPromise, hash: Hash): Promise<Seats> =>
|
|
- api.query.council.activeCouncil.at(hash);
|
|
|
|
|
|
+ api.query.council.activeCouncil.at(hash)
|
|
|
|
+
|
|
|
|
+export const getCouncils = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ head: number
|
|
|
|
+): Promise<Round[]> => {
|
|
|
|
+ // durations: [ announcing, voting, revealing, term, sum ]
|
|
|
|
+ // each chain starts with an election (duration: d[0]+d[1]+d[2])
|
|
|
|
+ // elections are repeated if not enough apply (round increments though)
|
|
|
|
+ // first term starts at begin of d[3] or some electionDuration later
|
|
|
|
+ // term lasts till the end of the next successful election
|
|
|
|
+ // `council.termEndsAt` returns the end of the current round
|
|
|
|
+ // to determine term starts check every electionDuration blocks
|
|
|
|
+
|
|
|
|
+ const d: number[] = await getCouncilElectionDurations(
|
|
|
|
+ api,
|
|
|
|
+ await getBlockHash(api, 1)
|
|
|
|
+ )
|
|
|
|
+ const electionDuration = d[0] + d[1] + d[2]
|
|
|
|
+
|
|
|
|
+ const starts: number[] = []
|
|
|
|
+ let lastEnd = 1
|
|
|
|
+ for (let block = lastEnd; block < head; block += electionDuration) {
|
|
|
|
+ const hash = await getBlockHash(api, block)
|
|
|
|
+ const end = Number(await api.query.council.termEndsAt.at(hash))
|
|
|
|
+ if (end === lastEnd) continue
|
|
|
|
+ lastEnd = end
|
|
|
|
+ starts.push(end - d[3] + 1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // index by round: each start is the end of the previous term
|
|
|
|
+ const rounds: { [key: number]: Round } = {}
|
|
|
|
+ await Promise.all(
|
|
|
|
+ starts.map(async (start: number, index: number) => {
|
|
|
|
+ const hash = await getBlockHash(api, start)
|
|
|
|
+ const round = await getCouncilRound(api, hash)
|
|
|
|
+ const isLast = index === starts.length - 1
|
|
|
|
+ const end = isLast ? start + d[4] : starts[index + 1] - 1
|
|
|
|
+ rounds[round] = { start, round, end }
|
|
|
|
+ })
|
|
|
|
+ )
|
|
|
|
+ return Object.values(rounds)
|
|
|
|
+}
|
|
|
|
|
|
export const getCouncilRound = async (
|
|
export const getCouncilRound = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.councilElection.round.at(hash)) as u32).toNumber();
|
|
|
|
|
|
+ ((await api.query.councilElection.round.at(hash)) as u32).toNumber()
|
|
|
|
+
|
|
|
|
+export const getCouncilElectionStage = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash
|
|
|
|
+): Promise<ElectionStage> =>
|
|
|
|
+ (await api.query.councilElection.stage.at(hash)) as ElectionStage
|
|
|
|
+
|
|
|
|
+export const getCouncilTermEnd = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash
|
|
|
|
+): Promise<number> =>
|
|
|
|
+ ((await api.query.council.termEndsAt.at(hash)) as BlockNumber).toNumber()
|
|
|
|
+
|
|
|
|
+export const getCouncilElectionStatus = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash
|
|
|
|
+): Promise<ElectionInfo> => {
|
|
|
|
+ const durations = await getCouncilElectionDurations(api, hash)
|
|
|
|
+ const round = await getCouncilRound(api, hash)
|
|
|
|
+ const stage: ElectionStage = await getCouncilElectionStage(api, hash)
|
|
|
|
+ const stageEndsAt: number = Number(stage.value as BlockNumber)
|
|
|
|
+ const termEndsAt: number = await getCouncilTermEnd(api, hash)
|
|
|
|
+ return { round, stageEndsAt, termEndsAt, stage, durations }
|
|
|
|
+}
|
|
|
|
|
|
export const getCouncilSize = async (
|
|
export const getCouncilSize = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.councilElection.councilSize.at(hash)) as u32).toNumber();
|
|
|
|
|
|
+ ((await api.query.councilElection.councilSize.at(hash)) as u32).toNumber()
|
|
|
|
|
|
export const getCouncilApplicants = (
|
|
export const getCouncilApplicants = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<Vec<AccountId>> => api.query.councilElection.applicants.at(hash);
|
|
|
|
|
|
+): Promise<Vec<AccountId>> => api.query.councilElection.applicants.at(hash)
|
|
|
|
|
|
export const getCouncilApplicantStakes = (
|
|
export const getCouncilApplicantStakes = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
applicant: AccountId
|
|
applicant: AccountId
|
|
): Promise<ElectionStake> =>
|
|
): Promise<ElectionStake> =>
|
|
- api.query.councilElection.applicantStakes.at(hash, applicant);
|
|
|
|
|
|
+ api.query.councilElection.applicantStakes.at(hash, applicant)
|
|
|
|
|
|
export const getCouncilCommitments = (
|
|
export const getCouncilCommitments = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<Vec<Hash>> => api.query.councilElection.commitments.at(hash);
|
|
|
|
|
|
+): Promise<Vec<Hash>> => api.query.councilElection.commitments.at(hash)
|
|
|
|
|
|
export const getCouncilPayoutInterval = (
|
|
export const getCouncilPayoutInterval = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<Option<BlockNumber>> => api.query.council.payoutInterval.at(hash);
|
|
|
|
|
|
+): Promise<Option<BlockNumber>> => api.query.council.payoutInterval.at(hash)
|
|
|
|
|
|
export const getCouncilPayout = (
|
|
export const getCouncilPayout = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<BalanceOf> => api.query.council.amountPerPayout.at(hash);
|
|
|
|
|
|
+): Promise<Balance> => api.query.council.amountPerPayout.at(hash)
|
|
|
|
+
|
|
|
|
+const getCouncilElectionPeriod = (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash,
|
|
|
|
+ period: string
|
|
|
|
+): Promise<BlockNumber> => api.query.councilElection[period].at(hash)
|
|
|
|
|
|
-const periods = [
|
|
|
|
- "announcingPeriod",
|
|
|
|
- "votingPeriod",
|
|
|
|
- "revealingPeriod",
|
|
|
|
- "newTermDuration",
|
|
|
|
-];
|
|
|
|
-export const getCouncilPeriods = (
|
|
|
|
|
|
+export const getCouncilElectionDurations = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<number>[] =>
|
|
|
|
- periods.map(async (period: string) =>
|
|
|
|
- ((await api.query.councilElection[period].at(
|
|
|
|
- hash
|
|
|
|
- )) as BlockNumber).toNumber()
|
|
|
|
- );
|
|
|
|
|
|
+): Promise<number[]> => {
|
|
|
|
+ const periods = [
|
|
|
|
+ 'announcingPeriod',
|
|
|
|
+ 'votingPeriod',
|
|
|
|
+ 'revealingPeriod',
|
|
|
|
+ 'newTermDuration',
|
|
|
|
+ ]
|
|
|
|
+ let durations = await Promise.all(
|
|
|
|
+ periods.map((period: string) => getCouncilElectionPeriod(api, hash, period))
|
|
|
|
+ ).then((d) => d.map((block: BlockNumber) => block.toNumber()))
|
|
|
|
+ durations.push(durations[0] + durations[1] + durations[2] + durations[3])
|
|
|
|
+ return durations
|
|
|
|
+}
|
|
|
|
|
|
// working groups
|
|
// working groups
|
|
export const getNextWorker = async (
|
|
export const getNextWorker = async (
|
|
@@ -127,98 +226,145 @@ export const getNextWorker = async (
|
|
group: string,
|
|
group: string,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query[group].nextWorkerId.at(hash)) as WorkerId).toNumber();
|
|
|
|
|
|
+ ((await api.query[group].nextWorkerId.at(hash)) as WorkerId).toNumber()
|
|
|
|
|
|
export const getWorker = (
|
|
export const getWorker = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
group: string,
|
|
group: string,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
id: number
|
|
id: number
|
|
-): Promise<WorkerOf> => api.query[group].workerById.at(hash, id);
|
|
|
|
|
|
+): Promise<Worker> => api.query[group].workerById.at(hash, id)
|
|
|
|
|
|
export const getWorkers = (
|
|
export const getWorkers = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
group: string,
|
|
group: string,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<number> => api.query[group].activeWorkerCount.at(hash);
|
|
|
|
|
|
+): Promise<number> => api.query[group].activeWorkerCount.at(hash)
|
|
|
|
|
|
export const getStake = async (
|
|
export const getStake = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
id: StakeId | number
|
|
id: StakeId | number
|
|
-): Promise<Stake> => (await api.query.stake.stakes(id)) as Stake;
|
|
|
|
|
|
+): Promise<Stake> => (await api.query.stake.stakes(id)) as Stake
|
|
|
|
|
|
export const getWorkerReward = (
|
|
export const getWorkerReward = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
id: RewardRelationshipId | number
|
|
id: RewardRelationshipId | number
|
|
): Promise<RewardRelationship> =>
|
|
): Promise<RewardRelationship> =>
|
|
- api.query.recurringRewards.rewardRelationships.at(hash, id);
|
|
|
|
|
|
+ api.query.recurringRewards.rewardRelationships.at(hash, id)
|
|
|
|
|
|
// mints
|
|
// mints
|
|
export const getCouncilMint = (api: ApiPromise, hash: Hash): Promise<MintId> =>
|
|
export const getCouncilMint = (api: ApiPromise, hash: Hash): Promise<MintId> =>
|
|
- api.query.council.councilMint.at(hash);
|
|
|
|
|
|
+ api.query.council.councilMint.at(hash)
|
|
|
|
|
|
export const getGroupMint = (
|
|
export const getGroupMint = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
group: string,
|
|
group: string,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<MintId> => api.query[group].mint.at(hash);
|
|
|
|
|
|
+): Promise<MintId> => api.query[group].mint.at(hash)
|
|
|
|
|
|
export const getMintsCreated = async (
|
|
export const getMintsCreated = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<number> => parseInt(await api.query.minting.mintsCreated.at(hash));
|
|
|
|
|
|
+): Promise<number> => parseInt(await api.query.minting.mintsCreated.at(hash))
|
|
|
|
|
|
export const getMint = (
|
|
export const getMint = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
id: MintId | number
|
|
id: MintId | number
|
|
-): Promise<Mint> => api.query.minting.mints.at(hash, id);
|
|
|
|
|
|
+): Promise<Mint> => api.query.minting.mints.at(hash, id)
|
|
|
|
|
|
// members
|
|
// members
|
|
|
|
+export const getAccounts = async (
|
|
|
|
+ api: ApiPromise
|
|
|
|
+): Promise<AccountBalance[]> => {
|
|
|
|
+ let accounts: AccountBalance[] = []
|
|
|
|
+ const entries = await api.query.system.account.entries()
|
|
|
|
+ for (const account of entries) {
|
|
|
|
+ const accountId = String(account[0].toHuman())
|
|
|
|
+ const balance = account[1].data.toJSON() as unknown as AccountData
|
|
|
|
+ accounts.push({ accountId, balance })
|
|
|
|
+ }
|
|
|
|
+ return accounts
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const getAccount = (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ hash: Hash,
|
|
|
|
+ account: AccountId | string
|
|
|
|
+): Promise<AccountInfo> => api.query.system.account.at(hash, account)
|
|
|
|
+
|
|
export const getNextMember = async (
|
|
export const getNextMember = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.members.nextMemberId.at(hash)) as MemberId).toNumber();
|
|
|
|
|
|
+ ((await api.query.members.nextMemberId.at(hash)) as MemberId).toNumber()
|
|
|
|
|
|
-export const getMember = (
|
|
|
|
|
|
+export const getMember = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
- hash: Hash,
|
|
|
|
- id: MemberId
|
|
|
|
-): Promise<Membership> => api.query.members.membershipById.at(hash, id);
|
|
|
|
|
|
+ id: MemberId | number,
|
|
|
|
+ hash?: Hash
|
|
|
|
+): Promise<Membership> =>
|
|
|
|
+ (await (hash
|
|
|
|
+ ? api.query.members.membershipById.at(hash, id)
|
|
|
|
+ : api.query.members.membershipById(id))) as Membership
|
|
|
|
+
|
|
|
|
+export const getMemberIdByAccount = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ accountId: AccountId
|
|
|
|
+): Promise<MemberId> => {
|
|
|
|
+ const ids = (await api.query.members.memberIdsByRootAccountId(
|
|
|
|
+ accountId
|
|
|
|
+ )) as Vec<MemberId>
|
|
|
|
+ return ids[0]
|
|
|
|
+}
|
|
|
|
|
|
// forum
|
|
// forum
|
|
export const getNextPost = async (
|
|
export const getNextPost = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.forum.nextPostId.at(hash)) as PostId).toNumber();
|
|
|
|
|
|
+ ((await api.query.forum.nextPostId.at(hash)) as PostId).toNumber()
|
|
|
|
|
|
export const getNextThread = async (
|
|
export const getNextThread = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.forum.nextThreadId.at(hash)) as ThreadId).toNumber();
|
|
|
|
|
|
+ ((await api.query.forum.nextThreadId.at(hash)) as ThreadId).toNumber()
|
|
|
|
|
|
export const getNextCategory = async (
|
|
export const getNextCategory = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.forum.nextCategoryId.at(hash)) as CategoryId).toNumber();
|
|
|
|
|
|
+ ((await api.query.forum.nextCategoryId.at(hash)) as CategoryId).toNumber()
|
|
|
|
+
|
|
|
|
+export const getCategory = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ id: number
|
|
|
|
+): Promise<Category> => (await api.query.forum.categoryById(id)) as Category
|
|
|
|
+
|
|
|
|
+export const getThread = async (api: ApiPromise, id: number): Promise<Thread> =>
|
|
|
|
+ (await api.query.forum.threadById(id)) as Thread
|
|
|
|
+
|
|
|
|
+export const getPost = async (api: ApiPromise, id: number): Promise<Post> =>
|
|
|
|
+ (await api.query.forum.postById(id)) as Post
|
|
|
|
|
|
// proposals
|
|
// proposals
|
|
export const getProposalCount = async (
|
|
export const getProposalCount = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
- hash: Hash
|
|
|
|
|
|
+ hash?: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.proposalsEngine.proposalCount.at(hash)) as u32).toNumber();
|
|
|
|
|
|
+ (
|
|
|
|
+ (await (hash
|
|
|
|
+ ? api.query.proposalsEngine.proposalCount.at(hash)
|
|
|
|
+ : api.query.proposalsEngine.proposalCount())) as u32
|
|
|
|
+ ).toNumber()
|
|
|
|
|
|
export const getProposalInfo = async (
|
|
export const getProposalInfo = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
id: ProposalId
|
|
id: ProposalId
|
|
-): Promise<ProposalOf> =>
|
|
|
|
- (await api.query.proposalsEngine.proposals(id)) as ProposalOf;
|
|
|
|
|
|
+): Promise<Proposal> =>
|
|
|
|
+ (await api.query.proposalsEngine.proposals(id)) as Proposal
|
|
|
|
|
|
export const getProposalDetails = async (
|
|
export const getProposalDetails = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
@@ -226,56 +372,147 @@ export const getProposalDetails = async (
|
|
): Promise<ProposalDetails> =>
|
|
): Promise<ProposalDetails> =>
|
|
(await api.query.proposalsCodex.proposalDetailsByProposalId(
|
|
(await api.query.proposalsCodex.proposalDetailsByProposalId(
|
|
id
|
|
id
|
|
- )) as ProposalDetails;
|
|
|
|
|
|
+ )) as ProposalDetails
|
|
|
|
+
|
|
|
|
+export const getProposalType = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ id: ProposalId
|
|
|
|
+): Promise<string> => {
|
|
|
|
+ const details = (await getProposalDetails(api, id)) as ProposalDetails
|
|
|
|
+ const [type]: string[] = Object.getOwnPropertyNames(details.toJSON())
|
|
|
|
+ return type
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const getProposal = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ id: ProposalId
|
|
|
|
+): Promise<ProposalDetail> => {
|
|
|
|
+ const proposal = await getProposalInfo(api, id)
|
|
|
|
+ const status: { [key: string]: any } = proposal.status
|
|
|
|
+ const stage: string = status.isActive ? 'Active' : 'Finalized'
|
|
|
|
+ const { finalizedAt, proposalStatus } = status[`as${stage}`]
|
|
|
|
+ const result: string = proposalStatus
|
|
|
|
+ ? (proposalStatus.isApproved && 'Approved') ||
|
|
|
|
+ (proposalStatus.isCanceled && 'Canceled') ||
|
|
|
|
+ (proposalStatus.isExpired && 'Expired') ||
|
|
|
|
+ (proposalStatus.isRejected && 'Rejected') ||
|
|
|
|
+ (proposalStatus.isSlashed && 'Slashed') ||
|
|
|
|
+ (proposalStatus.isVetoed && 'Vetoed')
|
|
|
|
+ : 'Pending'
|
|
|
|
+ const exec = proposalStatus ? proposalStatus['Approved'] : null
|
|
|
|
+
|
|
|
|
+ const { description, parameters, proposerId, votingResults } = proposal
|
|
|
|
+ const member = await getMember(api, proposerId)
|
|
|
|
+ const author = String(member ? member.handle : proposerId)
|
|
|
|
+ const title = proposal.title.toString()
|
|
|
|
+ const type = await getProposalType(api, id)
|
|
|
|
+ const args: string[] = [String(id), title, type, stage, result, author]
|
|
|
|
+ const message: string = `` //formatProposalMessage(args)
|
|
|
|
+ const created: number = Number(proposal.createdAt)
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ id: Number(id),
|
|
|
|
+ title,
|
|
|
|
+ created,
|
|
|
|
+ finalizedAt,
|
|
|
|
+ parameters: JSON.stringify(parameters),
|
|
|
|
+ message,
|
|
|
|
+ stage,
|
|
|
|
+ result,
|
|
|
|
+ exec,
|
|
|
|
+ description: description.toHuman(),
|
|
|
|
+ votes: votingResults,
|
|
|
|
+ type,
|
|
|
|
+ author,
|
|
|
|
+ authorId: Number(proposerId),
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const getProposalVotes = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ id: ProposalId | number
|
|
|
|
+): Promise<{ memberId: number; vote: string }[]> => {
|
|
|
|
+ let votes: { memberId: number; vote: string }[] = []
|
|
|
|
+ const entries =
|
|
|
|
+ await api.query.proposalsEngine.voteExistsByProposalByVoter.entries(id)
|
|
|
|
+ entries.forEach((entry: any) => {
|
|
|
|
+ const memberId = entry[0].args[1].toJSON()
|
|
|
|
+ const vote = entry[1].toString()
|
|
|
|
+ votes.push({ memberId, vote })
|
|
|
|
+ })
|
|
|
|
+ return votes
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const getProposalPost = async (
|
|
|
|
+ api: ApiPromise,
|
|
|
|
+ threadId: ThreadId | number,
|
|
|
|
+ postId: PostId | number
|
|
|
|
+): Promise<DiscussionPost> =>
|
|
|
|
+ (await api.query.proposalsDiscussion.postThreadIdByPostId(
|
|
|
|
+ threadId,
|
|
|
|
+ postId
|
|
|
|
+ )) as DiscussionPost
|
|
|
|
+
|
|
|
|
+export const getProposalPostCount = async (api: ApiPromise): Promise<number> =>
|
|
|
|
+ Number((await api.query.proposalsDiscussion.postCount()) as u64)
|
|
|
|
+
|
|
|
|
+export const getProposalThreadCount = async (
|
|
|
|
+ api: ApiPromise
|
|
|
|
+): Promise<number> =>
|
|
|
|
+ Number((await api.query.proposalsDiscussion.threadCount()) as u64)
|
|
|
|
|
|
// validators
|
|
// validators
|
|
export const getValidatorCount = async (
|
|
export const getValidatorCount = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.staking.validatorCount.at(hash)) as u32).toNumber();
|
|
|
|
|
|
+ ((await api.query.staking.validatorCount.at(hash)) as u32).toNumber()
|
|
|
|
|
|
-export const getValidators = (
|
|
|
|
|
|
+export const getValidators = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<Option<Vec<AccountId>>> =>
|
|
|
|
- api.query.staking.snapshotValidators.at(hash);
|
|
|
|
|
|
+): Promise<AccountId[]> =>
|
|
|
|
+ (
|
|
|
|
+ (await api.query.staking.snapshotValidators.at(hash)) as Option<
|
|
|
|
+ Vec<AccountId>
|
|
|
|
+ >
|
|
|
|
+ ).unwrap()
|
|
|
|
|
|
// media
|
|
// media
|
|
export const getNextEntity = async (
|
|
export const getNextEntity = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
): Promise<number> =>
|
|
): Promise<number> =>
|
|
- ((await api.query.contentDirectory.nextEntityId.at(
|
|
|
|
- hash
|
|
|
|
- )) as EntityId).toNumber();
|
|
|
|
|
|
+ (
|
|
|
|
+ (await api.query.contentDirectory.nextEntityId.at(hash)) as EntityId
|
|
|
|
+ ).toNumber()
|
|
|
|
|
|
export const getNextChannel = async (
|
|
export const getNextChannel = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<number> => api.query.content.nextChannelId.at(hash);
|
|
|
|
|
|
+): Promise<number> => api.query.content.nextChannelId.at(hash)
|
|
|
|
|
|
export const getNextVideo = async (
|
|
export const getNextVideo = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash
|
|
hash: Hash
|
|
-): Promise<number> => api.query.content.nextVideoId.at(hash);
|
|
|
|
|
|
+): Promise<number> => api.query.content.nextVideoId.at(hash)
|
|
|
|
|
|
export const getEntity = (
|
|
export const getEntity = (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
hash: Hash,
|
|
hash: Hash,
|
|
id: number
|
|
id: number
|
|
-): Promise<Entity> => api.query.contentDirectory.entityById.at(hash, id);
|
|
|
|
|
|
+): Promise<Entity> => api.query.contentDirectory.entityById.at(hash, id)
|
|
|
|
|
|
export const getDataObjects = async (
|
|
export const getDataObjects = async (
|
|
api: ApiPromise
|
|
api: ApiPromise
|
|
): Promise<Map<ContentId, DataObject>> =>
|
|
): Promise<Map<ContentId, DataObject>> =>
|
|
- ((await api.query.dataDirectory.dataByContentId.entries()) as unknown) as Map<
|
|
|
|
|
|
+ (await api.query.dataDirectory.dataByContentId.entries()) as unknown as Map<
|
|
ContentId,
|
|
ContentId,
|
|
DataObject
|
|
DataObject
|
|
- >;
|
|
|
|
|
|
+ >
|
|
|
|
|
|
export const getDataObject = async (
|
|
export const getDataObject = async (
|
|
api: ApiPromise,
|
|
api: ApiPromise,
|
|
id: ContentId
|
|
id: ContentId
|
|
): Promise<Option<DataObject>> =>
|
|
): Promise<Option<DataObject>> =>
|
|
- (await api.query.dataDirectory.dataByContentId(id)) as Option<DataObject>;
|
|
|
|
|
|
+ (await api.query.dataDirectory.dataByContentId(id)) as Option<DataObject>
|