Skip to content

Commit

Permalink
Update api.derive.staking calls with breaking changes (#5860)
Browse files Browse the repository at this point in the history
* Fix staking derives

* ownexposure

* fix query

* Add WithExposureMEta

* exposureMEta

* fix ownExposures

* Add page input for staking.query

* Update types for query

* add page param to ownExposure

* change page to exposurePaged

* fix small nit
  • Loading branch information
TarikGul committed Apr 22, 2024
1 parent ddb9b44 commit c4e8270
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 32 deletions.
25 changes: 16 additions & 9 deletions packages/api-derive/src/staking/ownExposure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,39 @@
// SPDX-License-Identifier: Apache-2.0

import type { Observable } from 'rxjs';
import type { Option, u32 } from '@polkadot/types';
import type { EraIndex } from '@polkadot/types/interfaces';
import type { SpStakingExposurePage } from '@polkadot/types/lookup';
import type { AnyNumber } from '@polkadot/types-codec/types';
import type { DeriveApi, DeriveOwnExposure } from '../types.js';

import { combineLatest, map, of } from 'rxjs';

import { firstMemo, memo } from '../util/index.js';
import { erasHistoricApplyAccount } from './util.js';

export function _ownExposures (instanceId: string, api: DeriveApi): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveOwnExposure[]> {
return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], _withActive: boolean): Observable<DeriveOwnExposure[]> =>
eras.length
export function _ownExposures (instanceId: string, api: DeriveApi): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean, page: u32 | AnyNumber) => Observable<DeriveOwnExposure[]> {
return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], _withActive: boolean, page: u32 | AnyNumber): Observable<DeriveOwnExposure[]> => {
return eras.length
? combineLatest([
// Backwards and forward compat for historical integrity when using `erasHistoricApplyAccount`
combineLatest(eras.map((e) => api.query.staking.erasStakersClipped(e, accountId))),
combineLatest(eras.map((e) => api.query.staking.erasStakers(e, accountId)))
combineLatest(eras.map((e) => api.query.staking.erasStakers(e, accountId))),
combineLatest(eras.map((e) => api.query.staking.erasStakersPaged<Option<SpStakingExposurePage>>(e, accountId, page))),
combineLatest(eras.map((e) => api.query.staking.erasStakersOverview(e, accountId)))
]).pipe(
map(([clp, exp]): DeriveOwnExposure[] =>
eras.map((era, index) => ({ clipped: clp[index], era, exposure: exp[index] }))
map(([clp, exp, paged, expMeta]): DeriveOwnExposure[] =>
eras.map((era, index) => ({ clipped: clp[index], era, exposure: exp[index], exposureMeta: expMeta[index], exposurePaged: paged[index] }))
)
)
: of([])
: of([]);
}
);
}

export const ownExposure = /*#__PURE__*/ firstMemo(
(api: DeriveApi, accountId: Uint8Array | string, era: EraIndex) =>
api.derive.staking._ownExposures(accountId, [era], true)
(api: DeriveApi, accountId: Uint8Array | string, era: EraIndex, page?: u32 | AnyNumber) =>
api.derive.staking._ownExposures(accountId, [era], true, page || 0)
);

export const ownExposures = /*#__PURE__*/ erasHistoricApplyAccount('_ownExposures');
41 changes: 24 additions & 17 deletions packages/api-derive/src/staking/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

import type { Observable } from 'rxjs';
import type { Option } from '@polkadot/types';
import type { Option, u32 } from '@polkadot/types';
import type { AccountId, EraIndex } from '@polkadot/types/interfaces';
import type { PalletStakingNominations, PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure } from '@polkadot/types/lookup';
import type { PalletStakingNominations, PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup';
import type { AnyNumber } from '@polkadot/types-codec/types';
import type { DeriveApi, DeriveStakingQuery, StakingQueryFlags } from '../types.js';

import { combineLatest, map, of, switchMap } from 'rxjs';
Expand All @@ -19,11 +20,12 @@ function rewardDestinationCompat (rewardDestination: PalletStakingRewardDestinat
: (rewardDestination as PalletStakingRewardDestination);
}

function parseDetails (stashId: AccountId, controllerIdOpt: Option<AccountId> | null, nominatorsOpt: Option<PalletStakingNominations>, rewardDestinationOpts: Option<PalletStakingRewardDestination> | PalletStakingRewardDestination, validatorPrefs: PalletStakingValidatorPrefs, exposure: SpStakingExposure, stakingLedgerOpt: Option<PalletStakingStakingLedger>): DeriveStakingQuery {
function parseDetails (stashId: AccountId, controllerIdOpt: Option<AccountId> | null, nominatorsOpt: Option<PalletStakingNominations>, rewardDestinationOpts: Option<PalletStakingRewardDestination> | PalletStakingRewardDestination, validatorPrefs: PalletStakingValidatorPrefs, exposure: Option<SpStakingExposurePage>, stakingLedgerOpt: Option<PalletStakingStakingLedger>, exposureMeta: Option<SpStakingPagedExposureMetadata>): DeriveStakingQuery {
return {
accountId: stashId,
controllerId: controllerIdOpt?.unwrapOr(null) || null,
exposure,
exposureMeta,
exposurePaged: exposure,
nominators: nominatorsOpt.isSome
? nominatorsOpt.unwrap().targets
: [],
Expand Down Expand Up @@ -57,11 +59,12 @@ function getLedgers (api: DeriveApi, optIds: (Option<AccountId> | null)[], { wit
);
}

function getStashInfo (api: DeriveApi, stashIds: AccountId[], activeEra: EraIndex, { withController, withDestination, withExposure, withLedger, withNominations, withPrefs }: StakingQueryFlags): Observable<[(Option<AccountId> | null)[], Option<PalletStakingNominations>[], Option<PalletStakingRewardDestination>[], PalletStakingValidatorPrefs[], SpStakingExposure[]]> {
function getStashInfo (api: DeriveApi, stashIds: AccountId[], activeEra: EraIndex, { withController, withDestination, withExposure, withExposureMeta, withLedger, withNominations, withPrefs }: StakingQueryFlags, page: u32 | AnyNumber): Observable<[(Option<AccountId> | null)[], Option<PalletStakingNominations>[], Option<PalletStakingRewardDestination>[], PalletStakingValidatorPrefs[], Option<SpStakingExposurePage>[], Option<SpStakingPagedExposureMetadata>[]]> {
const emptyNoms = api.registry.createType<Option<PalletStakingNominations>>('Option<Nominations>');
const emptyRewa = api.registry.createType<Option<PalletStakingRewardDestination>>('RewardDestination');
const emptyExpo = api.registry.createType<SpStakingExposure>('Exposure');
const emptyExpo = api.registry.createType<Option<SpStakingExposurePage>>('Option<SpStakingExposurePage>');
const emptyPrefs = api.registry.createType<PalletStakingValidatorPrefs>('ValidatorPrefs');
const emptyExpoMeta = api.registry.createType<Option<SpStakingPagedExposureMetadata>>('Option<SpStakingPagedExposureMetadata>');

return combineLatest([
withController || withLedger
Expand All @@ -77,18 +80,21 @@ function getStashInfo (api: DeriveApi, stashIds: AccountId[], activeEra: EraInde
? combineLatest(stashIds.map((s) => api.query.staking.validators(s)))
: of(stashIds.map(() => emptyPrefs)),
withExposure
? combineLatest(stashIds.map((s) => api.query.staking.erasStakers(activeEra, s)))
: of(stashIds.map(() => emptyExpo))
? combineLatest(stashIds.map((s) => api.query.staking.erasStakersPaged<Option<SpStakingExposurePage>>(activeEra, s, page)))
: of(stashIds.map(() => emptyExpo)),
withExposureMeta
? combineLatest(stashIds.map((s) => api.query.staking.erasStakersOverview(activeEra, s)))
: of(stashIds.map(() => emptyExpoMeta))
]);
}

function getBatch (api: DeriveApi, activeEra: EraIndex, stashIds: AccountId[], flags: StakingQueryFlags): Observable<DeriveStakingQuery[]> {
return getStashInfo(api, stashIds, activeEra, flags).pipe(
switchMap(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure]): Observable<DeriveStakingQuery[]> =>
function getBatch (api: DeriveApi, activeEra: EraIndex, stashIds: AccountId[], flags: StakingQueryFlags, page: u32 | AnyNumber): Observable<DeriveStakingQuery[]> {
return getStashInfo(api, stashIds, activeEra, flags, page).pipe(
switchMap(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure, exposureMeta]): Observable<DeriveStakingQuery[]> =>
getLedgers(api, controllerIdOpt, flags).pipe(
map((stakingLedgerOpts) =>
stashIds.map((stashId, index) =>
parseDetails(stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index])
parseDetails(stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index], exposureMeta[index])
)
)
)
Expand All @@ -101,18 +107,19 @@ function getBatch (api: DeriveApi, activeEra: EraIndex, stashIds: AccountId[], f
* @description From a stash, retrieve the controllerId and all relevant details
*/
export const query = /*#__PURE__*/ firstMemo(
(api: DeriveApi, accountId: Uint8Array | string, flags: StakingQueryFlags) =>
api.derive.staking.queryMulti([accountId], flags)
(api: DeriveApi, accountId: Uint8Array | string, flags: StakingQueryFlags, page?: u32) =>
api.derive.staking.queryMulti([accountId], flags, page)
);

export function queryMulti (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags) => Observable<DeriveStakingQuery[]> {
return memo(instanceId, (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags): Observable<DeriveStakingQuery[]> =>
export function queryMulti (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags, page?: u32 | AnyNumber) => Observable<DeriveStakingQuery[]> {
return memo(instanceId, (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags, page?: u32 | AnyNumber): Observable<DeriveStakingQuery[]> =>
api.derive.session.indexes().pipe(
switchMap(({ activeEra }): Observable<DeriveStakingQuery[]> => {
const stashIds = accountIds.map((a) => api.registry.createType('AccountId', a));
const p = page || 0;

return stashIds.length
? getBatch(api, activeEra, stashIds, flags)
? getBatch(api, activeEra, stashIds, flags, p)
: of([]);
})
)
Expand Down
9 changes: 7 additions & 2 deletions packages/api-derive/src/staking/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2024 @polkadot/api-derive authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { Option } from '@polkadot/types';
import type { AccountId, Balance, EraIndex, RewardPoint } from '@polkadot/types/interfaces';
import type { PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure, SpStakingExposurePage } from '@polkadot/types/lookup';
import type { PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup';
import type { BN } from '@polkadot/util';
import type { DeriveSessionIndexes } from '../session/types.js';

Expand Down Expand Up @@ -42,8 +43,10 @@ export interface DeriveStakerPoints {

export interface DeriveOwnExposure {
clipped: SpStakingExposure;
exposurePaged: Option<SpStakingExposurePage>;
era: EraIndex;
exposure: SpStakingExposure;
exposureMeta: Option<SpStakingPagedExposureMetadata>;
}

export interface DeriveEraExposureNominating {
Expand Down Expand Up @@ -115,7 +118,8 @@ export interface DeriveStakingValidators {

export interface DeriveStakingStash {
controllerId: AccountId | null;
exposure: SpStakingExposure;
exposurePaged: Option<SpStakingExposurePage>;
exposureMeta: Option<SpStakingPagedExposureMetadata>;
nominators: AccountId[];
rewardDestination: PalletStakingRewardDestination | null;
stashId: AccountId;
Expand Down Expand Up @@ -160,4 +164,5 @@ export interface StakingQueryFlags {
withLedger?: boolean;
withNominations?: boolean;
withPrefs?: boolean;
withExposureMeta?: boolean;
}
6 changes: 4 additions & 2 deletions packages/api-derive/src/staking/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

import type { Observable } from 'rxjs';
import type { ObsInnerType } from '@polkadot/api-base/types';
import type { u32 } from '@polkadot/types';
import type { EraIndex } from '@polkadot/types/interfaces';
import type { AnyNumber } from '@polkadot/types-codec/types';
import type { ExactDerive } from '../derive.js';
import type { DeriveApi } from '../types.js';

Expand Down Expand Up @@ -60,9 +62,9 @@ export function erasHistoricApplyAccount <F extends '_ownExposures' | '_ownSlash
return (instanceId: string, api: DeriveApi) =>
// Cannot quite get the typing right, but it is right in the code
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
memo(instanceId, (accountId: string | Uint8Array, withActive = false) =>
memo(instanceId, (accountId: string | Uint8Array, withActive = false, page?: u32 | AnyNumber) =>
api.derive.staking.erasHistoric(withActive).pipe(
switchMap((e) => api.derive.staking[fn](accountId, e, withActive))
switchMap((e) => api.derive.staking[fn](accountId, e, withActive, page || 0))
)
) as any;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/api-derive/src/staking/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { memo } from '../util/index.js';

export function nextElected (instanceId: string, api: DeriveApi): () => Observable<AccountId[]> {
return memo(instanceId, (): Observable<AccountId[]> =>
api.query.staking.erasStakers
api.query.staking.erasStakersPaged
? api.derive.session.indexes().pipe(
// only populate for next era in the last session, so track both here - entries are not
// subscriptions, so we need a trigger - currentIndex acts as that trigger to refresh
switchMap(({ currentEra }) => api.query.staking.erasStakers.keys(currentEra)),
switchMap(({ currentEra }) => api.query.staking.erasStakersPaged.keys(currentEra)),
map((keys) => keys.map(({ args: [, accountId] }) => accountId))
)
: api.query.staking['currentElected']<AccountId[]>()
Expand Down

0 comments on commit c4e8270

Please sign in to comment.