diff --git a/packages/types/src/codec/create/registry.ts b/packages/types/src/codec/create/registry.ts index e369256230d7..0e2c9fffdb24 100644 --- a/packages/types/src/codec/create/registry.ts +++ b/packages/types/src/codec/create/registry.ts @@ -18,6 +18,47 @@ const FN_UNKNOWN: Partial = { section: 'unknown' }; +// create event classes from metadata +function decorateEvents (registry: Registry, metadata: RegistryMetadata, metadataEvents: Record>): void { + // decorate the events + metadata.asLatest.modules + .filter(({ events }): boolean => events.isSome) + .forEach((section, sectionIndex): void => { + const sectionName = stringCamelCase(section.name.toString()); + + section.events.unwrap().forEach((meta, methodIndex): void => { + const methodName = meta.name.toString(); + const eventIndex = new Uint8Array([sectionIndex, methodIndex]); + const typeDef = meta.args.map((arg): TypeDef => getTypeDef(arg.toString())); + let Types: Constructor[] = []; + + try { + Types = typeDef.map((typeDef): Constructor => getTypeClass(registry, typeDef)); + } catch (error) { + console.error(error); + } + + metadataEvents[eventIndex.toString()] = class extends EventData { + constructor (registry: Registry, value: Uint8Array) { + super(registry, Types, value, typeDef, meta, sectionName, methodName); + } + }; + }); + }); +} + +// create extrinsic mapping from metadata +function decorateExtrinsics (registry: Registry, metadata: RegistryMetadata, metadataCalls: Record): void { + const extrinsics = extrinsicsFromMeta(registry, metadata); + + // decorate the extrinsics + Object.values(extrinsics).forEach((methods): void => + Object.values(methods).forEach((method): void => { + metadataCalls[method.callIndex.toString()] = method; + }) + ); +} + export class TypeRegistry implements Registry { private _classes: Map = new Map(); @@ -50,6 +91,8 @@ export class TypeRegistry implements Registry { } public findMetaEvent (eventIndex: Uint8Array): Constructor { + assert(Object.keys(this._metadataEvents).length > 0, 'Calling registry.findMetaEvent before metadata has been attached.'); + const Event = this._metadataEvents[eventIndex.toString()]; assert(!isUndefined(Event), `Unable to find Event with index ${u8aToHex(eventIndex)}`); @@ -147,33 +190,7 @@ export class TypeRegistry implements Registry { // sets the metadata public setMetadata (metadata: RegistryMetadata): void { - const extrinsics = extrinsicsFromMeta(this, metadata); - - // decorate the extrinsics - Object.values(extrinsics).forEach((methods): void => - Object.values(methods).forEach((method): void => { - this._metadataCalls[method.callIndex.toString()] = method; - }) - ); - - // decorate the events - metadata.asLatest.modules - .filter(({ events }): boolean => events.isSome) - .forEach((section, sectionIndex): void => { - const sectionName = stringCamelCase(section.name.toString()); - - section.events.unwrap().forEach((meta, methodIndex): void => { - const methodName = meta.name.toString(); - const eventIndex = new Uint8Array([sectionIndex, methodIndex]); - const typeDef = meta.args.map((arg): TypeDef => getTypeDef(arg.toString())); - const Types = typeDef.map((typeDef): Constructor => getTypeClass(this, typeDef)); - - this._metadataEvents[eventIndex.toString()] = class extends EventData { - constructor (registry: Registry, value: Uint8Array) { - super(registry, Types, value, typeDef, meta, sectionName, methodName); - } - }; - }); - }); + decorateExtrinsics(this, metadata, this._metadataCalls); + decorateEvents(this, metadata, this._metadataEvents); } } diff --git a/packages/types/src/index.spec.ts b/packages/types/src/index.spec.ts index d79aedbf6cec..d9600a128176 100644 --- a/packages/types/src/index.spec.ts +++ b/packages/types/src/index.spec.ts @@ -23,6 +23,9 @@ const UNCONSTRUCTABLE = [ const registry = new TypeRegistry(); +// eslint-disable-next-line no-new +new Metadata(registry, metadataStatic); + function testTypes (type: string, typeNames: string[]): void { describe(type, (): void => { describe(`${type}:: default creation`, (): void => { @@ -41,9 +44,6 @@ function testTypes (type: string, typeNames: string[]): void { }); describe(`${type}:: default creation (empty bytes)`, (): void => { - // eslint-disable-next-line no-new - new Metadata(registry, metadataStatic); - typeNames.forEach((name): void => { it(`creates an empty ${name} (from empty bytes)`, (): void => { const constructFn = (): Codec => diff --git a/packages/types/src/interfaceRegistry.ts b/packages/types/src/interfaceRegistry.ts index dc4cfce841da..c1786751ed43 100644 --- a/packages/types/src/interfaceRegistry.ts +++ b/packages/types/src/interfaceRegistry.ts @@ -3,7 +3,7 @@ import { Compact, Option, Vec } from '@polkadot/types/codec'; import { Bytes, Data, Fixed64, H160, H256, H512, Null, StorageData, StorageHasher, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive'; -import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Permill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime'; +import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Permill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime'; import { InclusionHeight, Uncle, UncleEntryItem } from '@polkadot/types/interfaces/authorship'; import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura'; import { BabeAuthorityWeight, BabeBlockWeight, BabeWeight, MaybeVrf, RawBabePreDigest, RawBabePreDigest0to159, RawBabePreDigestCompat, RawBabePreDigestPrimary, RawBabePreDigestPrimary0to159, RawBabePreDigestSecondary, RawBabePreDigestSecondary0to159, SlotNumber, VrfData, VrfProof } from '@polkadot/types/interfaces/babe'; @@ -167,6 +167,9 @@ export interface InterfaceRegistry { DispatchClass: DispatchClass; 'Option': Option; 'Vec': Vec; + DispatchInfo: DispatchInfo; + 'Option': Option; + 'Vec': Vec; Extrinsic: Extrinsic; 'Option': Option; 'Vec': Vec; diff --git a/packages/types/src/interfaces/runtime/definitions.ts b/packages/types/src/interfaces/runtime/definitions.ts index b78f4f95e89d..76027f703698 100644 --- a/packages/types/src/interfaces/runtime/definitions.ts +++ b/packages/types/src/interfaces/runtime/definitions.ts @@ -20,6 +20,10 @@ export default { DispatchClass: { _enum: ['Normal', 'Operational'] }, + DispatchInfo: { + weight: 'Weight', + class: 'DispatchClass' + }, Extrinsic: 'GenericExtrinsic', ExtrinsicEra: 'GenericExtrinsicEra', ExtrinsicPayload: 'GenericExtrinsicPayload', diff --git a/packages/types/src/interfaces/runtime/types.ts b/packages/types/src/interfaces/runtime/types.ts index 94cb14ca009b..b3e8f75a3c91 100644 --- a/packages/types/src/interfaces/runtime/types.ts +++ b/packages/types/src/interfaces/runtime/types.ts @@ -55,6 +55,14 @@ export interface DispatchClass extends Enum { readonly isOperational: boolean; } +/** Struct */ +export interface DispatchInfo extends Struct { + /** Weight */ + readonly weight: Weight; + /** DispatchClass */ + readonly class: DispatchClass; +} + /** Uint8Array, Codec */ export interface EcdsaSignature extends Uint8Array, Codec {}