diff --git a/packages/api-derive/src/staking/currentPoints.ts b/packages/api-derive/src/staking/currentPoints.ts index 7c99685405..d88c6c2c47 100644 --- a/packages/api-derive/src/staking/currentPoints.ts +++ b/packages/api-derive/src/staking/currentPoints.ts @@ -16,7 +16,7 @@ function retrievePointsPrev (api: ApiInterfaceRx, currentElected: AccountId[]): api.registry.createType('EraRewardPoints', { individual: new Map( individual - .map((points): RewardPoint => api.registry.createType('RewardPoint', points)) + .map((points) => api.registry.createType('RewardPoint', points)) .map((points, index): [AccountId, RewardPoint] => [currentElected[index], points]) ), total diff --git a/packages/api-derive/src/staking/electedInfo.ts b/packages/api-derive/src/staking/electedInfo.ts index 546edb4220..ee9e2cd310 100644 --- a/packages/api-derive/src/staking/electedInfo.ts +++ b/packages/api-derive/src/staking/electedInfo.ts @@ -18,9 +18,7 @@ export function electedInfo (api: ApiInterfaceRx): () => Observable => - api.derive.staking.query(accountId) - ) + nextElected.map((accountId) => api.derive.staking.query(accountId)) ) ]) ), diff --git a/packages/api-derive/src/staking/erasHistoric.ts b/packages/api-derive/src/staking/erasHistoric.ts index 28e10a6efa..32071e30bc 100644 --- a/packages/api-derive/src/staking/erasHistoric.ts +++ b/packages/api-derive/src/staking/erasHistoric.ts @@ -5,6 +5,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { ActiveEraInfo, EraIndex } from '@polkadot/types/interfaces'; +import BN from 'bn.js'; import { Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { Option, u32 } from '@polkadot/types'; @@ -21,7 +22,7 @@ export function erasHistoric (api: ApiInterfaceRx): (withActive?: boolean) => Ob map(([activeEraOpt, historyDepth]): EraIndex[] => { const result: EraIndex[] = []; const max = historyDepth.toNumber(); - const activeEra = activeEraOpt.unwrapOrDefault().index.toBn(); + const activeEra: BN = activeEraOpt.unwrapOrDefault().index; let lastEra = activeEra; while (lastEra.gten(0) && (result.length < max)) { diff --git a/packages/api-derive/src/staking/ownSlashes.ts b/packages/api-derive/src/staking/ownSlashes.ts index f478b31c51..5c451a96b7 100644 --- a/packages/api-derive/src/staking/ownSlashes.ts +++ b/packages/api-derive/src/staking/ownSlashes.ts @@ -29,9 +29,7 @@ export function ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | strin era, total: optVal.isSome ? optVal.unwrap()[1] - : optNom.isSome - ? optNom.unwrap() - : api.registry.createType('Balance') + : optNom.unwrapOrDefault() })) ) ); diff --git a/packages/api-derive/src/staking/stakerExposure.ts b/packages/api-derive/src/staking/stakerExposure.ts index ee608a8e59..49a246af3e 100644 --- a/packages/api-derive/src/staking/stakerExposure.ts +++ b/packages/api-derive/src/staking/stakerExposure.ts @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { ApiInterfaceRx } from '@polkadot/api/types'; -import { DeriveStakerExposure, DeriveEraExposureNominating, DeriveEraValidatorExposure } from '../types'; +import { DeriveStakerExposure, DeriveEraValidatorExposure } from '../types'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -19,13 +19,11 @@ export function stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | s exposures.map(({ era, nominators: allNominators, validators: allValidators }): DeriveStakerExposure => { const isValidator = !!allValidators[stakerId]; const validators: DeriveEraValidatorExposure = {}; - let nominating: DeriveEraExposureNominating[] = []; + const nominating = allNominators[stakerId] || []; if (isValidator) { validators[stakerId] = allValidators[stakerId]; - } else if (allNominators[stakerId]) { - nominating = allNominators[stakerId]; - + } else if (nominating) { nominating.forEach(({ validatorId }): void => { validators[validatorId] = allValidators[validatorId]; }); diff --git a/packages/api-derive/src/staking/stakerPoints.ts b/packages/api-derive/src/staking/stakerPoints.ts index 961d27f3e6..fefd0672d5 100644 --- a/packages/api-derive/src/staking/stakerPoints.ts +++ b/packages/api-derive/src/staking/stakerPoints.ts @@ -19,9 +19,7 @@ export function stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | str points.map(({ era, eraPoints, validators }): DeriveStakerPoints => ({ era, eraPoints, - points: validators[stakerId] - ? validators[stakerId] - : api.registry.createType('RewardPoint') + points: validators[stakerId] || api.registry.createType('RewardPoint') })) ) ); diff --git a/packages/api-derive/src/staking/validators.ts b/packages/api-derive/src/staking/validators.ts index 1f231b7aad..54c26598d6 100644 --- a/packages/api-derive/src/staking/validators.ts +++ b/packages/api-derive/src/staking/validators.ts @@ -8,7 +8,6 @@ import { DeriveStakingValidators } from '../types'; import { Observable, combineLatest, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { StorageKey } from '@polkadot/types'; import { memo } from '../util'; @@ -18,9 +17,7 @@ export function nextElected (api: ApiInterfaceRx): () => Observable ? api.derive.session.indexes().pipe( // only populate for next era in the last session, so track both here - entries are not // subscriptions, so we need a trigger - currentIndex acts as that trigger to refresh - switchMap(({ currentEra }): Observable => - api.query.staking.erasStakers.keys(currentEra) - ), + switchMap(({ currentEra }) => api.query.staking.erasStakers.keys(currentEra)), map((keys): AccountId[] => keys.map((key): AccountId => key.args[1] as AccountId) ) diff --git a/packages/api/src/base/Decorate.ts b/packages/api/src/base/Decorate.ts index 53f42ad217..eda3189a1c 100644 --- a/packages/api/src/base/Decorate.ts +++ b/packages/api/src/base/Decorate.ts @@ -13,7 +13,6 @@ import BN from 'bn.js'; import { BehaviorSubject, Observable, combineLatest, from, of } from 'rxjs'; import { concatMap, map, switchMap, take, tap, toArray } from 'rxjs/operators'; import decorateDerive, { ExactDerive } from '@polkadot/api-derive'; -import { memo } from '@polkadot/api-derive/util'; import DecoratedMeta from '@polkadot/metadata/Decorated'; import getHasher from '@polkadot/metadata/Decorated/storage/fromMetadata/getHasher'; import RpcCore from '@polkadot/rpc-core'; @@ -338,9 +337,6 @@ export default abstract class Decorate extends Events decorated.at = decorateMethod((hash: Hash, arg1?: Arg, arg2?: Arg): Observable => this._rpcCore.state.getStorage(getArgs(arg1, arg2), hash)); - decorated.entries = decorateMethod(memo((doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> => - this.retrieveMapEntries(creator, doubleMapArg))); - decorated.hash = decorateMethod((arg1?: Arg, arg2?: Arg): Observable => this._rpcCore.state.getStorageHash(getArgs(arg1, arg2))); @@ -350,9 +346,22 @@ export default abstract class Decorate extends Events decorated.keyPrefix = (): string => u8aToHex(creator.keyPrefix); - decorated.keys = decorateMethod(memo((doubleMapArg?: Arg): Observable => - this.retrieveMapKeys(creator, doubleMapArg))); + decorated.range = decorateMethod((range: [Hash, Hash?], arg1?: Arg, arg2?: Arg): Observable<[Hash, Codec][]> => + this.decorateStorageRange(decorated, [arg1, arg2], range)); + decorated.size = decorateMethod((arg1?: Arg, arg2?: Arg): Observable => + this._rpcCore.state.getStorageSize(getArgs(arg1, arg2))); + + // .keys() & .entries() only available on map types + if (creator.iterKey && (creator.meta.type.isMap || creator.meta.type.isDoubleMap)) { + decorated.entries = decorateMethod((doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> => + this.retrieveMapEntries(creator, doubleMapArg)); + + decorated.keys = decorateMethod((doubleMapArg?: Arg): Observable => + this.retrieveMapKeys(creator, doubleMapArg)); + } + + // only support multi where subs are available if (this.hasSubscriptions) { // When using double map storage function, user need to pass double map key as an array decorated.multi = decorateMethod((args: (Arg | Arg[])[]): Observable => @@ -360,12 +369,6 @@ export default abstract class Decorate extends Events args.map((arg: Arg[] | Arg): [StorageEntry, Arg | Arg[]] => [creator, arg]))); } - decorated.range = decorateMethod(memo((range: [Hash, Hash?], arg1?: Arg, arg2?: Arg): Observable<[Hash, Codec][]> => - this.decorateStorageRange(decorated, [arg1, arg2], range))); - - decorated.size = decorateMethod((arg1?: Arg, arg2?: Arg): Observable => - this._rpcCore.state.getStorageSize(getArgs(arg1, arg2))); - return this.decorateFunctionMeta(creator, decorated) as unknown as QueryableStorageEntry; } @@ -471,9 +474,7 @@ export default abstract class Decorate extends Events ? startSubject.pipe( switchMap((startKey) => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_KEYS, startKey).pipe( - map((keys): StorageKey[] => - keys.map((key) => key.decodeArgsFromMeta(meta)) - ) + map((keys) => keys.map((key) => key.decodeArgsFromMeta(meta))) ) ), tap((keys): void => { @@ -482,16 +483,10 @@ export default abstract class Decorate extends Events : startSubject.complete(); }), toArray(), // toArray since we want to startSubject to be completed - map((keysArr: StorageKey[][]): StorageKey[] => - keysArr.reduce((result: StorageKey[], keys): StorageKey[] => - result.concat(keys), [] - ) - ) + map((keysArr: StorageKey[][]) => keysArr.reduce((result: StorageKey[], keys) => result.concat(keys), [])) ) : this._rpcCore.state.getKeys(headKey).pipe( - map((keys): StorageKey[] => - keys.map((key) => key.decodeArgsFromMeta(meta)) - ) + map((keys) => keys.map((key) => key.decodeArgsFromMeta(meta))) ); } @@ -512,9 +507,7 @@ export default abstract class Decorate extends Events }), toArray(), map((valsArr: Option[][]): Option[] => - valsArr.reduce((result: Option[], vals): Option[] => - result.concat(vals), [] - ) + valsArr.reduce((result: Option[], vals) => result.concat(vals), []) ) ) ]) diff --git a/packages/api/src/promise/Api.ts b/packages/api/src/promise/Api.ts index 63fcea8a44..9d06aaf6c5 100644 --- a/packages/api/src/promise/Api.ts +++ b/packages/api/src/promise/Api.ts @@ -79,7 +79,7 @@ export function decorateMethod (method: Method, opti catchError((error): Observable => tracker.reject(error) ), - // upon the first result, resolve the with the unsub function + // upon the first result, resolve with the unsub function tap((): void => tracker.resolve((): void => subscription.unsubscribe()) ) diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index 2c8120c929..5d534585eb 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -181,7 +181,7 @@ export default class Rpc implements RpcInterface { // - first do `of(1)` - won't throw // - then do `map(()=>this.formatInputs)` - might throw, but inside Observable. return of(1).pipe( - map((): Codec[] => this.formatInputs(def, values)), + map(() => this.formatInputs(def, values)), switchMap((params): Observable<[Codec[], any]> => combineLatest([ of(params),