@polkadot/types/interfaces#EraIndex TypeScript Examples
The following examples show how to use
@polkadot/types/interfaces#EraIndex.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 7 votes |
erasLastBlock = async (indexes: EraIndex[], api: ApiPromise): Promise<EraLastBlock[]> => {
const result = await Promise.all(indexes.map(async index => {
return {era: index, block: await lastBlockOf(index,api)}
}))
return result
}
Example #2
Source File: utils.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 7 votes |
lastBlockOf = async (eraIndex: EraIndex, api: ApiPromise): Promise<number> => {
const howManyErasAgoVar = await howManyErasAgo(eraIndex, api)
if (howManyErasAgoVar == 0) return (await api.rpc.chain.getHeader()).number.unwrap().toNumber()
const lastBlockPreviousEra = await firstBlockCurrentEra(api) - 1
const deriveSessionProgress = await api.derive.session.progress();
// the api result is still not reliable => guessed
const guessedResult = lastBlockPreviousEra - ( ( howManyErasAgoVar - 1 ) * deriveSessionProgress.eraLength.toNumber() )
const hash = await api.rpc.chain.getBlockHash(guessedResult + 50)
const apiAt = await api.at(hash)
const [_,firstBlockNextTargetEra] = await apiAt.query.babe.epochStart()
return firstBlockNextTargetEra.toNumber() - 1
}
Example #3
Source File: useStakerPayouts.ts From crust-apps with Apache License 2.0 | 6 votes |
export default function useStakerPayouts (): BN {
const { api } = useApi();
const migrateEraOpt = useCall<Option<EraIndex>>(api.query.staking?.migrateEra);
return useMemo(
() => (migrateEraOpt && migrateEraOpt.isSome && migrateEraOpt.unwrap()) || (
isFunction(api.tx.staking.payoutStakers)
? BN_ZERO
: BN_BILLION
),
[api, migrateEraOpt]
);
}
Example #4
Source File: utils.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 6 votes |
howManyErasAgo = async (eraIndex: EraIndex, api: ApiPromise): Promise<number> => {
const currentEraIndex = (await api.query.staking.activeEra()).unwrap().index;
return currentEraIndex.toNumber() - eraIndex.toNumber()
}
Example #5
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 6 votes |
private _writeEraCSVHistorical = async (): Promise<void> => {
const network = this.chain.toString().toLowerCase()
const erasHistoric = await this.api.derive.staking.erasHistoric(false);
const eraIndexes = erasHistoric.slice(
Math.max(erasHistoric.length - this.historySize, 0)
)
this.logger.info(`Requested Historical data for eras: ${eraIndexes.map(era => era.toString()).join(', ')}`);
//A to big number of era indexes could make crush the API => Chunk splitting
const size = 10
const eraIndexesChucked: EraIndex[][] = []
for (let i = 0; i < eraIndexes.length; i += size) {
const chunk = eraIndexes.slice(i, i + size)
eraIndexesChucked.push(chunk)
}
for (const chunk of eraIndexesChucked) {
this.logger.debug(`the handled chunk size is ${chunk.length}`)
const request = {api:this.api,network,exportDir:this.exportDir,eraIndexes:chunk}
const chainData = await gatherChainDataHistorical(request, this.logger)
await writeHistoricErasCSV(request, chainData, this.logger)
}
}
Example #6
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private _writeEraCSV = async (eraIndex: EraIndex, sessionIndex: SessionIndex, blockNumber: Compact<BlockNumber>): Promise<void> => {
const network = this.chain.toString().toLowerCase()
const request = {api:this.api,network,apiChunkSize:this.apiChunkSize,exportDir:this.exportDir,eraIndex,sessionIndex,blockNumber}
const chainData = await gatherChainData(request, this.logger)
await writeSessionCSV(request, chainData, this.logger)
await writeEraCSV(request, chainData, this.logger)
}
Example #7
Source File: subscriberEraScanner.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private _handleEraChange = async (newEra: EraIndex): Promise<void> =>{
this.eraIndex = newEra
this._requestNewScan()
}
Example #8
Source File: subscriberEraScanner.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private eraIndex: EraIndex;
Example #9
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private _handleEraChange = async (newEra: EraIndex, newSession: SessionIndex): Promise<void> =>{
this.eraIndex = newEra
await this._handleSessionChange(newSession)
}
Example #10
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private _writeSessionCSV = async (eraIndex: EraIndex, sessionIndex: SessionIndex, blockNumber: Compact<BlockNumber>): Promise<void> => {
const network = this.chain.toString().toLowerCase()
const request = {api:this.api,network,apiChunkSize:this.apiChunkSize,exportDir:this.exportDir,eraIndex,sessionIndex,blockNumber}
const chainData = await gatherChainData(request, this.logger)
await writeSessionCSV(request, chainData, this.logger)
}
Example #11
Source File: api.ts From community-repo with GNU General Public License v3.0 | 5 votes |
getEraStake = async (
api: ApiPromise,
hash: Hash,
era: EraIndex | number
): Promise<number> =>
(await api.query.staking.erasTotalStake.at(hash, era)).toNumber()
Example #12
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 5 votes |
private eraIndex: EraIndex;
Example #13
Source File: useOwnEraRewards.ts From subscan-multisig-react with Apache License 2.0 | 5 votes |
export function useOwnEraRewards(maxEras?: number, ownValidators?: StakerState[]): State {
const { api } = useApi();
const mountedRef = useIsMountedRef();
const stashIds = useOwnStashIds();
const allEras = useCall<EraIndex[]>(api.derive.staking?.erasHistoric);
const [{ filteredEras, validatorEras }, setFiltered] = useState<Filtered>({ filteredEras: [], validatorEras: [] });
const [state, setState] = useState<State>({ isLoadingRewards: true, rewardCount: 0 });
const stakerRewards = useCall<[[string[]], DeriveStakerReward[][]]>(
!ownValidators?.length && !!filteredEras.length && stashIds && api.derive.staking?.stakerRewardsMultiEras,
[stashIds, filteredEras],
{ withParams: true }
);
const erasPoints = useCall<DeriveEraPoints[]>(
!!validatorEras.length && !!filteredEras.length && api.derive.staking._erasPoints,
[filteredEras, false]
);
const erasRewards = useCall<DeriveEraRewards[]>(
!!validatorEras.length && !!filteredEras.length && api.derive.staking._erasRewards,
[filteredEras, false]
);
useEffect((): void => {
setState({ allRewards: null, isLoadingRewards: true, rewardCount: 0 });
}, [maxEras, ownValidators]);
useEffect((): void => {
if (allEras && maxEras) {
// eslint-disable-next-line
const filteredEras = allEras.slice(-1 * maxEras);
// eslint-disable-next-line
const validatorEras: ValidatorWithEras[] = [];
if (allEras.length === 0) {
setState({
allRewards: {},
isLoadingRewards: false,
rewardCount: 0,
});
setFiltered({ filteredEras, validatorEras });
} else if (ownValidators?.length) {
ownValidators.forEach(({ stakingLedger, stashId }): void => {
if (stakingLedger) {
const eras = filteredEras.filter((era) => !stakingLedger.claimedRewards.some((c) => era.eq(c)));
if (eras.length) {
validatorEras.push({ eras, stashId });
}
}
});
// When we have just claimed, we have filtered eras, but no validator eras - set accordingly
if (filteredEras.length && !validatorEras.length) {
setState({
allRewards: {},
isLoadingRewards: false,
rewardCount: 0,
});
}
}
setFiltered({ filteredEras, validatorEras });
}
}, [allEras, maxEras, ownValidators]);
useEffect((): void => {
// eslint-disable-next-line
mountedRef.current && stakerRewards && !ownValidators && setState(getRewards(stakerRewards));
}, [mountedRef, ownValidators, stakerRewards]);
useEffect((): void => {
// eslint-disable-next-line
mountedRef &&
erasPoints &&
erasRewards &&
ownValidators &&
setState(getValRewards(api, validatorEras, erasPoints, erasRewards));
}, [api, erasPoints, erasRewards, mountedRef, ownValidators, validatorEras]);
return state;
}
Example #14
Source File: useAvailableSlashes.ts From subscan-multisig-react with Apache License 2.0 | 5 votes |
export function useAvailableSlashes(): [BN, UnappliedSlash[]][] {
const { api } = useApi();
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes);
const earliestSlash = useCall<Option<EraIndex>>(api.query.staking?.earliestUnappliedSlash);
const mountedRef = useIsMountedRef();
const [slashes, setSlashes] = useState<[BN, UnappliedSlash[]][]>([]);
// eslint-disable-next-line
useEffect((): Unsub => {
let unsub: Unsub | undefined;
if (mountedRef.current && indexes && earliestSlash && earliestSlash.isSome) {
const from = earliestSlash.unwrap();
const range: BN[] = [];
let start = new BN(from);
// any <= activeEra (we include activeEra since slashes are immediately reflected)
while (start.lte(indexes.activeEra)) {
range.push(start);
start = start.add(BN_ONE);
}
if (range.length) {
(async (): Promise<void> => {
unsub = await api.query.staking.unappliedSlashes.multi<Vec<UnappliedSlash>>(range, (values): void => {
// eslint-disable-next-line
mountedRef.current &&
setSlashes(
values
.map((value, index): [BN, UnappliedSlash[]] => [from.addn(index), value])
// eslint-disable-next-line
.filter(([, slashes]) => slashes.length)
);
});
})().catch(console.error);
}
}
return (): void => {
// eslint-disable-next-line
unsub && unsub();
};
}, [api, earliestSlash, indexes, mountedRef]);
return slashes;
}
Example #15
Source File: useAvailableSlashes.ts From crust-apps with Apache License 2.0 | 5 votes |
export function useAvailableSlashes (): [BN, UnappliedSlash[]][] {
const { api } = useApi();
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes);
const earliestSlash = useCall<Option<EraIndex>>(api.query.staking?.earliestUnappliedSlash);
const mountedRef = useIsMountedRef();
const [slashes, setSlashes] = useState<[BN, UnappliedSlash[]][]>([]);
useEffect((): Unsub => {
let unsub: Unsub | undefined;
if (mountedRef.current && indexes && earliestSlash && earliestSlash.isSome) {
const from = earliestSlash.unwrap();
const range: BN[] = [];
let start = new BN(from);
// any <= activeEra (we include activeEra since slashes are immediately reflected)
while (start.lte(indexes.activeEra)) {
range.push(start);
start = start.add(BN_ONE);
}
if (range.length) {
(async (): Promise<void> => {
unsub = await api.query.staking.unappliedSlashes.multi<Vec<UnappliedSlash>>(range, (values): void => {
mountedRef.current && setSlashes(
values
.map((value, index): [BN, UnappliedSlash[]] => [from.addn(index), value])
.filter(([, slashes]) => slashes.length)
);
});
})().catch(console.error);
}
}
return (): void => {
unsub && unsub();
};
}, [api, earliestSlash, indexes, mountedRef]);
return slashes;
}
Example #16
Source File: useInactives.ts From crust-apps with Apache License 2.0 | 5 votes |
function extractState (api: ApiPromise, stashId: string, slashes: Option<SlashingSpans>[], nominees: string[], { activeEra }: DeriveSessionIndexes, submittedIn: EraIndex, exposures: Exposure[]): Inactives {
const max = api.consts.staking?.maxNominatorRewardedPerValidator;
// chilled
const nomsChilled = nominees.filter((_, index): boolean => {
if (slashes[index].isNone) {
return false;
}
const { lastNonzeroSlash } = slashes[index].unwrap();
return !lastNonzeroSlash.isZero() && lastNonzeroSlash.gte(submittedIn);
});
// all nominations that are oversubscribed
const nomsOver = exposures
.map(({ others }) => others.sort((a, b) => b.value.unwrap().cmp(a.value.unwrap())))
.map((others, index) =>
!max || max.gtn(others.map(({ who }) => who.toString()).indexOf(stashId))
? null
: nominees[index]
)
.filter((nominee): nominee is string => !!nominee && !nomsChilled.includes(nominee));
// first a blanket find of nominations not in the active set
let nomsInactive = exposures
.map((exposure, index) =>
exposure.others.some(({ who }) => who.eq(stashId))
? null
: nominees[index]
)
.filter((nominee): nominee is string => !!nominee);
// waiting if validator is inactive or we have not submitted long enough ago
const nomsWaiting = exposures
.map((exposure, index) =>
exposure.total.unwrap().isZero() || (
nomsInactive.includes(nominees[index]) &&
// it could be activeEra + 1 (currentEra for last session)
submittedIn.gte(activeEra)
)
? nominees[index]
: null
)
.filter((nominee): nominee is string => !!nominee)
.filter((nominee) => !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
// filter based on all inactives
const nomsActive = nominees.filter((nominee) => !nomsInactive.includes(nominee) && !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
// inactive also contains waiting, remove those
nomsInactive = nomsInactive.filter((nominee) => !nomsWaiting.includes(nominee) && !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
return {
nomsActive,
nomsChilled,
nomsInactive,
nomsOver,
nomsWaiting
};
}
Example #17
Source File: useOwnEraRewards.ts From crust-apps with Apache License 2.0 | 4 votes |
export function useOwnEraRewards (maxEras?: number, ownValidators?: StakerState[]): State {
const { api } = useApi();
const mountedRef = useIsMountedRef();
const stashIds = useOwnStashIds();
const allEras = useCall<EraIndex[]>(api.derive.staking?.erasHistoric);
const [{ filteredEras, validatorEras }, setFiltered] = useState<Filtered>({ filteredEras: [], validatorEras: [] });
const [state, setState] = useState<State>({ isLoadingRewards: true, rewardCount: 0 });
const stakerRewards = useCall<[[string[]], DeriveStakerReward[][]]>(!ownValidators?.length && !!filteredEras.length && stashIds && api.derive.staking?.stakerRewardsMultiEras, [stashIds, filteredEras], { withParams: true });
const erasPoints = useCall<DeriveEraPoints[]>(!!validatorEras.length && !!filteredEras.length && api.derive.staking._erasPoints, [filteredEras, false]);
const erasRewards = useCall<DeriveEraRewards[]>(!!validatorEras.length && !!filteredEras.length && api.derive.staking._erasRewards, [filteredEras, false]);
const stakingOverview = useCall<DeriveStakingOverview>(api.derive.staking.overview);
const waitingInfo = useCall<DeriveStakingWaiting>(api.derive.staking.waitingInfo);
const allValidators = stakingOverview && waitingInfo && [...waitingInfo.waiting, ...stakingOverview.nextElected];
const stakingAccounts = useCall<DeriveStakingAccount[]>(allValidators && api.derive.staking.accounts, [allValidators]);
const [eraStashExposure, setEraStashExposure] = useState<EraStashExposure[]>([]);
const [eraStakingPayouts, setEraStakingPayouts] = useState<EraStakingPayout[]>();
useEffect(() => {
let unsub: (() => void) | undefined;
if (allValidators && filteredEras && mountedRef.current) {
const query: [EraIndex, string][] = [];
for (const v of allValidators) {
filteredEras.forEach((era) => query.push([era, v.toString()]));
}
const fns: any[] = [
[api.query.staking.erasStakers.multi as any, query]
];
api.combineLatest<Exposure[]>(fns, ([exposures]): void => {
const tmp: EraStashExposure[] = [];
if (Array.isArray(exposures) && mountedRef.current && exposures.length && exposures.length === query.length) {
for (const [index, a] of query.entries()) {
tmp.push({
era: a[0],
stashId: a[1],
exposure: exposures[index]
});
}
setEraStashExposure(tmp);
}
}).then((_unsub): void => {
unsub = _unsub;
}).catch(console.error);
}
return (): void => {
unsub && unsub();
};
}, [filteredEras, allValidators]);
useEffect(() => {
let unsub: (() => void) | undefined;
if (filteredEras && mountedRef.current) {
const query: number[] = [];
filteredEras.forEach((era) => query.push(era.toNumber()));
const fns: any[] = [
[api.query.staking.erasStakingPayout.multi as any, query]
];
api.combineLatest<BalanceOf[]>(fns, ([balanceOfs]): void => {
const tmp: EraStakingPayout[] = [];
const result = JSON.parse(JSON.stringify(balanceOfs))
if (Array.isArray(result) && mountedRef.current && result.length && result.length === query.length) {
for (const [index, a] of query.entries()) {
tmp.push({
era: a,
hasReward: !!result[index]
});
}
setEraStakingPayouts(tmp);
}
}).then((_unsub): void => {
unsub = _unsub;
}).catch(console.error);
}
return (): void => {
unsub && unsub();
};
}, [filteredEras]);
useEffect((): void => {
setState({ allRewards: null, isLoadingRewards: true, rewardCount: 0 });
}, [maxEras, ownValidators]);
useEffect((): void => {
if (allEras && maxEras) {
const filteredEras = allEras.slice(-1 * maxEras);
const validatorEras: ValidatorWithEras[] = [];
if (allEras.length === 0) {
setState({
allRewards: {},
isLoadingRewards: false,
rewardCount: 0
});
setFiltered({ filteredEras, validatorEras });
} else if (ownValidators?.length) {
ownValidators.forEach(({ stakingLedger, stashId }): void => {
if (stakingLedger) {
const eras = filteredEras.filter((era) => !stakingLedger.claimedRewards.some((c) => era.eq(c)));
if (eras.length) {
validatorEras.push({ eras, stashId });
}
}
});
// When we have just claimed, we have filtered eras, but no validator eras - set accordingly
if (filteredEras.length && !validatorEras.length) {
setState({
allRewards: {},
isLoadingRewards: false,
rewardCount: 0
});
}
}
setFiltered({ filteredEras, validatorEras });
}
}, [allEras, maxEras, ownValidators]);
useEffect((): void => {
mountedRef.current && stakerRewards && !ownValidators && stakingAccounts && eraStakingPayouts && setState(
getRewards(stakerRewards, stakingAccounts, eraStakingPayouts)
);
}, [mountedRef, ownValidators, stakerRewards, stakingAccounts, eraStakingPayouts]);
useEffect((): void => {
mountedRef && erasPoints && erasRewards && ownValidators && eraStashExposure && eraStakingPayouts && setState(
getValRewards(api, validatorEras, erasPoints, erasRewards, eraStashExposure, eraStakingPayouts)
);
}, [api, erasPoints, erasRewards, mountedRef, ownValidators, validatorEras, eraStashExposure, eraStakingPayouts]);
return state;
}