diff --git a/packages/api/src/base/Init.ts b/packages/api/src/base/Init.ts index 4c20e90953..ee41b19260 100644 --- a/packages/api/src/base/Init.ts +++ b/packages/api/src/base/Init.ts @@ -8,13 +8,13 @@ import { ApiBase, ApiOptions, ApiTypes, DecorateMethod } from '../types'; import DecoratedMeta from '@polkadot/metadata/Decorated'; import { Metadata, u32 as U32 } from '@polkadot/types'; +import { getChainTypes, getMetadataTypes } from '@polkadot/types/known'; import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/primitive/Extrinsic/Extrinsic'; import { logger } from '@polkadot/util'; import { cryptoWaitReady, setSS58Format } from '@polkadot/util-crypto'; import addressDefaults from '@polkadot/util-crypto/address/defaults'; import Decorate from './Decorate'; -import { getChainTypes, getMetadataTypes } from './typeInjector'; const KEEPALIVE_INTERVAL = 15000; diff --git a/packages/api/src/base/typeInjector.ts b/packages/api/src/base/typeInjector.ts deleted file mode 100644 index daec735d64..0000000000 --- a/packages/api/src/base/typeInjector.ts +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2017-2020 @polkadot/api 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 { RuntimeVersion } from '@polkadot/types/interfaces'; -import { RegistryTypes } from '@polkadot/types/types'; - -import { Text } from '@polkadot/types'; -import { isUndefined } from '@polkadot/util'; - -interface VersionedType { - minmax: [number?, number?]; // min (v >= min) and max (v <= max) - types: RegistryTypes; -} - -// these are override types for Polkadot & Kusama chains -// NOTE The SessionKeys definition for Polkadot and Substrate (OpaqueKeys -// implementation) are different. Detect Polkadot and inject the `Keys` -// definition as applicable. (4 keys in substrate vs 5 in Polkadot/CC3). -const TYPES_POLKADOT_VERSIONED: VersionedType[] = [ - { - minmax: [1000, undefined], // from launch - types: { - Keys: 'SessionKeys5' - } - } -]; - -const TYPES_KUSAMA_VERSIONED: VersionedType[] = [ - { - minmax: [1019, 1031], - types: { - DispatchError: 'DispatchErrorTo198', - Keys: 'SessionKeys5', - SlashingSpans: 'SlashingSpansTo204' - } - }, - { - minmax: [1032, 1042], - types: { - Keys: 'SessionKeys5', - SlashingSpans: 'SlashingSpansTo204' - } - }, - { - minmax: [1043, undefined], - types: { - Keys: 'SessionKeys5' - } - } -]; - -// Type overrides based on specific nodes -const TYPES_CHAIN: Record = {}; - -// Type overrides based on metadata versions -const TYPES_META: VersionedType[] = [ - { - // NOTE this is for support of old, e.g. Alex, old metadata and BlockNumber/Index - // This is detected based on metadata version, since this is what we have up-front - // v3 = Alex - // v4 = v1.0 branch - minmax: [0, 4], - types: { - BlockNumber: 'u64', - Index: 'u64', - EventRecord: 'EventRecordTo76', - ValidatorPrefs: 'ValidatorPrefsTo145' - } - } -]; - -// Type overrides for specific spec types & versions as given in runtimeVersion -const TYPES_SPEC: Record = { - kusama: TYPES_KUSAMA_VERSIONED, - polkadot: TYPES_POLKADOT_VERSIONED -}; - -// flatten a VersionedType[] into a Record -function filterVersions (versions: VersionedType[] = [], version: number): RegistryTypes { - return versions - .filter(({ minmax: [min, max] }): boolean => - (isUndefined(min) || version >= min) && - (isUndefined(max) || version <= max) - ) - .reduce((result: RegistryTypes, { types }): RegistryTypes => ({ - ...result, - ...types - }), {}); -} - -// based on the metadata version, return the registry types -export function getMetadataTypes (version: number): RegistryTypes { - return filterVersions(TYPES_META, version); -} - -// based on the chain and runtimeVersion, get the applicable types (ready for registration) -export function getChainTypes (chainName: Text, { specName, specVersion }: RuntimeVersion, typesChain: Record = {}, typesSpec: Record = {}): RegistryTypes { - const _chainName = chainName.toString(); - const _specName = specName.toString(); - const _specVersion = specVersion.toNumber(); - - return { - ...filterVersions(TYPES_SPEC[_specName], _specVersion), - ...filterVersions(TYPES_CHAIN[_chainName], _specVersion), - ...(typesSpec[_specName] || {}), - ...(typesChain[_chainName] || {}) - }; -} diff --git a/packages/metadata/src/Metadata/v10/static-polkadot.json b/packages/metadata/src/Metadata/v10/static-polkadot.json index 277d2a204e..3df52dcf6b 100644 --- a/packages/metadata/src/Metadata/v10/static-polkadot.json +++ b/packages/metadata/src/Metadata/v10/static-polkadot.json @@ -6658,7 +6658,7 @@ }, { "name": "judgement", - "type": "Judgement" + "type": "IdentityJudgement" } ], "documentation": [ diff --git a/packages/metadata/src/Metadata/v10/static-substrate.json b/packages/metadata/src/Metadata/v10/static-substrate.json index 75e6db9470..0eec9bf739 100644 --- a/packages/metadata/src/Metadata/v10/static-substrate.json +++ b/packages/metadata/src/Metadata/v10/static-substrate.json @@ -6264,7 +6264,7 @@ }, { "name": "judgement", - "type": "Judgement" + "type": "IdentityJudgement" } ], "documentation": [ @@ -7041,7 +7041,7 @@ }, { "name": "judgement", - "type": "Judgement" + "type": "SocietyJudgement" } ], "documentation": [ diff --git a/packages/metadata/src/Metadata/v10/toV11.ts b/packages/metadata/src/Metadata/v10/toV11.ts index 4aad79cc3f..6feac435f4 100644 --- a/packages/metadata/src/Metadata/v10/toV11.ts +++ b/packages/metadata/src/Metadata/v10/toV11.ts @@ -2,10 +2,13 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { MetadataV10, MetadataV11, ModuleMetadataV10, ModuleMetadataV11, StorageEntryTypeV10 } from '@polkadot/types/interfaces/metadata'; +import { OverrideModuleType } from '@polkadot/types/known/types'; +import { FunctionMetadataV10, FunctionMetadataV11, MetadataV10, MetadataV11, ModuleMetadataV10, ModuleMetadataV11, StorageEntryTypeV10 } from '@polkadot/types/interfaces/metadata'; import { Registry } from '@polkadot/types/types'; +import { getModuleTypes } from '@polkadot/types/known'; import { createType } from '@polkadot/types'; +import { stringCamelCase } from '@polkadot/util'; // migrate a storage entry type - only map types are different (with a kind enum) // all return the actual value for the enum, followed by the numeric index @@ -25,11 +28,31 @@ function createStorageType (registry: Registry, entryType: StorageEntryTypeV10): }, 1]; } +// apply module-specific type overrides +function convertCalls (registry: Registry, calls: FunctionMetadataV10[], sectionTypes: OverrideModuleType[]): FunctionMetadataV11[] { + return calls.map(({ args, documentation, name }): FunctionMetadataV11 => { + args.forEach(({ type }): void => { + const queued = sectionTypes.find(({ name }): boolean => type.eq(name)); + + if (queued) { + type.setOverride(queued.override); + } + }); + + return createType(registry, 'FunctionMetadataV11', { args, name, documentation }); + }); +} + function convertModule (registry: Registry, mod: ModuleMetadataV10): ModuleMetadataV11 { + const calls = mod.calls.unwrapOr(null); const storage = mod.storage.unwrapOr(null); + const sectionTypes = getModuleTypes(stringCamelCase(mod.name.toString())) || []; return createType(registry, 'ModuleMetadataV11', { ...mod, + calls: calls + ? convertCalls(registry, calls, sectionTypes) + : null, storage: storage ? { ...storage, diff --git a/packages/types/src/interfaceRegistry.ts b/packages/types/src/interfaceRegistry.ts index 13451dd3b2..b34a0d3258 100644 --- a/packages/types/src/interfaceRegistry.ts +++ b/packages/types/src/interfaceRegistry.ts @@ -16,12 +16,12 @@ import { AccountInfo, Amount, AssetOf, InherentOfflineReport, LockPeriods, NewAc import { ApprovalFlag, SetIndex, Vote, VoteIndex, VoteThreshold, VoterInfo } from '@polkadot/types/interfaces/elections'; import { AssetOptions, Owner, PermissionLatest, PermissionVersions, PermissionsV1 } from '@polkadot/types/interfaces/genericAsset'; import { AuthorityIndex, AuthorityList, AuthorityWeight, NextAuthority, PendingPause, PendingResume, SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa'; -import { IdentityInfo, IdentityInfoAdditional, Judgement, RegistrarIndex, RegistrarInfo, Registration, RegistrationJudgement } from '@polkadot/types/interfaces/identity'; +import { IdentityInfo, IdentityInfoAdditional, IdentityJudgement, RegistrarIndex, RegistrarInfo, Registration, RegistrationJudgement } from '@polkadot/types/interfaces/identity'; import { AuthIndex, AuthoritySignature, Heartbeat, OpaqueMultiaddr, OpaqueNetworkState, OpaquePeerId } from '@polkadot/types/interfaces/imOnline'; import { Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences'; import { ActiveRecovery, RecoveryConfig } from '@polkadot/types/interfaces/recovery'; import { FullIdentification, IdentificationTuple, Keys, SessionIndex, SessionKeys1, SessionKeys2, SessionKeys3, SessionKeys4, SessionKeys5, SessionKeys6 } from '@polkadot/types/interfaces/session'; -import { Bid, BidKind, BidKindVouch, StrikeCount, VouchingStatus } from '@polkadot/types/interfaces/society'; +import { Bid, BidKind, BidKindVouch, SocietyJudgement, StrikeCount, VouchingStatus } from '@polkadot/types/interfaces/society'; import { EraIndex, EraPoints, EraRewards, Exposure, Forcing, IndividualExposure, MomentOf, Nominations, Points, RewardDestination, SlashJournalEntry, SlashingSpans, SlashingSpansTo204, SpanIndex, SpanRecord, StakingLedger, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196 } from '@polkadot/types/interfaces/staking'; import { DigestOf, DispatchError, DispatchErrorModule, DispatchErrorTo198, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, EventRecordTo76, Key, Phase } from '@polkadot/types/interfaces/system'; import { OpenTip, OpenTipFinder, OpenTipTip, TreasuryProposal } from '@polkadot/types/interfaces/treasury'; @@ -560,9 +560,9 @@ export interface InterfaceRegistry { IdentityInfo: IdentityInfo; 'Option': Option; 'Vec': Vec; - Judgement: Judgement; - 'Option': Option; - 'Vec': Vec; + IdentityJudgement: IdentityJudgement; + 'Option': Option; + 'Vec': Vec; RegistrationJudgement: RegistrationJudgement; 'Option': Option; 'Vec': Vec; @@ -659,6 +659,9 @@ export interface InterfaceRegistry { BidKind: BidKind; 'Option': Option; 'Vec': Vec; + SocietyJudgement: SocietyJudgement; + 'Option': Option; + 'Vec': Vec; StrikeCount: StrikeCount; 'Compact': Compact; 'Option': Option; diff --git a/packages/types/src/interfaces/identity/definitions.ts b/packages/types/src/interfaces/identity/definitions.ts index 78d75d3b09..2cdbbb010e 100644 --- a/packages/types/src/interfaces/identity/definitions.ts +++ b/packages/types/src/interfaces/identity/definitions.ts @@ -16,7 +16,7 @@ export default { image: 'Data', twitter: 'Data' }, - Judgement: { + IdentityJudgement: { _enum: { Unknown: 'Null', FeePaid: 'Balance', @@ -27,7 +27,7 @@ export default { Erroneous: 'Null' } }, - RegistrationJudgement: '(RegistrarIndex, Judgement)', + RegistrationJudgement: '(RegistrarIndex, IdentityJudgement)', Registration: { judgements: 'Vec', deposit: 'Balance', diff --git a/packages/types/src/interfaces/identity/types.ts b/packages/types/src/interfaces/identity/types.ts index f082d7a012..759e951c8e 100644 --- a/packages/types/src/interfaces/identity/types.ts +++ b/packages/types/src/interfaces/identity/types.ts @@ -32,7 +32,7 @@ export interface IdentityInfo extends Struct { export interface IdentityInfoAdditional extends ITuple<[Data, Data]> {} /** Enum */ -export interface Judgement extends Enum { +export interface IdentityJudgement extends Enum { /** 0:: Unknown */ readonly isUnknown: boolean; /** 1:: FeePaid(Balance) */ @@ -74,5 +74,5 @@ export interface Registration extends Struct { readonly info: IdentityInfo; } -/** ITuple<[RegistrarIndex, Judgement]> */ -export interface RegistrationJudgement extends ITuple<[RegistrarIndex, Judgement]> {} +/** ITuple<[RegistrarIndex, IdentityJudgement]> */ +export interface RegistrationJudgement extends ITuple<[RegistrarIndex, IdentityJudgement]> {} diff --git a/packages/types/src/interfaces/society/definitions.ts b/packages/types/src/interfaces/society/definitions.ts index 64128fa00d..7ac0f63c08 100644 --- a/packages/types/src/interfaces/society/definitions.ts +++ b/packages/types/src/interfaces/society/definitions.ts @@ -16,6 +16,10 @@ export default { Vouch: 'BidKindVouch' } }, + // a society-specific Judgement (not the same as identity Judgement) + SocietyJudgement: { + _enum: ['Rebid', 'Reject', 'Approve'] + }, StrikeCount: 'u32', VouchingStatus: { _enum: ['Vouching', 'Banned'] diff --git a/packages/types/src/interfaces/society/types.ts b/packages/types/src/interfaces/society/types.ts index 209f0569c9..8c23e1427f 100644 --- a/packages/types/src/interfaces/society/types.ts +++ b/packages/types/src/interfaces/society/types.ts @@ -31,6 +31,16 @@ export interface BidKind extends Enum { /** ITuple<[AccountId, Balance]> */ export interface BidKindVouch extends ITuple<[AccountId, Balance]> {} +/** Enum */ +export interface SocietyJudgement extends Enum { + /** 0:: Rebid */ + readonly isRebid: boolean; + /** 1:: Reject */ + readonly isReject: boolean; + /** 2:: Approve */ + readonly isApprove: boolean; +} + /** u32 */ export interface StrikeCount extends u32 {} diff --git a/packages/types/src/known/index.ts b/packages/types/src/known/index.ts new file mode 100644 index 0000000000..5a2f3cc49e --- /dev/null +++ b/packages/types/src/known/index.ts @@ -0,0 +1,49 @@ +// Copyright 2017-2020 @polkadot/types 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 { RuntimeVersion } from '../interfaces'; +import { RegistryTypes } from '../types'; +import { OverrideModuleType, OverrideVersionedType } from './types'; + +import { Text } from '@polkadot/types'; +import { isUndefined } from '@polkadot/util'; + +import { TYPES_CHAIN, TYPES_META, TYPES_MODULES, TYPES_SPEC } from './overrides'; + +// flatten a VersionedType[] into a Record +function filterVersions (versions: OverrideVersionedType[] = [], version: number): RegistryTypes { + return versions + .filter(({ minmax: [min, max] }): boolean => + (isUndefined(min) || version >= min) && + (isUndefined(max) || version <= max) + ) + .reduce((result: RegistryTypes, { types }): RegistryTypes => ({ + ...result, + ...types + }), {}); +} + +// based on the metadata version, return the registry types +export function getMetadataTypes (version: number): RegistryTypes { + return filterVersions(TYPES_META, version); +} + +// based on the chain and runtimeVersion, get the applicable types (ready for registration) +export function getChainTypes (chainName: Text, { specName, specVersion }: RuntimeVersion, typesChain: Record = {}, typesSpec: Record = {}): RegistryTypes { + const _chainName = chainName.toString(); + const _specName = specName.toString(); + const _specVersion = specVersion.toNumber(); + + return { + ...filterVersions(TYPES_SPEC[_specName], _specVersion), + ...filterVersions(TYPES_CHAIN[_chainName], _specVersion), + ...(typesSpec[_specName] || {}), + ...(typesChain[_chainName] || {}) + }; +} + +// get types for specific modules (metadata override) +export function getModuleTypes (section: string): OverrideModuleType[] { + return TYPES_MODULES[section] || []; +} diff --git a/packages/types/src/known/overrides.ts b/packages/types/src/known/overrides.ts new file mode 100644 index 0000000000..7dccb4940d --- /dev/null +++ b/packages/types/src/known/overrides.ts @@ -0,0 +1,86 @@ +// Copyright 2017-2020 @polkadot/types 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 { OverrideModuleType, OverrideVersionedType } from './types'; + +// type overrides for modules (where dupliacted between modules do exist) +const TYPES_MODULES: Record = { + identity: [ + { + name: 'Judgement', + override: 'IdentityJudgement' + } + ], + society: [ + { + name: 'Judgement', + override: 'SocietyJudgement' + } + ] +}; + +// these are override types for Polkadot & Kusama chains +// NOTE The SessionKeys definition for Polkadot and Substrate (OpaqueKeys +// implementation) are different. Detect Polkadot and inject the `Keys` +// definition as applicable. (4 keys in substrate vs 5 in Polkadot/CC3). +const TYPES_POLKADOT_VERSIONED: OverrideVersionedType[] = [ + { + minmax: [1000, undefined], // from launch + types: { + Keys: 'SessionKeys5' + } + } +]; + +const TYPES_KUSAMA_VERSIONED: OverrideVersionedType[] = [ + { + minmax: [1019, 1031], + types: { + DispatchError: 'DispatchErrorTo198', + Keys: 'SessionKeys5', + SlashingSpans: 'SlashingSpansTo204' + } + }, + { + minmax: [1032, 1042], + types: { + Keys: 'SessionKeys5', + SlashingSpans: 'SlashingSpansTo204' + } + }, + { + minmax: [1043, undefined], + types: { + Keys: 'SessionKeys5' + } + } +]; + +// Type overrides based on specific nodes +const TYPES_CHAIN: Record = {}; + +// Type overrides based on metadata versions +const TYPES_META: OverrideVersionedType[] = [ + { + // NOTE this is for support of old, e.g. Alex, old metadata and BlockNumber/Index + // This is detected based on metadata version, since this is what we have up-front + // v3 = Alex + // v4 = v1.0 branch + minmax: [0, 4], + types: { + BlockNumber: 'u64', + Index: 'u64', + EventRecord: 'EventRecordTo76', + ValidatorPrefs: 'ValidatorPrefsTo145' + } + } +]; + +// Type overrides for specific spec types & versions as given in runtimeVersion +const TYPES_SPEC: Record = { + kusama: TYPES_KUSAMA_VERSIONED, + polkadot: TYPES_POLKADOT_VERSIONED +}; + +export { TYPES_CHAIN, TYPES_META, TYPES_MODULES, TYPES_SPEC }; diff --git a/packages/types/src/known/types.ts b/packages/types/src/known/types.ts new file mode 100644 index 0000000000..b48564dd09 --- /dev/null +++ b/packages/types/src/known/types.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2020 @polkadot/types 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 { RegistryTypes } from '../types'; + +export interface OverrideVersionedType { + minmax: [number?, number?]; // min (v >= min) and max (v <= max) + types: RegistryTypes; +} + +export interface OverrideModuleType { + name: string; + override: string; +} diff --git a/packages/types/src/primitive/Text.ts b/packages/types/src/primitive/Text.ts index 446bc44707..49f15d5c9d 100644 --- a/packages/types/src/primitive/Text.ts +++ b/packages/types/src/primitive/Text.ts @@ -23,6 +23,7 @@ import Raw from '../codec/Raw'; // - Strings should probably be trimmed (docs do come through with extra padding) export default class Text extends String implements Codec { public readonly registry: Registry; + private _override: string | null = null; constructor (registry: Registry, value: Text | string | AnyU8a | { toString: () => string } = '') { super(Text.decodeText(value)); @@ -93,6 +94,13 @@ export default class Text extends String implements Codec { : false; } + /** + * @description Set an override value for this + */ + public setOverride (override: string): void { + this._override = override; + } + /** * @description Returns a hex string representation of the value */ @@ -120,8 +128,7 @@ export default class Text extends String implements Codec { * @description Returns the string representation of the value */ public toString (): string { - // only included here since we do not inherit docs - return super.toString(); + return this._override || super.toString(); } /** diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index c011d116a0..7aeb96b51a 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -325,10 +325,18 @@ export interface ISignerPayload { toRaw (): SignerPayloadRaw; } +export interface RegistryMetadataText extends String, Codec { + setOverride (override: string): void; +} + +export interface RegistryMetadataCallArg { + name: RegistryMetadataText; + type: RegistryMetadataText; +} + export interface RegistryMetadataCall { - args: any[]; - // eslint-disable-next-line @typescript-eslint/ban-types - name: String & Codec; + args: RegistryMetadataCallArg[]; + name: RegistryMetadataText; toJSON (): string | AnyJsonObject; } @@ -356,8 +364,7 @@ export type RegistryMetadataErrors = RegistryMetadataError[]; export interface RegistryMetadataEvent { args: any[]; - // eslint-disable-next-line @typescript-eslint/ban-types - name: String & Codec; + name: RegistryMetadataText; } export interface RegistryMetadataEvents { @@ -369,8 +376,7 @@ export interface RegistryMetadataModule { calls: RegistryMetadataCalls; errors: RegistryMetadataErrors; events: RegistryMetadataEvents; - // eslint-disable-next-line @typescript-eslint/ban-types - name: String & Codec; + name: RegistryMetadataText; } export interface RegistryMetadataLatest {