import type { AnyJson, Codec, CodecClass } from 'https://deno.land/x/polkadot@0.2.33/types-codec/types/index.ts';import type { TypeDef } from 'https://deno.land/x/polkadot@0.2.33/types-create/types/index.ts';import type { EventMetadataLatest } from '../interfaces/metadata/index.ts';import type { EventId } from '../interfaces/system/index.ts';import type { IEvent, IEventData, InterfaceTypes, Registry } from '../types/index.ts';
import { Null, Struct, Tuple } from 'https://deno.land/x/polkadot@0.2.33/types-codec/mod.ts';import { objectProperties, objectSpread } from 'https://deno.land/x/polkadot@0.2.33/util/mod.ts';
interface Decoded { DataType: CodecClass<Null> | CodecClass<GenericEventData>; value?: { index: Uint8Array; data: Uint8Array; }}
function decodeEvent (registry: Registry, value?: Uint8Array): Decoded { if (!value || !value.length) { return { DataType: Null }; }
const index = value.subarray(0, 2);
return { DataType: registry.findMetaEvent(index), value: { data: value.subarray(2), index } };}
export class GenericEventData extends Tuple implements IEventData { readonly #meta: EventMetadataLatest; readonly #method: string; readonly #names: string[] | null = null; readonly #section: string; readonly #typeDef: TypeDef[];
constructor (registry: Registry, value: Uint8Array, meta: EventMetadataLatest, section = '<unknown>', method = '<unknown>') { const fields = meta?.fields || [];
super(registry, fields.map(({ type }) => registry.createLookupType(type) as keyof InterfaceTypes), value);
this.#meta = meta; this.#method = method; this.#section = section; this.#typeDef = fields.map(({ type }) => registry.lookup.getTypeDef(type));
const names = fields .map(({ name }) => registry.lookup.sanitizeField(name)[0]) .filter((n): n is string => !!n);
if (names.length === fields.length) { this.#names = names;
objectProperties(this, names, (_, i) => this[i]); } }
public get meta (): EventMetadataLatest { return this.#meta; }
public get method (): string { return this.#method; }
public get names (): string[] | null { return this.#names; }
public get section (): string { return this.#section; }
public get typeDef (): TypeDef[] { return this.#typeDef; }
public override toHuman (isExtended?: boolean): AnyJson { if (this.#names !== null) { const json: Record<string, AnyJson> = {};
for (let i = 0; i < this.#names.length; i++) { json[this.#names[i]] = this[i].toHuman(isExtended); }
return json; }
return super.toHuman(isExtended); }}
export class GenericEvent extends Struct implements IEvent<Codec[]> { constructor (registry: Registry, _value?: Uint8Array) { const { DataType, value } = decodeEvent(registry, _value);
super(registry, { index: 'EventId', data: DataType }, value); }
public get data (): IEvent<Codec[]>['data'] { return this.getT('data'); }
public get index (): EventId { return this.getT('index'); }
public get meta (): EventMetadataLatest { return this.data.meta; }
public get method (): string { return this.data.method; }
public get section (): string { return this.data.section; }
public get typeDef (): TypeDef[] { return this.data.typeDef; }
public override toHuman (isExpanded?: boolean): Record<string, AnyJson> { return objectSpread( { method: this.method, section: this.section }, isExpanded ? { docs: this.meta.docs.map((d) => d.toString()) } : null, super.toHuman(isExpanded) ); }}