// import { BlockNumber } from '@polkadot/types/interfaces'; import { IQueryEvent, QueryEvent } from './' import { EventRecord, SignedBlock, RuntimeVersion, LastRuntimeUpgradeInfo, Extrinsic, AccountId, } from '@polkadot/types/interfaces' import { u32 } from '@polkadot/types' export interface QueryEventBlock { blockNumber: number blockEvents: IQueryEvent[] } export interface BlockData { events: EventRecord[] signedBlock: SignedBlock timestamp: number lastRuntimeUpgrade: LastRuntimeUpgradeInfo runtimeVersion: RuntimeVersion validatorId: AccountId } export function fromBlockData({ events, signedBlock: { block }, timestamp, }: BlockData): QueryEventBlock { const extrinsics = block.extrinsics.toArray() const blockNumber = block.header.number.toNumber() const blockEvents: IQueryEvent[] = events.map( (record, index): IQueryEvent => { // Extract the phase, event const extrinsic = getExtrinsic({ record, extrinsics }) return new QueryEvent(record, blockNumber, index, timestamp, extrinsic) } ) return { blockNumber, blockEvents } } /** * If the event record was emitted by an extrinsic call, * and can extract the extrinsic index by looking at the `phase` object. * * @param record - event record as decoded by Polkadot API * @returns extrinsic index, if the phase is `applyExtrinsic` or `undefined` otherwise */ export function getExtrinsicIndex(record: { phase: { isApplyExtrinsic: boolean; asApplyExtrinsic: u32 } }): number | undefined { const { phase } = record // Try to recover extrinsic: only possible if its right phase, and extrinsics arra is non-empty, the last constraint // is needed to avoid events from build config code in genesis, and possibly other cases. return phase.isApplyExtrinsic ? phase.asApplyExtrinsic.toNumber() : undefined } export function getExtrinsic(eventInBlock: { record: { phase: { isApplyExtrinsic: boolean; asApplyExtrinsic: u32 } } extrinsics: Extrinsic[] }): Extrinsic | undefined { const extrinsicIndex = getExtrinsicIndex(eventInBlock.record) return getOrUndefined(extrinsicIndex, eventInBlock.extrinsics) } /** * * @param e - event record * @returns full event name `${section}.${method}` */ export const fullName = (e: { section: string; method: string }): string => `${e.section}.${e.method}` /** * Safely get an element from an array allowing the index and the array itself to be undefined */ export function getOrUndefined<T>( index: number | undefined, from: T[] | undefined ): T | undefined { if (index !== undefined && from !== undefined && from.length > index) { return from[index] } }