Fix some Codeclimate smells (#450)
* Fix some Codeclimate smells * Cleanup Metadata complexity * Cleanup uniqueTypes * Bump deps
This commit is contained in:
@@ -33,6 +33,6 @@
|
||||
"@polkadot/jsonrpc": "^0.33.5",
|
||||
"@polkadot/rpc-provider": "^0.33.5",
|
||||
"@polkadot/types": "^0.33.5",
|
||||
"@polkadot/util": "^0.33.9"
|
||||
"@polkadot/util": "^0.33.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.5",
|
||||
"@polkadot/keyring": "^0.33.9",
|
||||
"@polkadot/keyring": "^0.33.11",
|
||||
"@polkadot/storage": "^0.33.5",
|
||||
"@polkadot/util": "^0.33.9",
|
||||
"@polkadot/util-crypto": "^0.33.9",
|
||||
"@polkadot/util": "^0.33.11",
|
||||
"@polkadot/util-crypto": "^0.33.11",
|
||||
"@types/nock": "^9.3.0",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
|
||||
@@ -149,11 +149,9 @@ export default class WsProvider implements WSProviderInterface {
|
||||
const json = this.coder.encodeJson(method, params);
|
||||
const id = this.coder.getId();
|
||||
const callback = (error?: Error | null, result?: any) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
error
|
||||
? reject(error)
|
||||
: resolve(result);
|
||||
};
|
||||
|
||||
l.debug(() => ['calling', method, params, json, !!subscription]);
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.5",
|
||||
"@polkadot/types": "^0.33.5",
|
||||
"@polkadot/util": "^0.33.9"
|
||||
"@polkadot/util": "^0.33.11"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import Metadata from '@polkadot/types/Metadata';
|
||||
import json from '@polkadot/types/Metadata.rpc';
|
||||
import json from '@polkadot/types/Metadata/static';
|
||||
|
||||
import fromMetadata from './fromMetadata';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { RuntimeModuleMetadata } from '@polkadot/types/Metadata';
|
||||
import { RuntimeModuleMetadata } from '@polkadot/types/Metadata/Modules';
|
||||
import { Extrinsics, ModuleExtrinsics } from '@polkadot/types/Method';
|
||||
import { Metadata } from '@polkadot/types/index';
|
||||
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@ describe('extrinsics', () => {
|
||||
10101
|
||||
).sign(
|
||||
keyring.nobody,
|
||||
1234
|
||||
1234,
|
||||
new Uint8Array()
|
||||
).toU8a(true)
|
||||
).toEqual(
|
||||
new Uint8Array([
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import metadataRpc from '@polkadot/types/Metadata.rpc';
|
||||
import metadataRpc from '@polkadot/types/Metadata/static';
|
||||
import Metadata from '@polkadot/types/Metadata';
|
||||
|
||||
import fromMetadata from './fromMetadata';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { FunctionMetadata } from '@polkadot/types/Metadata';
|
||||
import { FunctionMetadata } from '@polkadot/types/Metadata/Modules';
|
||||
import { ExtrinsicFunction } from '@polkadot/types/Method';
|
||||
import { Extrinsic, Method } from '@polkadot/types/index';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-storage#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.5",
|
||||
"@polkadot/keyring": "^0.33.9",
|
||||
"@polkadot/keyring": "^0.33.11",
|
||||
"@polkadot/types": "^0.33.5",
|
||||
"@polkadot/util": "^0.33.9",
|
||||
"@polkadot/util-crypto": "^0.33.9"
|
||||
"@polkadot/util": "^0.33.11",
|
||||
"@polkadot/util-crypto": "^0.33.11"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import Metadata from '@polkadot/types/Metadata';
|
||||
import json from '@polkadot/types/Metadata.rpc';
|
||||
import json from '@polkadot/types/Metadata/static';
|
||||
|
||||
import fromMetadata from './fromMetadata';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import metadataRpc from '@polkadot/types/Metadata.rpc';
|
||||
import metadataRpc from '@polkadot/types/Metadata/static';
|
||||
import Metadata from '@polkadot/types/Metadata';
|
||||
|
||||
import fromMetadata from './fromMetadata';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { StorageFunctionMetadata, StorageFunctionModifier, StorageFunctionType } from '@polkadot/types/Metadata';
|
||||
import { StorageFunctionMetadata, StorageFunctionModifier, StorageFunctionType } from '@polkadot/types/Metadata/Modules';
|
||||
import { StorageFunction } from '@polkadot/types/StorageKey';
|
||||
import Text from '@polkadot/types/Text';
|
||||
import Vector from '@polkadot/types/codec/Vector';
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ describe('createFunction', () => {
|
||||
createFunction(
|
||||
'Timestamp',
|
||||
'Now',
|
||||
{ type: {} }
|
||||
{ type: {} } as any
|
||||
)()
|
||||
).toEqual(
|
||||
Uint8Array.from([64, 14, 73, 68, 207, 217, 141, 111, 76, 195, 116, 209, 111, 90, 78, 63, 156]) // Length-prefixed
|
||||
@@ -22,7 +22,7 @@ describe('createFunction', () => {
|
||||
createFunction(
|
||||
'Substrate',
|
||||
':auth:len',
|
||||
{ type: {} },
|
||||
{ type: {} } as any,
|
||||
{
|
||||
isUnhashed: true,
|
||||
method: 'authorityCount'
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import Compact from '@polkadot/types/codec/Compact';
|
||||
import { createType } from '@polkadot/types/codec';
|
||||
import { StorageFunctionMetadata } from '@polkadot/types/Metadata';
|
||||
import { StorageFunctionMetadata } from '@polkadot/types/Metadata/Modules';
|
||||
import { StorageFunction } from '@polkadot/types/StorageKey';
|
||||
import { Text } from '@polkadot/types/index';
|
||||
import { assert, isNull, isUndefined, stringLowerFirst, stringToU8a, u8aConcat } from '@polkadot/util';
|
||||
@@ -25,12 +25,7 @@ export interface CreateItemOptions {
|
||||
* are not known at runtime (from state_getMetadata), they need to be supplied
|
||||
* by us manually at compile time.
|
||||
*/
|
||||
export default function createFunction (
|
||||
section: Text,
|
||||
method: Text,
|
||||
meta: StorageFunctionMetadata,
|
||||
options: CreateItemOptions = {}
|
||||
): StorageFunction {
|
||||
export default function createFunction (section: Text | string, method: Text | string, meta: StorageFunctionMetadata, options: CreateItemOptions = {}): StorageFunction {
|
||||
let storageFn: any;
|
||||
|
||||
// NOTE Here we assume everything in the 'Substrate' prefix is unhashed. (Despite not passing empty, i.e. '',
|
||||
@@ -45,28 +40,22 @@ export default function createFunction (
|
||||
// - storage.balances.freeBalance(address)
|
||||
// - storage.timestamp.blockPeriod()
|
||||
storageFn = (arg?: any): Uint8Array => {
|
||||
const key = stringToU8a(`${section.toString()} ${method.toString()}`);
|
||||
|
||||
if (!meta.type.isMap) {
|
||||
return Compact.addLengthPrefix(
|
||||
xxhashAsU8a(
|
||||
stringToU8a(`${section.toString()} ${method.toString()}`),
|
||||
128
|
||||
)
|
||||
xxhashAsU8a(key, 128)
|
||||
);
|
||||
}
|
||||
|
||||
assert(!isUndefined(arg) && !isNull(arg), `${meta.name} expects one argument`);
|
||||
|
||||
const type = meta.type.asMap.key.toString(); // Argument type, as string
|
||||
const param = createType(type, arg).toU8a(true);
|
||||
|
||||
// StorageKey is a Bytes, so is length-prefixed
|
||||
return Compact.addLengthPrefix(
|
||||
xxhashAsU8a(
|
||||
u8aConcat(
|
||||
stringToU8a(`${section.toString()} ${method.toString()}`),
|
||||
createType(type, arg).toU8a(true)
|
||||
),
|
||||
128
|
||||
)
|
||||
xxhashAsU8a(u8aConcat(key, param), 128)
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -74,8 +63,7 @@ export default function createFunction (
|
||||
storageFn.meta = meta;
|
||||
storageFn.method = stringLowerFirst((options.method || method).toString());
|
||||
storageFn.section = stringLowerFirst(section.toString());
|
||||
storageFn.toJSON = (): any =>
|
||||
meta.toJSON();
|
||||
storageFn.toJSON = (): any => meta.toJSON();
|
||||
|
||||
return storageFn as StorageFunction;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.5",
|
||||
"@polkadot/keyring": "^0.33.9",
|
||||
"@polkadot/util": "^0.33.9"
|
||||
"@polkadot/keyring": "^0.33.11",
|
||||
"@polkadot/util": "^0.33.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ import Struct from './codec/Struct';
|
||||
import Tuple from './codec/Tuple';
|
||||
import U8aFixed from './codec/U8aFixed';
|
||||
import { TypeDef, getTypeClass, getTypeDef } from './codec/createType';
|
||||
import Metadata, { EventMetadata } from './Metadata';
|
||||
import Metadata from './Metadata';
|
||||
import { EventMetadata } from './Metadata/Events';
|
||||
|
||||
const EventTypes: { [index: string]: Constructor<EventData> } = {};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import AccountId from './AccountId';
|
||||
import Event from './Event';
|
||||
import EventRecord from './EventRecord';
|
||||
import Metadata from './Metadata';
|
||||
import metadataRpc from './/Metadata.rpc';
|
||||
import metadataRpc from './Metadata/static';
|
||||
|
||||
describe('EventRecord', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -13,7 +13,7 @@ import Struct from './codec/Struct';
|
||||
import Address from './Address';
|
||||
import ExtrinsicSignature from './ExtrinsicSignature';
|
||||
import Hash from './Hash';
|
||||
import { FunctionMetadata } from './Metadata';
|
||||
import { FunctionMetadata } from './Metadata/Modules';
|
||||
import Method from './Method';
|
||||
|
||||
type ExtrinsicValue = {
|
||||
|
||||
@@ -1,572 +0,0 @@
|
||||
// Copyright 2017-2018 @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 { AnyNumber } from './types';
|
||||
|
||||
import { assert, hexToU8a, isHex, isU8a, isUndefined } from '@polkadot/util';
|
||||
|
||||
import { getTypeDef, TypeDef, TypeDefInfo } from './codec/createType';
|
||||
import Compact from './codec/Compact';
|
||||
import Enum from './codec/Enum';
|
||||
import EnumType from './codec/EnumType';
|
||||
import Option from './codec/Option';
|
||||
import Struct from './codec/Struct';
|
||||
import Tuple from './codec/Tuple';
|
||||
import Vector from './codec/Vector';
|
||||
import Text from './Text';
|
||||
import Type from './Type';
|
||||
import U16 from './U16';
|
||||
import * as allTypes from './index';
|
||||
|
||||
// Decodes the runtime metadata as passed through from the `state_getMetadata` call. This
|
||||
// file is probably best understood from the bottom-up, i.e. start reading right at the
|
||||
// end and work up. (Just so we don't use before definition)
|
||||
|
||||
// Quick and dirty flatten (.flat() not available)
|
||||
function flattenUniq (list: Array<any>): Array<any> {
|
||||
const flat = list.reduce((result, entry) => {
|
||||
return result.concat(
|
||||
Array.isArray(entry)
|
||||
? flattenUniq(entry)
|
||||
: entry
|
||||
);
|
||||
}, []);
|
||||
|
||||
return [...new Set(flat)]
|
||||
.filter((value: any) => value)
|
||||
.sort();
|
||||
}
|
||||
|
||||
export class OuterDispatchCall extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
prefix: Text,
|
||||
index: U16
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[U16]] index for the call
|
||||
*/
|
||||
get index (): U16 {
|
||||
return this.get('index') as U16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the call
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The call prefix (or section)
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterDispatchMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
calls: Vector.with(OuterDispatchCall)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[OuterDispathCall]] wrapped
|
||||
*/
|
||||
get calls (): Vector<OuterDispatchCall> {
|
||||
return this.get('calls') as Vector<OuterDispatchCall>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the dispatch
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class EventMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
arguments: Vector.with(Type),
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The arguments of [[Type]]
|
||||
*/
|
||||
get arguments (): Vector<Type> {
|
||||
return this.get('arguments') as Vector<Type>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the event
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterEventMetadataEvent extends Tuple {
|
||||
constructor (value?: any) {
|
||||
super([
|
||||
Text,
|
||||
Vector.with(EventMetadata)
|
||||
], value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[EventMetadata]]
|
||||
*/
|
||||
get events (): Vector<EventMetadata> {
|
||||
return this[1] as Vector<EventMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name of the section
|
||||
*/
|
||||
get name (): Text {
|
||||
return this[0] as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterEventMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
events: Vector.with(OuterEventMetadataEvent)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[OuterEventMetadataEvent]]
|
||||
*/
|
||||
get events (): Vector<OuterEventMetadataEvent> {
|
||||
return this.get('events') as Vector<OuterEventMetadataEvent>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name of the event
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class FunctionArgumentMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
type: Type
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The argument name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Type]]
|
||||
*/
|
||||
get type (): Type {
|
||||
return this.get('type') as Type;
|
||||
}
|
||||
}
|
||||
|
||||
export class FunctionMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
id: U16,
|
||||
name: Text,
|
||||
arguments: Vector.with(FunctionArgumentMetadata),
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[FunctionArgumentMetadata]] for arguments
|
||||
*/
|
||||
get arguments (): Vector<FunctionArgumentMetadata> {
|
||||
return this.get('arguments') as Vector<FunctionArgumentMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The `[sectionIndex, methodIndex]` call id
|
||||
*/
|
||||
get id (): U16 {
|
||||
return this.get('id') as U16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The call name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class CallMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
functions: Vector.with(FunctionMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The functions available as [[FunctionMetadata]]
|
||||
*/
|
||||
get functions (): Vector<FunctionMetadata> {
|
||||
return this.get('functions') as Vector<FunctionMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The section name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class ModuleMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
call: CallMetadata
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The calls as [[CallMetadata]]
|
||||
*/
|
||||
get call (): CallMetadata {
|
||||
return this.get('call') as CallMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionModifier extends Enum {
|
||||
constructor (value?: any) {
|
||||
super(['None', 'Default', 'Required'], value);
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionType$Map extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
key: Type,
|
||||
value: Type
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The mapped key as [[Type]]
|
||||
*/
|
||||
get key (): Type {
|
||||
return this.get('key') as Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The mapped value as [[Type]]
|
||||
*/
|
||||
get value (): Type {
|
||||
return this.get('value') as Type;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionType extends EnumType<Type | StorageFunctionType$Map> {
|
||||
constructor (value?: any, index?: number) {
|
||||
super([
|
||||
Type,
|
||||
StorageFunctionType$Map
|
||||
], value, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a map
|
||||
*/
|
||||
get isMap (): boolean {
|
||||
return this.toNumber() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a mapped value
|
||||
*/
|
||||
get asMap (): StorageFunctionType$Map {
|
||||
return this.value as StorageFunctionType$Map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a [[Type]] value
|
||||
*/
|
||||
get asType (): Type {
|
||||
return this.value as Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
toString (): string {
|
||||
return this.isMap
|
||||
? this.asMap.value.toString()
|
||||
: this.asType.toString();
|
||||
}
|
||||
}
|
||||
|
||||
type StorageFunctionMetadataValue = {
|
||||
name?: string | Text,
|
||||
modifier?: StorageFunctionModifier | AnyNumber,
|
||||
type?: StorageFunctionType,
|
||||
documentation?: Vector<Text> | Array<string>
|
||||
};
|
||||
|
||||
export class StorageFunctionMetadata extends Struct {
|
||||
constructor (value?: StorageFunctionMetadataValue) {
|
||||
super({
|
||||
name: Text,
|
||||
modifier: StorageFunctionModifier,
|
||||
type: StorageFunctionType,
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The key name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The modifier
|
||||
*/
|
||||
get modifier (): StorageFunctionModifier {
|
||||
return this.get('modifier') as StorageFunctionModifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[StorageFunctionType]]
|
||||
*/
|
||||
get type (): StorageFunctionType {
|
||||
return this.get('type') as StorageFunctionType;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
prefix: Text,
|
||||
functions: Vector.with(StorageFunctionMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[StorageFunctionMetadata]] for the section
|
||||
*/
|
||||
get functions (): Vector<StorageFunctionMetadata> {
|
||||
return this.get('functions') as Vector<StorageFunctionMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The section prefix
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class RuntimeModuleMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
prefix: Text,
|
||||
module: ModuleMetadata,
|
||||
storage: Option.with(StorageMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ModuleMetadata]]
|
||||
*/
|
||||
get module (): ModuleMetadata {
|
||||
return this.get('module') as ModuleMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The prefix
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The optional [[StorageMetadata]]
|
||||
*/
|
||||
get storage (): Option<StorageMetadata> {
|
||||
return this.get('storage') as Option<StorageMetadata>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Metadata
|
||||
* @description
|
||||
* The runtime metadata as a decoded structure
|
||||
*/
|
||||
export default class Metadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
outerEvent: OuterEventMetadata,
|
||||
modules: Vector.with(RuntimeModuleMetadata),
|
||||
outerDispatch: OuterDispatchMetadata
|
||||
}, Metadata.decodeMetadata(value));
|
||||
}
|
||||
|
||||
static decodeMetadata (value: string | Uint8Array | object): object | Uint8Array {
|
||||
if (isHex(value)) {
|
||||
// We receive this as an hex in the JSON output from the Node.
|
||||
// Convert to u8a and use the U8a version to do the actual parsing.
|
||||
return Metadata.decodeMetadata(hexToU8a(value));
|
||||
} else if (isU8a(value)) {
|
||||
// HACK 13 Oct 2018 - For current running BBQ nodes, Metadata is not properly
|
||||
// encoded, it does not have a length prefix. For latest substrate master, it
|
||||
// is properly encoded. Here we pull the prefix, check it agianst the length -
|
||||
// if matches, then we have the length, otherwise we assume it is an older node
|
||||
// and use the whole buffer
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
|
||||
return value.length === (offset + length.toNumber())
|
||||
? value.subarray(offset)
|
||||
: value;
|
||||
}
|
||||
|
||||
// Decode as normal struct
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[OuterDispatchCall]]
|
||||
*/
|
||||
get calls (): Vector<OuterDispatchCall> {
|
||||
return (this.get('outerDispatch') as OuterDispatchMetadata).calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[OuterEventMetadataEvent]]
|
||||
*/
|
||||
get events (): Vector<OuterEventMetadataEvent> {
|
||||
return (this.get('outerEvent') as OuterEventMetadata).events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[RuntimeModuleMetadata]]
|
||||
*/
|
||||
get modules (): Vector<RuntimeModuleMetadata> {
|
||||
return this.get('modules') as Vector<RuntimeModuleMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Helper to retrieve a list of all type that are found, sorted and de-deuplicated
|
||||
*/
|
||||
getUniqTypes (): Array<string> {
|
||||
const events = this.events.map((module) =>
|
||||
module.events.map((event) =>
|
||||
event.arguments.map((argument) =>
|
||||
argument.toString()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const storages = this.modules.map((module) =>
|
||||
module.storage.isSome
|
||||
? module.storage.unwrap().functions.map((fn) =>
|
||||
fn.type.isMap
|
||||
? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]
|
||||
: [fn.type.asType.toString()]
|
||||
)
|
||||
: []
|
||||
);
|
||||
|
||||
const args = this.modules.map((module) =>
|
||||
module.module.call.functions.map((fn) =>
|
||||
fn.arguments.map((argument) =>
|
||||
argument.type.toString()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const types = flattenUniq([events, storages, args]);
|
||||
|
||||
this.validateTypes(types);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
private validateTypes (types: Array<string>): void {
|
||||
const extractTypes = (types: Array<string>): Array<any> => {
|
||||
return types.map((type) => {
|
||||
const decoded = getTypeDef(type);
|
||||
|
||||
switch (decoded.info) {
|
||||
case TypeDefInfo.Plain:
|
||||
return decoded.type;
|
||||
|
||||
case TypeDefInfo.Compact:
|
||||
case TypeDefInfo.Vector:
|
||||
return extractTypes([(decoded.sub as TypeDef).type]);
|
||||
|
||||
case TypeDefInfo.Tuple:
|
||||
return extractTypes(
|
||||
(decoded.sub as Array<TypeDef>).map((sub) => sub.type)
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Error('Unreachable');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const missing = flattenUniq(extractTypes(types)).filter((type) =>
|
||||
isUndefined((allTypes as any)[type])
|
||||
);
|
||||
|
||||
assert(missing.length === 0, `Unknown types found, no types for ${missing}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2017-2018 @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 Struct from '../codec/Struct';
|
||||
import Vector from '../codec/Vector';
|
||||
import Text from '../Text';
|
||||
import U16 from '../U16';
|
||||
|
||||
export class OuterDispatchCall extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
prefix: Text,
|
||||
index: U16
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[U16]] index for the call
|
||||
*/
|
||||
get index (): U16 {
|
||||
return this.get('index') as U16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the call
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The call prefix (or section)
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterDispatchMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
calls: Vector.with(OuterDispatchCall)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[OuterDispathCall]] wrapped
|
||||
*/
|
||||
get calls (): Vector<OuterDispatchCall> {
|
||||
return this.get('calls') as Vector<OuterDispatchCall>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the dispatch
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2017-2018 @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 Struct from '../codec/Struct';
|
||||
import Tuple from '../codec/Tuple';
|
||||
import Vector from '../codec/Vector';
|
||||
import Text from '../Text';
|
||||
import Type from '../Type';
|
||||
|
||||
export class EventMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
arguments: Vector.with(Type),
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The arguments of [[Type]]
|
||||
*/
|
||||
get arguments (): Vector<Type> {
|
||||
return this.get('arguments') as Vector<Type>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name for the event
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterEventMetadataEvent extends Tuple {
|
||||
constructor (value?: any) {
|
||||
super([
|
||||
Text,
|
||||
Vector.with(EventMetadata)
|
||||
], value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[EventMetadata]]
|
||||
*/
|
||||
get events (): Vector<EventMetadata> {
|
||||
return this[1] as Vector<EventMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name of the section
|
||||
*/
|
||||
get name (): Text {
|
||||
return this[0] as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class OuterEventMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
events: Vector.with(OuterEventMetadataEvent)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[OuterEventMetadataEvent]]
|
||||
*/
|
||||
get events (): Vector<OuterEventMetadataEvent> {
|
||||
return this.get('events') as Vector<OuterEventMetadataEvent>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name of the event
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import bbqBirch from './json/Metadata.bbq.json';
|
||||
import compacted from './json/Metadata.latest.json';
|
||||
import Metadata from './Metadata';
|
||||
import rpcdata from './Metadata.rpc';
|
||||
import latestParsed from './Metadata.latest.json';
|
||||
import bbqBirch from '../json/Metadata.bbq.json';
|
||||
import compacted from '../json/Metadata.latest.json';
|
||||
import Metadata from './index';
|
||||
import rpcdata from './static';
|
||||
import latestParsed from './latest.json';
|
||||
|
||||
describe('Metadata', () => {
|
||||
it('decodes properly', () => {
|
||||
@@ -0,0 +1,290 @@
|
||||
// Copyright 2017-2018 @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 { AnyNumber } from '../types';
|
||||
|
||||
import Enum from '../codec/Enum';
|
||||
import EnumType from '../codec/EnumType';
|
||||
import Option from '../codec/Option';
|
||||
import Struct from '../codec/Struct';
|
||||
import Vector from '../codec/Vector';
|
||||
import Text from '../Text';
|
||||
import Type from '../Type';
|
||||
import U16 from '../U16';
|
||||
|
||||
export class FunctionArgumentMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
type: Type
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The argument name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Type]]
|
||||
*/
|
||||
get type (): Type {
|
||||
return this.get('type') as Type;
|
||||
}
|
||||
}
|
||||
|
||||
export class FunctionMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
id: U16,
|
||||
name: Text,
|
||||
arguments: Vector.with(FunctionArgumentMetadata),
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[FunctionArgumentMetadata]] for arguments
|
||||
*/
|
||||
get arguments (): Vector<FunctionArgumentMetadata> {
|
||||
return this.get('arguments') as Vector<FunctionArgumentMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The `[sectionIndex, methodIndex]` call id
|
||||
*/
|
||||
get id (): U16 {
|
||||
return this.get('id') as U16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The call name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class CallMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
functions: Vector.with(FunctionMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The functions available as [[FunctionMetadata]]
|
||||
*/
|
||||
get functions (): Vector<FunctionMetadata> {
|
||||
return this.get('functions') as Vector<FunctionMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The section name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class ModuleMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
name: Text,
|
||||
call: CallMetadata
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The calls as [[CallMetadata]]
|
||||
*/
|
||||
get call (): CallMetadata {
|
||||
return this.get('call') as CallMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionModifier extends Enum {
|
||||
constructor (value?: any) {
|
||||
super(['None', 'Default', 'Required'], value);
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionType$Map extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
key: Type,
|
||||
value: Type
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The mapped key as [[Type]]
|
||||
*/
|
||||
get key (): Type {
|
||||
return this.get('key') as Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The mapped value as [[Type]]
|
||||
*/
|
||||
get value (): Type {
|
||||
return this.get('value') as Type;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionType extends EnumType<Type | StorageFunctionType$Map> {
|
||||
constructor (value?: any, index?: number) {
|
||||
super([
|
||||
Type,
|
||||
StorageFunctionType$Map
|
||||
], value, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a map
|
||||
*/
|
||||
get isMap (): boolean {
|
||||
return this.toNumber() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a mapped value
|
||||
*/
|
||||
get asMap (): StorageFunctionType$Map {
|
||||
return this.value as StorageFunctionType$Map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a [[Type]] value
|
||||
*/
|
||||
get asType (): Type {
|
||||
return this.value as Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
toString (): string {
|
||||
return this.isMap
|
||||
? this.asMap.value.toString()
|
||||
: this.asType.toString();
|
||||
}
|
||||
}
|
||||
|
||||
type StorageFunctionMetadataValue = {
|
||||
name?: string | Text,
|
||||
modifier?: StorageFunctionModifier | AnyNumber,
|
||||
type?: StorageFunctionType,
|
||||
documentation?: Vector<Text> | Array<string>
|
||||
};
|
||||
|
||||
export class StorageFunctionMetadata extends Struct {
|
||||
constructor (value?: StorageFunctionMetadataValue) {
|
||||
super({
|
||||
name: Text,
|
||||
modifier: StorageFunctionModifier,
|
||||
type: StorageFunctionType,
|
||||
documentation: Vector.with(Text)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Text]] documentation
|
||||
*/
|
||||
get documentation (): Vector<Text> {
|
||||
return this.get('documentation') as Vector<Text>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The key name
|
||||
*/
|
||||
get name (): Text {
|
||||
return this.get('name') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The modifier
|
||||
*/
|
||||
get modifier (): StorageFunctionModifier {
|
||||
return this.get('modifier') as StorageFunctionModifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[StorageFunctionType]]
|
||||
*/
|
||||
get type (): StorageFunctionType {
|
||||
return this.get('type') as StorageFunctionType;
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
prefix: Text,
|
||||
functions: Vector.with(StorageFunctionMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[StorageFunctionMetadata]] for the section
|
||||
*/
|
||||
get functions (): Vector<StorageFunctionMetadata> {
|
||||
return this.get('functions') as Vector<StorageFunctionMetadata>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The section prefix
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
}
|
||||
|
||||
export class RuntimeModuleMetadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
prefix: Text,
|
||||
module: ModuleMetadata,
|
||||
storage: Option.with(StorageMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ModuleMetadata]]
|
||||
*/
|
||||
get module (): ModuleMetadata {
|
||||
return this.get('module') as ModuleMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The prefix
|
||||
*/
|
||||
get prefix (): Text {
|
||||
return this.get('prefix') as Text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The optional [[StorageMetadata]]
|
||||
*/
|
||||
get storage (): Option<StorageMetadata> {
|
||||
return this.get('storage') as Option<StorageMetadata>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// Copyright 2017-2018 @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 { assert, hexToU8a, isHex, isU8a, isUndefined } from '@polkadot/util';
|
||||
|
||||
import { getTypeDef, TypeDef, TypeDefInfo } from '../codec/createType';
|
||||
import Compact from '../codec/Compact';
|
||||
import Struct from '../codec/Struct';
|
||||
import Vector from '../codec/Vector';
|
||||
import { OuterDispatchMetadata, OuterDispatchCall } from './Calls';
|
||||
import { OuterEventMetadata, OuterEventMetadataEvent } from './Events';
|
||||
import { RuntimeModuleMetadata } from './Modules';
|
||||
|
||||
// Decodes the runtime metadata as passed through from the `state_getMetadata` call. This
|
||||
// file is probably best understood from the bottom-up, i.e. start reading right at the
|
||||
// end and work up. (Just so we don't use before definition)
|
||||
|
||||
// Quick and dirty flatten (.flat() not available)
|
||||
function flattenUniq (list: Array<any>): Array<any> {
|
||||
const flat = list.reduce((result, entry) => {
|
||||
return result.concat(
|
||||
Array.isArray(entry)
|
||||
? flattenUniq(entry)
|
||||
: entry
|
||||
);
|
||||
}, []);
|
||||
|
||||
return [...new Set(flat)]
|
||||
.filter((value: any) => value)
|
||||
.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Metadata
|
||||
* @description
|
||||
* The runtime metadata as a decoded structure
|
||||
*/
|
||||
export default class Metadata extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
outerEvent: OuterEventMetadata,
|
||||
modules: Vector.with(RuntimeModuleMetadata),
|
||||
outerDispatch: OuterDispatchMetadata
|
||||
}, Metadata.decodeMetadata(value));
|
||||
}
|
||||
|
||||
static decodeMetadata (value: string | Uint8Array | object): object | Uint8Array {
|
||||
if (isHex(value)) {
|
||||
// We receive this as an hex in the JSON output from the Node.
|
||||
// Convert to u8a and use the U8a version to do the actual parsing.
|
||||
return Metadata.decodeMetadata(hexToU8a(value));
|
||||
} else if (isU8a(value)) {
|
||||
// HACK 13 Oct 2018 - For current running BBQ nodes, Metadata is not properly
|
||||
// encoded, it does not have a length prefix. For latest substrate master, it
|
||||
// is properly encoded. Here we pull the prefix, check it agianst the length -
|
||||
// if matches, then we have the length, otherwise we assume it is an older node
|
||||
// and use the whole buffer
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
|
||||
return value.length === (offset + length.toNumber())
|
||||
? value.subarray(offset)
|
||||
: value;
|
||||
}
|
||||
|
||||
// Decode as normal struct
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[OuterDispatchCall]]
|
||||
*/
|
||||
get calls (): Vector<OuterDispatchCall> {
|
||||
return (this.get('outerDispatch') as OuterDispatchMetadata).calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[OuterEventMetadataEvent]]
|
||||
*/
|
||||
get events (): Vector<OuterEventMetadataEvent> {
|
||||
return (this.get('outerEvent') as OuterEventMetadata).events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Wrapped [[RuntimeModuleMetadata]]
|
||||
*/
|
||||
get modules (): Vector<RuntimeModuleMetadata> {
|
||||
return this.get('modules') as Vector<RuntimeModuleMetadata>;
|
||||
}
|
||||
|
||||
private get argNames () {
|
||||
return this.modules.map((module) =>
|
||||
module.module.call.functions.map((fn) =>
|
||||
fn.arguments.map((argument) => argument.type.toString())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private get eventNames () {
|
||||
return this.events.map((module) =>
|
||||
module.events.map((event) =>
|
||||
event.arguments.map((argument) => argument.toString())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private get storageNames () {
|
||||
return this.modules.map((module) =>
|
||||
module.storage.isSome
|
||||
? module.storage.unwrap().functions.map((fn) =>
|
||||
fn.type.isMap
|
||||
? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]
|
||||
: [fn.type.asType.toString()]
|
||||
)
|
||||
: []
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Helper to retrieve a list of all type that are found, sorted and de-deuplicated
|
||||
*/
|
||||
getUniqTypes (): Array<string> {
|
||||
const types = flattenUniq([this.argNames, this.eventNames, this.storageNames]);
|
||||
|
||||
this.validateTypes(types);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
private validateTypes (types: Array<string>): void {
|
||||
const extractTypes = (types: Array<string>): Array<any> => {
|
||||
return types.map((type) => {
|
||||
const decoded = getTypeDef(type);
|
||||
|
||||
switch (decoded.info) {
|
||||
case TypeDefInfo.Plain:
|
||||
return decoded.type;
|
||||
|
||||
case TypeDefInfo.Compact:
|
||||
case TypeDefInfo.Vector:
|
||||
return extractTypes([(decoded.sub as TypeDef).type]);
|
||||
|
||||
case TypeDefInfo.Tuple:
|
||||
return extractTypes(
|
||||
(decoded.sub as Array<TypeDef>).map((sub) => sub.type)
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Error('Unreachable');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const allTypes = require('../index');
|
||||
const missing = flattenUniq(extractTypes(types)).filter((type) =>
|
||||
isUndefined(allTypes[type])
|
||||
);
|
||||
|
||||
assert(missing.length === 0, `Unknown types found, no types for ${missing}`);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import { getTypeDef, getTypeClass } from './codec/createType';
|
||||
import Struct from './codec/Struct';
|
||||
import U8aFixed from './codec/U8aFixed';
|
||||
import Extrinsic from './Extrinsic';
|
||||
import { FunctionMetadata, FunctionArgumentMetadata } from './Metadata';
|
||||
import { FunctionMetadata, FunctionArgumentMetadata } from './Metadata/Modules';
|
||||
|
||||
const FN_UNKNOWN = {
|
||||
method: 'unknown',
|
||||
@@ -101,20 +101,13 @@ export default class Method extends Struct {
|
||||
// Find metadata with callIndex
|
||||
const meta = _meta || Method.findFunction(callIndex).meta;
|
||||
|
||||
// Get Struct definition of the arguments
|
||||
const argsDef = Method.getArgsDef(meta);
|
||||
|
||||
return {
|
||||
args: value.subarray(2),
|
||||
argsDef,
|
||||
argsDef: Method.getArgsDef(meta),
|
||||
callIndex,
|
||||
meta
|
||||
};
|
||||
} else if (
|
||||
isObject(value) &&
|
||||
value.callIndex &&
|
||||
value.args
|
||||
) {
|
||||
} else if (isObject(value) && value.callIndex && value.args) {
|
||||
// destructure value, we only pass args/methodsIndex out
|
||||
const { args, callIndex } = value;
|
||||
|
||||
@@ -126,12 +119,9 @@ export default class Method extends Struct {
|
||||
// Find metadata with callIndex
|
||||
const meta = _meta || Method.findFunction(lookupIndex).meta;
|
||||
|
||||
// Get Struct definition of the arguments
|
||||
const argsDef = Method.getArgsDef(meta);
|
||||
|
||||
return {
|
||||
args,
|
||||
argsDef,
|
||||
argsDef: Method.getArgsDef(meta),
|
||||
meta,
|
||||
callIndex
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AnyU8a } from './types';
|
||||
import { isFunction } from '@polkadot/util';
|
||||
|
||||
import Bytes from './Bytes';
|
||||
import { StorageFunctionMetadata } from './Metadata';
|
||||
import { StorageFunctionMetadata } from './Metadata/Modules';
|
||||
|
||||
export interface StorageFunction {
|
||||
(arg?: any): Uint8Array;
|
||||
|
||||
@@ -90,9 +90,9 @@ export default class Type extends Text {
|
||||
if (value[index] === '>') {
|
||||
if (!depth) {
|
||||
return index;
|
||||
} else {
|
||||
depth--;
|
||||
}
|
||||
|
||||
depth--;
|
||||
} else if (value[index] === '<') {
|
||||
depth++;
|
||||
}
|
||||
|
||||
@@ -78,36 +78,30 @@ export default class Struct<
|
||||
// used to track at which index we are currently parsing in that array.
|
||||
let currentIndex = 0;
|
||||
|
||||
return (Object
|
||||
.keys(Types) as Array<keyof S>)
|
||||
.reduce((raw: T, key, index) => {
|
||||
// The key in the JSON can be snake_case (or other cases), but in our
|
||||
// Types, result or any other maps, it's camelCase
|
||||
const jsonKey = (jsonMap.get(key as any) && !value[key]) ? jsonMap.get(key as any) : key;
|
||||
return Object.keys(Types).reduce((raw: T, key: keyof S, index) => {
|
||||
// The key in the JSON can be snake_case (or other cases), but in our
|
||||
// Types, result or any other maps, it's camelCase
|
||||
const jsonKey = (jsonMap.get(key as any) && !value[key]) ? jsonMap.get(key as any) : key;
|
||||
|
||||
if (isU8a(value)) {
|
||||
raw[key] = new Types[key](
|
||||
value.subarray(
|
||||
currentIndex
|
||||
)
|
||||
);
|
||||
if (isU8a(value)) {
|
||||
raw[key] = new Types[key](value.subarray(currentIndex));
|
||||
|
||||
// Move the currentIndex forward
|
||||
currentIndex += raw[key].encodedLength;
|
||||
} else if (Array.isArray(value)) {
|
||||
raw[key] = value[index] instanceof Types[key]
|
||||
? value[index]
|
||||
: new Types[key](value[index]);
|
||||
} else if (isObject(value)) {
|
||||
raw[key] = value[jsonKey as string] instanceof Types[key]
|
||||
? value[jsonKey as string]
|
||||
: new Types[key](value[jsonKey as string]);
|
||||
} else {
|
||||
throw new Error(`Struct: cannot decode type "${Types[key].name}" with value "${JSON.stringify(value)}".`);
|
||||
}
|
||||
// Move the currentIndex forward
|
||||
currentIndex += raw[key].encodedLength;
|
||||
} else if (Array.isArray(value)) {
|
||||
raw[key] = value[index] instanceof Types[key]
|
||||
? value[index]
|
||||
: new Types[key](value[index]);
|
||||
} else if (isObject(value)) {
|
||||
raw[key] = value[jsonKey as string] instanceof Types[key]
|
||||
? value[jsonKey as string]
|
||||
: new Types[key](value[jsonKey as string]);
|
||||
} else {
|
||||
throw new Error(`Struct: cannot decode type ${Types[key].name} with value ${JSON.stringify(value)}`);
|
||||
}
|
||||
|
||||
return raw;
|
||||
}, {} as T);
|
||||
return raw;
|
||||
}, {} as T);
|
||||
}
|
||||
|
||||
static with<
|
||||
|
||||
@@ -117,28 +117,22 @@ export function getTypeDef (_type: Text | string): TypeDef {
|
||||
// Returns the type Class for construction
|
||||
export function getTypeClass (value: TypeDef): Constructor {
|
||||
if (value.info === TypeDefInfo.Tuple) {
|
||||
if (!Array.isArray(value.sub)) {
|
||||
throw new Error(`Expected nested subtypes for Tuple`);
|
||||
}
|
||||
assert(Array.isArray(value.sub), 'Expected nested subtypes for Tuple');
|
||||
|
||||
return Tuple.with(
|
||||
value.sub.map(getTypeClass)
|
||||
(value.sub as Array<TypeDef>).map(getTypeClass)
|
||||
);
|
||||
} else if (value.info === TypeDefInfo.Compact) {
|
||||
if (!value.sub || Array.isArray(value.sub)) {
|
||||
throw new Error(`Expected subtype for Compact`);
|
||||
}
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Compact');
|
||||
|
||||
return Compact.with(
|
||||
getTypeClass(value.sub) as Constructor<UInt>
|
||||
getTypeClass(value.sub as TypeDef) as Constructor<UInt>
|
||||
);
|
||||
} else if (value.info === TypeDefInfo.Vector) {
|
||||
if (!value.sub || Array.isArray(value.sub)) {
|
||||
throw new Error(`Expected subtype for Vector`);
|
||||
}
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Vector');
|
||||
|
||||
return Vector.with(
|
||||
getTypeClass(value.sub)
|
||||
getTypeClass(value.sub as TypeDef)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
const fs = require('fs');
|
||||
|
||||
import Metadata from '../Metadata';
|
||||
import rpcdata from '../Metadata.rpc';
|
||||
import rpcdata from '../Metadata/static';
|
||||
|
||||
function metadataStringifyAsJson () {
|
||||
const decoded = new Metadata(rpcdata);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { stringCamelCase, stringLowerFirst } from '@polkadot/util';
|
||||
|
||||
import interfaces from '../../../type-jsonrpc/src';
|
||||
import Metadata from '../Metadata';
|
||||
import rpcdata from '../Metadata.rpc';
|
||||
import rpcdata from '../Metadata/static';
|
||||
import Method from '../Method';
|
||||
|
||||
const ANCHOR_TOP = `<a id='top' style='text-decoration: none;'>`;
|
||||
|
||||
Reference in New Issue
Block a user