From b6d1be6ee55a419f96c0b91a221c77b7d543cdbd Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 2 Sep 2020 17:13:38 +0200 Subject: [PATCH] Only memomize via instanceId (#2572) * Add memoizee instanceId * Gotcha. * linitng --- packages/api-derive/src/accounts/accountId.ts | 4 ++-- packages/api-derive/src/accounts/flags.ts | 4 ++-- .../api-derive/src/accounts/idAndIndex.ts | 4 ++-- packages/api-derive/src/accounts/idToIndex.ts | 4 ++-- packages/api-derive/src/accounts/indexToId.ts | 4 ++-- packages/api-derive/src/accounts/indexes.ts | 4 ++-- packages/api-derive/src/accounts/info.ts | 4 ++-- packages/api-derive/src/balances/account.ts | 4 ++-- packages/api-derive/src/balances/all.ts | 4 ++-- packages/api-derive/src/balances/fees.ts | 4 ++-- .../api-derive/src/balances/votingBalances.ts | 4 ++-- packages/api-derive/src/chain/bestNumber.ts | 4 ++-- .../src/chain/bestNumberFinalized.ts | 4 ++-- .../api-derive/src/chain/bestNumberLag.ts | 4 ++-- packages/api-derive/src/chain/getBlock.ts | 4 ++-- packages/api-derive/src/chain/getHeader.ts | 4 ++-- .../api-derive/src/chain/subscribeNewHeads.ts | 4 ++-- .../api-derive/src/collective/proposals.ts | 4 ++-- packages/api-derive/src/contracts/fees.ts | 4 ++-- packages/api-derive/src/council/proposals.ts | 4 ++-- packages/api-derive/src/council/votes.ts | 4 ++-- packages/api-derive/src/council/votesOf.ts | 4 ++-- .../api-derive/src/democracy/dispatchQueue.ts | 4 ++-- packages/api-derive/src/democracy/locks.ts | 4 ++-- .../api-derive/src/democracy/nextExternal.ts | 4 ++-- packages/api-derive/src/democracy/preimage.ts | 4 ++-- .../api-derive/src/democracy/preimages.ts | 4 ++-- .../api-derive/src/democracy/proposals.ts | 4 ++-- .../api-derive/src/democracy/referendumIds.ts | 4 ++-- .../api-derive/src/democracy/referendums.ts | 4 ++-- .../src/democracy/referendumsActive.ts | 4 ++-- .../src/democracy/referendumsFinished.ts | 4 ++-- .../src/democracy/referendumsInfo.ts | 16 ++++++------- .../src/democracy/sqrtElectorate.ts | 4 ++-- packages/api-derive/src/elections/info.ts | 4 ++-- .../src/imOnline/receivedHeartbeats.ts | 4 ++-- packages/api-derive/src/index.ts | 10 ++++---- packages/api-derive/src/parachains/info.ts | 4 ++-- .../api-derive/src/parachains/overview.ts | 4 ++-- packages/api-derive/src/session/eraLength.ts | 4 ++-- .../api-derive/src/session/eraProgress.ts | 4 ++-- packages/api-derive/src/session/indexes.ts | 4 ++-- packages/api-derive/src/session/info.ts | 4 ++-- packages/api-derive/src/session/progress.ts | 4 ++-- .../api-derive/src/session/sessionProgress.ts | 4 ++-- packages/api-derive/src/society/candidates.ts | 4 ++-- packages/api-derive/src/society/info.ts | 4 ++-- packages/api-derive/src/society/member.ts | 4 ++-- packages/api-derive/src/society/members.ts | 4 ++-- packages/api-derive/src/staking/account.ts | 8 +++---- .../api-derive/src/staking/currentPoints.ts | 4 ++-- .../api-derive/src/staking/electedInfo.ts | 4 ++-- .../api-derive/src/staking/erasExposure.ts | 16 ++++++------- .../api-derive/src/staking/erasHistoric.ts | 4 ++-- packages/api-derive/src/staking/erasPoints.ts | 8 +++---- packages/api-derive/src/staking/erasPrefs.ts | 16 ++++++------- .../api-derive/src/staking/erasRewards.ts | 8 +++---- .../api-derive/src/staking/erasSlashes.ts | 16 ++++++------- packages/api-derive/src/staking/overview.ts | 4 ++-- .../api-derive/src/staking/ownExposure.ts | 16 ++++++------- packages/api-derive/src/staking/ownSlashes.ts | 16 ++++++------- packages/api-derive/src/staking/query.ts | 8 +++---- .../api-derive/src/staking/stakerExposure.ts | 8 +++---- .../api-derive/src/staking/stakerPoints.ts | 8 +++---- .../api-derive/src/staking/stakerRewards.ts | 20 ++++++++-------- .../api-derive/src/staking/stakerSlashes.ts | 8 +++---- packages/api-derive/src/staking/stashes.ts | 4 ++-- packages/api-derive/src/staking/validators.ts | 8 +++---- .../api-derive/src/staking/waitingInfo.ts | 4 ++-- .../src/technicalCommittee/proposals.ts | 4 ++-- packages/api-derive/src/treasury/proposals.ts | 4 ++-- packages/api-derive/src/tx/events.ts | 4 ++-- packages/api-derive/src/tx/signingInfo.ts | 2 +- packages/api-derive/src/util/memo.ts | 4 ++-- packages/api/src/base/Decorate.ts | 23 +++++++++++-------- packages/api/src/rx/Api.ts | 12 +++++----- .../api/src/submittable/createSubmittable.ts | 14 ++--------- packages/api/src/util/augmentObject.ts | 2 +- packages/rpc-core/src/cached.spec.ts | 2 +- packages/rpc-core/src/index.spec.ts | 4 ++-- packages/rpc-core/src/index.ts | 9 +++++--- packages/rpc-core/src/methodSend.spec.ts | 2 +- packages/rpc-core/src/replay.spec.ts | 2 +- 83 files changed, 244 insertions(+), 246 deletions(-) diff --git a/packages/api-derive/src/accounts/accountId.ts b/packages/api-derive/src/accounts/accountId.ts index 6a655be621..bce5575284 100644 --- a/packages/api-derive/src/accounts/accountId.ts +++ b/packages/api-derive/src/accounts/accountId.ts @@ -37,7 +37,7 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn * @param {(Address | AccountId | AccountIndex | string | null)} address - An accounts address in various formats. * @description An [[AccountId]] */ -export function accountId (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable { - return memo((address?: Address | AccountId | AccountIndex | string | null): Observable => +export function accountId (instanceId: string, api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable { + return memo(instanceId, (address?: Address | AccountId | AccountIndex | string | null): Observable => retrieve(api, address)); } diff --git a/packages/api-derive/src/accounts/flags.ts b/packages/api-derive/src/accounts/flags.ts index 4a95f4ee60..dd6b8a67f3 100644 --- a/packages/api-derive/src/accounts/flags.ts +++ b/packages/api-derive/src/accounts/flags.ts @@ -31,8 +31,8 @@ function isIncludedFn (accountId: AccountId | Address | string): (_: AccountId | * @name info * @description Returns account membership flags */ -export function flags (api: ApiInterfaceRx): (address?: AccountId | Address | string | null) => Observable { - return memo((address?: AccountId | Address | string | null): Observable => { +export function flags (instanceId: string, api: ApiInterfaceRx): (address?: AccountId | Address | string | null) => Observable { + return memo(instanceId, (address?: AccountId | Address | string | null): Observable => { const councilSection = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections'; return ( diff --git a/packages/api-derive/src/accounts/idAndIndex.ts b/packages/api-derive/src/accounts/idAndIndex.ts index e32c633b0b..c4a73e2634 100644 --- a/packages/api-derive/src/accounts/idAndIndex.ts +++ b/packages/api-derive/src/accounts/idAndIndex.ts @@ -51,7 +51,7 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn * }); * ``` */ -export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable { - return memo((address?: Address | AccountId | AccountIndex | string | null): Observable => +export function idAndIndex (instanceId: string, api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable { + return memo(instanceId, (address?: Address | AccountId | AccountIndex | string | null): Observable => retrieve(api, address)); } diff --git a/packages/api-derive/src/accounts/idToIndex.ts b/packages/api-derive/src/accounts/idToIndex.ts index ebdc21fe80..4a0b327dfb 100644 --- a/packages/api-derive/src/accounts/idToIndex.ts +++ b/packages/api-derive/src/accounts/idToIndex.ts @@ -25,8 +25,8 @@ import { memo } from '../util'; * }); * ``` */ -export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable { - return memo((accountId: AccountId | string): Observable => +export function idToIndex (instanceId: string, api: ApiInterfaceRx): (accountId: AccountId | string) => Observable { + return memo(instanceId, (accountId: AccountId | string): Observable => api.derive.accounts.indexes().pipe( map((indexes: AccountIndexes): AccountIndex | undefined => (indexes || {})[accountId.toString()] diff --git a/packages/api-derive/src/accounts/indexToId.ts b/packages/api-derive/src/accounts/indexToId.ts index c824cb5e5e..cede9a32df 100644 --- a/packages/api-derive/src/accounts/indexToId.ts +++ b/packages/api-derive/src/accounts/indexToId.ts @@ -49,8 +49,8 @@ function query (api: ApiInterfaceRx, accountIndex: AccountIndex | string): Obser * }); * ``` */ -export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable { - return memo((accountIndex: AccountIndex | string): Observable => +export function indexToId (instanceId: string, api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable { + return memo(instanceId, (accountIndex: AccountIndex | string): Observable => api.query.indices ? isFunction(api.query.indices.accounts) ? query(api, accountIndex) diff --git a/packages/api-derive/src/accounts/indexes.ts b/packages/api-derive/src/accounts/indexes.ts index 72d9f5f94c..84a0dba71c 100644 --- a/packages/api-derive/src/accounts/indexes.ts +++ b/packages/api-derive/src/accounts/indexes.ts @@ -72,8 +72,8 @@ function queryAccounts (api: ApiInterfaceRx): Observable { * }); * ``` */ -export function indexes (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function indexes (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => indicesCache ? of(indicesCache) : ( diff --git a/packages/api-derive/src/accounts/info.ts b/packages/api-derive/src/accounts/info.ts index 394a9e9031..54132523ca 100644 --- a/packages/api-derive/src/accounts/info.ts +++ b/packages/api-derive/src/accounts/info.ts @@ -113,8 +113,8 @@ function retrieveIdentity (api: ApiInterfaceRx, accountId?: AccountId): Observab * @name info * @description Returns aux. info with regards to an account, current that includes the accountId, accountIndex and nickname */ -export function info (api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable { - return memo((address?: AccountIndex | AccountId | Address | string | null): Observable => +export function info (instanceId: string, api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable { + return memo(instanceId, (address?: AccountIndex | AccountId | Address | string | null): Observable => api.derive.accounts.idAndIndex(address).pipe( switchMap(([accountId, accountIndex]): Observable<[Partial, DeriveAccountRegistration, string?]> => combineLatest([ diff --git a/packages/api-derive/src/balances/account.ts b/packages/api-derive/src/balances/account.ts index ebd759a135..6c3d35eb7f 100644 --- a/packages/api-derive/src/balances/account.ts +++ b/packages/api-derive/src/balances/account.ts @@ -80,8 +80,8 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable Observable { - return memo((address: AccountIndex | AccountId | Address | string): Observable => +export function account (instanceId: string, api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable { + return memo(instanceId, (address: AccountIndex | AccountId | Address | string): Observable => api.derive.accounts.accountId(address).pipe( switchMap((accountId): Observable<[AccountId, Result]> => (accountId diff --git a/packages/api-derive/src/balances/all.ts b/packages/api-derive/src/balances/all.ts index c97c283eb9..e6fda4def4 100644 --- a/packages/api-derive/src/balances/all.ts +++ b/packages/api-derive/src/balances/all.ts @@ -128,8 +128,8 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable Observable { - return memo((address: AccountIndex | AccountId | Address | string): Observable => +export function all (instanceId: string, api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable { + return memo(instanceId, (address: AccountIndex | AccountId | Address | string): Observable => api.derive.balances.account(address).pipe( switchMap((account): Observable => (!account.accountId.isEmpty diff --git a/packages/api-derive/src/balances/fees.ts b/packages/api-derive/src/balances/fees.ts index 412ae4de3a..041b6acd95 100644 --- a/packages/api-derive/src/balances/fees.ts +++ b/packages/api-derive/src/balances/fees.ts @@ -24,8 +24,8 @@ import { memo } from '../util'; * }); * ``` */ -export function fees (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function fees (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => of([ // deprecated - remove (api.consts.balances?.creationFee as unknown as Balance) || api.registry.createType('Balance'), diff --git a/packages/api-derive/src/balances/votingBalances.ts b/packages/api-derive/src/balances/votingBalances.ts index 909882d9c3..d9b56db87e 100644 --- a/packages/api-derive/src/balances/votingBalances.ts +++ b/packages/api-derive/src/balances/votingBalances.ts @@ -10,8 +10,8 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { memo } from '../util'; -export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable { - return memo((addresses?: (AccountId | AccountIndex | Address | string)[]): Observable => +export function votingBalances (instanceId: string, api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable { + return memo(instanceId, (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable => !addresses || !addresses.length ? of([] as DeriveBalancesAccount[]) : combineLatest( diff --git a/packages/api-derive/src/chain/bestNumber.ts b/packages/api-derive/src/chain/bestNumber.ts index 6442a1695e..9aed96155a 100644 --- a/packages/api-derive/src/chain/bestNumber.ts +++ b/packages/api-derive/src/chain/bestNumber.ts @@ -22,8 +22,8 @@ import { memo } from '../util'; * }); * ``` */ -export function bestNumber (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function bestNumber (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.chain.subscribeNewHeads().pipe( map((header) => header.number.unwrap()) )); diff --git a/packages/api-derive/src/chain/bestNumberFinalized.ts b/packages/api-derive/src/chain/bestNumberFinalized.ts index d0f17dc742..8def98e5ba 100644 --- a/packages/api-derive/src/chain/bestNumberFinalized.ts +++ b/packages/api-derive/src/chain/bestNumberFinalized.ts @@ -23,8 +23,8 @@ import { memo } from '../util'; * }); * ``` */ -export function bestNumberFinalized (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function bestNumberFinalized (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.rpc.chain.subscribeFinalizedHeads().pipe( map((header) => header.number.unwrap()) )); diff --git a/packages/api-derive/src/chain/bestNumberLag.ts b/packages/api-derive/src/chain/bestNumberLag.ts index 294fc326a8..c0396e20b5 100644 --- a/packages/api-derive/src/chain/bestNumberLag.ts +++ b/packages/api-derive/src/chain/bestNumberLag.ts @@ -23,8 +23,8 @@ import { memo } from '../util'; * }); * ``` */ -export function bestNumberLag (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function bestNumberLag (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => combineLatest([ api.derive.chain.bestNumber(), api.derive.chain.bestNumberFinalized() diff --git a/packages/api-derive/src/chain/getBlock.ts b/packages/api-derive/src/chain/getBlock.ts index 156124d4e0..a0734d87d9 100644 --- a/packages/api-derive/src/chain/getBlock.ts +++ b/packages/api-derive/src/chain/getBlock.ts @@ -23,8 +23,8 @@ import { memo } from '../util'; * console.log(`block #${number} was authored by ${author}`); * ``` */ -export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable { - return memo((hash: Uint8Array | string): Observable => +export function getHeader (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable { + return memo(instanceId, (hash: Uint8Array | string): Observable => combineLatest([ api.rpc.chain.getBlock(hash), api.query.session diff --git a/packages/api-derive/src/chain/getHeader.ts b/packages/api-derive/src/chain/getHeader.ts index 7ba2997efc..8cfb9a5c78 100644 --- a/packages/api-derive/src/chain/getHeader.ts +++ b/packages/api-derive/src/chain/getHeader.ts @@ -24,8 +24,8 @@ import { memo } from '../util'; * console.log(`block #${number} was authored by ${author}`); * ``` */ -export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable { - return memo((hash: Uint8Array | string): Observable => +export function getHeader (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable { + return memo(instanceId, (hash: Uint8Array | string): Observable => combineLatest([ api.rpc.chain.getHeader(hash), api.query.session diff --git a/packages/api-derive/src/chain/subscribeNewHeads.ts b/packages/api-derive/src/chain/subscribeNewHeads.ts index d895bf38d4..7b8769e0a3 100644 --- a/packages/api-derive/src/chain/subscribeNewHeads.ts +++ b/packages/api-derive/src/chain/subscribeNewHeads.ts @@ -23,8 +23,8 @@ import { memo } from '../util'; * }); * ``` */ -export function subscribeNewHeads (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function subscribeNewHeads (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => combineLatest([ api.rpc.chain.subscribeNewHeads(), api.query.session diff --git a/packages/api-derive/src/collective/proposals.ts b/packages/api-derive/src/collective/proposals.ts index e67747d22f..a423693bac 100644 --- a/packages/api-derive/src/collective/proposals.ts +++ b/packages/api-derive/src/collective/proposals.ts @@ -29,8 +29,8 @@ function parse ([hashes, proposals, votes]: Result): DeriveCollectiveProposal[] .filter((proposal): proposal is DeriveCollectiveProposal => !!proposal); } -export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable { - return memo((): Observable => +export function proposals (instanceId: string, api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable { + return memo(instanceId, (): Observable => isFunction(api.query[section]?.proposals) ? api.query[section].proposals().pipe( switchMap((hashes: Hash[]): Observable => diff --git a/packages/api-derive/src/contracts/fees.ts b/packages/api-derive/src/contracts/fees.ts index 31baf9c20f..933a04a37c 100644 --- a/packages/api-derive/src/contracts/fees.ts +++ b/packages/api-derive/src/contracts/fees.ts @@ -45,8 +45,8 @@ function queryConstants (api: ApiInterfaceRx): Observable { * }); * ``` */ -export function fees (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => { +export function fees (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => { return queryConstants(api).pipe( map(([callBaseFee, contractFee, creationFee, transactionBaseFee, transactionByteFee, transferFee, rentByteFee, rentDepositOffset, surchargeReward, tombstoneDeposit]): DeriveContractFees => ({ callBaseFee, diff --git a/packages/api-derive/src/council/proposals.ts b/packages/api-derive/src/council/proposals.ts index 0cfef25a06..787327bf89 100644 --- a/packages/api-derive/src/council/proposals.ts +++ b/packages/api-derive/src/council/proposals.ts @@ -9,6 +9,6 @@ import { Observable } from 'rxjs'; import { proposals as collectiveProposals } from '../collective'; import { memo } from '../util'; -export function proposals (api: ApiInterfaceRx): () => Observable { - return memo(collectiveProposals(api, 'council')); +export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, collectiveProposals(instanceId, api, 'council')); } diff --git a/packages/api-derive/src/council/votes.ts b/packages/api-derive/src/council/votes.ts index c248130fb9..e4cddf63a2 100644 --- a/packages/api-derive/src/council/votes.ts +++ b/packages/api-derive/src/council/votes.ts @@ -81,8 +81,8 @@ function retrieveCurrent (api: ApiInterfaceRx): Observable { ); } -export function votes (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function votes (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => (api.query.electionsPhragmen || api.query.elections).stakeOf ? retrievePrev(api) : retrieveCurrent(api) diff --git a/packages/api-derive/src/council/votesOf.ts b/packages/api-derive/src/council/votesOf.ts index 88d6581f02..1a51b0a2b4 100644 --- a/packages/api-derive/src/council/votesOf.ts +++ b/packages/api-derive/src/council/votesOf.ts @@ -10,8 +10,8 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { memo } from '../util'; -export function votesOf (api: ApiInterfaceRx): (accountId: string | Uint8Array | AccountId) => Observable { - return memo((accountId: string | Uint8Array | AccountId): Observable => +export function votesOf (instanceId: string, api: ApiInterfaceRx): (accountId: string | Uint8Array | AccountId) => Observable { + return memo(instanceId, (accountId: string | Uint8Array | AccountId): Observable => api.derive.council.votes().pipe( map((votes): DeriveCouncilVote => ( diff --git a/packages/api-derive/src/democracy/dispatchQueue.ts b/packages/api-derive/src/democracy/dispatchQueue.ts index 7ddce13d26..f49f88c5e9 100644 --- a/packages/api-derive/src/democracy/dispatchQueue.ts +++ b/packages/api-derive/src/democracy/dispatchQueue.ts @@ -94,8 +94,8 @@ function queryScheduler (api: ApiInterfaceRx): Observable { ); } -export function dispatchQueue (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function dispatchQueue (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => isFunction(api.query.scheduler?.agenda) ? queryScheduler(api) : api.query.democracy.dispatchQueue diff --git a/packages/api-derive/src/democracy/locks.ts b/packages/api-derive/src/democracy/locks.ts index 3ed6f26cde..a9acf5fc44 100644 --- a/packages/api-derive/src/democracy/locks.ts +++ b/packages/api-derive/src/democracy/locks.ts @@ -74,8 +74,8 @@ function directLocks (api: ApiInterfaceRx, { votes }: VotingDirect): Observable< ); } -export function locks (api: ApiInterfaceRx): (accountId: string | AccountId) => Observable { - return memo((accountId: string | AccountId): Observable => +export function locks (instanceId: string, api: ApiInterfaceRx): (accountId: string | AccountId) => Observable { + return memo(instanceId, (accountId: string | AccountId): Observable => api.query.democracy.votingOf(accountId).pipe( switchMap((voting): Observable => voting.isDirect diff --git a/packages/api-derive/src/democracy/nextExternal.ts b/packages/api-derive/src/democracy/nextExternal.ts index 708dfb4695..38e3ee336c 100644 --- a/packages/api-derive/src/democracy/nextExternal.ts +++ b/packages/api-derive/src/democracy/nextExternal.ts @@ -29,8 +29,8 @@ function withImage (api: ApiInterfaceRx, nextOpt: Option Observable { - return memo((): Observable => +export function nextExternal (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.democracy?.nextExternal ? api.query.democracy.nextExternal>>().pipe( switchMap((nextOpt) => withImage(api, nextOpt)) diff --git a/packages/api-derive/src/democracy/preimage.ts b/packages/api-derive/src/democracy/preimage.ts index bc8ddd9c90..c9752410a5 100644 --- a/packages/api-derive/src/democracy/preimage.ts +++ b/packages/api-derive/src/democracy/preimage.ts @@ -16,8 +16,8 @@ import { parseImage } from './util'; type PreImage = Option>; -export function preimage (api: ApiInterfaceRx): (hash: Hash) => Observable { - return memo((hash: Hash): Observable => +export function preimage (instanceId: string, api: ApiInterfaceRx): (hash: Hash) => Observable { + return memo(instanceId, (hash: Hash): Observable => api.query.democracy.preimages(hash).pipe( map((imageOpt) => parseImage(api, imageOpt)) ) diff --git a/packages/api-derive/src/democracy/preimages.ts b/packages/api-derive/src/democracy/preimages.ts index cb2b8b8f1d..3aff0b5d97 100644 --- a/packages/api-derive/src/democracy/preimages.ts +++ b/packages/api-derive/src/democracy/preimages.ts @@ -16,8 +16,8 @@ import { parseImage } from './util'; type PreImage = Option>; -export function preimages (api: ApiInterfaceRx): (hashes: Hash[]) => Observable<(DeriveProposalImage | undefined)[]> { - return memo((hashes: Hash[]): Observable<(DeriveProposalImage | undefined)[]> => +export function preimages (instanceId: string, api: ApiInterfaceRx): (hashes: Hash[]) => Observable<(DeriveProposalImage | undefined)[]> { + return memo(instanceId, (hashes: Hash[]): Observable<(DeriveProposalImage | undefined)[]> => api.query.democracy.preimages.multi(hashes).pipe( map((images): (DeriveProposalImage | undefined)[] => images.map((imageOpt) => parseImage(api, imageOpt)) diff --git a/packages/api-derive/src/democracy/proposals.ts b/packages/api-derive/src/democracy/proposals.ts index b6f93b7dd2..403d073f44 100644 --- a/packages/api-derive/src/democracy/proposals.ts +++ b/packages/api-derive/src/democracy/proposals.ts @@ -49,8 +49,8 @@ function parse ([proposals, images, optDepositors]: Result): DeriveProposal[] { }); } -export function proposals (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.democracy?.publicProps && api.query.democracy?.preimages ? api.query.democracy.publicProps().pipe( switchMap((proposals) => diff --git a/packages/api-derive/src/democracy/referendumIds.ts b/packages/api-derive/src/democracy/referendumIds.ts index 3960dcbc2d..60294372ff 100644 --- a/packages/api-derive/src/democracy/referendumIds.ts +++ b/packages/api-derive/src/democracy/referendumIds.ts @@ -11,8 +11,8 @@ import { map } from 'rxjs/operators'; import { memo } from '../util'; -export function referendumIds (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function referendumIds (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.democracy?.lowestUnbaked ? api.queryMulti<[ReferendumIndex, ReferendumIndex]>([ api.query.democracy.lowestUnbaked, diff --git a/packages/api-derive/src/democracy/referendums.ts b/packages/api-derive/src/democracy/referendums.ts index d278fdd950..b5afd99dff 100644 --- a/packages/api-derive/src/democracy/referendums.ts +++ b/packages/api-derive/src/democracy/referendums.ts @@ -10,8 +10,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function referendums (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function referendums (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.democracy.referendumsActive().pipe( switchMap((referendums) => combineLatest([ diff --git a/packages/api-derive/src/democracy/referendumsActive.ts b/packages/api-derive/src/democracy/referendumsActive.ts index fdc022fe72..8abc31cb80 100644 --- a/packages/api-derive/src/democracy/referendumsActive.ts +++ b/packages/api-derive/src/democracy/referendumsActive.ts @@ -10,8 +10,8 @@ import { switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function referendumsActive (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function referendumsActive (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.democracy.referendumIds().pipe( switchMap((ids): Observable => ids.length diff --git a/packages/api-derive/src/democracy/referendumsFinished.ts b/packages/api-derive/src/democracy/referendumsFinished.ts index 9aa8d41da8..1b1df4240b 100644 --- a/packages/api-derive/src/democracy/referendumsFinished.ts +++ b/packages/api-derive/src/democracy/referendumsFinished.ts @@ -11,8 +11,8 @@ import { Option } from '@polkadot/types'; import { memo } from '../util'; -export function referendumsFinished (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function referendumsFinished (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.democracy.referendumIds().pipe( switchMap((ids) => api.query.democracy.referendumInfoOf.multi>(ids)), map((infos): ReferendumInfoFinished[] => diff --git a/packages/api-derive/src/democracy/referendumsInfo.ts b/packages/api-derive/src/democracy/referendumsInfo.ts index 60bc6ea2f2..fba30679e5 100644 --- a/packages/api-derive/src/democracy/referendumsInfo.ts +++ b/packages/api-derive/src/democracy/referendumsInfo.ts @@ -92,8 +92,8 @@ function votesCurr (api: ApiInterfaceRx, referendumId: BN): Observable Observable { - return memo((referendum: DeriveReferendum): Observable => +export function _referendumVotes (instanceId: string, api: ApiInterfaceRx): (referendum: DeriveReferendum) => Observable { + return memo(instanceId, (referendum: DeriveReferendum): Observable => combineLatest([ api.derive.democracy.sqrtElectorate(), isFunction(api.query.democracy.votingOf) @@ -107,8 +107,8 @@ export function _referendumVotes (api: ApiInterfaceRx): (referendum: DeriveRefer ); } -export function _referendumsVotes (api: ApiInterfaceRx): (referendums: DeriveReferendum[]) => Observable { - return memo((referendums: DeriveReferendum[]): Observable => +export function _referendumsVotes (instanceId: string, api: ApiInterfaceRx): (referendums: DeriveReferendum[]) => Observable { + return memo(instanceId, (referendums: DeriveReferendum[]): Observable => referendums.length ? combineLatest( referendums.map((referendum): Observable => @@ -119,8 +119,8 @@ export function _referendumsVotes (api: ApiInterfaceRx): (referendums: DeriveRef ); } -export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option) => Observable { - return memo((index: BN, info: Option): Observable => { +export function _referendumInfo (instanceId: string, api: ApiInterfaceRx): (index: BN, info: Option) => Observable { + return memo(instanceId, (index: BN, info: Option): Observable => { const status = getStatus(info); return status @@ -136,8 +136,8 @@ export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option< }); } -export function referendumsInfo (api: ApiInterfaceRx): (ids: BN[]) => Observable { - return memo((ids: BN[]): Observable => +export function referendumsInfo (instanceId: string, api: ApiInterfaceRx): (ids: BN[]) => Observable { + return memo(instanceId, (ids: BN[]): Observable => ids.length ? api.query.democracy.referendumInfoOf.multi>(ids).pipe( switchMap((infos): Observable<(DeriveReferendum | null)[]> => diff --git a/packages/api-derive/src/democracy/sqrtElectorate.ts b/packages/api-derive/src/democracy/sqrtElectorate.ts index b23ce3bb55..5cd98b030f 100644 --- a/packages/api-derive/src/democracy/sqrtElectorate.ts +++ b/packages/api-derive/src/democracy/sqrtElectorate.ts @@ -11,8 +11,8 @@ import { bnSqrt } from '@polkadot/util'; import { memo } from '../util'; -export function sqrtElectorate (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function sqrtElectorate (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.balances.totalIssuance().pipe( map((totalIssuance) => bnSqrt(totalIssuance) diff --git a/packages/api-derive/src/elections/info.ts b/packages/api-derive/src/elections/info.ts index 281343198a..f65c50d66a 100644 --- a/packages/api-derive/src/elections/info.ts +++ b/packages/api-derive/src/elections/info.ts @@ -55,6 +55,6 @@ function queryElections (api: ApiInterfaceRx): Observable { * }); * ``` */ -export function info (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => queryElections(api)); +export function info (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => queryElections(api)); } diff --git a/packages/api-derive/src/imOnline/receivedHeartbeats.ts b/packages/api-derive/src/imOnline/receivedHeartbeats.ts index a309acc5e2..8d18672d78 100644 --- a/packages/api-derive/src/imOnline/receivedHeartbeats.ts +++ b/packages/api-derive/src/imOnline/receivedHeartbeats.ts @@ -16,8 +16,8 @@ import { memo } from '../util'; /** * @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session */ -export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function receivedHeartbeats (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.imOnline?.receivedHeartbeats ? api.derive.staking.overview().pipe( switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option[], u32[]]> => diff --git a/packages/api-derive/src/index.ts b/packages/api-derive/src/index.ts index 641e84c1ed..bac865ed0d 100644 --- a/packages/api-derive/src/index.ts +++ b/packages/api-derive/src/index.ts @@ -60,7 +60,7 @@ const deriveAvail: Record = { * `allSections`, and keep the object architecture of `allSections`. */ /** @internal */ -function injectFunctions (api: ApiInterfaceRx, allSections: AllSections): DeriveAllSections { +function injectFunctions (instanceId: string, api: ApiInterfaceRx, allSections: AllSections): DeriveAllSections { const queryKeys = Object.keys(api.query); return Object @@ -77,7 +77,7 @@ function injectFunctions (api: ApiInterfaceRx, allSections: AllSect const methodName = _methodName as keyof typeof section; // Not sure what to do here, casting as any. Though the final types are good // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call - const method = (section[methodName] as any)(api); + const method = (section[methodName] as any)(instanceId, api); // idem // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access @@ -93,9 +93,9 @@ function injectFunctions (api: ApiInterfaceRx, allSections: AllSect // FIXME The return type of this function should be {...ExactDerive, ...DeriveCustom} // For now we just drop the custom derive typings /** @internal */ -export default function decorateDerive (api: ApiInterfaceRx, custom: DeriveCustom = {}): ExactDerive { +export default function decorateDerive (instanceId: string, api: ApiInterfaceRx, custom: DeriveCustom = {}): ExactDerive { return { - ...injectFunctions(api, derive), - ...injectFunctions(api, custom) + ...injectFunctions(instanceId, api, derive), + ...injectFunctions(instanceId, api, custom) }; } diff --git a/packages/api-derive/src/parachains/info.ts b/packages/api-derive/src/parachains/info.ts index 1a2b6818bb..c9d8f8a4fe 100644 --- a/packages/api-derive/src/parachains/info.ts +++ b/packages/api-derive/src/parachains/info.ts @@ -77,8 +77,8 @@ function parse (id: ParaId, [active, retryQueue, selectedThreads, didUpdate, inf }; } -export function info (api: ApiInterfaceRx): (id: ParaId | number) => Observable { - return memo((id: ParaId | number): Observable => +export function info (instanceId: string, api: ApiInterfaceRx): (id: ParaId | number) => Observable { + return memo(instanceId, (id: ParaId | number): Observable => api.query.registrar && api.query.parachains ? api.queryMulti([ api.query.registrar.active, diff --git a/packages/api-derive/src/parachains/overview.ts b/packages/api-derive/src/parachains/overview.ts index e3a32a2a72..846eb6f344 100644 --- a/packages/api-derive/src/parachains/overview.ts +++ b/packages/api-derive/src/parachains/overview.ts @@ -34,8 +34,8 @@ function parse ([ids, didUpdate, infos, pendingSwaps, relayDispatchQueueSizes]: }); } -export function overview (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function overview (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.registrar?.parachains && api.query.parachains ? api.query.registrar.parachains().pipe( switchMap((paraIds) => diff --git a/packages/api-derive/src/session/eraLength.ts b/packages/api-derive/src/session/eraLength.ts index b1350ec826..e3b853680b 100644 --- a/packages/api-derive/src/session/eraLength.ts +++ b/packages/api-derive/src/session/eraLength.ts @@ -10,8 +10,8 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { memo } from '../util'; -export function eraLength (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function eraLength (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.session.info().pipe( map((info) => info.eraLength) )); diff --git a/packages/api-derive/src/session/eraProgress.ts b/packages/api-derive/src/session/eraProgress.ts index ca39eeaae5..3a43297e2e 100644 --- a/packages/api-derive/src/session/eraProgress.ts +++ b/packages/api-derive/src/session/eraProgress.ts @@ -10,8 +10,8 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { memo } from '../util'; -export function eraProgress (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function eraProgress (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.session.progress().pipe( map((info) => info.eraProgress) )); diff --git a/packages/api-derive/src/session/indexes.ts b/packages/api-derive/src/session/indexes.ts index 7a2609239d..dda2b2969e 100644 --- a/packages/api-derive/src/session/indexes.ts +++ b/packages/api-derive/src/session/indexes.ts @@ -76,8 +76,8 @@ function empty (api: ApiInterfaceRx): Observable { ]); } -export function indexes (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function indexes (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => ( api.query.session && api.query.staking ? isFunction(api.query.staking.activeEra) diff --git a/packages/api-derive/src/session/info.ts b/packages/api-derive/src/session/info.ts index 3baf82b15d..24eb1223ef 100644 --- a/packages/api-derive/src/session/info.ts +++ b/packages/api-derive/src/session/info.ts @@ -62,8 +62,8 @@ function queryBabe (api: ApiInterfaceRx): Observable { /** * @description Retrieves all the session and era query and calculates specific values on it as the length of the session and eras */ -export function info (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function info (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.consts.babe ? queryBabe(api) : queryAura(api) diff --git a/packages/api-derive/src/session/progress.ts b/packages/api-derive/src/session/progress.ts index 8c07eab2fc..f289778d8c 100644 --- a/packages/api-derive/src/session/progress.ts +++ b/packages/api-derive/src/session/progress.ts @@ -72,8 +72,8 @@ function queryBabeNoHistory (api: ApiInterfaceRx): Observable<[DeriveSessionInfo /** * @description Retrieves all the session and era query and calculates specific values on it as the length of the session and eras */ -export function progress (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function progress (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.consts.babe ? ( isFunction(api.query.staking.erasStartSessionIndex) diff --git a/packages/api-derive/src/session/sessionProgress.ts b/packages/api-derive/src/session/sessionProgress.ts index df804d4f9c..c692d32a72 100644 --- a/packages/api-derive/src/session/sessionProgress.ts +++ b/packages/api-derive/src/session/sessionProgress.ts @@ -10,8 +10,8 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { memo } from '../util'; -export function sessionProgress (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function sessionProgress (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.session.progress().pipe( map((info) => info.sessionProgress) )); diff --git a/packages/api-derive/src/society/candidates.ts b/packages/api-derive/src/society/candidates.ts index 8a6abcfbf2..5ad35acca1 100644 --- a/packages/api-derive/src/society/candidates.ts +++ b/packages/api-derive/src/society/candidates.ts @@ -19,8 +19,8 @@ type Result = [Bid[], ResultSuspend[]] /** * @description Get the candidate info for a society */ -export function candidates (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function candidates (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.society.candidates>().pipe( switchMap((candidates: Vec): Observable => combineLatest([ diff --git a/packages/api-derive/src/society/info.ts b/packages/api-derive/src/society/info.ts index 0d621954fc..0384dcef35 100644 --- a/packages/api-derive/src/society/info.ts +++ b/packages/api-derive/src/society/info.ts @@ -17,8 +17,8 @@ type Result = [Vec, Option, Option, Option /** * @description Get the overall info for a society */ -export function info (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function info (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.queryMulti([ api.query.society.bids, api.query.society.defender, diff --git a/packages/api-derive/src/society/member.ts b/packages/api-derive/src/society/member.ts index e80afb3ef2..29b4ebcff0 100644 --- a/packages/api-derive/src/society/member.ts +++ b/packages/api-derive/src/society/member.ts @@ -18,8 +18,8 @@ type Result = [Vec>, StrikeCount, Option Observable { - return memo((accountId: AccountId): Observable => +export function member (instanceId: string, api: ApiInterfaceRx): (accountId: AccountId) => Observable { + return memo(instanceId, (accountId: AccountId): Observable => api.queryMulti([ [api.query.society.payouts, accountId], [api.query.society.strikes, accountId], diff --git a/packages/api-derive/src/society/members.ts b/packages/api-derive/src/society/members.ts index 5ca7b50523..a0febf9958 100644 --- a/packages/api-derive/src/society/members.ts +++ b/packages/api-derive/src/society/members.ts @@ -14,8 +14,8 @@ import { memo } from '../util'; /** * @description Get the member info for a society */ -export function members (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function members (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.society.members().pipe( switchMap((members): Observable => combineLatest( diff --git a/packages/api-derive/src/staking/account.ts b/packages/api-derive/src/staking/account.ts index 8ce30072de..638bf17f20 100644 --- a/packages/api-derive/src/staking/account.ts +++ b/packages/api-derive/src/staking/account.ts @@ -57,8 +57,8 @@ function parseResult (api: ApiInterfaceRx, sessionInfo: DeriveSessionInfo, query /** * @description From a list of stashes, fill in all the relevant staking details */ -export function accounts (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable { - return memo((accountIds: (Uint8Array | string)[]): Observable => +export function accounts (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[]): Observable => api.derive.session.info().pipe( switchMap((sessionInfo) => api.derive.staking.queryMulti(accountIds).pipe( @@ -72,8 +72,8 @@ export function accounts (api: ApiInterfaceRx): (accountIds: (Uint8Array | strin /** * @description From a stash, retrieve the controllerId and fill in all the relevant staking details */ -export function account (api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable { - return memo((accountId: Uint8Array | string): Observable => +export function account (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable { + return memo(instanceId, (accountId: Uint8Array | string): Observable => api.derive.staking.accounts([accountId]).pipe( map(([first]) => first) ) diff --git a/packages/api-derive/src/staking/currentPoints.ts b/packages/api-derive/src/staking/currentPoints.ts index d88c6c2c47..9dc2fb6cf3 100644 --- a/packages/api-derive/src/staking/currentPoints.ts +++ b/packages/api-derive/src/staking/currentPoints.ts @@ -28,8 +28,8 @@ function retrievePointsPrev (api: ApiInterfaceRx, currentElected: AccountId[]): /** * @description Retrieve the staking overview, including elected and points earned */ -export function currentPoints (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function currentPoints (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.staking.overview().pipe( switchMap(({ activeEra, nextElected }) => api.query.staking.erasRewardPoints diff --git a/packages/api-derive/src/staking/electedInfo.ts b/packages/api-derive/src/staking/electedInfo.ts index d4963df409..3fd24d3237 100644 --- a/packages/api-derive/src/staking/electedInfo.ts +++ b/packages/api-derive/src/staking/electedInfo.ts @@ -10,8 +10,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function electedInfo (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function electedInfo (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.derive.staking.validators().pipe( switchMap(({ nextElected }): Observable => api.derive.staking.queryMulti(nextElected).pipe( diff --git a/packages/api-derive/src/staking/erasExposure.ts b/packages/api-derive/src/staking/erasExposure.ts index d5a7d1ecc4..c4ae536615 100644 --- a/packages/api-derive/src/staking/erasExposure.ts +++ b/packages/api-derive/src/staking/erasExposure.ts @@ -36,8 +36,8 @@ function mapStakers (era: EraIndex, stakers: KeysAndExposures): DeriveEraExposur return { era, nominators, validators }; } -export function _eraExposure (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { - return memo((era: EraIndex, withActive: boolean): Observable => { +export function _eraExposure (instanceId: string, api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { + return memo(instanceId, (era: EraIndex, withActive: boolean): Observable => { const cacheKey = `${CACHE_KEY}-${era.toString()}`; const cached = withActive ? undefined @@ -57,22 +57,22 @@ export function _eraExposure (api: ApiInterfaceRx): (era: EraIndex, withActive: }); } -export function eraExposure (api: ApiInterfaceRx): (era: EraIndex) => Observable { - return memo((era: EraIndex): Observable => +export function eraExposure (instanceId: string, api: ApiInterfaceRx): (era: EraIndex) => Observable { + return memo(instanceId, (era: EraIndex): Observable => api.derive.staking._eraExposure(era, true) ); } -export function _erasExposure (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => +export function _erasExposure (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => eras.length ? combineLatest(eras.map((era) => api.derive.staking._eraExposure(era, withActive))) : of([]) ); } -export function erasExposure (api: ApiInterfaceRx): (withActive?: boolean) => Observable { - return memo((withActive = false): Observable => +export function erasExposure (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._erasExposure(eras, withActive)) ) diff --git a/packages/api-derive/src/staking/erasHistoric.ts b/packages/api-derive/src/staking/erasHistoric.ts index 4321a3f54d..e16ca1da8d 100644 --- a/packages/api-derive/src/staking/erasHistoric.ts +++ b/packages/api-derive/src/staking/erasHistoric.ts @@ -12,8 +12,8 @@ import { Option, u32 } from '@polkadot/types'; import { memo } from '../util'; -export function erasHistoric (api: ApiInterfaceRx): (withActive: boolean) => Observable { - return memo((withActive: boolean): Observable => +export function erasHistoric (instanceId: string, api: ApiInterfaceRx): (withActive: boolean) => Observable { + return memo(instanceId, (withActive: boolean): Observable => api.query.staking?.activeEra ? api.queryMulti<[Option, u32]>([ api.query.staking.activeEra, diff --git a/packages/api-derive/src/staking/erasPoints.ts b/packages/api-derive/src/staking/erasPoints.ts index c3e74672b7..c26781e4ac 100644 --- a/packages/api-derive/src/staking/erasPoints.ts +++ b/packages/api-derive/src/staking/erasPoints.ts @@ -32,8 +32,8 @@ function mapPoints (eras: EraIndex[], points: EraRewardPoints[]): DeriveEraPoint })); } -export function _erasPoints (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => { +export function _erasPoints (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => { if (!eras.length) { return of([]); } @@ -62,8 +62,8 @@ export function _erasPoints (api: ApiInterfaceRx): (eras: EraIndex[], withActive }); } -export function erasPoints (api: ApiInterfaceRx): (withActive?: boolean) => Observable { - return memo((withActive = false): Observable => +export function erasPoints (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._erasPoints(eras, withActive)) ) diff --git a/packages/api-derive/src/staking/erasPrefs.ts b/packages/api-derive/src/staking/erasPrefs.ts index caef07829b..84106bb40e 100644 --- a/packages/api-derive/src/staking/erasPrefs.ts +++ b/packages/api-derive/src/staking/erasPrefs.ts @@ -24,8 +24,8 @@ function mapPrefs (era: EraIndex, all: [StorageKey, ValidatorPrefs][]): DeriveEr return { era, validators }; } -export function _eraPrefs (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { - return memo((era: EraIndex, withActive: boolean): Observable => { +export function _eraPrefs (instanceId: string, api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { + return memo(instanceId, (era: EraIndex, withActive: boolean): Observable => { const cacheKey = `${CACHE_KEY}-${era.toString()}`; const cached = withActive ? undefined @@ -45,22 +45,22 @@ export function _eraPrefs (api: ApiInterfaceRx): (era: EraIndex, withActive: boo }); } -export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable { - return memo((era: EraIndex): Observable => +export function eraPrefs (instanceId: string, api: ApiInterfaceRx): (era: EraIndex) => Observable { + return memo(instanceId, (era: EraIndex): Observable => api.derive.staking._eraPrefs(era, true) ); } -export function _erasPrefs (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => +export function _erasPrefs (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => eras.length ? combineLatest(eras.map((era) => api.derive.staking._eraPrefs(era, withActive))) : of([]) ); } -export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean) => Observable { - return memo((withActive = false): Observable => +export function erasPrefs (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._erasPrefs(eras, withActive)) ) diff --git a/packages/api-derive/src/staking/erasRewards.ts b/packages/api-derive/src/staking/erasRewards.ts index 8158cc0624..eedbbb10d1 100644 --- a/packages/api-derive/src/staking/erasRewards.ts +++ b/packages/api-derive/src/staking/erasRewards.ts @@ -21,8 +21,8 @@ function mapRewards (eras: EraIndex[], optRewards: Option[]): DeriveEra })); } -export function _erasRewards (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => { +export function _erasRewards (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => { if (!eras.length) { return of([]); } @@ -53,8 +53,8 @@ export function _erasRewards (api: ApiInterfaceRx): (eras: EraIndex[], withActiv }); } -export function erasRewards (api: ApiInterfaceRx): (withActive?: boolean) => Observable { - return memo((withActive = false): Observable => +export function erasRewards (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._erasRewards(eras, withActive)) ) diff --git a/packages/api-derive/src/staking/erasSlashes.ts b/packages/api-derive/src/staking/erasSlashes.ts index ec413359a1..fe5c41fd30 100644 --- a/packages/api-derive/src/staking/erasSlashes.ts +++ b/packages/api-derive/src/staking/erasSlashes.ts @@ -30,8 +30,8 @@ function mapSlashes (era: EraIndex, noms: [StorageKey, Option][], val return { era, nominators, validators }; } -export function _eraSlashes (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { - return memo((era: EraIndex, withActive: boolean): Observable => { +export function _eraSlashes (instanceId: string, api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable { + return memo(instanceId, (era: EraIndex, withActive: boolean): Observable => { const cacheKey = `${CACHE_KEY}-${era.toString()}`; const cached = withActive ? undefined @@ -54,14 +54,14 @@ export function _eraSlashes (api: ApiInterfaceRx): (era: EraIndex, withActive: b }); } -export function eraSlashes (api: ApiInterfaceRx): (era: EraIndex) => Observable { - return memo((era: EraIndex): Observable => +export function eraSlashes (instanceId: string, api: ApiInterfaceRx): (era: EraIndex) => Observable { + return memo(instanceId, (era: EraIndex): Observable => api.derive.staking._eraSlashes(era, true) ); } -export function _erasSlashes (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => +export function _erasSlashes (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => eras.length ? combineLatest( eras.map((era) => api.derive.staking._eraSlashes(era, withActive)) @@ -70,8 +70,8 @@ export function _erasSlashes (api: ApiInterfaceRx): (eras: EraIndex[], withActiv ); } -export function erasSlashes (api: ApiInterfaceRx): (withActive?: boolean) => Observable { - return memo((withActive = false): Observable => +export function erasSlashes (instanceId: string, api: ApiInterfaceRx): (withActive?: boolean) => Observable { + return memo(instanceId, (withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._erasSlashes(eras, withActive)) ) diff --git a/packages/api-derive/src/staking/overview.ts b/packages/api-derive/src/staking/overview.ts index 7dccfd640e..ae0813eb03 100644 --- a/packages/api-derive/src/staking/overview.ts +++ b/packages/api-derive/src/staking/overview.ts @@ -13,8 +13,8 @@ import { memo } from '../util'; /** * @description Retrieve the staking overview, including elected and points earned */ -export function overview (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function overview (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => combineLatest([ api.derive.session.indexes(), api.derive.staking.validators() diff --git a/packages/api-derive/src/staking/ownExposure.ts b/packages/api-derive/src/staking/ownExposure.ts index c6d9ee5a35..e5413e954a 100644 --- a/packages/api-derive/src/staking/ownExposure.ts +++ b/packages/api-derive/src/staking/ownExposure.ts @@ -13,8 +13,8 @@ import { deriveCache, memo } from '../util'; const CACHE_KEY = 'ownExposure'; -export function _ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { +export function _ownExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { const cacheKey = `${CACHE_KEY}-${era.toString()}-${accountId.toString()}`; const cached = withActive ? undefined @@ -37,14 +37,14 @@ export function _ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | str }); } -export function ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { - return memo((accountId: Uint8Array | string, era: EraIndex): Observable => +export function ownExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex): Observable => api.derive.staking._ownExposure(accountId, era, true) ); } -export function _ownExposures (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => +export function _ownExposures (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => eras.length ? combineLatest( eras.map((era) => api.derive.staking._ownExposure(accountId, era, withActive)) @@ -53,8 +53,8 @@ export function _ownExposures (api: ApiInterfaceRx): (accountId: Uint8Array | st ); } -export function ownExposures (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => { +export function ownExposures (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => { return api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._ownExposures(accountId, eras, withActive) diff --git a/packages/api-derive/src/staking/ownSlashes.ts b/packages/api-derive/src/staking/ownSlashes.ts index ef636c55c2..4d93295127 100644 --- a/packages/api-derive/src/staking/ownSlashes.ts +++ b/packages/api-derive/src/staking/ownSlashes.ts @@ -15,8 +15,8 @@ import { deriveCache, memo } from '../util'; const CACHE_KEY = 'ownSlash'; -export function _ownSlash (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { +export function _ownSlash (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { const cacheKey = `${CACHE_KEY}-${era.toString()}-${accountId.toString()}`; const cached = withActive ? undefined @@ -44,14 +44,14 @@ export function _ownSlash (api: ApiInterfaceRx): (accountId: Uint8Array | string }); } -export function ownSlash (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { - return memo((accountId: Uint8Array | string, era: EraIndex): Observable => +export function ownSlash (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, era: EraIndex): Observable => api.derive.staking._ownSlash(accountId, era, true) ); } -export function _ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => +export function _ownSlashes (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => eras.length ? combineLatest( eras.map((era) => api.derive.staking._ownSlash(accountId, era, withActive)) @@ -60,8 +60,8 @@ export function _ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | stri ); } -export function ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => { +export function ownSlashes (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => { return api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._ownSlashes(accountId, eras, withActive) diff --git a/packages/api-derive/src/staking/query.ts b/packages/api-derive/src/staking/query.ts index e3fe1a1877..ea1dd3b6ee 100644 --- a/packages/api-derive/src/staking/query.ts +++ b/packages/api-derive/src/staking/query.ts @@ -106,16 +106,16 @@ function retrieveControllers (api: ApiInterfaceRx, optControllerIds: Option Observable { - return memo((accountId: Uint8Array | string): Observable => +export function query (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable { + return memo(instanceId, (accountId: Uint8Array | string): Observable => api.derive.staking.queryMulti([accountId]).pipe( map(([first]) => first) ) ); } -export function queryMulti (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable { - return memo((accountIds: (Uint8Array | string)[]): Observable => +export function queryMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[]) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[]): Observable => accountIds.length ? combineLatest([ api.query.session.queuedKeys>>(), diff --git a/packages/api-derive/src/staking/stakerExposure.ts b/packages/api-derive/src/staking/stakerExposure.ts index 443ec679e1..41cdad7fd2 100644 --- a/packages/api-derive/src/staking/stakerExposure.ts +++ b/packages/api-derive/src/staking/stakerExposure.ts @@ -11,8 +11,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { +export function _stakerExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { const stakerId = api.registry.createType('AccountId', accountId).toString(); return api.derive.staking._erasExposure(eras, withActive).pipe( @@ -37,8 +37,8 @@ export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | }); } -export function stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => +export function stakerExposure (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._stakerExposure(accountId, eras, withActive)) ) diff --git a/packages/api-derive/src/staking/stakerPoints.ts b/packages/api-derive/src/staking/stakerPoints.ts index acf7c4cb53..6601a14fcf 100644 --- a/packages/api-derive/src/staking/stakerPoints.ts +++ b/packages/api-derive/src/staking/stakerPoints.ts @@ -11,8 +11,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { +export function _stakerPoints (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { const stakerId = api.registry.createType('AccountId', accountId).toString(); return api.derive.staking._erasPoints(eras, withActive).pipe( @@ -27,8 +27,8 @@ export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | st }); } -export function stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => +export function stakerPoints (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._stakerPoints(accountId, eras, withActive)) ) diff --git a/packages/api-derive/src/staking/stakerRewards.ts b/packages/api-derive/src/staking/stakerRewards.ts index d5cb03bd02..c4a10ecaec 100644 --- a/packages/api-derive/src/staking/stakerRewards.ts +++ b/packages/api-derive/src/staking/stakerRewards.ts @@ -158,8 +158,8 @@ function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], migrateEra: BN, r ); } -export function _stakerRewardsEras (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { - return memo((eras: EraIndex[], withActive: boolean): Observable => +export function _stakerRewardsEras (instanceId: string, api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (eras: EraIndex[], withActive: boolean): Observable => combineLatest([ isFunction(api.query.staking.migrateEra) ? api.query.staking.migrateEra>() @@ -171,8 +171,8 @@ export function _stakerRewardsEras (api: ApiInterfaceRx): (eras: EraIndex[], wit ); } -export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => +export function _stakerRewards (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => combineLatest([ api.derive.staking.query(accountId), api.derive.staking._stakerExposure(accountId, eras, withActive), @@ -191,24 +191,24 @@ export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | s ); } -export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => +export function stakerRewards (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._stakerRewards(accountId, eras, withActive)) ) ); } -export function stakerRewardsMultiEras (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[]) => Observable { - return memo((accountIds: (Uint8Array | string)[], eras: EraIndex[]): Observable => +export function stakerRewardsMultiEras (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], eras: EraIndex[]) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[]): Observable => accountIds.length && eras.length ? combineLatest(accountIds.map((acc) => api.derive.staking._stakerRewards(acc, eras, false))) : of([]) ); } -export function stakerRewardsMulti (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], withActive?: boolean) => Observable { - return memo((accountIds: (Uint8Array | string)[], withActive = false): Observable => +export function stakerRewardsMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], withActive?: boolean) => Observable { + return memo(instanceId, (accountIds: (Uint8Array | string)[], withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking.stakerRewardsMultiEras(accountIds, eras)) ) diff --git a/packages/api-derive/src/staking/stakerSlashes.ts b/packages/api-derive/src/staking/stakerSlashes.ts index 5b07c8c820..99bdc82d49 100644 --- a/packages/api-derive/src/staking/stakerSlashes.ts +++ b/packages/api-derive/src/staking/stakerSlashes.ts @@ -11,8 +11,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { - return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { +export function _stakerSlashes (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => { const stakerId = api.registry.createType('AccountId', accountId).toString(); return api.derive.staking._erasSlashes(eras, withActive).pipe( @@ -26,8 +26,8 @@ export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | s }); } -export function stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive = false): Observable => +export function stakerSlashes (instanceId: string, api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo(instanceId, (accountId: Uint8Array | string, withActive = false): Observable => api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => api.derive.staking._stakerSlashes(accountId, eras, withActive)) ) diff --git a/packages/api-derive/src/staking/stashes.ts b/packages/api-derive/src/staking/stashes.ts index 5a9d0cede3..b9094aa839 100644 --- a/packages/api-derive/src/staking/stashes.ts +++ b/packages/api-derive/src/staking/stashes.ts @@ -15,8 +15,8 @@ import { memo } from '../util'; /** * @description Retrieve the list of all validator stashes */ -export function stashes (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function stashes (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.staking.validators.creator.meta.type.asMap.linked.isTrue ? api.query.staking.validators, Vec]>>().pipe( map(([stashIds]) => stashIds) diff --git a/packages/api-derive/src/staking/validators.ts b/packages/api-derive/src/staking/validators.ts index 4ce352b9de..e70357554f 100644 --- a/packages/api-derive/src/staking/validators.ts +++ b/packages/api-derive/src/staking/validators.ts @@ -11,8 +11,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function nextElected (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function nextElected (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.staking.erasStakers ? api.derive.session.indexes().pipe( // only populate for next era in the last session, so track both here - entries are not @@ -27,8 +27,8 @@ export function nextElected (api: ApiInterfaceRx): () => Observable /** * @description Retrieve latest list of validators */ -export function validators (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function validators (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => // Sadly the node-template is (for some obscure reason) not comprehensive, so while the derive works // in all actual real-world deployed chains, it does create some confusion for limited template chains // NOTE: Not doing multi queries here, since we have validators as a single in the derived newHead diff --git a/packages/api-derive/src/staking/waitingInfo.ts b/packages/api-derive/src/staking/waitingInfo.ts index aacf8874b2..b0a1e2df9b 100644 --- a/packages/api-derive/src/staking/waitingInfo.ts +++ b/packages/api-derive/src/staking/waitingInfo.ts @@ -10,8 +10,8 @@ import { map, switchMap } from 'rxjs/operators'; import { memo } from '../util'; -export function waitingInfo (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function waitingInfo (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => combineLatest([ api.derive.staking.validators(), api.derive.staking.stashes() diff --git a/packages/api-derive/src/technicalCommittee/proposals.ts b/packages/api-derive/src/technicalCommittee/proposals.ts index 66e1bbae31..493cad96f2 100644 --- a/packages/api-derive/src/technicalCommittee/proposals.ts +++ b/packages/api-derive/src/technicalCommittee/proposals.ts @@ -9,6 +9,6 @@ import { Observable } from 'rxjs'; import { proposals as collectiveProposals } from '../collective'; import { memo } from '../util'; -export function proposals (api: ApiInterfaceRx): () => Observable { - return memo(collectiveProposals(api, 'technicalCommittee')); +export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, collectiveProposals(instanceId, api, 'technicalCommittee')); } diff --git a/packages/api-derive/src/treasury/proposals.ts b/packages/api-derive/src/treasury/proposals.ts index 5cda8187f9..434b6d6780 100644 --- a/packages/api-derive/src/treasury/proposals.ts +++ b/packages/api-derive/src/treasury/proposals.ts @@ -74,8 +74,8 @@ function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, a /** * @description Retrieve all active and approved treasury proposals, along with their info */ -export function proposals (api: ApiInterfaceRx): () => Observable { - return memo((): Observable => +export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable { + return memo(instanceId, (): Observable => api.query.treasury ? combineLatest([ api.query.treasury.proposalCount(), diff --git a/packages/api-derive/src/tx/events.ts b/packages/api-derive/src/tx/events.ts index d288e94e98..87d6ebc7fd 100644 --- a/packages/api-derive/src/tx/events.ts +++ b/packages/api-derive/src/tx/events.ts @@ -15,8 +15,8 @@ interface Result { events: EventRecord[]; } -export function events (api: ApiInterfaceRx): (at: Hash) => Observable { - return memo((at: Hash): Observable => +export function events (instanceId: string, api: ApiInterfaceRx): (at: Hash) => Observable { + return memo(instanceId, (at: Hash): Observable => combineLatest([ api.query.system.events.at(at), api.rpc.chain.getBlock(at) diff --git a/packages/api-derive/src/tx/signingInfo.ts b/packages/api-derive/src/tx/signingInfo.ts index acf95e4e41..ac4f589e80 100644 --- a/packages/api-derive/src/tx/signingInfo.ts +++ b/packages/api-derive/src/tx/signingInfo.ts @@ -40,7 +40,7 @@ function signingHeader (api: ApiInterfaceRx): Observable
{ ); } -export function signingInfo (api: ApiInterfaceRx): (address: string, nonce?: AnyNumber | Codec, era?: IExtrinsicEra | number) => Observable { +export function signingInfo (_instanceId: string, api: ApiInterfaceRx): (address: string, nonce?: AnyNumber | Codec, era?: IExtrinsicEra | number) => Observable { // no memo, we want to do this fresh on each run return (address: string, nonce?: AnyNumber | Codec, era?: IExtrinsicEra | number): Observable => combineLatest([ diff --git a/packages/api-derive/src/util/memo.ts b/packages/api-derive/src/util/memo.ts index aff6704f79..0eab2148af 100644 --- a/packages/api-derive/src/util/memo.ts +++ b/packages/api-derive/src/util/memo.ts @@ -12,7 +12,7 @@ type ObsFn = (...params: any[]) => Observable; // 1. creates a memo of the inner fn -> Observable, removing when unsubscribed // 2. wraps the observable in a drr() (which includes an unsub delay) /** @internal */ -export function memo (inner: ObsFn): ObsFn { +export function memo (instanceId: string, inner: ObsFn): ObsFn { const cached = createMemo( (...params: any[]): Observable => new Observable((observer: Observer): TeardownLogic => { @@ -26,7 +26,7 @@ export function memo (inner: ObsFn): ObsFn { { // Normalize via JSON.stringify, allow e.g. AccountId -> ss58 // eslint-disable-next-line @typescript-eslint/unbound-method - normalizer: JSON.stringify + normalizer: (args) => instanceId + JSON.stringify(args) } ); diff --git a/packages/api/src/base/Decorate.ts b/packages/api/src/base/Decorate.ts index da68127480..1f776ee2f5 100644 --- a/packages/api/src/base/Decorate.ts +++ b/packages/api/src/base/Decorate.ts @@ -44,7 +44,11 @@ const PAGE_SIZE_VALS = PAGE_SIZE_KEYS; const l = logger('api/init'); +let instanceCounter = 0; + export default abstract class Decorate extends Events { + readonly #instanceId: string; + #registry: Registry; // HACK Use BN import so decorateDerive works... yes, wtf. @@ -127,6 +131,7 @@ export default abstract class Decorate extends Events constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod) { super(); + this.#instanceId = `${++instanceCounter}`; this.#registry = options.registry || new TypeRegistry(); const thisProvider = options.source @@ -136,7 +141,7 @@ export default abstract class Decorate extends Events this._decorateMethod = decorateMethod; this._options = options; this._type = type; - this._rpcCore = new RpcCore(this.#registry, thisProvider, this._options.rpc); + this._rpcCore = new RpcCore(this.#instanceId, this.#registry, thisProvider, this._options.rpc); this._isConnected = new BehaviorSubject(this._rpcCore.provider.isConnected()); this._rx.hasSubscriptions = this._rpcCore.provider.hasSubscriptions; this._rx.registry = this.#registry; @@ -178,7 +183,7 @@ export default abstract class Decorate extends Events this._rx.tx = this._decorateExtrinsics(decoratedMeta.tx, this._rxDecorateMethod); } else { augmentObject('tx', this._decorateExtrinsics(decoratedMeta.tx, this._decorateMethod), this._extrinsics, false); - augmentObject('', this._decorateExtrinsics(decoratedMeta.tx, this._rxDecorateMethod), this._rx.tx, false); + augmentObject(null, this._decorateExtrinsics(decoratedMeta.tx, this._rxDecorateMethod), this._rx.tx, false); } // this API @@ -186,8 +191,8 @@ export default abstract class Decorate extends Events augmentObject('consts', decoratedMeta.consts, this._consts, fromEmpty); // rx - augmentObject('', this._decorateStorage(decoratedMeta.query, this._rxDecorateMethod), this._rx.query, fromEmpty); - augmentObject('', decoratedMeta.consts, this._rx.consts, fromEmpty); + augmentObject(null, this._decorateStorage(decoratedMeta.query, this._rxDecorateMethod), this._rx.query, fromEmpty); + augmentObject(null, decoratedMeta.consts, this._rx.consts, fromEmpty); } private _decorateFunctionMeta (input: MetaDecoration, output: MetaDecoration): MetaDecoration { @@ -360,19 +365,19 @@ export default abstract class Decorate extends Events // .keys() & .entries() only available on map types if (creator.iterKey && (creator.meta.type.isMap || creator.meta.type.isDoubleMap)) { decorated.entries = decorateMethod( - memo((doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> => + memo(this.#instanceId, (doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> => this._retrieveMapEntries(creator, doubleMapArg))); decorated.entriesPaged = decorateMethod( - memo((opts: PaginationOptions): Observable<[StorageKey, Codec][]> => + memo(this.#instanceId, (opts: PaginationOptions): Observable<[StorageKey, Codec][]> => this._retrieveMapEntriesPaged(creator, opts))); decorated.keys = decorateMethod( - memo((doubleMapArg?: Arg): Observable => + memo(this.#instanceId, (doubleMapArg?: Arg): Observable => this._retrieveMapKeys(creator, doubleMapArg))); decorated.keysPaged = decorateMethod( - memo((opts: PaginationOptions): Observable => + memo(this.#instanceId, (opts: PaginationOptions): Observable => this._retrieveMapKeysPaged(creator, opts))); } @@ -569,7 +574,7 @@ export default abstract class Decorate extends Events protected _decorateDeriveRx (decorateMethod: DecorateMethod): DeriveAllSections<'rxjs', ExactDerive> { // Pull in derive from api-derive - const derive = decorateDerive(this._rx, this._options.derives); + const derive = decorateDerive(this.#instanceId, this._rx, this._options.derives); return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod); } diff --git a/packages/api/src/rx/Api.ts b/packages/api/src/rx/Api.ts index c2934c79a4..0b97492242 100644 --- a/packages/api/src/rx/Api.ts +++ b/packages/api/src/rx/Api.ts @@ -21,7 +21,7 @@ export function decorateMethod > (method: Metho * @name ApiRx * * @description - * ApiRx is a powerfull RxJS Observable wrapper around the RPC and interfaces on the Polkadot network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values. + * ApiRx is a powerful RxJS Observable wrapper around the RPC and interfaces on the Polkadot network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values. * * The API is well suited to real-time applications where the latest state is needed, unlocking the subscription-based features of Polkadot (and Substrate) clients. Some familiarity with RxJS is a requirement to use the API, however just understanding `.subscribe` and `.pipe` on Observables will unlock full-scale use thereof. * @@ -35,7 +35,7 @@ export function decorateMethod > (method: Metho * ```javascript * import ApiRx from '@polkadot/api/rx'; * - * // initialise via Promise & static create + * // initialize via Promise & static create * const api = await ApiRx.create().toPromise(); * * // make a call to retrieve the current network head @@ -54,10 +54,10 @@ export function decorateMethod > (method: Metho * import { ApiRx, WsProvider } from '@polkadot/api'; * * - * // initialise a provider with a specific endpoint + * // initialize a provider with a specific endpoint * const provider = new WsProvider('wss://example.com:9944') * - * // initialise via isReady & new with specific provider + * // initialize via isReady & new with specific provider * new ApiRx({ provider }) * .isReady * .pipe( @@ -99,7 +99,7 @@ export function decorateMethod > (method: Metho * api.tx.balances * // create transfer * .transfer(keyring.bob.address, 12345) - * // sign the transcation + * // sign the transaction * .sign(keyring.alice, { nonce }) * // send the transaction * .send() @@ -118,7 +118,7 @@ export default class ApiRx extends ApiBase<'rxjs'> { /** * @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance. - * @param options options that is passed to the class contructor. Can be either [[ApiOptions]] or [[WsProvider]] + * @param options options that is passed to the class constructor. Can be either [[ApiOptions]] or [[WsProvider]] * @example *
* diff --git a/packages/api/src/submittable/createSubmittable.ts b/packages/api/src/submittable/createSubmittable.ts index be6ae3a048..9da797da9b 100644 --- a/packages/api/src/submittable/createSubmittable.ts +++ b/packages/api/src/submittable/createSubmittable.ts @@ -3,7 +3,6 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { Call, Extrinsic } from '@polkadot/types/interfaces'; -import { Constructor } from '@polkadot/types/types'; import { ApiInterfaceRx, ApiTypes } from '../types'; import { SubmittableExtrinsic } from './types'; @@ -12,16 +11,7 @@ import createClass from './createClass'; type Creator = (extrinsic: Call | Uint8Array | string) => SubmittableExtrinsic; -let Submittable: Constructor>; - export default function createSubmittable (apiType: ApiTypes, api: ApiInterfaceRx, decorateMethod: ApiBase['_decorateMethod']): Creator { - return (extrinsic: Call | Extrinsic | Uint8Array | string): SubmittableExtrinsic => { - // This is not great, but basically what we do here is to only require the - // class right at the point it is actually needed - delaying initialization - if (!Submittable) { - Submittable = createClass({ api, apiType, decorateMethod }); - } - - return new Submittable(api.registry, extrinsic) as SubmittableExtrinsic; - }; + return (extrinsic: Call | Extrinsic | Uint8Array | string): SubmittableExtrinsic => + new (createClass({ api, apiType, decorateMethod }))(api.registry, extrinsic); } diff --git a/packages/api/src/util/augmentObject.ts b/packages/api/src/util/augmentObject.ts index ee9fd00833..fd38cee3ec 100644 --- a/packages/api/src/util/augmentObject.ts +++ b/packages/api/src/util/augmentObject.ts @@ -74,7 +74,7 @@ function extractMethods (src: Record>, dst: Record>, dst: Record>, fromEmpty = false): Record> { +export default function augmentObject (prefix: string | null, src: Record>, dst: Record>, fromEmpty = false): Record> { if (fromEmpty) { Object.keys(dst).forEach((key): void => { delete dst[key]; diff --git a/packages/rpc-core/src/cached.spec.ts b/packages/rpc-core/src/cached.spec.ts index ce8cea3eb0..ae2ee23359 100644 --- a/packages/rpc-core/src/cached.spec.ts +++ b/packages/rpc-core/src/cached.spec.ts @@ -14,7 +14,7 @@ describe('Cached Observables', (): void => { const keyring = testingPairs(); beforeEach((): void => { - rpc = new Rpc(registry, new MockProvider(registry)); + rpc = new Rpc('123', registry, new MockProvider(registry)); }); it('creates a single observable for subscriptions (multiple calls)', (): void => { diff --git a/packages/rpc-core/src/index.spec.ts b/packages/rpc-core/src/index.spec.ts index ffdecddf17..f66043d4a2 100644 --- a/packages/rpc-core/src/index.spec.ts +++ b/packages/rpc-core/src/index.spec.ts @@ -13,12 +13,12 @@ describe('Api', (): void => { it('requires a provider with a send method', (): void => { expect( - (): Rpc => new Rpc(registry, {} as any) + (): Rpc => new Rpc('234', registry, {} as any) ).toThrow(/Expected Provider/); }); it('allows for the definition of user RPCs', (): void => { - const rpc = new Rpc(registry, new MockProvider(registry), { + const rpc = new Rpc('567', registry, new MockProvider(registry), { testing: { foo: { description: 'foo', diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index d45ec7c668..ade4f18297 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -66,6 +66,8 @@ function logErrorMessage (method: string, { params, type }: DefinitionRpc, error * ``` */ export default class Rpc implements RpcInterface { + #instanceId: string; + #registryDefault: Registry; #getBlockRegistry?: (blockHash: string | Uint8Array) => Promise<{ registry: Registry }>; @@ -111,10 +113,11 @@ export default class Rpc implements RpcInterface { * Default constructor for the Api Object * @param {ProviderInterface} provider An API provider using HTTP or WebSocket */ - constructor (registry: Registry, provider: ProviderInterface, userRpc: Record> = {}) { + constructor (instanceId: string, registry: Registry, provider: ProviderInterface, userRpc: Record> = {}) { // eslint-disable-next-line @typescript-eslint/unbound-method assert(provider && isFunction(provider.send), 'Expected Provider to API create'); + this.#instanceId = instanceId; this.#registryDefault = registry; this.provider = provider; @@ -251,7 +254,7 @@ export default class Rpc implements RpcInterface { memoized = memoizee(this._createMethodWithRaw(creator), { length: false, - normalizer: JSON.stringify + normalizer: (args) => this.#instanceId + JSON.stringify(args) }); return memoized; @@ -340,7 +343,7 @@ export default class Rpc implements RpcInterface { // together are cached together. // E.g.: `query.my.method('abc') === query.my.method(createType('AccountId', 'abc'));` // eslint-disable-next-line @typescript-eslint/unbound-method - normalizer: JSON.stringify + normalizer: (args) => this.#instanceId + JSON.stringify(args) }); return memoized; diff --git a/packages/rpc-core/src/methodSend.spec.ts b/packages/rpc-core/src/methodSend.spec.ts index ae1419fccf..14311f80c3 100644 --- a/packages/rpc-core/src/methodSend.spec.ts +++ b/packages/rpc-core/src/methodSend.spec.ts @@ -36,7 +36,7 @@ describe('methodSend', (): void => { }) }; - rpc = new Rpc(registry, provider); + rpc = new Rpc('987', registry, provider); }); it('checks for mismatched parameters', (done): void => { diff --git a/packages/rpc-core/src/replay.spec.ts b/packages/rpc-core/src/replay.spec.ts index fa26379466..3cde1ecf24 100644 --- a/packages/rpc-core/src/replay.spec.ts +++ b/packages/rpc-core/src/replay.spec.ts @@ -13,7 +13,7 @@ describe('replay', (): void => { let rpc: Rpc; beforeEach((): void => { - rpc = new Rpc(registry, new MockProvider(registry)); + rpc = new Rpc('653', registry, new MockProvider(registry)); }); it('subscribes via the rpc section', (done): void => {