Staking overview derive (#1537)
* Staking overview derive * Expand derives * Extract currentIndex/currentEra * WIP * Controllers opt * Add memo * Memomize the whole lot * Doc building fixes * Doc fixes #2
This commit is contained in:
@@ -10,9 +10,10 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { isU8a } from '@polkadot/util';
|
||||
import { decodeAddress } from '@polkadot/util-crypto';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { idToIndex } from './idToIndex';
|
||||
import { indexToId } from './indexToId';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
interface Calls {
|
||||
idToIndexCall (accountId: string | AccountId): Observable<AccountIndex | undefined>;
|
||||
@@ -59,12 +60,13 @@ function retrieve (address: Address | AccountId | AccountIndex | string | null |
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> {
|
||||
export const idAndIndex = memo((api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> => {
|
||||
const calls = {
|
||||
idToIndexCall: idToIndex(api),
|
||||
indexToIdCall: indexToId(api)
|
||||
};
|
||||
|
||||
return (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
|
||||
retrieve(address, calls).pipe(drr());
|
||||
}
|
||||
return memo((address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
|
||||
retrieve(address, calls).pipe(drr())
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { map, startWith } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { indexes, AccountIndexes } from './indexes';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name idToIndex
|
||||
@@ -25,15 +25,16 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
|
||||
export const idToIndex = memo((api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> => {
|
||||
const indexesCall = indexes(api);
|
||||
|
||||
return (accountId: AccountId | string): Observable<AccountIndex | undefined> =>
|
||||
return memo((accountId: AccountId | string): Observable<AccountIndex | undefined> =>
|
||||
indexesCall().pipe(
|
||||
startWith({}),
|
||||
map((indexes: AccountIndexes): AccountIndex | undefined =>
|
||||
(indexes || {})[accountId.toString()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { createType, ClassOf, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name indexToId
|
||||
@@ -25,8 +25,8 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> {
|
||||
return (_accountIndex: AccountIndex | string): Observable<AccountId | undefined> => {
|
||||
export const indexToId = memo((api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> => {
|
||||
return memo((_accountIndex: AccountIndex | string): Observable<AccountId | undefined> => {
|
||||
const querySection = api.query.indices || api.query.balances;
|
||||
const accountIndex = _accountIndex instanceof ClassOf('AccountIndex')
|
||||
? _accountIndex
|
||||
@@ -41,5 +41,5 @@ export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | s
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { map, switchMap } from 'rxjs/operators';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
export type AccountIndexes = Record<string, AccountIndex>;
|
||||
|
||||
@@ -31,8 +31,8 @@ const enumsetSize = ENUMSET_SIZE.toNumber();
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
|
||||
return (): Observable<AccountIndexes> => {
|
||||
export const indexes = memo((api: ApiInterfaceRx): () => Observable<AccountIndexes> => {
|
||||
return memo((): Observable<AccountIndexes> => {
|
||||
return api.query.indices
|
||||
.nextEnumSet<AccountIndex>()
|
||||
.pipe(
|
||||
@@ -57,5 +57,5 @@ export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes>
|
||||
}, {} as AccountIndexes)),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { map, switchMap } from 'rxjs/operators';
|
||||
import { Bytes, Option, u32 } from '@polkadot/types';
|
||||
import { u8aToString } from '@polkadot/util';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { idAndIndex } from './idAndIndex';
|
||||
|
||||
function retrieveNick (api: ApiInterfaceRx): (accountId?: AccountId) => Observable<Option<[Bytes, Balance] & Codec> | undefined> {
|
||||
@@ -26,11 +26,11 @@ function retrieveNick (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<DeriveAccountInfo> {
|
||||
export const info = memo((api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable<DeriveAccountInfo> => {
|
||||
const idAndIndexCall = idAndIndex(api);
|
||||
const nickCall = retrieveNick(api);
|
||||
|
||||
return (address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
|
||||
return memo((address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
|
||||
idAndIndexCall(address).pipe(
|
||||
switchMap(([accountId, accountIndex]): Observable<[DeriveAccountInfo, Option<[Bytes, Balance] & Codec>?]> => {
|
||||
return combineLatest([
|
||||
@@ -46,5 +46,6 @@ export function info (api: ApiInterfaceRx): (address?: AccountIndex | AccountId
|
||||
: undefined
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -14,7 +14,7 @@ import { bnMax } from '@polkadot/util';
|
||||
import { info } from '../accounts/info';
|
||||
import { bestNumber } from '../chain/bestNumber';
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
type ResultBalance = [Balance, Balance, BalanceLock[], Option<VestingSchedule>];
|
||||
type Result = [AccountId, BlockNumber, ResultBalance, Index];
|
||||
@@ -77,11 +77,11 @@ function queryBalances (api: ApiInterfaceRx, accountId: AccountId): Observable<R
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalances> {
|
||||
export const all = memo((api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalances> => {
|
||||
const bestNumberCall = bestNumber(api);
|
||||
const infoCall = info(api);
|
||||
|
||||
return (address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> => {
|
||||
return memo((address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> => {
|
||||
return infoCall(address).pipe(
|
||||
switchMap(({ accountId }): Observable<Result> =>
|
||||
(accountId
|
||||
@@ -102,5 +102,5 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
|
||||
map(calcBalances),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DerivedFees } from '../types';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
type Result = [Balance, Balance, Balance, Balance, Balance];
|
||||
|
||||
@@ -51,8 +51,8 @@ function queryV1 (api: ApiInterfaceRx): Observable<Result> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
|
||||
return (): Observable<DerivedFees> => {
|
||||
export const fees = memo((api: ApiInterfaceRx): () => Observable<DerivedFees> => {
|
||||
return memo((): Observable<DerivedFees> => {
|
||||
return (
|
||||
api.consts.balances
|
||||
? queryV2(api)
|
||||
@@ -67,5 +67,5 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -8,11 +8,11 @@ import { combineLatest, Observable, of } from 'rxjs';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { all } from './all';
|
||||
|
||||
export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DerivedBalances[]> {
|
||||
return (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> => {
|
||||
export const votingBalances = memo((api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DerivedBalances[]> => {
|
||||
return memo((addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> => {
|
||||
return (
|
||||
!addresses || !addresses.length
|
||||
? of([] as DerivedBalances[])
|
||||
@@ -20,5 +20,5 @@ export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId |
|
||||
).pipe(
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -11,13 +11,13 @@ import { Vec } from '@polkadot/types';
|
||||
|
||||
import { info } from '../accounts/info';
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { votingBalances } from './votingBalances';
|
||||
|
||||
export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable<DerivedBalances[]> {
|
||||
export const votingBalancesNominatorsFor = memo((api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable<DerivedBalances[]> => {
|
||||
const infoCall = info(api);
|
||||
|
||||
return (address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> => {
|
||||
return memo((address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> => {
|
||||
return infoCall(address).pipe(
|
||||
switchMap(({ accountId }): Observable<AccountId[]> =>
|
||||
accountId
|
||||
@@ -27,5 +27,5 @@ export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: Acc
|
||||
switchMap(votingBalances(api)),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumber
|
||||
@@ -22,10 +22,11 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function bestNumber (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
export const bestNumber = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
api.rpc.chain.subscribeNewHeads().pipe(
|
||||
map((header): BlockNumber => header.number.unwrap()),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumberFinalized
|
||||
@@ -23,10 +23,11 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function bestNumberFinalized (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
export const bestNumberFinalized = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
api.rpc.chain.subscribeFinalizedHeads().pipe(
|
||||
map((header): BlockNumber => header.number.unwrap()),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { bestNumber } from './bestNumber';
|
||||
import { bestNumberFinalized } from './bestNumberFinalized';
|
||||
|
||||
@@ -26,11 +26,11 @@ import { bestNumberFinalized } from './bestNumberFinalized';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
export const bestNumberLag = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
const bestNumberCall = bestNumber(api);
|
||||
const bestNumberFinalizedCall = bestNumberFinalized(api);
|
||||
|
||||
return (): Observable<BlockNumber> =>
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
combineLatest([
|
||||
bestNumberCall(),
|
||||
bestNumberFinalizedCall()
|
||||
@@ -39,5 +39,6 @@ export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumbe
|
||||
createType('BlockNumber', bestNumber.sub(bestNumberFinalized))
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { HeaderExtended } from '../type';
|
||||
import { drr } from '../util';
|
||||
import { HeaderAndValidators } from './subscribeNewHeads';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumberFinalized
|
||||
@@ -24,14 +27,12 @@ import { HeaderAndValidators } from './subscribeNewHeads';
|
||||
* console.log(`block #${number} was authored by ${author}`);
|
||||
* ```
|
||||
*/
|
||||
export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
|
||||
return (hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
|
||||
(combineLatest([
|
||||
export const getHeader = memo((api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> => {
|
||||
return memo((hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getHeader(hash),
|
||||
api.query.session
|
||||
? api.query.session.validators.at(hash)
|
||||
: of([])
|
||||
]) as Observable<HeaderAndValidators>).pipe(
|
||||
api.query.session.validators.at(hash) as Observable<Vec<AccountId>>
|
||||
]).pipe(
|
||||
map(([header, validators]): HeaderExtended =>
|
||||
new HeaderExtended(header, validators)
|
||||
),
|
||||
@@ -42,5 +43,6 @@ export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) =>
|
||||
of()
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Header } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { HeaderExtended } from '../type';
|
||||
import { drr } from '../util';
|
||||
|
||||
export type HeaderAndValidators = [Header, AccountId[]];
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name subscribeNewHeads
|
||||
@@ -26,23 +25,16 @@ export type HeaderAndValidators = [Header, AccountId[]];
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function subscribeNewHeads (api: ApiInterfaceRx): () => Observable<HeaderExtended> {
|
||||
return (): Observable<HeaderExtended> =>
|
||||
api.rpc.chain.subscribeNewHeads().pipe(
|
||||
switchMap((header: Header): Observable<HeaderAndValidators> =>
|
||||
(combineLatest([
|
||||
of(header),
|
||||
// theoretically we could combine at the first call with session.validators(), however
|
||||
// we make 100% sure we actually get the validators at a specific block so when these
|
||||
// change at an era boundary, we have the previous values to ensure our indexes are correct
|
||||
api.query.session
|
||||
? api.query.session.validators.at(header.hash)
|
||||
: of([])
|
||||
]) as Observable<HeaderAndValidators>)
|
||||
),
|
||||
export const subscribeNewHeads = memo((api: ApiInterfaceRx): () => Observable<HeaderExtended> => {
|
||||
return memo((): Observable<HeaderExtended> =>
|
||||
combineLatest([
|
||||
api.rpc.chain.subscribeNewHeads(),
|
||||
api.query.session.validators<Vec<AccountId>>()
|
||||
]).pipe(
|
||||
map(([header, validators]): HeaderExtended =>
|
||||
new HeaderExtended(header, validators)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -9,7 +9,7 @@ import BN from 'bn.js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
type ResultV2 = [BN, BN, BN, BN, BN, BN, BN, BN, BN, BN];
|
||||
|
||||
@@ -103,8 +103,8 @@ function queryConstants (api: ApiInterfaceRx): Observable<ResultV2> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees> {
|
||||
return (): Observable<DerivedContractFees> => {
|
||||
export const fees = memo((api: ApiInterfaceRx): () => Observable<DerivedContractFees> => {
|
||||
return memo((): Observable<DerivedContractFees> => {
|
||||
if (api.query.contract && !api.query.contract.rentByteFee) {
|
||||
return queryV1(api);
|
||||
}
|
||||
@@ -122,5 +122,5 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Option } from '@polkadot/types';
|
||||
import { isNull } from '@polkadot/util';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
export function constructInfo (index: BN | number, optionInfo?: Option<ReferendumInfo>): Option<ReferendumInfoExtended> {
|
||||
const info = optionInfo
|
||||
@@ -27,8 +27,8 @@ export function constructInfo (index: BN | number, optionInfo?: Option<Referendu
|
||||
);
|
||||
}
|
||||
|
||||
export function referendumInfo (api: ApiInterfaceRx): (index: BN | number) => Observable<Option<ReferendumInfoExtended>> {
|
||||
return (index: BN | number): Observable<Option<ReferendumInfoExtended>> => {
|
||||
export const referendumInfo = memo((api: ApiInterfaceRx): (index: BN | number) => Observable<Option<ReferendumInfoExtended>> => {
|
||||
return memo((index: BN | number): Observable<Option<ReferendumInfoExtended>> => {
|
||||
return (api.query.democracy.referendumInfoOf<Option<ReferendumInfo>>(index))
|
||||
.pipe(
|
||||
map((optionInfo): Option<ReferendumInfoExtended> =>
|
||||
@@ -36,5 +36,5 @@ export function referendumInfo (api: ApiInterfaceRx): (index: BN | number) => Ob
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -11,11 +11,11 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { constructInfo } from './referendumInfo';
|
||||
|
||||
export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<Option<ReferendumInfoExtended>[]> {
|
||||
return (ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> => {
|
||||
export const referendumInfos = memo((api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<Option<ReferendumInfoExtended>[]> => {
|
||||
return memo((ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> => {
|
||||
return (
|
||||
!ids || !ids.length
|
||||
? of([] as Option<ReferendumInfo>[])
|
||||
@@ -28,5 +28,5 @@ export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) =
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -11,15 +11,15 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec, createType } from '@polkadot/types';
|
||||
|
||||
import { DerivedBalances, DerivedReferendumVote } from '../types';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { votes } from './votes';
|
||||
import { votingBalances } from '../balances/votingBalances';
|
||||
|
||||
export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> {
|
||||
export const referendumVotesFor = memo((api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> => {
|
||||
const votesCall = votes(api);
|
||||
const votingBalancesCall = votingBalances(api);
|
||||
|
||||
return (referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
|
||||
return memo((referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
|
||||
(api.query.democracy.votersFor<Vec<AccountId>>(referendumId)).pipe(
|
||||
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalances[]]> =>
|
||||
combineLatest([
|
||||
@@ -36,5 +36,6 @@ export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | nu
|
||||
} as unknown as DerivedReferendumVote))
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -11,13 +11,13 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { referendumInfos } from './referendumInfos';
|
||||
|
||||
export function referendums (api: ApiInterfaceRx): () => Observable<Option<ReferendumInfoExtended>[]> {
|
||||
export const referendums = memo((api: ApiInterfaceRx): () => Observable<Option<ReferendumInfoExtended>[]> => {
|
||||
const referendumInfosCall = referendumInfos(api);
|
||||
|
||||
return (): Observable<Option<ReferendumInfoExtended>[]> =>
|
||||
return memo((): Observable<Option<ReferendumInfoExtended>[]> =>
|
||||
(api.queryMulti([
|
||||
api.query.democracy.nextTally,
|
||||
api.query.democracy.referendumCount
|
||||
@@ -32,5 +32,6 @@ export function referendums (api: ApiInterfaceRx): () => Observable<Option<Refer
|
||||
: of([])
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -9,10 +9,10 @@ import { Observable, of } from 'rxjs';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable<Vote[]> {
|
||||
return (referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> => {
|
||||
export const votes = memo((api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable<Vote[]> => {
|
||||
return memo((referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> => {
|
||||
return ((
|
||||
!accountIds || !accountIds.length
|
||||
? of([])
|
||||
@@ -22,5 +22,5 @@ export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: Acc
|
||||
)
|
||||
)
|
||||
) as Observable<Vec<Vote>>).pipe(drr());
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
|
||||
import { Vec } from '@polkadot/types';
|
||||
import { switchMap, map } from 'rxjs/operators';
|
||||
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name approvalsOf
|
||||
@@ -23,8 +23,8 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function approvalsOf (api: ApiInterfaceRx): (who: AccountId) => Observable<boolean[][]> {
|
||||
return (who: AccountId | string): Observable<boolean[][]> =>
|
||||
export const approvalsOf = memo((api: ApiInterfaceRx): (who: AccountId) => Observable<boolean[][]> => {
|
||||
return memo((who: AccountId | string): Observable<boolean[][]> =>
|
||||
api.query.elections.nextVoterSet<SetIndex>().pipe(
|
||||
switchMap((nextVoterSet: SetIndex): Observable<Vec<ApprovalFlag>[]> =>
|
||||
api.query.elections.approvalsOf.multi(
|
||||
@@ -39,5 +39,6 @@ export function approvalsOf (api: ApiInterfaceRx): (who: AccountId) => Observabl
|
||||
)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name approvalsOfAt
|
||||
@@ -25,10 +25,11 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function approvalsOfAt (api: ApiInterfaceRx): (who: AccountId, at: SetIndex) => Observable<boolean[]> {
|
||||
return (who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> =>
|
||||
export const approvalsOfAt = memo((api: ApiInterfaceRx): (who: AccountId, at: SetIndex) => Observable<boolean[]> => {
|
||||
return memo((who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> =>
|
||||
api.query.elections.approvalsOf<Vec<ApprovalFlag>>([who.toString(), at]).pipe(
|
||||
map((flags: Vec<ApprovalFlag>): boolean[] => approvalFlagsToBools(flags)),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { createType, Vec, u32 } from '@polkadot/types';
|
||||
|
||||
import { DerivedElectionsInfo } from '../types';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
type ResultElectionsInner = [u32, u32, Vec<[AccountId, BlockNumber] & Codec>, SetIndex, BlockNumber, VoteIndex, SetIndex];
|
||||
type ResultElections = [Vec<AccountId>, ResultElectionsInner];
|
||||
@@ -89,10 +89,10 @@ function queryPhragmen (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInfo> {
|
||||
return (): Observable<DerivedElectionsInfo> => {
|
||||
export const info = memo((api: ApiInterfaceRx): () => Observable<DerivedElectionsInfo> => {
|
||||
return memo((): Observable<DerivedElectionsInfo> => {
|
||||
return api.query.electionsPhragmen
|
||||
? queryPhragmen(api)
|
||||
: queryElections(api);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -10,7 +10,8 @@ import { DerivedVoterPositions } from '../types';
|
||||
import BN from 'bn.js';
|
||||
import { of, combineLatest, Observable } from 'rxjs';
|
||||
import { switchMap, map } from 'rxjs/operators';
|
||||
import { drr } from '../util';
|
||||
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name voterPositions
|
||||
@@ -25,8 +26,8 @@ import { drr } from '../util';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVoterPositions> {
|
||||
return (): Observable<DerivedVoterPositions> =>
|
||||
export const voterPositions = memo((api: ApiInterfaceRx): () => Observable<DerivedVoterPositions> => {
|
||||
return memo((): Observable<DerivedVoterPositions> =>
|
||||
api.query.elections.nextVoterSet<SetIndex>().pipe(
|
||||
switchMap((nextVoterSet: SetIndex): Observable<[BN, Vec<Option<AccountId>>[]]> => combineLatest(
|
||||
of(api.consts.elections.voterSetSize) as any as Observable<BN>,
|
||||
@@ -53,5 +54,6 @@ export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVo
|
||||
}, {});
|
||||
}),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { createType, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { voterPositions } from './voterPositions';
|
||||
|
||||
/**
|
||||
@@ -25,10 +25,10 @@ import { voterPositions } from './voterPositions';
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
|
||||
export const voters = memo((api: ApiInterfaceRx): () => Observable<Vec<AccountId>> => {
|
||||
const voterPositionsCall = voterPositions(api);
|
||||
|
||||
return (): Observable<Vec<AccountId>> =>
|
||||
return memo((): Observable<Vec<AccountId>> =>
|
||||
voterPositionsCall().pipe(
|
||||
map(
|
||||
(voterPositions: DerivedVoterPositions): Vec<AccountId> =>
|
||||
@@ -40,5 +40,6 @@ export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
|
||||
)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -8,24 +8,24 @@ import { DerivedHeartbeats } from '../types';
|
||||
import { of, Observable, combineLatest } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Bytes, Vec, u32 } from '@polkadot/types';
|
||||
import { Bytes, Option, u32 } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { overview as stakingOverview } from '../staking';
|
||||
import { drr, 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<DerivedHeartbeats> {
|
||||
return (): Observable<DerivedHeartbeats> => {
|
||||
export const receivedHeartbeats = memo((api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> => {
|
||||
const stakingOverviewvCall = stakingOverview(api);
|
||||
|
||||
return memo((): Observable<DerivedHeartbeats> => {
|
||||
return api.query.imOnline && api.query.imOnline.receivedHeartbeats && api.query.imOnline.authoredBlocks
|
||||
? api.queryMulti<[SessionIndex, Vec<AccountId>]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.session.validators
|
||||
]).pipe(
|
||||
switchMap(([currentIndex, validators]): Observable<[AccountId[], Bytes[], u32[]]> =>
|
||||
? stakingOverviewvCall().pipe(
|
||||
switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option<Bytes>[], u32[]]> =>
|
||||
combineLatest([
|
||||
of(validators),
|
||||
api.query.imOnline.receivedHeartbeats.multi<Bytes>(validators.map((_address, index): [SessionIndex, number] => [currentIndex, index])),
|
||||
api.query.imOnline.receivedHeartbeats.multi<Option<Bytes>>(validators.map((_address, index): [SessionIndex, number] => [currentIndex, index])),
|
||||
api.query.imOnline.authoredBlocks.multi<u32>(validators.map((address): [SessionIndex, AccountId] => [currentIndex, address]))
|
||||
])
|
||||
),
|
||||
@@ -42,5 +42,5 @@ export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<Deriv
|
||||
drr()
|
||||
)
|
||||
: of({});
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -8,15 +8,16 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { info } from './info';
|
||||
|
||||
export function eraLength (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
export const eraLength = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
const infoCall = info(api);
|
||||
|
||||
return (): Observable<BlockNumber> =>
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
infoCall().pipe(
|
||||
map(({ eraLength }): BlockNumber => eraLength),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -2,20 +2,22 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { info } from './info';
|
||||
|
||||
export function eraProgress (api: ApiInterfaceRx): () => Observable<BN> {
|
||||
export const eraProgress = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
const infoCall = info(api);
|
||||
|
||||
return (): Observable<BN> =>
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
infoCall().pipe(
|
||||
map(({ eraProgress }): BN => eraProgress),
|
||||
map(({ eraProgress }): BlockNumber => eraProgress),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
|
||||
export * from './eraLength';
|
||||
export * from './eraProgress';
|
||||
export * from './indexes';
|
||||
export * from './info';
|
||||
export * from './sessionProgress';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { EraIndex, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { u32 } from '@polkadot/types';
|
||||
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
export const indexes = memo((api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> => {
|
||||
return memo((): Observable<DeriveSessionIndexes> =>
|
||||
api.queryMulti<[SessionIndex, EraIndex, u32]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra,
|
||||
api.query.staking.validatorCount
|
||||
]).pipe(
|
||||
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
|
||||
currentIndex, currentEra, validatorCount
|
||||
})),
|
||||
drr()
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
@@ -2,27 +2,32 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber, EraIndex, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo } from '../types';
|
||||
import { BlockNumber, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo, DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option, u64, createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { bestNumber } from '../chain';
|
||||
import { indexes } from './indexes';
|
||||
|
||||
type ResultV1Session = [SessionIndex, Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
|
||||
type ResultV1 = [BlockNumber, ResultV1Session];
|
||||
type ResultV1Session = [Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
|
||||
type ResultV1 = [BlockNumber, DeriveSessionIndexes, ResultV1Session];
|
||||
|
||||
type ResultIndex = [SessionIndex, EraIndex];
|
||||
type ResultSlots = [u64, u64, u64, SessionIndex, EraIndex, SessionIndex];
|
||||
type ResultSlots = [u64, u64, u64, SessionIndex];
|
||||
type ResultType = [boolean, u64, SessionIndex];
|
||||
type Result = [ResultType, ResultSlots];
|
||||
type Result = [ResultType, DeriveSessionIndexes, ResultSlots];
|
||||
|
||||
interface Calls {
|
||||
bestNumberCall (): Observable<BlockNumber>;
|
||||
indexesCall (): Observable<DeriveSessionIndexes>;
|
||||
}
|
||||
|
||||
// internal helper to just split the logic - take all inputs, do the calculations and combine
|
||||
function createDerivedV1 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: ResultV1): DerivedSessionInfo {
|
||||
function createDerivedV1 ([bestNumber, { currentIndex, validatorCount }, [_lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: ResultV1): DerivedSessionInfo {
|
||||
const lastLengthChange = (_lastLengthChange && _lastLengthChange.unwrapOr(null)) || createType('BlockNumber');
|
||||
const sessionProgress = bestNumber
|
||||
.sub(lastLengthChange)
|
||||
@@ -45,15 +50,18 @@ function createDerivedV1 ([bestNumber, [currentIndex, _lastLengthChange, session
|
||||
lastLengthChange,
|
||||
sessionLength,
|
||||
sessionsPerEra,
|
||||
sessionProgress: createType('BlockNumber', sessionProgress)
|
||||
sessionProgress: createType('BlockNumber', sessionProgress),
|
||||
validatorCount
|
||||
};
|
||||
}
|
||||
|
||||
function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], [currentSlot, epochIndex, epochOrGenesisStartSlot, currentIndex, currentEra, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
|
||||
function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
|
||||
const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
|
||||
const sessionProgress = currentSlot.sub(epochStartSlot);
|
||||
const eraProgress = currentIndex.sub(currentEraStartSessionIndex).add(sessionProgress);
|
||||
|
||||
// console.log(sessionProgress);
|
||||
|
||||
return {
|
||||
currentEra,
|
||||
currentIndex,
|
||||
@@ -64,15 +72,16 @@ function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], [curren
|
||||
lastLengthChange: createType('BlockNumber', epochStartSlot),
|
||||
sessionLength: epochDuration,
|
||||
sessionsPerEra,
|
||||
sessionProgress: createType('BlockNumber', sessionProgress)
|
||||
sessionProgress: createType('BlockNumber', sessionProgress),
|
||||
validatorCount
|
||||
};
|
||||
}
|
||||
|
||||
function infoV1 (api: ApiInterfaceRx, bestNumberCall: () => Observable<BlockNumber>): Observable<DerivedSessionInfo> {
|
||||
function infoV1 (api: ApiInterfaceRx, { bestNumberCall, indexesCall }: Calls): Observable<DerivedSessionInfo> {
|
||||
return combineLatest([
|
||||
bestNumberCall(),
|
||||
indexesCall(),
|
||||
api.queryMulti<ResultV1Session>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.session.lastLengthChange,
|
||||
api.query.session.sessionLength,
|
||||
api.query.staking.lastEraLengthChange,
|
||||
@@ -84,33 +93,33 @@ function infoV1 (api: ApiInterfaceRx, bestNumberCall: () => Observable<BlockNumb
|
||||
);
|
||||
}
|
||||
|
||||
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return api.queryMulti<ResultIndex>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra
|
||||
]).pipe(
|
||||
map(([currentIndex, currentEra]): DerivedSessionInfo =>
|
||||
function infoLatestAura (api: ApiInterfaceRx, { indexesCall }: Calls): Observable<DerivedSessionInfo> {
|
||||
return indexesCall().pipe(
|
||||
map((indexes): DerivedSessionInfo =>
|
||||
createDerivedLatest([
|
||||
[false, createType('u64', 1), api.consts.staking.sessionsPerEra as SessionIndex],
|
||||
[createType('u64', 1), createType('u64', 1), createType('u64', 1), currentIndex, currentEra, createType('SessionIndex', 1)]
|
||||
indexes,
|
||||
[createType('u64', 1), createType('u64', 1), createType('u64', 1), createType('SessionIndex', 1)]
|
||||
])
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return api.queryMulti<ResultSlots>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot,
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra,
|
||||
api.query.staking.currentEraStartSessionIndex
|
||||
function infoLatestBabe (api: ApiInterfaceRx, { indexesCall }: Calls): Observable<DerivedSessionInfo> {
|
||||
return combineLatest([
|
||||
indexesCall(),
|
||||
api.queryMulti<ResultSlots>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot,
|
||||
api.query.staking.currentEraStartSessionIndex
|
||||
])
|
||||
]).pipe(
|
||||
map((slots: ResultSlots): DerivedSessionInfo =>
|
||||
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo =>
|
||||
createDerivedLatest([
|
||||
[true, api.consts.babe.epochDuration as u64, api.consts.staking.sessionsPerEra as SessionIndex],
|
||||
indexes,
|
||||
slots
|
||||
])
|
||||
),
|
||||
@@ -121,14 +130,17 @@ function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
/**
|
||||
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
|
||||
const bestNumberCall = bestNumber(api);
|
||||
export const info = memo((api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> => {
|
||||
const calls = {
|
||||
bestNumberCall: bestNumber(api),
|
||||
indexesCall: indexes(api)
|
||||
};
|
||||
|
||||
return (): Observable<DerivedSessionInfo> => {
|
||||
return memo((): Observable<DerivedSessionInfo> => {
|
||||
return api.consts.staking
|
||||
? api.consts.babe
|
||||
? infoLatestBabe(api) // 2.x with Babe
|
||||
: infoLatestAura(api) // 2.x with Aura (not all info there)
|
||||
: infoV1(api, bestNumberCall); // 1.x
|
||||
};
|
||||
}
|
||||
? infoLatestBabe(api, calls) // 2.x with Babe
|
||||
: infoLatestAura(api, calls) // 2.x with Aura (not all info there)
|
||||
: infoV1(api, calls); // 1.x
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -8,15 +8,16 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
import { info } from './info';
|
||||
|
||||
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
export const sessionProgress = memo((api: ApiInterfaceRx): () => Observable<BlockNumber> => {
|
||||
const infoCall = info(api);
|
||||
|
||||
return (): Observable<BlockNumber> =>
|
||||
return memo((): Observable<BlockNumber> =>
|
||||
infoCall().pipe(
|
||||
map(({ sessionProgress }): BlockNumber => sessionProgress),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DerivedStaking } from '../types';
|
||||
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { controllers } from './controllers';
|
||||
import { info } from './info';
|
||||
|
||||
/**
|
||||
* @description Retrieve all the staking info available for the chain
|
||||
*/
|
||||
export function all (api: ApiInterfaceRx): () => Observable<DerivedStaking[]> {
|
||||
const infoCall = info(api);
|
||||
const controllersCall = controllers(api);
|
||||
|
||||
return (): Observable<DerivedStaking[]> =>
|
||||
controllersCall().pipe(
|
||||
switchMap(([accountIds]): Observable<DerivedStaking[]> =>
|
||||
combineLatest(
|
||||
accountIds.map((accountId): Observable<DerivedStaking> => infoCall(accountId))
|
||||
)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -2,31 +2,32 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
/**
|
||||
* @description From the list of stash accounts, retrieve the list of controllers
|
||||
*/
|
||||
export function controllers (api: ApiInterfaceRx): () => Observable<[AccountId[], Option<AccountId>[]]> {
|
||||
return (): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
api.query.staking
|
||||
.validators<[AccountId[]] & Codec>()
|
||||
.pipe(
|
||||
switchMap(([stashIds]): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
combineLatest([
|
||||
of(stashIds),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
api.query.staking.bonded.multi(stashIds) as Observable<Option<AccountId>[]>
|
||||
])
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
export const controllers = memo((api: ApiInterfaceRx): () => Observable<[AccountId[], Option<AccountId>[]]> => {
|
||||
return memo((): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
api.query.staking.validators<[AccountId[]] & Codec>().pipe(
|
||||
switchMap(([stashIds]): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
combineLatest([
|
||||
of(stashIds),
|
||||
// for V2, don't return all the controllers, we call bonded at a later point
|
||||
api.consts.session
|
||||
? of([])
|
||||
: api.query.staking.bonded.multi<Option<AccountId>>(stashIds)
|
||||
])
|
||||
),
|
||||
drr()
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './all';
|
||||
export * from './controllers';
|
||||
export * from './info';
|
||||
export * from './overview';
|
||||
export * from './recentlyOffline';
|
||||
export * from './validators';
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Balance, BlockNumber } from '@polkadot/types/interfaces/runtime';
|
||||
import { Keys } from '@polkadot/types/interfaces/session';
|
||||
import { Exposure, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
|
||||
import { AccountId, Balance, BlockNumber, Exposure, Keys, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
@@ -20,7 +18,7 @@ import { isUndefined } from '@polkadot/util';
|
||||
import { bestNumber } from '../chain/bestNumber';
|
||||
import { eraLength } from '../session/eraLength';
|
||||
import { recentlyOffline } from './recentlyOffline';
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
interface Calls {
|
||||
bestNumberCall (): Observable<BlockNumber>;
|
||||
@@ -103,7 +101,7 @@ function redeemableSum (stakingLedger: StakingLedger | undefined, eraLength: BN,
|
||||
}, new BN(0)));
|
||||
}
|
||||
|
||||
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; nextSessionId?: AccountId; sessionIds: AccountId[]; sessionId?: AccountId } {
|
||||
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
|
||||
// for 2.x we have a Vec<(ValidatorId,Keys)> of the keys
|
||||
if (Array.isArray(queuedKeys)) {
|
||||
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
|
||||
@@ -112,9 +110,7 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [
|
||||
const nextSessionIds = nextKeys.unwrapOr([] as AccountId[]);
|
||||
|
||||
return {
|
||||
nextSessionId: nextSessionIds[0],
|
||||
nextSessionIds,
|
||||
sessionId: sessionIds[0],
|
||||
sessionIds
|
||||
};
|
||||
}
|
||||
@@ -125,9 +121,7 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [
|
||||
: [];
|
||||
|
||||
return {
|
||||
nextSessionId: nextSessionIds[0],
|
||||
nextSessionIds,
|
||||
sessionId: nextSessionIds[0],
|
||||
sessionIds: nextSessionIds
|
||||
};
|
||||
}
|
||||
@@ -230,18 +224,18 @@ function retrieveV2 (api: ApiInterfaceRx, calls: Calls, stashId: AccountId): Obs
|
||||
/**
|
||||
* @description From a stash, retrieve the controllerId and fill in all the relevant staking details
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStaking> {
|
||||
export const info = memo((api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStaking> => {
|
||||
const calls = {
|
||||
eraLengthCall: eraLength(api),
|
||||
bestNumberCall: bestNumber(api),
|
||||
recentlyOfflineCall: recentlyOffline(api)
|
||||
};
|
||||
|
||||
return (_accountId: Uint8Array | string): Observable<DerivedStaking> => {
|
||||
return memo((_accountId: Uint8Array | string): Observable<DerivedStaking> => {
|
||||
const accountId = createType('AccountId', _accountId);
|
||||
|
||||
return api.consts.session
|
||||
? retrieveV2(api, calls, accountId)
|
||||
: retrieveV1(api, calls, accountId);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Exposure, Keys, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { DerivedStakingStash } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
// NOTE Unused ATM, preparing for V2-only
|
||||
|
||||
type Result = [Option<AccountId>, [Vec<AccountId>], RewardDestination, Exposure, ValidatorPrefs, Option<Keys>?];
|
||||
type ResultV1 = [Option<AccountId>, ITuple<[Vec<AccountId>]>, RewardDestination, Exposure, ValidatorPrefs];
|
||||
type ResultV2 = [Option<AccountId>, ITuple<[Vec<AccountId>]>, RewardDestination, Exposure, ValidatorPrefs, Option<Keys>];
|
||||
|
||||
function parse (stashId: AccountId, [_controllerId, [nominators], rewardDestination, stakers, validatorPrefs, _nextKeys]: Result): DerivedStakingStash {
|
||||
return {
|
||||
controllerId: _controllerId.unwrapOr(undefined),
|
||||
nextKeys: _nextKeys && _nextKeys.unwrapOr(undefined),
|
||||
nominators,
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stashId,
|
||||
validatorPrefs
|
||||
};
|
||||
}
|
||||
|
||||
function retrieveV1 (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
|
||||
return api.queryMulti<ResultV1>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId]
|
||||
]);
|
||||
}
|
||||
|
||||
function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
|
||||
return api.queryMulti<ResultV2>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
|
||||
]);
|
||||
}
|
||||
|
||||
export const infoStash = memo((api: ApiInterfaceRx): (stashId: AccountId) => Observable<DerivedStakingStash> => {
|
||||
return memo((stashId: AccountId): Observable<DerivedStakingStash> => {
|
||||
return (
|
||||
api.consts.session
|
||||
? retrieveV2(api, stashId)
|
||||
: retrieveV1(api, stashId)
|
||||
).pipe(
|
||||
map((result): DerivedStakingStash => parse(stashId, result)),
|
||||
drr()
|
||||
);
|
||||
});
|
||||
}, true);
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, EraPoints } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedStakingOverview } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { drr, memo } from '../util';
|
||||
import { indexes as sessionIndexes } from '../session';
|
||||
|
||||
/**
|
||||
* @description Retrieve the staking overview, including elected and points earned
|
||||
*/
|
||||
export const overview = memo((api: ApiInterfaceRx): () => Observable<DerivedStakingOverview> => {
|
||||
const sessionIndexesCall = sessionIndexes(api);
|
||||
|
||||
return memo((): Observable<DerivedStakingOverview> =>
|
||||
combineLatest([
|
||||
sessionIndexesCall(),
|
||||
api.queryMulti<[Vec<AccountId>, Vec<AccountId>]>([
|
||||
api.query.session.validators,
|
||||
api.query.staking.currentElected
|
||||
])
|
||||
]).pipe(
|
||||
switchMap(([{ currentEra, currentIndex, validatorCount }, [validators, currentElected]]) =>
|
||||
combineLatest([
|
||||
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
|
||||
// this will change on a per block basis, keep it innermost (and it needs eraIndex)
|
||||
api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
|
||||
])
|
||||
),
|
||||
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
|
||||
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
|
||||
})),
|
||||
drr()
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
@@ -11,7 +11,7 @@ import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedRecentlyOffline } from '../types';
|
||||
|
||||
import { drr } from '../util';
|
||||
import { drr, memo } from '../util';
|
||||
|
||||
type OfflineResult = [AccountId, BlockNumber, BN][] & Codec;
|
||||
|
||||
@@ -35,8 +35,8 @@ function expandDerived (recentlyOffline: OfflineResult): DerivedRecentlyOffline
|
||||
/**
|
||||
* @description Retrieve a keyed record of accounts recently reported to be offline
|
||||
*/
|
||||
export function recentlyOffline (api: ApiInterfaceRx): () => Observable<DerivedRecentlyOffline> {
|
||||
return (): Observable<DerivedRecentlyOffline> =>
|
||||
export const recentlyOffline = memo((api: ApiInterfaceRx): () => Observable<DerivedRecentlyOffline> => {
|
||||
return memo((): Observable<DerivedRecentlyOffline> =>
|
||||
(
|
||||
// TODO recentlyOffline has been dropped for 2.x and replaced, figure out the
|
||||
// replacement as actually use and implement it
|
||||
@@ -46,5 +46,6 @@ export function recentlyOffline (api: ApiInterfaceRx): () => Observable<DerivedR
|
||||
).pipe(
|
||||
map(expandDerived),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr, memo } from '../util';
|
||||
import { overview } from './overview';
|
||||
|
||||
/**
|
||||
* @description Retrieve latest list of validators
|
||||
*/
|
||||
export const validators = memo((api: ApiInterfaceRx): () => Observable<AccountId[]> => {
|
||||
const overviewCall = overview(api);
|
||||
|
||||
return memo((): Observable<AccountId[]> =>
|
||||
overviewCall().pipe(
|
||||
map(({ validators }): AccountId[] => validators),
|
||||
drr()
|
||||
)
|
||||
);
|
||||
}, true);
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, Exposure, Index, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Index, Keys, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { u32 } from '@polkadot/types';
|
||||
@@ -83,9 +83,13 @@ export interface DerivedReferendumVote {
|
||||
vote: Vote;
|
||||
}
|
||||
|
||||
export interface DerivedSessionInfo {
|
||||
export interface DeriveSessionIndexes {
|
||||
currentEra: EraIndex;
|
||||
currentIndex: SessionIndex;
|
||||
validatorCount: u32;
|
||||
}
|
||||
|
||||
export interface DerivedSessionInfo extends DeriveSessionIndexes {
|
||||
eraLength: BlockNumber;
|
||||
eraProgress: BlockNumber;
|
||||
isEpoch: boolean;
|
||||
@@ -111,25 +115,31 @@ export interface DerivedStakingOnlineStatus {
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface DerivedStaking extends DerivedStakingOnlineStatus {
|
||||
accountId: AccountId;
|
||||
export interface DerivedStakingStash {
|
||||
controllerId?: AccountId;
|
||||
// @deprecated Use nextSessionIds instead
|
||||
nextSessionId?: AccountId;
|
||||
nextSessionIds: AccountId[];
|
||||
nominators?: AccountId[];
|
||||
redeemable?: Balance;
|
||||
rewardDestination?: RewardDestination;
|
||||
// @deprecated Use sessionIds instead
|
||||
sessionId?: AccountId;
|
||||
sessionIds: AccountId[];
|
||||
nextKeys?: Keys;
|
||||
stakers?: Exposure;
|
||||
stakingLedger?: StakingLedger;
|
||||
stashId?: AccountId;
|
||||
unlocking?: DerivedUnlocking[];
|
||||
validatorPrefs?: ValidatorPrefs;
|
||||
}
|
||||
|
||||
export interface DerivedStaking extends DerivedStakingOnlineStatus, DerivedStakingStash {
|
||||
accountId: AccountId;
|
||||
nextSessionIds: AccountId[];
|
||||
redeemable?: Balance;
|
||||
sessionIds: AccountId[];
|
||||
stakingLedger?: StakingLedger;
|
||||
unlocking?: DerivedUnlocking[];
|
||||
}
|
||||
|
||||
export interface DerivedStakingOverview extends DeriveSessionIndexes {
|
||||
currentElected: AccountId[];
|
||||
eraPoints: EraPoints;
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
export type DerivedUnlocking = { remainingBlocks: BlockNumber; value: Balance };
|
||||
|
||||
export interface VoterPosition {
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
export { drr } from '@polkadot/rpc-core/rxjs';
|
||||
|
||||
export * from './approvalFlagsToBools';
|
||||
export * from './memo';
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.v
|
||||
|
||||
import createMemo from 'memoizee';
|
||||
|
||||
export function memo <T extends Function> (fn: T, withoutJSON?: boolean): T {
|
||||
return withoutJSON
|
||||
? createMemo(fn)
|
||||
: createMemo(fn, {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
normalizer: JSON.stringify
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user