diff --git a/packages/api-derive/src/accounts/identity.ts b/packages/api-derive/src/accounts/identity.ts index dff561d450..caacc62d81 100644 --- a/packages/api-derive/src/accounts/identity.ts +++ b/packages/api-derive/src/accounts/identity.ts @@ -13,7 +13,7 @@ import { combineLatest, map, of, switchMap } from 'rxjs'; import { isHex, u8aToString } from '@polkadot/util'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; type IdentityInfoAdditional = PalletIdentityIdentityInfo['additional'][0]; @@ -104,11 +104,10 @@ export function identity (instanceId: string, api: ApiInterfaceRx): (accountId?: ); } -export function hasIdentity (instanceId: string, api: ApiInterfaceRx): (accountId: AccountId | Uint8Array | string) => Observable { - return memo(instanceId, (accountId: AccountId | Uint8Array | string): Observable => - firstObservable(api.derive.accounts.hasIdentityMulti([accountId])) - ); -} +export const hasIdentity = firstMemo( + (api: ApiInterfaceRx, accountId: AccountId | Uint8Array | string) => + api.derive.accounts.hasIdentityMulti([accountId]) +); export function hasIdentityMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (AccountId | Uint8Array | string)[]) => Observable { return memo(instanceId, (accountIds: (AccountId | Uint8Array | string)[]): Observable => diff --git a/packages/api-derive/src/chain/bestNumber.ts b/packages/api-derive/src/chain/bestNumber.ts index 8b3902552a..8c0d07a3d3 100644 --- a/packages/api-derive/src/chain/bestNumber.ts +++ b/packages/api-derive/src/chain/bestNumber.ts @@ -1,6 +1,8 @@ // Copyright 2017-2021 @polkadot/api-derive authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiInterfaceRx } from '@polkadot/api/types'; + import { unwrapBlockNumber } from './util'; /** @@ -15,4 +17,7 @@ import { unwrapBlockNumber } from './util'; * }); * ``` */ -export const bestNumber = unwrapBlockNumber((api) => api.derive.chain.subscribeNewHeads()); +export const bestNumber = unwrapBlockNumber( + (api: ApiInterfaceRx) => + api.derive.chain.subscribeNewHeads() +); diff --git a/packages/api-derive/src/chain/bestNumberFinalized.ts b/packages/api-derive/src/chain/bestNumberFinalized.ts index 8f609ac9b9..a382115175 100644 --- a/packages/api-derive/src/chain/bestNumberFinalized.ts +++ b/packages/api-derive/src/chain/bestNumberFinalized.ts @@ -1,6 +1,8 @@ // Copyright 2017-2021 @polkadot/api-derive authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiInterfaceRx } from '@polkadot/api/types'; + import { unwrapBlockNumber } from './util'; /** @@ -16,4 +18,7 @@ import { unwrapBlockNumber } from './util'; * }); * ``` */ -export const bestNumberFinalized = unwrapBlockNumber((api) => api.rpc.chain.subscribeFinalizedHeads()); +export const bestNumberFinalized = unwrapBlockNumber( + (api: ApiInterfaceRx) => + api.rpc.chain.subscribeFinalizedHeads() +); diff --git a/packages/api-derive/src/staking/account.ts b/packages/api-derive/src/staking/account.ts index c2297b44ef..4979dc4a8d 100644 --- a/packages/api-derive/src/staking/account.ts +++ b/packages/api-derive/src/staking/account.ts @@ -11,7 +11,7 @@ import { combineLatest, map, switchMap } from 'rxjs'; import { BN, BN_ZERO } from '@polkadot/util'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; const QUERY_OPTS = { withDestination: true, @@ -73,7 +73,9 @@ export function accounts (instanceId: string, api: ApiInterfaceRx): (accountIds: api.derive.staking.keysMulti(accountIds), api.derive.staking.queryMulti(accountIds, QUERY_OPTS) ]).pipe( - map(([keys, queries]) => queries.map((query, index) => parseResult(api, sessionInfo, keys[index], query))) + map(([keys, queries]) => + queries.map((q, index) => parseResult(api, sessionInfo, keys[index], q)) + ) ) ) ) @@ -83,8 +85,7 @@ export function accounts (instanceId: string, api: ApiInterfaceRx): (accountIds: /** * @description From a stash, retrieve the controllerId and fill in all the relevant staking details */ -export function account (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable { - return memo(instanceId, (accountId: Uint8Array | string): Observable => - firstObservable(api.derive.staking.accounts([accountId])) - ); -} +export const account = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string) => + api.derive.staking.accounts([accountId]) +); diff --git a/packages/api-derive/src/staking/erasExposure.ts b/packages/api-derive/src/staking/erasExposure.ts index 994c7a36dd..d556767c8c 100644 --- a/packages/api-derive/src/staking/erasExposure.ts +++ b/packages/api-derive/src/staking/erasExposure.ts @@ -38,8 +38,8 @@ function mapStakers (era: EraIndex, stakers: KeysAndExposures): DeriveEraExposur return { era, nominators, validators }; } -export function _eraExposure (instanceId: string, api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { - return memo(instanceId, (era: EraIndex, withActive: boolean): Observable => { +export function _eraExposure (instanceId: string, api: ApiInterfaceRx): (era: EraIndex, withActive?: boolean) => Observable { + return memo(instanceId, (era: EraIndex, withActive = false): Observable => { const [cacheKey, cached] = getEraCache(CACHE_KEY, era, withActive); return cached diff --git a/packages/api-derive/src/staking/erasHistoric.ts b/packages/api-derive/src/staking/erasHistoric.ts index 7553f5ef71..2e942e83dc 100644 --- a/packages/api-derive/src/staking/erasHistoric.ts +++ b/packages/api-derive/src/staking/erasHistoric.ts @@ -13,8 +13,8 @@ import { BN_ONE, BN_ZERO } from '@polkadot/util'; import { memo } from '../util'; -export function erasHistoric (instanceId: string, api: ApiInterfaceRx): (withActive: boolean) => Observable { - return memo(instanceId, (withActive: boolean): Observable => +export function erasHistoric (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive?: boolean): Observable => api.queryMulti<[Option, u32]>([ api.query.staking.activeEra, api.query.staking.historyDepth diff --git a/packages/api-derive/src/staking/keys.ts b/packages/api-derive/src/staking/keys.ts index d61ff08d46..a8242fbef2 100644 --- a/packages/api-derive/src/staking/keys.ts +++ b/packages/api-derive/src/staking/keys.ts @@ -11,7 +11,7 @@ import type { DeriveStakingKeys } from './types'; import { combineLatest, map, of, switchMap } from 'rxjs'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; function extractsIds (stashId: Uint8Array | string, queuedKeys: [AccountId, NodeRuntimeSessionKeys | AccountId[]][], nextKeys: Option): DeriveStakingKeys { const sessionIds = (queuedKeys.find(([currentId]) => currentId.eq(stashId)) || [undefined, [] as AccountId[]])[1]; @@ -27,11 +27,10 @@ function extractsIds (stashId: Uint8Array | string, queuedKeys: [AccountId, Node }; } -export function keys (instanceId: string, api: ApiInterfaceRx): (stashId: Uint8Array | string) => Observable { - return memo(instanceId, (stashId: Uint8Array | string): Observable => - firstObservable(api.derive.staking.keysMulti([stashId])) - ); -} +export const keys = firstMemo( + (api: ApiInterfaceRx, stashId: Uint8Array | string) => + api.derive.staking.keysMulti([stashId]) +); export function keysMulti (instanceId: string, api: ApiInterfaceRx): (stashIds: (Uint8Array | string)[]) => Observable { return memo(instanceId, (stashIds: (Uint8Array | string)[]): Observable => diff --git a/packages/api-derive/src/staking/ownExposure.ts b/packages/api-derive/src/staking/ownExposure.ts index de6382caf1..246223b5bf 100644 --- a/packages/api-derive/src/staking/ownExposure.ts +++ b/packages/api-derive/src/staking/ownExposure.ts @@ -9,7 +9,7 @@ import type { DeriveOwnExposure } from '../types'; import { map, of } from 'rxjs'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; import { erasHistoricApplyAccount } from './util'; export function _ownExposures (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { @@ -28,10 +28,9 @@ export function _ownExposures (instanceId: string, api: ApiInterfaceRx): (accoun ); } -export function ownExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { - return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex): Observable => - firstObservable(api.derive.staking._ownExposures(accountId, [era], true)) - ); -} +export const ownExposure = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string, era: EraIndex) => + api.derive.staking._ownExposures(accountId, [era], true) +); export const ownExposures = erasHistoricApplyAccount('_ownExposures'); diff --git a/packages/api-derive/src/staking/ownSlashes.ts b/packages/api-derive/src/staking/ownSlashes.ts index d76c6b1169..9a131bab0d 100644 --- a/packages/api-derive/src/staking/ownSlashes.ts +++ b/packages/api-derive/src/staking/ownSlashes.ts @@ -10,7 +10,7 @@ import type { DeriveStakerSlashes } from '../types'; import { map, of } from 'rxjs'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; import { erasHistoricApplyAccount } from './util'; export function _ownSlashes (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { @@ -34,10 +34,9 @@ export function _ownSlashes (instanceId: string, api: ApiInterfaceRx): (accountI ); } -export function ownSlash (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { - return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex): Observable => - firstObservable(api.derive.staking._ownSlashes(accountId, [era], true)) - ); -} +export const ownSlash = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string, era: EraIndex) => + api.derive.staking._ownSlashes(accountId, [era], true) +); export const ownSlashes = erasHistoricApplyAccount('_ownSlashes'); diff --git a/packages/api-derive/src/staking/query.ts b/packages/api-derive/src/staking/query.ts index 0cda50bda1..bdd443ccbf 100644 --- a/packages/api-derive/src/staking/query.ts +++ b/packages/api-derive/src/staking/query.ts @@ -10,7 +10,7 @@ import type { DeriveStakingQuery, StakingQueryFlags } from '../types'; import { combineLatest, map, of, switchMap } from 'rxjs'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; function parseDetails (stashId: AccountId, controllerIdOpt: Option | null, nominatorsOpt: Option, rewardDestination: PalletStakingRewardDestination, validatorPrefs: PalletStakingValidatorPrefs, exposure: PalletStakingExposure, stakingLedgerOpt: Option): DeriveStakingQuery { return { @@ -93,11 +93,10 @@ function getBatch (api: ApiInterfaceRx, activeEra: EraIndex, stashIds: AccountId /** * @description From a stash, retrieve the controllerId and all relevant details */ -export function query (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, flags: StakingQueryFlags) => Observable { - return memo(instanceId, (accountId: Uint8Array | string, flags: StakingQueryFlags): Observable => - firstObservable(api.derive.staking.queryMulti([accountId], flags)) - ); -} +export const query = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string, flags: StakingQueryFlags) => + api.derive.staking.queryMulti([accountId], flags) +); export function queryMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags) => Observable { return memo(instanceId, (accountIds: (Uint8Array | string)[], flags: StakingQueryFlags): Observable => diff --git a/packages/api-derive/src/staking/stakerExposure.ts b/packages/api-derive/src/staking/stakerExposure.ts index 8fa09f1fd9..92840f978a 100644 --- a/packages/api-derive/src/staking/stakerExposure.ts +++ b/packages/api-derive/src/staking/stakerExposure.ts @@ -8,10 +8,10 @@ import type { DeriveEraValidatorExposure, DeriveStakerExposure } from '../types' import { map, switchMap } from 'rxjs'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; -export function _stakerExposures (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive: boolean) => Observable { - return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive: boolean): Observable => { +export function _stakerExposures (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive?: boolean) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive = false): Observable => { const stakerIds = accountIds.map((a) => api.registry.createType('AccountId', a).toString()); return api.derive.staking._erasExposure(eras, withActive).pipe( @@ -46,8 +46,7 @@ export function stakerExposures (instanceId: string, api: ApiInterfaceRx): (acco ); } -export function stakerExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => - firstObservable(api.derive.staking.stakerExposures([accountId], withActive)) - ); -} +export const stakerExposure = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string, withActive?: boolean) => + api.derive.staking.stakerExposures([accountId], withActive) +); diff --git a/packages/api-derive/src/staking/stakerRewards.ts b/packages/api-derive/src/staking/stakerRewards.ts index 0f94559020..8607dfe15c 100644 --- a/packages/api-derive/src/staking/stakerRewards.ts +++ b/packages/api-derive/src/staking/stakerRewards.ts @@ -13,7 +13,7 @@ import { combineLatest, map, of, switchMap } from 'rxjs'; import { BN_BILLION, BN_ZERO } from '@polkadot/util'; -import { firstObservable, memo } from '../util'; +import { firstMemo, memo } from '../util'; type ErasResult = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[]]; @@ -132,8 +132,8 @@ function filterRewards (eras: EraIndex[], valInfo: [string, DeriveStakingQuery][ })); } -export function _stakerRewardsEras (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => +export function _stakerRewardsEras (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive?: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive = false): Observable => combineLatest([ api.derive.staking._erasPoints(eras, withActive), api.derive.staking._erasPrefs(eras, withActive), @@ -142,8 +142,8 @@ export function _stakerRewardsEras (instanceId: string, api: ApiInterfaceRx): (e ); } -export function _stakerRewards (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive: boolean) => Observable { - return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive: boolean): Observable => +export function _stakerRewards (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive?: boolean) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive = false): Observable => combineLatest([ api.derive.staking.queryMulti(accountIds, { withLedger: true }), api.derive.staking._stakerExposures(accountIds, eras, withActive), @@ -184,13 +184,12 @@ export function _stakerRewards (instanceId: string, api: ApiInterfaceRx): (accou ); } -export function stakerRewards (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => - firstObservable(api.derive.staking.erasHistoric(withActive).pipe( +export const stakerRewards = firstMemo( + (api: ApiInterfaceRx, accountId: Uint8Array | string, withActive?: boolean) => + api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._stakerRewards([accountId], eras, withActive)) - )) - ); -} + ) +); export function stakerRewardsMultiEras (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[]) => Observable { return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[]): Observable => diff --git a/packages/api-derive/src/util/first.ts b/packages/api-derive/src/util/first.ts new file mode 100644 index 0000000000..acc7a383a2 --- /dev/null +++ b/packages/api-derive/src/util/first.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2021 @polkadot/api-derive authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Observable } from 'rxjs'; +import type { ApiInterfaceRx } from '@polkadot/api/types'; + +import { map } from 'rxjs'; + +import { memo } from '@polkadot/rpc-core'; + +// We are re-exporting these from here to ensure that *.d.ts generation is correct +export type { ApiInterfaceRx } from '@polkadot/api/types'; + +export function firstObservable (obs: Observable): Observable { + return obs.pipe(map(([a]) => a)); +} + +export function firstMemo (fn: (api: ApiInterfaceRx, ...args: A) => Observable): (instanceId: string, api: ApiInterfaceRx) => (...args: A) => Observable { + return (instanceId: string, api: ApiInterfaceRx) => + memo(instanceId, (...args: A) => + firstObservable(fn(api, ...args)) + ); +} diff --git a/packages/api-derive/src/util/index.ts b/packages/api-derive/src/util/index.ts index fad368e057..82e61ce4e5 100644 --- a/packages/api-derive/src/util/index.ts +++ b/packages/api-derive/src/util/index.ts @@ -1,16 +1,9 @@ // Copyright 2017-2021 @polkadot/api-derive authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Observable } from 'rxjs'; - -import { map } from 'rxjs'; - export { drr, memo } from '@polkadot/rpc-core'; export * from './approvalFlagsToBools'; export * from './cache'; export * from './cacheImpl'; - -export function firstObservable (obs: Observable): Observable { - return obs.pipe(map(([a]) => a)); -} +export * from './first';