Filter old rewards with stakingLedger (ledger can update) (#2155)
* Filter old rewards with stakingLedger (ledger can update) * Cleanup internal functions
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
// 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 { ReferendumInfo, ReferendumInfoTo239 } from '@polkadot/types/interfaces';
|
||||
import { DeriveReferendum } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
import { getStatus, parseImage } from './util';
|
||||
|
||||
export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
|
||||
return memo((index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
|
||||
const status = getStatus(info);
|
||||
|
||||
return status
|
||||
? api.query.democracy.preimages(status.proposalHash).pipe(
|
||||
map((preimage): DeriveReferendum => ({
|
||||
image: parseImage(api, preimage),
|
||||
imageHash: status.proposalHash,
|
||||
index: api.registry.createType('ReferendumIndex', index),
|
||||
status
|
||||
}))
|
||||
)
|
||||
: of(null);
|
||||
});
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// 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, Vote, Voting, VotingDirectVote } from '@polkadot/types/interfaces';
|
||||
import { DeriveBalancesAccount, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable, of, combineLatest } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
import { calcVotes } from './util';
|
||||
|
||||
function votesPrev (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
||||
return api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
|
||||
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DeriveBalancesAccount[]]> =>
|
||||
combineLatest([
|
||||
of(votersFor),
|
||||
votersFor.length
|
||||
? api.query.democracy.voteOf.multi<Vote>(
|
||||
votersFor.map((accountId): [BN | number, AccountId] =>
|
||||
[referendumId, accountId]
|
||||
)
|
||||
)
|
||||
: of([]),
|
||||
api.derive.balances.votingBalances(votersFor)
|
||||
])
|
||||
),
|
||||
map(([votersFor, votes, balances]): DeriveReferendumVote[] =>
|
||||
votersFor.map((accountId, index): DeriveReferendumVote => ({
|
||||
accountId,
|
||||
balance: balances[index].votingBalance || api.registry.createType('Balance'),
|
||||
vote: votes[index] || api.registry.createType('Vote')
|
||||
}))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function votesCurr (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
||||
return api.query.democracy.votingOf.entries<Voting>().pipe(
|
||||
map((allVoting): DeriveReferendumVote[] =>
|
||||
allVoting
|
||||
.map(([key, voting]): [AccountId, Voting] => [key.args[0] as AccountId, voting])
|
||||
// FIXME We are ignoring delegated votes
|
||||
.filter(([, voting]) => voting.isDirect)
|
||||
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
|
||||
accountId,
|
||||
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
|
||||
])
|
||||
.filter(([, directVotes]) => !!directVotes.length)
|
||||
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
|
||||
// FIXME We are ignoring split votes
|
||||
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
|
||||
if (vote.isStandard) {
|
||||
result.push({
|
||||
accountId,
|
||||
...vote.asStandard
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}, result), []
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function _referendumVotes (api: ApiInterfaceRx): (referendum: DeriveReferendum) => Observable<DeriveReferendumVotes> {
|
||||
return memo((referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
|
||||
combineLatest([
|
||||
api.derive.democracy.sqrtElectorate(),
|
||||
api.query.democracy.votingOf
|
||||
? votesCurr(api, referendum.index)
|
||||
: votesPrev(api, referendum.index)
|
||||
]).pipe(
|
||||
map(([sqrtElectorate, votes]) =>
|
||||
calcVotes(sqrtElectorate, referendum, votes)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// 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 { DeriveReferendum, DeriveReferendumVotes } from '../types';
|
||||
|
||||
import { Observable, of, combineLatest } from 'rxjs';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
export function _referendumsVotes (api: ApiInterfaceRx): (referendums: DeriveReferendum[]) => Observable<DeriveReferendumVotes[]> {
|
||||
return memo((referendums: DeriveReferendum[]): Observable<DeriveReferendumVotes[]> =>
|
||||
referendums.length
|
||||
? combineLatest(
|
||||
referendums.map((referendum): Observable<DeriveReferendumVotes> =>
|
||||
api.derive.democracy._referendumVotes(referendum)
|
||||
)
|
||||
)
|
||||
: of([])
|
||||
);
|
||||
}
|
||||
@@ -2,9 +2,6 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './_referendumsVotes';
|
||||
export * from './_referendumVotes';
|
||||
export * from './_referendumInfo';
|
||||
export * from './dispatchQueue';
|
||||
export * from './nextExternal';
|
||||
export * from './preimage';
|
||||
|
||||
@@ -3,15 +3,114 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { ReferendumInfo } from '@polkadot/types/interfaces';
|
||||
import { DeriveReferendum } from '../types';
|
||||
import { AccountId, ReferendumInfo, ReferendumInfoTo239, Vote, Voting, VotingDirectVote } from '@polkadot/types/interfaces';
|
||||
import { DeriveBalancesAccount, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable, of, combineLatest } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Option } from '@polkadot/types';
|
||||
import { Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
import { calcVotes, getStatus, parseImage } from './util';
|
||||
|
||||
function votesPrev (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
||||
return api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
|
||||
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DeriveBalancesAccount[]]> =>
|
||||
combineLatest([
|
||||
of(votersFor),
|
||||
votersFor.length
|
||||
? api.query.democracy.voteOf.multi<Vote>(
|
||||
votersFor.map((accountId): [BN | number, AccountId] =>
|
||||
[referendumId, accountId]
|
||||
)
|
||||
)
|
||||
: of([]),
|
||||
api.derive.balances.votingBalances(votersFor)
|
||||
])
|
||||
),
|
||||
map(([votersFor, votes, balances]): DeriveReferendumVote[] =>
|
||||
votersFor.map((accountId, index): DeriveReferendumVote => ({
|
||||
accountId,
|
||||
balance: balances[index].votingBalance || api.registry.createType('Balance'),
|
||||
vote: votes[index] || api.registry.createType('Vote')
|
||||
}))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function votesCurr (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
||||
return api.query.democracy.votingOf.entries<Voting>().pipe(
|
||||
map((allVoting): DeriveReferendumVote[] =>
|
||||
allVoting
|
||||
.map(([key, voting]): [AccountId, Voting] => [key.args[0] as AccountId, voting])
|
||||
// FIXME We are ignoring delegated votes
|
||||
.filter(([, voting]) => voting.isDirect)
|
||||
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
|
||||
accountId,
|
||||
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
|
||||
])
|
||||
.filter(([, directVotes]) => !!directVotes.length)
|
||||
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
|
||||
// FIXME We are ignoring split votes
|
||||
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
|
||||
if (vote.isStandard) {
|
||||
result.push({
|
||||
accountId,
|
||||
...vote.asStandard
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}, result), []
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function _referendumVotes (api: ApiInterfaceRx): (referendum: DeriveReferendum) => Observable<DeriveReferendumVotes> {
|
||||
return memo((referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
|
||||
combineLatest([
|
||||
api.derive.democracy.sqrtElectorate(),
|
||||
api.query.democracy.votingOf
|
||||
? votesCurr(api, referendum.index)
|
||||
: votesPrev(api, referendum.index)
|
||||
]).pipe(
|
||||
map(([sqrtElectorate, votes]) =>
|
||||
calcVotes(sqrtElectorate, referendum, votes)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function _referendumsVotes (api: ApiInterfaceRx): (referendums: DeriveReferendum[]) => Observable<DeriveReferendumVotes[]> {
|
||||
return memo((referendums: DeriveReferendum[]): Observable<DeriveReferendumVotes[]> =>
|
||||
referendums.length
|
||||
? combineLatest(
|
||||
referendums.map((referendum): Observable<DeriveReferendumVotes> =>
|
||||
api.derive.democracy._referendumVotes(referendum)
|
||||
)
|
||||
)
|
||||
: of([])
|
||||
);
|
||||
}
|
||||
|
||||
export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
|
||||
return memo((index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
|
||||
const status = getStatus(info);
|
||||
|
||||
return status
|
||||
? api.query.democracy.preimages(status.proposalHash).pipe(
|
||||
map((preimage): DeriveReferendum => ({
|
||||
image: parseImage(api, preimage),
|
||||
imageHash: status.proposalHash,
|
||||
index: api.registry.createType('ReferendumIndex', index),
|
||||
status
|
||||
}))
|
||||
)
|
||||
: of(null);
|
||||
});
|
||||
}
|
||||
|
||||
export function referendumsInfo (api: ApiInterfaceRx): (ids: BN[]) => Observable<DeriveReferendum[]> {
|
||||
return memo((ids: BN[]): Observable<DeriveReferendum[]> =>
|
||||
|
||||
@@ -42,7 +42,7 @@ export function eraExposure (api: ApiInterfaceRx): (era: EraIndex) => Observable
|
||||
);
|
||||
}
|
||||
|
||||
export function erasExposureOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraExposure[]> {
|
||||
export function _erasExposure (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraExposure[]> {
|
||||
return memo((eras: EraIndex[]): Observable<DeriveEraExposure[]> =>
|
||||
eras.length
|
||||
? combineLatest(eras.map((era) => api.derive.staking.eraExposure(era)))
|
||||
@@ -53,7 +53,7 @@ export function erasExposureOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Ob
|
||||
export function erasExposure (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraExposure[]> {
|
||||
return memo((withActive?: boolean): Observable<DeriveEraExposure[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.erasExposureOver(eras))
|
||||
switchMap((eras) => api.derive.staking._erasExposure(eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ function mapValidators ({ individual }: EraRewardPoints): DeriveEraValPoints {
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function erasPointsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPoints[]> {
|
||||
export function _erasPoints (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPoints[]> {
|
||||
return memo((eras: EraIndex[]): Observable<DeriveEraPoints[]> =>
|
||||
eras.length
|
||||
? api.query.staking.erasRewardPoints.multi<EraRewardPoints>(eras).pipe(
|
||||
@@ -40,7 +40,7 @@ export function erasPointsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Obse
|
||||
export function erasPoints (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPoints[]> {
|
||||
return memo((withActive?: boolean): Observable<DeriveEraPoints[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.erasPointsOver(eras))
|
||||
switchMap((eras) => api.derive.staking._erasPoints(eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable<De
|
||||
);
|
||||
}
|
||||
|
||||
export function erasPrefsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPrefs[]> {
|
||||
export function _erasPrefs (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPrefs[]> {
|
||||
return memo((eras: EraIndex[]): Observable<DeriveEraPrefs[]> =>
|
||||
eras.length
|
||||
? combineLatest(eras.map((era) => api.derive.staking.eraPrefs(era)))
|
||||
@@ -41,7 +41,7 @@ export function erasPrefsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Obser
|
||||
export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPrefs[]> {
|
||||
return memo((withActive?: boolean): Observable<DeriveEraPrefs[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.erasPrefsOver(eras))
|
||||
switchMap((eras) => api.derive.staking._erasPrefs(eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Option } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
export function erasRewardsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraRewards[]> {
|
||||
export function _erasRewards (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraRewards[]> {
|
||||
return memo((eras: EraIndex[]): Observable<DeriveEraRewards[]> =>
|
||||
eras.length
|
||||
? api.query.staking.erasValidatorReward.multi<Option<Balance>>(eras).pipe(
|
||||
@@ -28,7 +28,7 @@ export function erasRewardsOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Obs
|
||||
export function erasRewards (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraRewards[]> {
|
||||
return memo((withActive?: boolean): Observable<DeriveEraRewards[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.erasRewardsOver(eras))
|
||||
switchMap((eras) => api.derive.staking._erasRewards(eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export function eraSlashes (api: ApiInterfaceRx): (era: EraIndex) => Observable<
|
||||
);
|
||||
}
|
||||
|
||||
export function erasSlashesOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraSlashes[]> {
|
||||
export function _erasSlashes (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraSlashes[]> {
|
||||
return memo((eras: EraIndex[]): Observable<DeriveEraSlashes[]> =>
|
||||
eras.length
|
||||
? combineLatest(
|
||||
@@ -52,7 +52,7 @@ export function erasSlashesOver (api: ApiInterfaceRx): (eras: EraIndex[]) => Obs
|
||||
export function erasSlashes (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraSlashes[]> {
|
||||
return memo((withActive?: boolean): Observable<DeriveEraSlashes[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.erasSlashesOver(eras))
|
||||
switchMap((eras) => api.derive.staking._erasSlashes(eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ function retrieveCurr (api: ApiInterfaceRx, stashId: AccountId): Observable<Mult
|
||||
);
|
||||
}
|
||||
|
||||
function retrieveController (api: ApiInterfaceRx, stashId: AccountId, [queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, nextKeys, exposure]]: [Vec<ITuple<[AccountId, Keys]>>, MultiResult]): Observable<DeriveStakingQuery> {
|
||||
function retrieveController (api: ApiInterfaceRx, stashId: AccountId, queuedKeys: Vec<ITuple<[AccountId, Keys]>>, [controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, nextKeys, exposure]: MultiResult): Observable<DeriveStakingQuery> {
|
||||
const controllerId = controllerIdOpt.unwrapOr(null);
|
||||
const nominators = nominatorsOpt.unwrapOr(null);
|
||||
|
||||
@@ -82,30 +82,41 @@ function retrieveController (api: ApiInterfaceRx, stashId: AccountId, [queuedKey
|
||||
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
|
||||
}
|
||||
|
||||
/**
|
||||
* @description From a stash, retrieve the controllerId and all relevant details
|
||||
*/
|
||||
export function query (api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable<DeriveStakingQuery> {
|
||||
return memo((accountId: Uint8Array | string): Observable<DeriveStakingQuery> => {
|
||||
export function queryWithQueued (api: ApiInterfaceRx): (accountId: Uint8Array | string, queuedKeys: Vec<ITuple<[AccountId, Keys]>>) => Observable<DeriveStakingQuery> {
|
||||
return memo((accountId: Uint8Array | string, queuedKeys: Vec<ITuple<[AccountId, Keys]>>): Observable<DeriveStakingQuery> => {
|
||||
const stashId = api.registry.createType('AccountId', accountId);
|
||||
|
||||
return combineLatest([
|
||||
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
|
||||
return (
|
||||
api.query.staking.erasStakers
|
||||
? retrieveCurr(api, stashId)
|
||||
: retrievePrev(api, stashId)
|
||||
]).pipe(
|
||||
).pipe(
|
||||
switchMap((result): Observable<DeriveStakingQuery> =>
|
||||
retrieveController(api, stashId, result)
|
||||
retrieveController(api, stashId, queuedKeys, result)
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description From a stash, retrieve the controllerId and all relevant details
|
||||
*/
|
||||
export function query (api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable<DeriveStakingQuery> {
|
||||
return memo((accountId: Uint8Array | string): Observable<DeriveStakingQuery> =>
|
||||
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>().pipe(
|
||||
switchMap((queuedKeys) => api.derive.staking.queryWithQueued(accountId, queuedKeys))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function queryMulti (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable<DeriveStakingQuery[]> {
|
||||
return memo((accountIds: (Uint8Array | string)[]): Observable<DeriveStakingQuery[]> =>
|
||||
accountIds.length
|
||||
? combineLatest(accountIds.map((acc) => api.derive.staking.query(acc)))
|
||||
? api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>().pipe(
|
||||
switchMap((queuedKeys) => combineLatest(
|
||||
accountIds.map((acc) => api.derive.staking.queryWithQueued(acc, queuedKeys))
|
||||
))
|
||||
)
|
||||
: of([])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
export function stakerExposureOver (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerExposure[]> {
|
||||
export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerExposure[]> {
|
||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerExposure[]> => {
|
||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||
|
||||
return api.derive.staking.erasExposureOver(eras).pipe(
|
||||
return api.derive.staking._erasExposure(eras).pipe(
|
||||
map((exposures): DeriveStakerExposure[] =>
|
||||
exposures.map(({ era, nominators: allNominators, validators: allValidators }): DeriveStakerExposure => {
|
||||
const isValidator = !!allValidators[stakerId];
|
||||
@@ -40,7 +40,7 @@ export function stakerExposureOver (api: ApiInterfaceRx): (accountId: Uint8Array
|
||||
export function stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerExposure[]> {
|
||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerExposure[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.stakerExposureOver(accountId, eras))
|
||||
switchMap((eras) => api.derive.staking._stakerExposure(accountId, eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
export function stakerPointsOver (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerPoints[]> {
|
||||
export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerPoints[]> {
|
||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerPoints[]> => {
|
||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||
|
||||
return api.derive.staking.erasPointsOver(eras).pipe(
|
||||
return api.derive.staking._erasPoints(eras).pipe(
|
||||
map((points): DeriveStakerPoints[] =>
|
||||
points.map(({ era, eraPoints, validators }): DeriveStakerPoints => ({
|
||||
era,
|
||||
@@ -30,7 +30,7 @@ export function stakerPointsOver (api: ApiInterfaceRx): (accountId: Uint8Array |
|
||||
export function stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerPoints[]> {
|
||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerPoints[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.stakerPointsOver(accountId, eras))
|
||||
switchMap((eras) => api.derive.staking._stakerPoints(accountId, eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ import { memo } from '../util';
|
||||
type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]];
|
||||
|
||||
const ZERO = new BN(0);
|
||||
const MIN_ONE = new BN(-1);
|
||||
const COMM_DIV = new BN(1_000_000_000);
|
||||
const MAX_ERAS = new BN(1_000_000_000);
|
||||
|
||||
function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] {
|
||||
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
|
||||
@@ -25,7 +27,6 @@ function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, era
|
||||
const { validators: allValPrefs } = erasPrefs.find((p) => p.era.eq(era)) || { validators: {} as DeriveEraValPrefs };
|
||||
const validators: Record<string, DeriveStakerRewardValidator> = {};
|
||||
const stakerId = stashId.toString();
|
||||
let total = ZERO;
|
||||
|
||||
Object.entries(eraValidators).forEach(([validatorId, exposure]): void => {
|
||||
const valPoints = allValPoints[validatorId] || ZERO;
|
||||
@@ -49,7 +50,6 @@ function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, era
|
||||
}
|
||||
|
||||
value = avail.sub(valCut).mul(staked).div(expTotal).add(validatorId === stakerId ? valCut : ZERO);
|
||||
total = total.add(value);
|
||||
}
|
||||
|
||||
validators[validatorId] = {
|
||||
@@ -64,7 +64,6 @@ function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, era
|
||||
isEmpty,
|
||||
isValidator,
|
||||
nominating,
|
||||
total: api.registry.createType('Balance', total),
|
||||
validators
|
||||
};
|
||||
});
|
||||
@@ -88,7 +87,17 @@ function isOldLedger (ledger?: StakingLedger | StakingLedgerTo240): ledger is St
|
||||
return !!(ledger as StakingLedgerTo240)?.lastReward;
|
||||
}
|
||||
|
||||
function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], withActive?: boolean): Observable<DeriveStakerReward[]> {
|
||||
function filterEra (era: EraIndex, stakingLedger: StakingLedger): boolean {
|
||||
return isOldLedger(stakingLedger)
|
||||
? era.gt(stakingLedger.lastReward.unwrapOr(MIN_ONE))
|
||||
: !stakingLedger.claimedRewards.some((e) => e.eq(era));
|
||||
}
|
||||
|
||||
function filterEras (eras: EraIndex[], stakingLedger: StakingLedger): EraIndex[] {
|
||||
return eras.filter((era) => filterEra(era, stakingLedger));
|
||||
}
|
||||
|
||||
function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive?: boolean): Observable<DeriveStakerReward[]> {
|
||||
if (withActive) {
|
||||
return of(rewards);
|
||||
}
|
||||
@@ -98,20 +107,20 @@ function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], with
|
||||
return combineLatest([
|
||||
api.query.staking.migrateEra
|
||||
? api.query.staking.migrateEra<Option<EraIndex>>()
|
||||
: of(api.registry.createType('Option<EraIndex>', api.tx.staking.payoutStakers ? 0 : 1_000_000_000)),
|
||||
: of({ unwrapOr: () => api.tx.staking.payoutStakers ? MIN_ONE : MAX_ERAS }),
|
||||
api.tx.staking.payoutStakers
|
||||
? api.derive.staking.queryMulti(validators)
|
||||
: of([])
|
||||
]).pipe(
|
||||
map(([optMigrate, queryValidators]): DeriveStakerReward[] => {
|
||||
const migrateEra = optMigrate.unwrapOr(new BN(-1));
|
||||
const migrateEra: BN = optMigrate.unwrapOr(MIN_ONE);
|
||||
|
||||
return rewards
|
||||
.filter(({ isEmpty }) => !isEmpty)
|
||||
.filter((reward): boolean => {
|
||||
if (reward.era.lte(migrateEra)) {
|
||||
// we have already filtered these inside the stakerRewardsOver query, so all are valid
|
||||
return true;
|
||||
// we filter again here, the actual ledger may have changed, e.g. something has been claimed
|
||||
return filterEra(reward.era, stakingLedger);
|
||||
}
|
||||
|
||||
reward.isStakerPayout = true;
|
||||
@@ -145,19 +154,7 @@ function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], with
|
||||
);
|
||||
}
|
||||
|
||||
function filterEras (eras: EraIndex[], stakingLedger: StakingLedger): EraIndex[] {
|
||||
if (!stakingLedger) {
|
||||
return eras;
|
||||
} else if (isOldLedger(stakingLedger)) {
|
||||
const lastReward = stakingLedger.lastReward.unwrapOr(new BN(-1));
|
||||
|
||||
return eras.filter((era) => era.gt(lastReward));
|
||||
}
|
||||
|
||||
return eras.filter((era) => !stakingLedger.claimedRewards.some((e) => e.eq(era)));
|
||||
}
|
||||
|
||||
export function stakerRewardsOver (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
||||
export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
||||
return memo((accountId: Uint8Array | string, _eras: EraIndex[], withActive?: boolean): Observable<DeriveStakerReward[]> =>
|
||||
api.derive.staking.query(accountId).pipe(
|
||||
switchMap(({ stakingLedger, stashId }): Observable<DeriveStakerReward[]> => {
|
||||
@@ -170,13 +167,13 @@ export function stakerRewardsOver (api: ApiInterfaceRx): (accountId: Uint8Array
|
||||
: filterEras(_eras, stakingLedger);
|
||||
|
||||
return combineLatest([
|
||||
api.derive.staking.erasPointsOver(eras),
|
||||
api.derive.staking.erasPrefsOver(eras),
|
||||
api.derive.staking.erasRewardsOver(eras),
|
||||
api.derive.staking.stakerExposureOver(stashId, eras)
|
||||
api.derive.staking._erasPoints(eras),
|
||||
api.derive.staking._erasPrefs(eras),
|
||||
api.derive.staking._erasRewards(eras),
|
||||
api.derive.staking._stakerExposure(stashId, eras)
|
||||
]).pipe(
|
||||
switchMap((result): Observable<DeriveStakerReward[]> =>
|
||||
filterRewards(api, parseRewards(api, stashId, result), withActive)
|
||||
filterRewards(api, parseRewards(api, stashId, result), stakingLedger, withActive)
|
||||
)
|
||||
);
|
||||
})
|
||||
@@ -187,7 +184,7 @@ export function stakerRewardsOver (api: ApiInterfaceRx): (accountId: Uint8Array
|
||||
export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerReward[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.stakerRewardsOver(accountId, eras, withActive))
|
||||
switchMap((eras) => api.derive.staking._stakerRewards(accountId, eras, withActive))
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -197,7 +194,7 @@ export function stakerRewardsMulti (api: ApiInterfaceRx): (accountIds: (Uint8Arr
|
||||
accountIds.length
|
||||
? api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) =>
|
||||
combineLatest(accountIds.map((acc) => api.derive.staking.stakerRewardsOver(acc, eras, withActive)))
|
||||
combineLatest(accountIds.map((acc) => api.derive.staking._stakerRewards(acc, eras, withActive)))
|
||||
)
|
||||
)
|
||||
: of([])
|
||||
|
||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
export function stakerSlashesOver (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerSlashes[]> {
|
||||
export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerSlashes[]> {
|
||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerSlashes[]> => {
|
||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||
|
||||
return api.derive.staking.erasSlashesOver(eras).pipe(
|
||||
return api.derive.staking._erasSlashes(eras).pipe(
|
||||
map((slashes): DeriveStakerSlashes[] =>
|
||||
slashes.map(({ era, nominators, validators }): DeriveStakerSlashes => ({
|
||||
era,
|
||||
@@ -29,7 +29,7 @@ export function stakerSlashesOver (api: ApiInterfaceRx): (accountId: Uint8Array
|
||||
export function stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerSlashes[]> {
|
||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerSlashes[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras) => api.derive.staking.stakerSlashesOver(accountId, eras))
|
||||
switchMap((eras) => api.derive.staking._stakerSlashes(accountId, eras))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ export interface DeriveStakerReward {
|
||||
isEmpty: boolean;
|
||||
isValidator: boolean;
|
||||
nominating: DeriveEraExposureNominating[];
|
||||
total: Balance;
|
||||
validators: Record<string, DeriveStakerRewardValidator>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user