|
|
|
@@ -14,14 +14,16 @@ import { isFunction } from '@polkadot/util';
|
|
|
|
|
|
|
|
|
|
import { memo } from '../util';
|
|
|
|
|
|
|
|
|
|
type MultiResult = [Option<AccountId>, Option<ITuple<[Nominations]> | Nominations>, RewardDestination, ITuple<[ValidatorPrefs]> | ValidatorPrefs, Exposure];
|
|
|
|
|
type MultiResultPrev = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, ITuple<[ValidatorPrefs]> | ValidatorPrefs, Exposure];
|
|
|
|
|
|
|
|
|
|
function parseController (stashId: AccountId, [controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure]: MultiResult, stakingLedgerOpt: Option<StakingLedger>): DeriveStakingQuery {
|
|
|
|
|
const nominators = nominatorsOpt.unwrapOr(null);
|
|
|
|
|
type MultiResultCombo = [Option<AccountId>, Option<ITuple<[Nominations]> | Nominations>, RewardDestination, ITuple<[ValidatorPrefs]> | ValidatorPrefs, Exposure];
|
|
|
|
|
|
|
|
|
|
function parseDetails (stashId: AccountId, [controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure]: MultiResultCombo, stakingLedgerOpt: Option<StakingLedger>): DeriveStakingQuery {
|
|
|
|
|
const nominators = nominatorsOpt && nominatorsOpt.unwrapOr(null);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
accountId: stashId,
|
|
|
|
|
controllerId: controllerIdOpt.unwrapOr(null),
|
|
|
|
|
controllerId: controllerIdOpt && controllerIdOpt.unwrapOr(null),
|
|
|
|
|
exposure,
|
|
|
|
|
nominators: nominators
|
|
|
|
|
? Array.isArray(nominators)
|
|
|
|
@@ -37,8 +39,8 @@ function parseController (stashId: AccountId, [controllerIdOpt, nominatorsOpt, r
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
|
|
|
|
|
return api.queryMulti<MultiResult>([
|
|
|
|
|
function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResultPrev> {
|
|
|
|
|
return api.queryMulti<MultiResultPrev>([
|
|
|
|
|
[api.query.staking.bonded, stashId],
|
|
|
|
|
[api.query.staking.nominators, stashId],
|
|
|
|
|
[api.query.staking.payee, stashId],
|
|
|
|
@@ -47,18 +49,26 @@ function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<Mult
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function retrieveCurr (api: ApiInterfaceRx, stashIds: AccountId[], activeEra: EraIndex): Observable<MultiResult[]> {
|
|
|
|
|
function retrieveCurr (api: ApiInterfaceRx, stashIds: AccountId[], activeEra: EraIndex, withFull: boolean): Observable<MultiResultCombo[]> {
|
|
|
|
|
const emptyCont = api.registry.createType('Option<AccountId>');
|
|
|
|
|
const emptyNoms = api.registry.createType('Option<Nominations>');
|
|
|
|
|
const emptyRewa = api.registry.createType('RewardDestination');
|
|
|
|
|
|
|
|
|
|
return combineLatest([
|
|
|
|
|
api.query.staking.bonded.multi<Option<AccountId>>(stashIds),
|
|
|
|
|
api.query.staking.nominators
|
|
|
|
|
withFull
|
|
|
|
|
? api.query.staking.bonded.multi<Option<AccountId>>(stashIds)
|
|
|
|
|
: of(stashIds.map(() => emptyCont)),
|
|
|
|
|
withFull && api.query.staking.nominators
|
|
|
|
|
? api.query.staking.nominators.multi<Option<Nominations>>(stashIds)
|
|
|
|
|
: of(stashIds.map(() => api.registry.createType('Option<Nominations>'))),
|
|
|
|
|
api.query.staking.payee.multi<RewardDestination>(stashIds),
|
|
|
|
|
: of(stashIds.map(() => emptyNoms)),
|
|
|
|
|
withFull
|
|
|
|
|
? api.query.staking.payee.multi<RewardDestination>(stashIds)
|
|
|
|
|
: of(stashIds.map(() => emptyRewa)),
|
|
|
|
|
api.query.staking.validators.multi<ValidatorPrefs>(stashIds),
|
|
|
|
|
api.query.staking.erasStakers.multi<Exposure>(stashIds.map((stashId) => [activeEra, stashId]))
|
|
|
|
|
]).pipe(
|
|
|
|
|
map(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure]): MultiResult[] =>
|
|
|
|
|
controllerIdOpt.map((controllerIdOpt, index): MultiResult =>
|
|
|
|
|
map(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure]): MultiResultCombo[] =>
|
|
|
|
|
controllerIdOpt.map((controllerIdOpt, index): MultiResultCombo =>
|
|
|
|
|
[controllerIdOpt, nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index]]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
@@ -67,9 +77,10 @@ function retrieveCurr (api: ApiInterfaceRx, stashIds: AccountId[], activeEra: Er
|
|
|
|
|
|
|
|
|
|
function retrieveControllers (api: ApiInterfaceRx, optControllerIds: Option<AccountId>[]): Observable<Option<StakingLedger>[]> {
|
|
|
|
|
const ids = optControllerIds.filter((opt) => opt.isSome).map((opt) => opt.unwrap());
|
|
|
|
|
const emptyLed = api.registry.createType('Option<StakingLedger>');
|
|
|
|
|
|
|
|
|
|
if (!ids.length) {
|
|
|
|
|
return of(optControllerIds.map(() => api.registry.createType('Option<StakingLedger>')));
|
|
|
|
|
return of(optControllerIds.map(() => emptyLed));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return api.query.staking.ledger.multi<Option<StakingLedger>>(ids).pipe(
|
|
|
|
@@ -79,7 +90,7 @@ function retrieveControllers (api: ApiInterfaceRx, optControllerIds: Option<Acco
|
|
|
|
|
return optControllerIds.map((opt): Option<StakingLedger> =>
|
|
|
|
|
opt.isSome
|
|
|
|
|
? optLedgers[++offset]
|
|
|
|
|
: api.registry.createType('Option<StakingLedger>')
|
|
|
|
|
: emptyLed
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
@@ -88,33 +99,38 @@ function retrieveControllers (api: ApiInterfaceRx, optControllerIds: Option<Acco
|
|
|
|
|
/**
|
|
|
|
|
* @description From a stash, retrieve the controllerId and all relevant details
|
|
|
|
|
*/
|
|
|
|
|
export function query (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable<DeriveStakingQuery> {
|
|
|
|
|
return memo(instanceId, (accountId: Uint8Array | string): Observable<DeriveStakingQuery> =>
|
|
|
|
|
api.derive.staking.queryMulti([accountId]).pipe(
|
|
|
|
|
export function query (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withFull?: boolean) => Observable<DeriveStakingQuery> {
|
|
|
|
|
return memo(instanceId, (accountId: Uint8Array | string, withFull?: boolean): Observable<DeriveStakingQuery> =>
|
|
|
|
|
api.derive.staking.queryMulti([accountId], withFull).pipe(
|
|
|
|
|
map(([first]) => first)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function queryMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable<DeriveStakingQuery[]> {
|
|
|
|
|
return memo(instanceId, (accountIds: (Uint8Array | string)[]): Observable<DeriveStakingQuery[]> =>
|
|
|
|
|
export function queryMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], withFull?: boolean) => Observable<DeriveStakingQuery[]> {
|
|
|
|
|
return memo(instanceId, (accountIds: (Uint8Array | string)[], withFull = true): Observable<DeriveStakingQuery[]> =>
|
|
|
|
|
accountIds.length
|
|
|
|
|
? api.derive.session.indexes().pipe(
|
|
|
|
|
switchMap(({ activeEra }): Observable<DeriveStakingQuery[]> => {
|
|
|
|
|
const stashIds = accountIds.map((accountId) => api.registry.createType('AccountId', accountId));
|
|
|
|
|
const emptyLed = api.registry.createType('Option<StakingLedger>');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
isFunction(api.query.staking.erasStakers)
|
|
|
|
|
? retrieveCurr(api, stashIds, activeEra)
|
|
|
|
|
? retrieveCurr(api, stashIds, activeEra, withFull)
|
|
|
|
|
: combineLatest(stashIds.map((stashId) => retrievePrev(api, stashId)))
|
|
|
|
|
).pipe(
|
|
|
|
|
switchMap((results): Observable<DeriveStakingQuery[]> =>
|
|
|
|
|
retrieveControllers(api, results.map(([optController]) => optController)).pipe(
|
|
|
|
|
map((stakingLedgerOpts) =>
|
|
|
|
|
stashIds.map((stashId, index) => parseController(stashId, results[index], stakingLedgerOpts[index]))
|
|
|
|
|
withFull
|
|
|
|
|
? switchMap((results): Observable<DeriveStakingQuery[]> =>
|
|
|
|
|
retrieveControllers(api, results.map(([optController]) => optController)).pipe(
|
|
|
|
|
map((stakingLedgerOpts) =>
|
|
|
|
|
stashIds.map((stashId, index) => parseDetails(stashId, results[index], stakingLedgerOpts[index]))
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: map((results): DeriveStakingQuery[] =>
|
|
|
|
|
stashIds.map((stashId, index) => parseDetails(stashId, results[index], emptyLed))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|