diff --git a/packages/api-derive/src/index.ts b/packages/api-derive/src/index.ts index 75ca705ec3..ac405fa274 100644 --- a/packages/api-derive/src/index.ts +++ b/packages/api-derive/src/index.ts @@ -16,6 +16,7 @@ import * as democracy from './democracy'; import * as elections from './elections'; import * as imOnline from './imOnline'; import * as session from './session'; +import * as society from './society'; import * as staking from './staking'; import * as technicalCommittee from './technicalCommittee'; import * as treasury from './treasury'; @@ -59,7 +60,7 @@ function injectFunctions (api: ApiInterfaceRx, allSections: AllSect }, {} as DeriveAllSections); } -export const derive = { accounts, balances, chain, contracts, council, democracy, elections, imOnline, session, staking, technicalCommittee, treasury }; +export const derive = { accounts, balances, chain, contracts, council, democracy, elections, imOnline, session, society, staking, technicalCommittee, treasury }; export type ExactDerive = DeriveAllSections; // FIXME The return type of this function should be {...ExactDerive, ...DeriveCustom} diff --git a/packages/api-derive/src/society/candidates.ts b/packages/api-derive/src/society/candidates.ts new file mode 100644 index 0000000000..0a22b3890e --- /dev/null +++ b/packages/api-derive/src/society/candidates.ts @@ -0,0 +1,45 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { ApiInterfaceRx } from '@polkadot/api/types'; +import { BalanceOf, Bid, BidKind } from '@polkadot/types/interfaces'; +import { ITuple } from '@polkadot/types/types'; +import { DeriveSocietyCandidate } from '../types'; + +import { combineLatest, of, Observable } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; +import { Option, Vec } from '@polkadot/types'; + +import { memo } from '../util'; + +type ResultSuspend = Option>; +type Result = [Bid[], ResultSuspend[]] + +/** + * @description Get the candidate info for a society + */ +export function candidates (api: ApiInterfaceRx): () => Observable { + return memo((): Observable => + api.query.society.candidates>().pipe( + switchMap((candidates: Vec): Observable => + combineLatest([ + of(candidates), + combineLatest( + candidates.map(({ who }: Bid): Observable => + api.query.society.suspendedCandidates(who) + ) + ) + ]) + ), + map(([candidates, suspended]: Result): DeriveSocietyCandidate[] => + candidates.map(({ who, kind, value }, index) => ({ + accountId: who, + isSuspended: suspended[index].isSome, + kind, + value + })) + ) + ) + ); +} diff --git a/packages/api-derive/src/society/index.ts b/packages/api-derive/src/society/index.ts new file mode 100644 index 0000000000..3a410cfb91 --- /dev/null +++ b/packages/api-derive/src/society/index.ts @@ -0,0 +1,8 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +export * from './candidates'; +export * from './info'; +export * from './member'; +export * from './members'; diff --git a/packages/api-derive/src/society/info.ts b/packages/api-derive/src/society/info.ts new file mode 100644 index 0000000000..c6b6c9cd1f --- /dev/null +++ b/packages/api-derive/src/society/info.ts @@ -0,0 +1,40 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { ApiInterfaceRx } from '@polkadot/api/types'; +import { AccountId, BalanceOf, Bid } from '@polkadot/types/interfaces'; +import { DeriveSociety } from '../types'; + +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { Option, Vec, u32 } from '@polkadot/types'; + +import { memo } from '../util'; + +type Result = [Vec, Option, Option, Option, u32, BalanceOf] + +/** + * @description Get the overall info for a society + */ +export function info (api: ApiInterfaceRx): () => Observable { + return memo((): Observable => + api.queryMulti([ + api.query.society.bids, + api.query.society.defender, + api.query.society.founder, + api.query.society.head, + api.query.society.maxMembers, + api.query.society.pot + ]).pipe( + map(([bids, defender, founder, head, maxMembers, pot]: Result): DeriveSociety => ({ + bids, + defender: defender.unwrapOr(undefined), + head: head.unwrapOr(undefined), + founder: founder.unwrapOr(undefined), + maxMembers, + pot + })) + ) + ); +} diff --git a/packages/api-derive/src/society/member.ts b/packages/api-derive/src/society/member.ts new file mode 100644 index 0000000000..a580848839 --- /dev/null +++ b/packages/api-derive/src/society/member.ts @@ -0,0 +1,46 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { ApiInterfaceRx } from '@polkadot/api/types'; +import { AccountId, Balance, BlockNumber, StrikeCount, VouchingStatus, Vote } from '@polkadot/types/interfaces'; +import { ITuple } from '@polkadot/types/types'; +import { DeriveSocietyMember } from '../types'; + +import { Observable, combineLatest } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { bool, Option, Vec } from '@polkadot/types'; + +import { memo } from '../util'; + +type ResultMulti = [Vec>, StrikeCount]; +type ResultSingle = [Option, bool, Option]; +type Result = [ResultMulti, ResultSingle]; + +/** + * @description Get the member info for a society + */ +export function member (api: ApiInterfaceRx): (accountId: AccountId) => Observable { + return memo((accountId: AccountId): Observable => + combineLatest([ + api.queryMulti([ + [api.query.society.payouts, accountId], + [api.query.society.strikes, accountId] + ]), + combineLatest([ + api.query.society.defenderVotes>(accountId), + api.query.society.suspendedMembers(accountId), + api.query.society.vouching>(accountId) + ]) + ]).pipe( + map(([[payouts, strikes], [defenderVote, suspended, vouching]]: Result): DeriveSocietyMember => ({ + accountId, + payouts, + isSuspended: !suspended.isEmpty, + strikes, + vote: defenderVote.unwrapOr(undefined), + vouching: vouching.unwrapOr(undefined) + })) + ) + ); +} diff --git a/packages/api-derive/src/society/members.ts b/packages/api-derive/src/society/members.ts new file mode 100644 index 0000000000..0728d6ed56 --- /dev/null +++ b/packages/api-derive/src/society/members.ts @@ -0,0 +1,27 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { ApiInterfaceRx } from '@polkadot/api/types'; +import { AccountId } from '@polkadot/types/interfaces'; +import { DeriveSocietyMember } from '../types'; + +import { combineLatest, Observable } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; + +import { memo } from '../util'; + +/** + * @description Get the member info for a society + */ +export function members (api: ApiInterfaceRx): () => Observable { + return memo((): Observable => + api.query.society.members().pipe( + switchMap((members): Observable => + combineLatest(members.map((accountId): Observable => + api.derive.society.member(accountId) + )) + ) + ) + ); +} diff --git a/packages/api-derive/src/types.ts b/packages/api-derive/src/types.ts index 29a36ee2da..497ae3ba22 100644 --- a/packages/api-derive/src/types.ts +++ b/packages/api-derive/src/types.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Hash, Index, Keys, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, StakingLedger, TreasuryProposal, ValidatorPrefs, Vote, Votes, VoteIndex } from '@polkadot/types/interfaces'; +import { AccountId, AccountIndex, Balance, BalanceLock, BalanceOf, Bid, BidKind, BlockNumber, EraIndex, EraPoints, Exposure, Hash, Index, Keys, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, StakingLedger, StrikeCount, TreasuryProposal, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces'; import BN from 'bn.js'; import { u32, Vec } from '@polkadot/types'; @@ -149,6 +149,31 @@ export interface DerivedSessionInfo extends DeriveSessionIndexes { sessionProgress: BlockNumber; } +export interface DeriveSociety { + bids: Bid[]; + defender?: AccountId; + head?: AccountId; + founder?: AccountId; + maxMembers: u32; + pot: BalanceOf; +} + +export interface DeriveSocietyCandidate { + accountId: AccountId; + kind: BidKind; + value: Balance; + isSuspended: boolean; +} + +export interface DeriveSocietyMember { + accountId: AccountId; + isSuspended: boolean; + payouts: [BlockNumber, Balance][]; + strikes: StrikeCount; + vote?: Vote; + vouching?: VouchingStatus; +} + export interface DerivedStakingElected { currentElected: AccountId[]; info: DerivedStakingQuery[];