Add council & treasury derives (#1654)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @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 './proposals';
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2017-2019 @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 { Hash, Proposal, Votes } from '@polkadot/types/interfaces';
|
||||
import { DerivedCouncilProposals } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
function retrieveProposals (api: ApiInterfaceRx, hashes: Hash[]): Observable<DerivedCouncilProposals> {
|
||||
return combineLatest([
|
||||
api.query.council.proposalOf.multi<Option<Proposal>>(hashes),
|
||||
api.query.council.voting.multi<Option<Votes>>(hashes)
|
||||
]).pipe(
|
||||
map(([proposals, votes]: [Option<Proposal>[], Option<Votes>[]]): DerivedCouncilProposals => {
|
||||
const result: DerivedCouncilProposals = [];
|
||||
|
||||
proposals.forEach((proposalOpt, index): void => {
|
||||
if (proposalOpt.isSome) {
|
||||
result.push({
|
||||
hash: hashes[index],
|
||||
proposal: proposalOpt.unwrap(),
|
||||
votes: votes[index].unwrapOr(null)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function proposals (api: ApiInterfaceRx): () => Observable<DerivedCouncilProposals> {
|
||||
return memo((): Observable<DerivedCouncilProposals> =>
|
||||
api.query.council
|
||||
? api.query.council.proposals().pipe(
|
||||
switchMap((proposals: Hash[]): Observable<DerivedCouncilProposals> =>
|
||||
retrieveProposals(api, proposals)
|
||||
)
|
||||
)
|
||||
: of([] as DerivedCouncilProposals)
|
||||
);
|
||||
}
|
||||
@@ -11,11 +11,13 @@ import * as accounts from './accounts';
|
||||
import * as balances from './balances';
|
||||
import * as chain from './chain';
|
||||
import * as contracts from './contracts';
|
||||
import * as council from './council';
|
||||
import * as democracy from './democracy';
|
||||
import * as elections from './elections';
|
||||
import * as imOnline from './imOnline';
|
||||
import * as session from './session';
|
||||
import * as staking from './staking';
|
||||
import * as treasury from './treasury';
|
||||
|
||||
export * from './type';
|
||||
|
||||
@@ -56,7 +58,7 @@ function injectFunctions<AllSections> (api: ApiInterfaceRx, allSections: AllSect
|
||||
}, {} as DeriveAllSections<AllSections>);
|
||||
}
|
||||
|
||||
export const derive = { accounts, balances, chain, contracts, democracy, elections, imOnline, session, staking };
|
||||
export const derive = { accounts, balances, chain, contracts, council, democracy, elections, imOnline, session, staking, treasury };
|
||||
export type ExactDerive = DeriveAllSections<typeof derive>;
|
||||
|
||||
// FIXME The return type of this function should be {...ExactDerive, ...DeriveCustom}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @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 './proposals';
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2017-2019 @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 { ProposalIndex, TreasuryProposal } from '@polkadot/types/interfaces';
|
||||
import { DerivedCouncilProposals, DerivedTreasuryProposal, DerivedTreasuryProposals } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { createType, Option } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
interface Result {
|
||||
allIds: ProposalIndex[];
|
||||
allProposals: Option<TreasuryProposal>[];
|
||||
approvalIds: ProposalIndex[];
|
||||
councilProposals: DerivedCouncilProposals;
|
||||
proposalCount: ProposalIndex;
|
||||
}
|
||||
|
||||
function parseResult (_api: ApiInterfaceRx, { allIds, allProposals, approvalIds, councilProposals, proposalCount }: Result): DerivedTreasuryProposals {
|
||||
const approvals: DerivedTreasuryProposal[] = [];
|
||||
const proposals: DerivedTreasuryProposal[] = [];
|
||||
const councilTreasury = councilProposals.filter(({ proposal: { methodName, sectionName } }): boolean =>
|
||||
sectionName === 'treasury' &&
|
||||
['approveProposal', 'rejectProposal'].includes(methodName)
|
||||
);
|
||||
|
||||
allIds.forEach((id, index): void => {
|
||||
if (allProposals[index].isSome) {
|
||||
const council = councilTreasury
|
||||
.filter(({ proposal }): boolean => id.eq(proposal.args[0]))
|
||||
.sort((a, b): number => a.proposal.methodName.localeCompare(b.proposal.methodName));
|
||||
const isApproval = approvalIds.some((approvalId): boolean => approvalId.eq(id));
|
||||
const derived = { council, id, proposal: allProposals[index].unwrap() };
|
||||
|
||||
if (isApproval) {
|
||||
approvals.push(derived);
|
||||
} else {
|
||||
proposals.push(derived);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { approvals, proposalCount, proposals };
|
||||
}
|
||||
|
||||
function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, approvalIds: ProposalIndex[]): Observable<DerivedTreasuryProposals> {
|
||||
const proposalIds: ProposalIndex[] = [];
|
||||
const count = proposalCount.toNumber();
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
const isApproval = approvalIds.some((id): boolean => id.eqn(index));
|
||||
|
||||
if (!isApproval) {
|
||||
proposalIds.push(createType(api.registry, 'ProposalIndex', index));
|
||||
}
|
||||
}
|
||||
|
||||
const allIds = [...proposalIds, ...approvalIds];
|
||||
|
||||
return combineLatest([
|
||||
api.query.treasury.proposals.multi<Option<TreasuryProposal>>(allIds),
|
||||
api.derive.council.proposals()
|
||||
]).pipe(
|
||||
map(([allProposals, councilProposals]: [Option<TreasuryProposal>[], DerivedCouncilProposals]): DerivedTreasuryProposals =>
|
||||
parseResult(api, { allIds, allProposals, approvalIds, councilProposals, proposalCount })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieve all active and approved treasury proposals, along with their info
|
||||
*/
|
||||
export function proposals (api: ApiInterfaceRx): () => Observable<DerivedTreasuryProposals> {
|
||||
return memo((): Observable<DerivedTreasuryProposals> =>
|
||||
api.query.treasury
|
||||
? combineLatest([
|
||||
api.query.treasury.proposalCount(),
|
||||
api.query.treasury.approvals()
|
||||
]).pipe(
|
||||
switchMap(([proposalCount, approvalIds]: [ProposalIndex, ProposalIndex[]]) =>
|
||||
retrieveProposals(api, proposalCount, approvalIds)
|
||||
)
|
||||
)
|
||||
: of({
|
||||
approvals: [],
|
||||
proposalCount: createType(api.registry, 'ProposalIndex'),
|
||||
proposals: []
|
||||
} as DerivedTreasuryProposals)
|
||||
);
|
||||
}
|
||||
@@ -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, ReferendumInfo, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Hash, Index, Keys, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RewardDestination, SessionIndex, SetIndex, StakingLedger, TreasuryProposal, ValidatorPrefs, Vote, Votes, VoteIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { u32, Vec } from '@polkadot/types';
|
||||
@@ -44,6 +44,14 @@ export interface DerivedContractFees {
|
||||
transferFee: BN;
|
||||
}
|
||||
|
||||
export interface DerivedCouncilProposal {
|
||||
hash: Hash;
|
||||
proposal: Proposal;
|
||||
votes: Votes | null;
|
||||
}
|
||||
|
||||
export type DerivedCouncilProposals = DerivedCouncilProposal[];
|
||||
|
||||
export interface DerivedElectionsInfo {
|
||||
candidates: AccountId[];
|
||||
candidateCount: u32;
|
||||
@@ -164,6 +172,18 @@ export interface DerivedStakingOverview extends DeriveSessionIndexes {
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
export interface DerivedTreasuryProposal {
|
||||
council: DerivedCouncilProposal[];
|
||||
id: ProposalIndex;
|
||||
proposal: TreasuryProposal;
|
||||
}
|
||||
|
||||
export interface DerivedTreasuryProposals {
|
||||
approvals: DerivedTreasuryProposal[];
|
||||
proposalCount: ProposalIndex;
|
||||
proposals: DerivedTreasuryProposal[];
|
||||
}
|
||||
|
||||
export type DerivedUnlocking = {
|
||||
remainingBlocks: BlockNumber;
|
||||
value: Balance;
|
||||
|
||||
Reference in New Issue
Block a user