Detect AccountId & Address via SpRuntime* defs (#4188)

* Detect AccountId & Address via SpRuntime* defs

* Always do check via UncheckedExtrinsic

* Adjust

* 6.7.2

* Add Signature detection

* Extract ExtrinsicSignature type
This commit is contained in:
Jaco
2021-11-09 11:14:31 +02:00
committed by GitHub
parent f4197f8752
commit 8bb6218132
22 changed files with 146 additions and 93 deletions
+10
View File
@@ -1,5 +1,15 @@
# CHANGELOG
## 6.7.2 Nov 9, 2021
Upgrade priority: Low. Recommended for chains on metadata v14 with non-default `Address` implementations.
Changes:
- Detect `AccountId` & `Address` types via `SpRuntime*` definitions
- Adjust api-derive call ordering when using `.queryAt`
## 6.7.1 Nov 7, 2021
Upgrade priority: Low. Internal maintenance updates, focussed on internal optimizations.
+1 -1
View File
@@ -11,7 +11,7 @@
},
"sideEffects": false,
"type": "commonjs",
"version": "6.7.2-0",
"version": "6.7.2",
"workspaces": [
"packages/*"
],
+3 -3
View File
@@ -20,12 +20,12 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/api": "6.7.2-0",
"@polkadot/types": "6.7.2-0",
"@polkadot/api": "6.7.2",
"@polkadot/types": "6.7.2",
"@polkadot/util": "^7.8.2",
"rxjs": "^7.4.0"
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/api-contract', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/api-contract', version: '6.7.2' };
+5 -5
View File
@@ -20,19 +20,19 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/api": "6.7.2-0",
"@polkadot/rpc-core": "6.7.2-0",
"@polkadot/types": "6.7.2-0",
"@polkadot/api": "6.7.2",
"@polkadot/rpc-core": "6.7.2",
"@polkadot/types": "6.7.2",
"@polkadot/util": "^7.8.2",
"@polkadot/util-crypto": "^7.8.2",
"rxjs": "^7.4.0"
},
"devDependencies": {
"@polkadot/keyring": "^7.8.2",
"@polkadot/rpc-provider": "6.7.2-0"
"@polkadot/rpc-provider": "6.7.2"
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/api-derive', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/api-derive', version: '6.7.2' };
+6 -6
View File
@@ -20,16 +20,16 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/api-derive": "6.7.2-0",
"@polkadot/api-derive": "6.7.2",
"@polkadot/keyring": "^7.8.2",
"@polkadot/rpc-core": "6.7.2-0",
"@polkadot/rpc-provider": "6.7.2-0",
"@polkadot/types": "6.7.2-0",
"@polkadot/types-known": "6.7.2-0",
"@polkadot/rpc-core": "6.7.2",
"@polkadot/rpc-provider": "6.7.2",
"@polkadot/types": "6.7.2",
"@polkadot/types-known": "6.7.2",
"@polkadot/util": "^7.8.2",
"@polkadot/util-crypto": "^7.8.2",
"eventemitter3": "^4.0.7",
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/api', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/api', version: '6.7.2' };
+3 -3
View File
@@ -20,12 +20,12 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/rpc-provider": "6.7.2-0",
"@polkadot/types": "6.7.2-0",
"@polkadot/rpc-provider": "6.7.2",
"@polkadot/types": "6.7.2",
"@polkadot/util": "^7.8.2",
"rxjs": "^7.4.0"
},
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/rpc-core', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/rpc-core', version: '6.7.2' };
+3 -3
View File
@@ -20,11 +20,11 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/types": "6.7.2-0",
"@polkadot/types": "6.7.2",
"@polkadot/util": "^7.8.2",
"@polkadot/util-crypto": "^7.8.2",
"@polkadot/x-fetch": "^7.8.2",
@@ -34,7 +34,7 @@
},
"devDependencies": {
"@polkadot/keyring": "^7.8.2",
"@polkadot/types": "6.7.2-0",
"@polkadot/types": "6.7.2",
"mock-socket": "^9.0.7",
"nock": "^13.1.4"
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/rpc-provider', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/rpc-provider', version: '6.7.2' };
+5 -5
View File
@@ -20,7 +20,7 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"bin": {
"polkadot-types-chain-info": "./scripts/polkadot-types-chain-info.cjs",
@@ -33,10 +33,10 @@
"@babel/core": "^7.16.0",
"@babel/register": "^7.16.0",
"@babel/runtime": "^7.16.0",
"@polkadot/api": "6.7.2-0",
"@polkadot/rpc-provider": "6.7.2-0",
"@polkadot/types": "6.7.2-0",
"@polkadot/types-support": "6.7.2-0",
"@polkadot/api": "6.7.2",
"@polkadot/rpc-provider": "6.7.2",
"@polkadot/types": "6.7.2",
"@polkadot/types-support": "6.7.2",
"@polkadot/util": "^7.8.2",
"handlebars": "^4.7.7",
"websocket": "^1.0.34",
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/typegen', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/typegen', version: '6.7.2' };
+2 -2
View File
@@ -20,12 +20,12 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@polkadot/networks": "^7.8.2",
"@polkadot/types": "6.7.2-0",
"@polkadot/types": "6.7.2",
"@polkadot/util": "^7.8.2"
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/types-known', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/types-known', version: '6.7.2' };
+1 -1
View File
@@ -20,7 +20,7 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/types-support', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/types-support', version: '6.7.2' };
+2 -2
View File
@@ -20,7 +20,7 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "6.7.2-0",
"version": "6.7.2",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
@@ -30,7 +30,7 @@
},
"devDependencies": {
"@polkadot/keyring": "^7.8.2",
"@polkadot/types-support": "6.7.2-0",
"@polkadot/types-support": "6.7.2",
"@types/bn.js": "^4.11.6",
"bn.js": "^4.12.0"
}
@@ -25,7 +25,7 @@ const PRIMITIVE_ALIAS: Record<string, string> = {
};
// These are types where we have a specific decoding/encoding override + helpers
const PATHS_PRIMITIVE = splitNamespace([
const PATHS_ALIAS = splitNamespace([
// match {node, polkadot, ...}_runtime
'*_runtime::Call',
'*_runtime::Event',
@@ -61,6 +61,10 @@ function splitNamespace (values: string[]): string[][] {
return values.map((v) => v.split('::'));
}
function createNamespace ({ path }: SiType): string {
return sanitizeDocs(path).join('::');
}
function sanitizeDocs (docs: Text[]): string[] {
return docs.map((d) => d.toString());
}
@@ -91,21 +95,21 @@ function matchParts (first: string[], second: (string | Text)[]): boolean {
});
}
// check if the path matches the PRIMITIVE_SP (with wildcards)
function getPrimitivePath (path: SiPath): string | null {
// check if the path matches the PATHS_ALIAS (with wildcards)
function getAliasPath (path: SiPath): string | null {
// TODO We need to handle ink! Balance in some way
return path.length && PATHS_PRIMITIVE.some((p) => matchParts(p, path))
return path.length && PATHS_ALIAS.some((p) => matchParts(p, path))
? path[path.length - 1].toString()
: null;
}
function removeDuplicateNames (lookup: PortableRegistry, names: [number, string | null, SiTypeParameter[]][]): [number, string][] {
function removeDuplicateNames (lookup: PortableRegistry, names: [number, string | null, SiTypeParameter[]][]): [number, string, SiTypeParameter[]][] {
const rewrite: Record<number, string> = {};
return names
.map(([lookupIndex, name, params]): [number, string | null] => {
.map(([lookupIndex, name, params]): [number, string | null, SiTypeParameter[]] => {
if (!name) {
return [lookupIndex, null];
return [lookupIndex, null, params];
}
// those where the name is matching
@@ -124,7 +128,7 @@ function removeDuplicateNames (lookup: PortableRegistry, names: [number, string
// everything matches, we can combine these
if (!anyDiff || !allSame[0][2].length) {
return [lookupIndex, name];
return [lookupIndex, name, params];
}
// find the first parameter that yields differences
@@ -138,22 +142,23 @@ function removeDuplicateNames (lookup: PortableRegistry, names: [number, string
// No param found that is different
if (paramIdx === -1) {
return [lookupIndex, name];
return [lookupIndex, name, params];
}
// see if using the param type helps
const adjusted = allSame.map(([oIndex, oName, oParams]): [number, string | null] => {
const adjusted = allSame.map(([oIndex, oName, oParams]): [number, string | null, SiTypeParameter[]] => {
const { def, path } = lookup.getSiType(oParams[paramIdx].type.unwrap());
if (!def.isPrimitive && !path.length) {
return [oIndex, null];
return [oIndex, null, params];
}
return [
oIndex,
def.isPrimitive
? `${oName as string}${def.asPrimitive.toString()}`
: `${oName as string}${path[path.length - 1].toString()}`
: `${oName as string}${path[path.length - 1].toString()}`,
params
];
});
@@ -174,13 +179,14 @@ function removeDuplicateNames (lookup: PortableRegistry, names: [number, string
}
return noDupes
? [lookupIndex, name]
: [lookupIndex, null];
? [lookupIndex, name, params]
: [lookupIndex, null, params];
})
.filter((n): n is [number, string] => !!n[1])
.map(([lookupIndex, name]) => [
.filter((n): n is [number, string, SiTypeParameter[]] => !!n[1])
.map(([lookupIndex, name, params]) => [
lookupIndex,
rewrite[lookupIndex] || name
rewrite[lookupIndex] || name,
params
]);
}
@@ -220,24 +226,26 @@ function extractName (types: PortableType[], { id, type: { params, path } }: Por
return [lookupIndex, typeName, params];
}
function extractNames (lookup: PortableRegistry, types: PortableType[]): Record<number, string> {
function extractNames (lookup: PortableRegistry, types: PortableType[]): [Record<number, string>, Record<string, SiTypeParameter[]>] {
const dedup = removeDuplicateNames(lookup, types.map((t) =>
extractName(types, t)
));
const names: Record<number, string> = {};
const lookups: Record<string, string> = {};
const names: Record<number, string> = {};
const params: Record<string, SiTypeParameter[]> = {};
for (let i = 0; i < dedup.length; i++) {
const [lookupIndex, name] = dedup[i];
const [lookupIndex, name, p] = dedup[i];
names[lookupIndex] = name;
lookups[name] = lookup.registry.createLookupType(lookupIndex);
params[name] = p;
}
lookup.registry.register(lookups);
return names;
return [names, params];
}
// types have an id, which means they are to be named by
@@ -266,9 +274,44 @@ export class PortableRegistry extends Struct {
types: 'Vec<PortableType>'
}, value);
this.#names = extractNames(this, this.types);
const [names, params] = extractNames(this, this.types);
this.#names = names;
this.#types = extractTypeMap(this.types);
// Try and extract the AccountId/Address/Signature type from UncheckedExtrinsic
if (params.SpRuntimeGenericUncheckedExtrinsic) {
// Address, Call, Signature, Extra
const [addrParam,, sigParam] = params.SpRuntimeGenericUncheckedExtrinsic;
const siAddress = this.getSiType(addrParam.type.unwrap());
const siSignature = this.getSiType(sigParam.type.unwrap());
const nsSignature = createNamespace(siSignature);
let nsAccountId = createNamespace(siAddress);
const isMultiAddress = nsAccountId === 'sp_runtime::multiaddress::MultiAddress';
// With multiaddress, we check the first type param again
if (isMultiAddress) {
// AccountId, AccountIndex
const [idParam] = siAddress.params;
nsAccountId = createNamespace(this.getSiType(idParam.type.unwrap()));
}
this.registry.register({
AccountId: ['sp_core::crypto::AccountId32'].includes(nsAccountId)
? 'AccountId32'
: ['account::AccountId20', 'primitive_types::H160'].includes(nsAccountId)
? 'AccountId20'
: 'AccountId32', // other, default to AccountId32
Address: isMultiAddress
? 'MultiAddress'
: 'AccountId',
ExtrinsicSignature: ['sp_runtime::MultiSignature'].includes(nsSignature)
? 'MultiSignature'
: names[sigParam.type.unwrap().toNumber()] || 'MultiSignature'
});
}
// console.timeEnd('PortableRegistry')
}
@@ -378,11 +421,11 @@ export class PortableRegistry extends Struct {
#extract (type: SiType, lookupIndex: number): TypeDef {
const namespace = [...type.path].join('::');
let typeDef: TypeDef;
const primType = getPrimitivePath(type.path);
const aliasType = getAliasPath(type.path);
try {
if (primType) {
typeDef = this.#extractPrimitivePath(lookupIndex, primType);
if (aliasType) {
typeDef = this.#extractAliasPath(lookupIndex, aliasType);
} else if (type.def.isArray) {
typeDef = this.#extractArray(lookupIndex, type.def.asArray);
} else if (type.def.isBitSequence) {
@@ -624,7 +667,7 @@ export class PortableRegistry extends Struct {
};
}
#extractPrimitivePath (_: number, type: string): TypeDef {
#extractAliasPath (_: number, type: string): TypeDef {
return {
info: TypeDefInfo.Plain,
type
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/types', version: '6.7.2-0' };
export const packageInfo = { name: '@polkadot/types', version: '6.7.2' };
+27 -27
View File
@@ -1845,40 +1845,40 @@ __metadata:
resolution: "@polkadot/api-contract@workspace:packages/api-contract"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/api": 6.7.2-0
"@polkadot/types": 6.7.2-0
"@polkadot/api": 6.7.2
"@polkadot/types": 6.7.2
"@polkadot/util": ^7.8.2
rxjs: ^7.4.0
languageName: unknown
linkType: soft
"@polkadot/api-derive@6.7.2-0, @polkadot/api-derive@workspace:packages/api-derive":
"@polkadot/api-derive@6.7.2, @polkadot/api-derive@workspace:packages/api-derive":
version: 0.0.0-use.local
resolution: "@polkadot/api-derive@workspace:packages/api-derive"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/api": 6.7.2-0
"@polkadot/api": 6.7.2
"@polkadot/keyring": ^7.8.2
"@polkadot/rpc-core": 6.7.2-0
"@polkadot/rpc-provider": 6.7.2-0
"@polkadot/types": 6.7.2-0
"@polkadot/rpc-core": 6.7.2
"@polkadot/rpc-provider": 6.7.2
"@polkadot/types": 6.7.2
"@polkadot/util": ^7.8.2
"@polkadot/util-crypto": ^7.8.2
rxjs: ^7.4.0
languageName: unknown
linkType: soft
"@polkadot/api@6.7.2-0, @polkadot/api@workspace:packages/api":
"@polkadot/api@6.7.2, @polkadot/api@workspace:packages/api":
version: 0.0.0-use.local
resolution: "@polkadot/api@workspace:packages/api"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/api-derive": 6.7.2-0
"@polkadot/api-derive": 6.7.2
"@polkadot/keyring": ^7.8.2
"@polkadot/rpc-core": 6.7.2-0
"@polkadot/rpc-provider": 6.7.2-0
"@polkadot/types": 6.7.2-0
"@polkadot/types-known": 6.7.2-0
"@polkadot/rpc-core": 6.7.2
"@polkadot/rpc-provider": 6.7.2
"@polkadot/types": 6.7.2
"@polkadot/types-known": 6.7.2
"@polkadot/util": ^7.8.2
"@polkadot/util-crypto": ^7.8.2
eventemitter3: ^4.0.7
@@ -2000,26 +2000,26 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/rpc-core@6.7.2-0, @polkadot/rpc-core@workspace:packages/rpc-core":
"@polkadot/rpc-core@6.7.2, @polkadot/rpc-core@workspace:packages/rpc-core":
version: 0.0.0-use.local
resolution: "@polkadot/rpc-core@workspace:packages/rpc-core"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/keyring": ^7.8.2
"@polkadot/rpc-provider": 6.7.2-0
"@polkadot/types": 6.7.2-0
"@polkadot/rpc-provider": 6.7.2
"@polkadot/types": 6.7.2
"@polkadot/util": ^7.8.2
rxjs: ^7.4.0
languageName: unknown
linkType: soft
"@polkadot/rpc-provider@6.7.2-0, @polkadot/rpc-provider@workspace:packages/rpc-provider":
"@polkadot/rpc-provider@6.7.2, @polkadot/rpc-provider@workspace:packages/rpc-provider":
version: 0.0.0-use.local
resolution: "@polkadot/rpc-provider@workspace:packages/rpc-provider"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/keyring": ^7.8.2
"@polkadot/types": 6.7.2-0
"@polkadot/types": 6.7.2
"@polkadot/util": ^7.8.2
"@polkadot/util-crypto": ^7.8.2
"@polkadot/x-fetch": ^7.8.2
@@ -2047,10 +2047,10 @@ __metadata:
"@babel/core": ^7.16.0
"@babel/register": ^7.16.0
"@babel/runtime": ^7.16.0
"@polkadot/api": 6.7.2-0
"@polkadot/rpc-provider": 6.7.2-0
"@polkadot/types": 6.7.2-0
"@polkadot/types-support": 6.7.2-0
"@polkadot/api": 6.7.2
"@polkadot/rpc-provider": 6.7.2
"@polkadot/types": 6.7.2
"@polkadot/types-support": 6.7.2
"@polkadot/util": ^7.8.2
"@types/websocket": ^1.0.4
"@types/yargs": ^17.0.5
@@ -2066,18 +2066,18 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/types-known@6.7.2-0, @polkadot/types-known@workspace:packages/types-known":
"@polkadot/types-known@6.7.2, @polkadot/types-known@workspace:packages/types-known":
version: 0.0.0-use.local
resolution: "@polkadot/types-known@workspace:packages/types-known"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/networks": ^7.8.2
"@polkadot/types": 6.7.2-0
"@polkadot/types": 6.7.2
"@polkadot/util": ^7.8.2
languageName: unknown
linkType: soft
"@polkadot/types-support@6.7.2-0, @polkadot/types-support@workspace:packages/types-support":
"@polkadot/types-support@6.7.2, @polkadot/types-support@workspace:packages/types-support":
version: 0.0.0-use.local
resolution: "@polkadot/types-support@workspace:packages/types-support"
dependencies:
@@ -2086,13 +2086,13 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/types@6.7.2-0, @polkadot/types@workspace:packages/types":
"@polkadot/types@6.7.2, @polkadot/types@workspace:packages/types":
version: 0.0.0-use.local
resolution: "@polkadot/types@workspace:packages/types"
dependencies:
"@babel/runtime": ^7.16.0
"@polkadot/keyring": ^7.8.2
"@polkadot/types-support": 6.7.2-0
"@polkadot/types-support": 6.7.2
"@polkadot/util": ^7.8.2
"@polkadot/util-crypto": ^7.8.2
"@types/bn.js": ^4.11.6