diff --git a/packages/api-contract/src/Abi.ts b/packages/api-contract/src/Abi.ts index bdc16b82f42e..722cd7c55fc9 100644 --- a/packages/api-contract/src/Abi.ts +++ b/packages/api-contract/src/Abi.ts @@ -45,13 +45,13 @@ export class Abi { assert(isObject(json) && !Array.isArray(json) && json.metadataVersion && isObject(json.spec) && !Array.isArray(json.spec) && Array.isArray(json.spec.constructors) && Array.isArray(json.spec.messages), 'Invalid JSON ABI structure supplied, expected a recent metadata version'); this.json = json; - this.registry = new MetaRegistry(chainProperties); + this.registry = new MetaRegistry(json.metadataVersion as string, chainProperties); this.project = this.registry.createType('ContractProject', json); this.registry.setMetaTypes(this.project.types); this.project.types.forEach((_, index) => - this.registry.getMetaTypeDef({ type: this.registry.createType('SiLookupTypeId', index + 1) }) + this.registry.getMetaTypeDef({ type: this.registry.createType('SiLookupTypeId', index + this.registry.typeOffset) }) ); this.constructors = this.project.spec.constructors.map((spec: ContractConstructorSpec, index) => this.#createMessage(spec, index, { diff --git a/packages/api-contract/src/MetaRegistry.ts b/packages/api-contract/src/MetaRegistry.ts index bfba0d2893e5..fb4e105fda87 100644 --- a/packages/api-contract/src/MetaRegistry.ts +++ b/packages/api-contract/src/MetaRegistry.ts @@ -14,8 +14,8 @@ interface PartialTypeSpec { } // convert the offset into project-specific, index-1 -export function getRegistryOffset (id: SiLookupTypeId): number { - return id.toNumber() - 1; +export function getRegistryOffset (id: SiLookupTypeId, typeOffset: number): number { + return id.toNumber() - typeOffset; } const PRIMITIVE_ALIAS: Record = { @@ -28,11 +28,18 @@ const PRIMITIVE_ALWAYS = ['AccountId', 'AccountIndex', 'Address', 'Balance']; export class MetaRegistry extends TypeRegistry { public readonly metaTypeDefs: TypeDef[] = []; + public readonly typeOffset; + #siTypes: SiType[] = []; - constructor (chainProperties?: ChainProperties) { + constructor (metadataVersion: string, chainProperties?: ChainProperties) { super(); + const [major] = metadataVersion.split('.'); + + // type indexes are 1-based pre-1.0 and 0-based post-1.0 + this.typeOffset = major === '0' ? 1 : 0; + if (chainProperties) { this.setChainProperties(chainProperties); } @@ -43,7 +50,7 @@ export class MetaRegistry extends TypeRegistry { } public getMetaTypeDef (typeSpec: PartialTypeSpec): TypeDef { - const offset = getRegistryOffset(typeSpec.type); + const offset = getRegistryOffset(typeSpec.type, this.typeOffset); let typeDef = this.metaTypeDefs[offset]; if (!typeDef) { @@ -78,7 +85,7 @@ export class MetaRegistry extends TypeRegistry { } #getMetaType = (id: SiLookupTypeId): SiType => { - const type = this.#siTypes[getRegistryOffset(id)]; + const type = this.#siTypes[getRegistryOffset(id, this.typeOffset)]; assert(!isUndefined(type), () => `getMetaType:: Unable to find ${id.toNumber()} in type values`);