Allow string types inputs into codec (#1292)

* Allow string types inputs into codec

* Linkage allows string constructors

* Import case

* Cleanup keyof imports

* Attempt linkage doc fix
This commit is contained in:
Jaco Greeff
2019-08-11 14:01:20 +02:00
committed by GitHub
parent d1be4ea780
commit 1aa7899a7a
28 changed files with 228 additions and 132 deletions
+7 -1
View File
@@ -113,7 +113,13 @@ describe('Compact', (): void => {
).toEqual(64);
});
it('has the correct encodedLength for constructor values (BlockNumber)', (): void => {
it('has the correct encodedLength for constructor values (string BlockNumber)', (): void => {
expect(
new Compact('BlockNumber', 0xfffffff9).encodedLength
).toEqual(5);
});
it('has the correct encodedLength for constructor values (class BlockNumber)', (): void => {
expect(
new Compact(ClassOf('BlockNumber'), 0xfffffff9).encodedLength
).toEqual(5);
+5 -4
View File
@@ -2,12 +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 { AnyNumber, Constructor } from '../types';
import { AnyNumber, Constructor, InterfaceTypes } from '../types';
import BN from 'bn.js';
import { bnToBn, compactAddLength, compactFromU8a, compactStripLength, compactToU8a, hexToBn, isBn, isHex, isNumber, isString } from '@polkadot/util';
import { DEFAULT_BITLENGTH } from '@polkadot/util/compact/defaults';
import { typeToConstructor } from './utils';
import { UIntBitLength } from './AbstractInt';
import CodecDate from './Date';
import UInt from './UInt';
@@ -26,11 +27,11 @@ export type CompactEncodable = UInt | CodecDate; // FIXME is there a way to do i
* a number and making the compact representation thereof
*/
export default class Compact<T extends CompactEncodable> extends Base<T> {
public constructor (Type: Constructor<T>, value: Compact<T> | AnyNumber = 0) {
super(Compact.decodeCompact<T>(Type, value));
public constructor (Type: Constructor<T> | InterfaceTypes, value: Compact<T> | AnyNumber = 0) {
super(Compact.decodeCompact<T>(typeToConstructor(Type), value));
}
public static with<T extends CompactEncodable> (Type: Constructor<T>): Constructor<Compact<T>> {
public static with<T extends CompactEncodable> (Type: Constructor<T> | InterfaceTypes): Constructor<Compact<T>> {
return class extends Compact<T> {
public constructor (value?: any) {
super(Type, value);
@@ -47,6 +47,15 @@ describe('Enum', (): void => {
).toEqual('4660'); // 0x1234 in decimal
});
it('decodes from hex (string types)', (): void => {
expect(
new Enum(
{ foo: 'Text', bar: 'u32' },
'0x0134120000'
).value.toString()
).toEqual('4660'); // 0x1234 in decimal
});
it('decodes from a JSON input (mixed case)', (): void => {
expect(
new Enum(
+6 -5
View File
@@ -2,11 +2,12 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AnyJson, Codec, Constructor } from '../types';
import { AnyJson, Codec, Constructor, InterfaceTypes } from '../types';
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, stringCamelCase, stringUpperFirst, u8aConcat, u8aToHex } from '@polkadot/util';
import Null from '../primitive/Null';
import { mapToTypeMap } from './utils';
import Base from './Base';
interface EnumConstructor<T = Codec> {
@@ -38,7 +39,7 @@ export default class Enum extends Base<Codec> {
private _isBasic: boolean;
public constructor (def: TypesDef | string[], value?: any, index?: number | Enum) {
public constructor (def: Record<string, InterfaceTypes | Constructor> | string[], value?: any, index?: number | Enum) {
const defInfo = Enum.extractDef(def);
const decoded = Enum.decodeEnum(defInfo.def, value, index);
@@ -50,10 +51,10 @@ export default class Enum extends Base<Codec> {
this._index = this._indexes.indexOf(decoded.index) || 0;
}
private static extractDef (def: TypesDef | string[]): { def: TypesDef; isBasic: boolean } {
private static extractDef (def: Record<string, InterfaceTypes | Constructor> | string[]): { def: TypesDef; isBasic: boolean } {
if (!Array.isArray(def)) {
return {
def,
def: mapToTypeMap(def),
isBasic: false
};
}
@@ -126,7 +127,7 @@ export default class Enum extends Base<Codec> {
};
}
public static with (Types: TypesDef | string[]): EnumConstructor<Enum> {
public static with (Types: Record<string, InterfaceTypes | Constructor> | string[]): EnumConstructor<Enum> {
return class extends Enum {
public constructor (value?: any, index?: number) {
super(Types, value, index);
+16 -4
View File
@@ -2,22 +2,30 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Struct, Option, Tuple, Vec } from '.';
import { Constructor, Codec } from '../types';
import { Constructor, Codec, InterfaceTypes } from '../types';
import Option from './Option';
import Struct from './Struct';
import Tuple from './Tuple';
import Vec from './Vec';
type TypeWithValues = [Constructor, any[]];
const EMPTY = new Uint8Array();
/**
* @name Linkage
* @description The wrapper for the result from a LinkedMap
*/
export default class Linkage<T extends Codec> extends Struct {
public constructor (Type: Constructor, value?: any) {
public constructor (Type: Constructor | InterfaceTypes, value?: any) {
super({
previous: Option.with(Type),
next: Option.with(Type)
}, value);
}
public static withKey<O extends Codec> (Type: Constructor): Constructor<Linkage<O>> {
public static withKey<O extends Codec> (Type: Constructor | InterfaceTypes): Constructor<Linkage<O>> {
return class extends Linkage<O> {
public constructor (value?: any) {
super(Type, value);
@@ -50,6 +58,10 @@ export default class Linkage<T extends Codec> extends Struct {
}
}
/**
* @name LinkageResult
* @description A Linkage keys/Values tuple
*/
export class LinkageResult extends Tuple {
public constructor ([TypeKey, keys]: TypeWithValues, [TypeValue, values]: TypeWithValues) {
super({
+6
View File
@@ -37,6 +37,12 @@ describe('Option', (): void => {
).toEqual('hello');
});
it('converts an option to an option (strings)', (): void => {
expect(
new Option('Text', new Option('Text', 'hello')).toString()
).toEqual('hello');
});
it('converts correctly from hex with toHex (Bytes)', (): void => {
// Option<Bytes> for a parachain head, however, this is effectively an
// Option<Option<Bytes>> (hence the length, since it is from storage)
+10 -8
View File
@@ -2,11 +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 { Codec, Constructor, InterfaceTypes } from '../types';
import { isNull, isU8a, isUndefined, u8aToHex } from '@polkadot/util';
import Base from './Base';
import { Codec, Constructor } from '../types';
import Null from '../primitive/Null';
import { typeToConstructor } from './utils';
import Base from './Base';
/**
* @name Option
@@ -19,12 +21,12 @@ import Null from '../primitive/Null';
export default class Option<T extends Codec> extends Base<T> {
private _Type: Constructor;
public constructor (Type: Constructor, value?: any) {
super(
Option.decodeOption(Type, value)
);
public constructor (Type: Constructor | InterfaceTypes, value?: any) {
const Clazz = typeToConstructor(Type);
this._Type = Type;
super(Option.decodeOption(Clazz, value));
this._Type = Clazz;
}
public static decodeOption (Type: Constructor, value?: any): Codec {
@@ -46,7 +48,7 @@ export default class Option<T extends Codec> extends Base<T> {
return new Type(value);
}
public static with<O extends Codec> (Type: Constructor): Constructor<Option<O>> {
public static with<O extends Codec> (Type: Constructor | InterfaceTypes): Constructor<Option<O>> {
return class extends Option<O> {
public constructor (value?: any) {
super(Type, value);
+12
View File
@@ -105,6 +105,18 @@ describe('Struct', (): void => {
).toEqual('{"txt":"foo","u32":1193046}');
});
it('provides a clean toString() (string types)', (): void => {
expect(
new (
Struct.with({
txt: 'Text',
num: 'u32',
cls: U32
})
)({ txt: 'foo', num: 0x123456, cls: 123 }).toString()
).toEqual('{"txt":"foo","num":1193046,"cls":123}');
});
it('exposes the properties on the object', (): void => {
const struct = new (
Struct.with({
+18 -27
View File
@@ -2,13 +2,15 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AnyJsonObject, Codec, Constructor, ConstructorDef, IHash } from '../types';
import { AnyJsonObject, Codec, Constructor, ConstructorDef, IHash, InterfaceTypes } from '../types';
import { hexToU8a, isHex, isObject, isU8a, isUndefined, u8aConcat, u8aToHex } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import { compareMap, decodeU8a } from './utils';
import { compareMap, decodeU8a, mapToTypeMap } from './utils';
type TypesDef<T = Codec> = Record<string, InterfaceTypes | Constructor<T>>;
/**
* @name Struct
@@ -22,7 +24,7 @@ import { compareMap, decodeU8a } from './utils';
*/
export default class Struct<
// The actual Class structure, i.e. key -> Class
S extends ConstructorDef = ConstructorDef,
S extends TypesDef = TypesDef,
// internal type, instance of classes mapped by key
T extends { [K in keyof S]: Codec } = { [K in keyof S]: Codec },
// input values, mapped by key can be anything (construction)
@@ -31,17 +33,16 @@ export default class Struct<
E extends { [K in keyof S]: string } = { [K in keyof S]: string }> extends Map<keyof S, Codec> implements Codec {
protected _jsonMap: Map<keyof S, string>;
protected _Types: S;
protected _Types: ConstructorDef;
public constructor (Types: S, value: V | Map<any, any> | any[] | string = {} as unknown as V, jsonMap: Map<keyof S, string> = new Map()) {
const decoded = Struct.decodeStruct<S, V, T>(Types, value, jsonMap);
const Clazzes = mapToTypeMap(Types);
const decoded = Struct.decodeStruct(Clazzes, value, jsonMap);
super(
Object.entries(decoded)
);
super(Object.entries(decoded as any));
this._jsonMap = jsonMap;
this._Types = Types;
this._Types = Clazzes;
}
/**
@@ -59,11 +60,7 @@ export default class Struct<
* `Object.keys(Types)`
* @param jsonMap
*/
private static decodeStruct<
S extends ConstructorDef,
_,
T extends { [K in keyof S]: Codec }
> (Types: S, value: any, jsonMap: Map<keyof S, string>): T {
private static decodeStruct <T> (Types: ConstructorDef, value: any, jsonMap: Map<any, string>): T {
// l.debug(() => ['Struct.decode', { Types, value }]);
if (isHex(value)) {
@@ -72,7 +69,7 @@ export default class Struct<
const values = decodeU8a(value, Object.values(Types));
// Transform array of values to {key: value} mapping
return Object.keys(Types).reduce((raw: T, key: keyof S, index): T => {
return Object.keys(Types).reduce((raw, key, index): T => {
// TS2322: Type 'Codec' is not assignable to type 'T[keyof S]'.
(raw as any)[key] = values[index];
@@ -86,30 +83,26 @@ export default class Struct<
return Struct.decodeStructFromObject(Types, value, jsonMap);
}
private static decodeStructFromObject<
S extends ConstructorDef,
_,
T extends { [K in keyof S]: Codec }
> (Types: S, value: any, jsonMap: Map<keyof S, string>): T {
return Object.keys(Types).reduce((raw: T, key: keyof S, index): T => {
private static decodeStructFromObject <T> (Types: ConstructorDef, value: any, jsonMap: Map<any, string>): T {
return Object.keys(Types).reduce((raw, key, index): T => {
// 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;
try {
if (Array.isArray(value)) {
raw[key] = value[index] instanceof Types[key]
// TS2322: Type 'Codec' is not assignable to type 'T[keyof S]'.
(raw as any)[key] = value[index] instanceof Types[key]
? value[index]
: new Types[key](value[index]);
} else if (value instanceof Map) {
const mapped = value.get(jsonKey);
// TS2322: Type 'Codec' is not assignable to type 'T[keyof S]'.
(raw as any)[key] = mapped instanceof Types[key]
? mapped
: new Types[key](mapped);
} else if (isObject(value)) {
raw[key] = value[jsonKey as string] instanceof Types[key]
(raw as any)[key] = value[jsonKey as string] instanceof Types[key]
? value[jsonKey as string]
: new Types[key](value[jsonKey as string]);
} else {
@@ -123,9 +116,7 @@ export default class Struct<
}, {} as unknown as T);
}
public static with<
S extends ConstructorDef
> (Types: S): Constructor<Struct<S>> {
public static with<S extends TypesDef> (Types: S): Constructor<Struct<S>> {
return class extends Struct<S> {
public constructor (value?: any, jsonMap?: Map<keyof S, string>) {
super(Types, value, jsonMap);
+9
View File
@@ -55,6 +55,15 @@ describe('Tuple', (): void => {
testEncode('toString', '["bazzing",69]');
});
it('creates from string types', (): void => {
expect(
new Tuple(
['Text', 'u32', U32],
['foo', 69, 42]
).toString()
).toEqual('["foo",69,42]');
});
it.skip('creates properly via actual hex string', (): void => {
Call.injectMethods(extrinsics);
+14 -8
View File
@@ -2,17 +2,21 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AnyNumber, AnyU8a, AnyString, Codec, Constructor } from '../types';
import { AnyNumber, AnyU8a, AnyString, Codec, Constructor, InterfaceTypes } from '../types';
import { isU8a, u8aConcat, isHex, hexToU8a } from '@polkadot/util';
import { decodeU8a } from './utils';
import { decodeU8a, mapToTypeMap, typeToConstructor } from './utils';
import AbstractArray from './AbstractArray';
type TupleConstructors = Constructor[] | {
[index: string]: Constructor;
};
type TupleTypes = (Constructor | InterfaceTypes)[] | {
[index: string]: Constructor | InterfaceTypes;
};
/**
* @name Tuple
* @description
@@ -22,12 +26,14 @@ type TupleConstructors = Constructor[] | {
export default class Tuple extends AbstractArray<Codec> {
private _Types: TupleConstructors;
public constructor (Types: TupleConstructors, value?: any) {
super(
...Tuple.decodeTuple(Types, value)
);
public constructor (Types: TupleTypes, value?: any) {
const Clazzes = Array.isArray(Types)
? Types.map((type): Constructor => typeToConstructor(type))
: mapToTypeMap(Types);
this._Types = Types;
super(...Tuple.decodeTuple(Clazzes, value));
this._Types = Clazzes;
}
private static decodeTuple (_Types: TupleConstructors, value: AnyU8a | string | (AnyU8a | AnyNumber | AnyString | undefined | null)[]): Codec[] {
@@ -50,7 +56,7 @@ export default class Tuple extends AbstractArray<Codec> {
});
}
public static with (Types: TupleConstructors): Constructor<Tuple> {
public static with (Types: TupleTypes): Constructor<Tuple> {
return class extends Tuple {
public constructor (value?: any) {
super(Types, value);
+6
View File
@@ -48,6 +48,12 @@ describe('Vec', (): void => {
).toEqual(['6', '7']);
});
it('allows contruction via JSON (string type)', (): void => {
expect(
new Vec('u32', ['6', '7']).toJSON()
).toEqual([6, 7]);
});
it('exposes the type', (): void => {
expect(vector.Type).toEqual('Text');
});
+11 -8
View File
@@ -2,11 +2,12 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Codec, Constructor, InterfaceTypes } from '../types';
import { u8aToU8a, assert } from '@polkadot/util';
import Compact from './Compact';
import { Codec, Constructor } from '../types';
import { decodeU8a } from './utils';
import { decodeU8a, typeToConstructor } from './utils';
import AbstractArray from './AbstractArray';
const MAX_LENGTH = 32768;
@@ -21,12 +22,12 @@ const MAX_LENGTH = 32768;
export default class Vec<T extends Codec> extends AbstractArray<T> {
private _Type: Constructor<T>;
public constructor (Type: Constructor<T>, value: Vec<any> | Uint8Array | string | any[] = [] as any[]) {
super(
...Vec.decodeVec(Type, value)
);
public constructor (Type: Constructor<T> | InterfaceTypes, value: Vec<any> | Uint8Array | string | any[] = [] as any[]) {
const Clazz = typeToConstructor<T>(Type);
this._Type = Type;
super(...Vec.decodeVec(Clazz, value));
this._Type = Clazz;
}
public static decodeVec<T extends Codec> (Type: Constructor<T>, value: Vec<any> | Uint8Array | string | any[]): T[] {
@@ -52,13 +53,15 @@ export default class Vec<T extends Codec> extends AbstractArray<T> {
return decodeU8a(u8a.subarray(offset), new Array(length.toNumber()).fill(Type)) as T[];
}
public static with<O extends Codec> (Type: Constructor<O>): Constructor<Vec<O>> {
public static with<O extends Codec> (Type: Constructor<O> | InterfaceTypes): Constructor<Vec<O>> {
return class extends Vec<O> {
public constructor (value?: any[]) {
super(Type, value);
}
// @ts-ignore
public static Fallback = Type.Fallback
// @ts-ignore
? Vec.with(Type.Fallback)
: undefined;
};
+7 -7
View File
@@ -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 { Codec, Constructor } from '../types';
import { Codec, Constructor, InterfaceTypes } from '../types';
import { assert, isU8a, u8aConcat, compactToU8a } from '@polkadot/util';
import AbstractArray from './AbstractArray';
import { typeToConstructor } from './utils';
import Vec from './Vec';
/**
@@ -17,12 +17,12 @@ import Vec from './Vec';
export default class VecFixed<T extends Codec> extends AbstractArray<T> {
private _Type: Constructor<T>;
public constructor (Type: Constructor<T>, length: number, value: VecFixed<any> | Uint8Array | string | any[] = [] as any[]) {
super(
...VecFixed.decodeVecFixed(Type, length, value)
);
public constructor (Type: Constructor<T> | InterfaceTypes, length: number, value: VecFixed<any> | Uint8Array | string | any[] = [] as any[]) {
const Clazz = typeToConstructor<T>(Type);
this._Type = Type;
super(...VecFixed.decodeVecFixed(Clazz, length, value));
this._Type = Clazz;
}
public static decodeVecFixed<T extends Codec> (Type: Constructor<T>, allocLength: number, value: VecFixed<any> | Uint8Array | string | any[]): T[] {
+25 -22
View File
@@ -2,15 +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 { Codec, Constructor, InterfaceTypes } from '../types';
import { TypeDef, TypeDefInfo, TypeDefExtVecFixed } from './types';
import memoizee from 'memoizee';
import { assert } from '@polkadot/util';
import { InterfaceRegistry } from '../interfaceRegistry';
import { Codec, Constructor } from '../types';
import Bytes from '../primitive/Bytes';
import Null from '../primitive/Null';
import Compact from './Compact';
import Enum from './Enum';
import Linkage from './Linkage';
@@ -19,13 +17,12 @@ import CodecSet from './Set';
import Struct from './Struct';
import Tuple from './Tuple';
import U8aFixed, { BitLength as U8aFixedBitLength } from './U8aFixed';
import UInt from './UInt';
import Vec from './Vec';
import VecFixed from './VecFixed';
import getTypeRegistry from './typeRegistry';
// Type which says: if `K` is in the InterfaceRegistry, then return InterfaceRegistry[K], else fallback to T
type FromReg<T extends Codec, K extends string> = K extends keyof InterfaceRegistry ? InterfaceRegistry[K] : T
type FromReg<T extends Codec, K extends string> = K extends InterfaceTypes ? InterfaceRegistry[K] : T
// safely split a string on ', ' while taking care of any nested occurences
export function typeSplit (type: string): string[] {
@@ -198,18 +195,24 @@ export function ClassOfUnsafe<T extends Codec = Codec, K extends string = string
}
// alias for createClass
export function ClassOf<K extends keyof InterfaceRegistry> (name: K): Constructor<InterfaceRegistry[K]> {
export function ClassOf<K extends InterfaceTypes> (name: K): Constructor<InterfaceRegistry[K]> {
return ClassOfUnsafe<Codec, K>(name) as Constructor<InterfaceRegistry[K]>;
}
// create an array of constructors from the input
export function getTypeClassMap (defs: TypeDef[]): { [index: string]: Constructor } {
return defs.reduce((result, sub): Record<string, Constructor> => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
result[sub.name as string] = getTypeClass(sub);
// create a maps of type string constructors from the input
export function getTypeClassMap (defs: TypeDef[]): Record<string, InterfaceTypes> {
return defs.reduce((result, sub): Record<string, InterfaceTypes> => {
result[sub.name as string] = sub.type as any;
return result;
}, {} as unknown as Record<string, Constructor>);
}, {} as unknown as Record<string, InterfaceTypes>);
}
// create an array of type string constructors from the input
export function getTypeClassArray (defs: TypeDef[]): (InterfaceTypes)[] {
return defs.map(({ type }): InterfaceTypes =>
type as any
);
}
// Returns the type Class for construction
@@ -224,19 +227,19 @@ export function getTypeClass<T extends Codec = Codec> (value: TypeDef, Fallback?
case TypeDefInfo.Compact:
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Compact');
return Compact.with(
getTypeClass<UInt>(value.sub as TypeDef)
(value.sub as TypeDef).type as any
) as unknown as Constructor<T>;
case TypeDefInfo.Enum:
assert(value.sub && Array.isArray(value.sub), 'Expected subtype for Enum');
return Enum.with(
getTypeClassMap(value.sub as TypeDef[])
getTypeClassMap(value.sub as TypeDef[]) as any
) as unknown as Constructor<T>;
case TypeDefInfo.Option:
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Option');
return Option.with(
getTypeClass(value.sub as TypeDef)
(value.sub as TypeDef).type as any
) as unknown as Constructor<T>;
case TypeDefInfo.Set:
@@ -258,7 +261,7 @@ export function getTypeClass<T extends Codec = Codec> (value: TypeDef, Fallback?
case TypeDefInfo.Tuple:
assert(Array.isArray(value.sub), 'Expected nested subtypes for Tuple');
return Tuple.with(
(value.sub as TypeDef[]).map((Type): Constructor<Codec> => getTypeClass(Type))
getTypeClassArray(value.sub as TypeDef[])
) as unknown as Constructor<T>;
case TypeDefInfo.Vec:
@@ -268,8 +271,8 @@ export function getTypeClass<T extends Codec = Codec> (value: TypeDef, Fallback?
return (
vsub.type === 'u8'
? Bytes
: Vec.with(getTypeClass<Codec>(vsub))
? ClassOf('Bytes')
: Vec.with(vsub.type as any)
) as unknown as Constructor<T>;
case TypeDefInfo.VecFixed:
@@ -280,13 +283,13 @@ export function getTypeClass<T extends Codec = Codec> (value: TypeDef, Fallback?
return (
ext.type === 'u8'
? U8aFixed.with((ext.length * 8) as U8aFixedBitLength)
: VecFixed.with(createClass<Codec>(ext.type), ext.length)
: VecFixed.with(ext.type as any, ext.length)
) as unknown as Constructor<T>;
case TypeDefInfo.Linkage:
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Linkage');
return Linkage.withKey(
getTypeClass<Codec>(value.sub as TypeDef)
(value.sub as TypeDef).type as any
) as unknown as Constructor<T>;
case TypeDefInfo.DoubleMap:
@@ -294,7 +297,7 @@ export function getTypeClass<T extends Codec = Codec> (value: TypeDef, Fallback?
return getTypeClass(value.sub as TypeDef);
case TypeDefInfo.Null:
return Null as unknown as Constructor<T>;
return ClassOf('Null') as unknown as Constructor<T>;
}
if (Fallback) {
@@ -367,7 +370,7 @@ export function createTypeUnsafe<T extends Codec = Codec, K extends string = str
* output's one. Slower, but ensures that we have a 100% grasp on the actual
* provided value
*/
export default function createType<K extends keyof InterfaceRegistry> (
export default function createType<K extends InterfaceTypes> (
type: K,
...params: any[]
): InterfaceRegistry[K] {
+1
View File
@@ -5,3 +5,4 @@
export { default as compareArray } from './compareArray';
export { default as compareMap } from './compareMap';
export { default as decodeU8a } from './decodeU8a';
export * from './mapToTypeMap';
@@ -0,0 +1,30 @@
// Copyright 2017-2019 @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 { Codec, Constructor, InterfaceTypes } from '../../types';
import { isString } from '@polkadot/util';
import { ClassOf } from '../createType';
export function typeToConstructor <T = Codec> (type: InterfaceTypes | Constructor<T>): Constructor<T> {
return (
isString(type)
? ClassOf(type as InterfaceTypes)
: type
) as Constructor<T>;
}
/**
* @description takes an input map of the form `{ [string]: string | Constructor }` and returns a map of `{ [string]: Conbstructor }`
*/
export function mapToTypeMap (input: Record<string, InterfaceTypes | Constructor>): Record<string, Constructor> {
const output: Record<string, Constructor> = {};
Object.entries(input).forEach(([key, type]): void => {
output[key] = typeToConstructor(type);
});
return output;
}
@@ -5,7 +5,6 @@
import { Hash, Index } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
import { ClassOf } from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import U8a from '../../../codec/U8a';
@@ -26,10 +25,10 @@ import { sign } from '../util';
export default class ExtrinsicPayloadV1 extends Struct {
public constructor (value?: ExtrinsicPayloadValue | Uint8Array | string) {
super({
nonce: ClassOf('Compact<Index>'),
nonce: 'Compact<Index>',
method: U8a,
era: ExtrinsicEra,
blockHash: ClassOf('Hash')
blockHash: 'Hash'
}, value);
}
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
import { ExtrinsicSignatureOptions } from '../types';
import createType, { ClassOf } from '../../../codec/createType';
import createType from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import Call from '../../Generic/Call';
@@ -27,9 +27,9 @@ export default class ExtrinsicSignatureV1 extends Struct implements IExtrinsicSi
// 1/2 bytes: The Transaction Era
public constructor (value?: ExtrinsicSignatureV1 | Uint8Array, { isSigned }: ExtrinsicSignatureOptions = {}) {
super({
signer: ClassOf('Address'),
signature: ClassOf('Signature'),
nonce: ClassOf('Compact<Index>'),
signer: 'Address',
signature: 'Signature',
nonce: 'Compact<Index>',
era: ExtrinsicEra
}, ExtrinsicSignatureV1.decodeExtrinsicSignature(value, isSigned));
}
@@ -5,7 +5,6 @@
import { Balance, Index } from '../../../interfaces/runtime';
import { ExtrinsicExtraValue } from '../types';
import { ClassOf } from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import Address from '../../Generic/Address';
@@ -20,8 +19,8 @@ export default class ExtrinsicExtraV2 extends Struct {
public constructor (value?: ExtrinsicExtraValue | Uint8Array) {
super({
era: ExtrinsicEra,
nonce: ClassOf('Compact<Index>'),
tip: ClassOf('Compact<Balance>')
nonce: 'Compact<Index>',
tip: 'Compact<Balance>'
}, value);
}
@@ -5,7 +5,6 @@
import { Balance, Hash, Index } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
import { ClassOf } from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import U8a from '../../../codec/U8a';
@@ -23,9 +22,9 @@ export default class ExtrinsicPayloadV2 extends Struct {
super({
method: U8a,
era: ExtrinsicEra,
nonce: ClassOf('Compact<Index>'),
tip: ClassOf('Compact<Balance>'),
blockHash: ClassOf('Hash')
nonce: 'Compact<Index>',
tip: 'Compact<Balance>',
blockHash: 'Hash'
}, value);
}
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
import { ExtrinsicSignatureOptions } from '../types';
import createType, { ClassOf } from '../../../codec/createType';
import createType from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import Call from '../../Generic/Call';
@@ -23,8 +23,8 @@ import ExtrinsicExtra from '../v2/ExtrinsicExtra';
export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSignature {
public constructor (value: ExtrinsicSignatureV2 | Uint8Array | undefined, { isSigned }: ExtrinsicSignatureOptions = {}) {
super({
signer: ClassOf('Address'),
signature: ClassOf('Signature'),
signer: 'Address',
signature: 'Signature',
extra: ExtrinsicExtra
}, ExtrinsicSignatureV2.decodeExtrinsicSignature(value, isSigned));
}
@@ -5,7 +5,6 @@
import { Balance, Hash, Index } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
import { ClassOf } from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import U8a from '../../../codec/U8a';
@@ -23,10 +22,10 @@ export default class ExtrinsicPayloadV3 extends Struct {
super({
method: U8a,
era: ExtrinsicEra,
nonce: ClassOf('Compact<Index>'),
tip: ClassOf('Compact<Balance>'),
genesisHash: ClassOf('Hash'),
blockHash: ClassOf('Hash')
nonce: 'Compact<Index>',
tip: 'Compact<Balance>',
genesisHash: 'Hash',
blockHash: 'Hash'
}, value);
}
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
import { ExtrinsicSignatureOptions } from '../types';
import createType, { ClassOf } from '../../../codec/createType';
import createType from '../../../codec/createType';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import Call from '../../Generic/Call';
@@ -23,8 +23,8 @@ import ExtrinsicExtra from '../v2/ExtrinsicExtra';
export default class ExtrinsicSignatureV3 extends Struct implements IExtrinsicSignature {
public constructor (value: ExtrinsicSignatureV3 | Uint8Array | undefined, { isSigned }: ExtrinsicSignatureOptions = {}) {
super({
signer: ClassOf('Address'),
signature: ClassOf('Signature'),
signer: 'Address',
signature: 'Signature',
extra: ExtrinsicExtra
}, ExtrinsicSignatureV3.decodeExtrinsicSignature(value, isSigned));
}
@@ -7,7 +7,7 @@ import { AnyNumber, AnyU8a } from '../../types';
import { blake2AsU8a } from '@polkadot/util-crypto';
import createType, { ClassOf } from '../../codec/createType';
import createType from '../../codec/createType';
import Extrinsic from '../Extrinsic/Extrinsic';
import Struct from '../../codec/Struct';
import Vec from '../../codec/Vec';
@@ -33,8 +33,8 @@ export interface BlockValue {
export default class Block extends Struct {
public constructor (value?: BlockValue | Uint8Array) {
super({
header: ClassOf('Header'),
extrinsics: ClassOf('Vec<Extrinsic>')
header: 'Header',
extrinsics: 'Vec<Extrinsic>'
}, value);
}
@@ -7,7 +7,6 @@ import { Consensus, Hash, PreRuntime, Seal, SealV0 } from '../../interfaces/runt
import { assert } from '@polkadot/util';
import { ClassOf } from '../../codec/createType';
import Enum from '../../codec/Enum';
import Struct from '../../codec/Struct';
import Vec from '../../codec/Vec';
@@ -21,13 +20,13 @@ import Bytes from '../Bytes';
export class DigestItem extends Enum {
public constructor (value: any) {
super({
Other: ClassOf('Bytes'), // 0
AuthoritiesChange: ClassOf('Vec<AuthorityId>'), // 1
ChangesTrieRoot: ClassOf('Hash'), // 2
SealV0: ClassOf('SealV0'), // 3
Consensus: ClassOf('Consensus'), // 4
Seal: ClassOf('Seal'), // 5
PreRuntime: ClassOf('PreRuntime') // 6
Other: 'Bytes', // 0
AuthoritiesChange: 'Vec<AuthorityId>', // 1
ChangesTrieRoot: 'Hash', // 2
SealV0: 'SealV0', // 3
Consensus: 'Consensus', // 4
Seal: 'Seal', // 5
PreRuntime: 'PreRuntime' // 6
}, value);
}
@@ -8,7 +8,7 @@ import { Constructor, Codec } from '../../types';
import { assert, isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util';
import { ClassOf, getTypeClass, getTypeDef } from '../../codec/createType';
import { getTypeClass, getTypeDef } from '../../codec/createType';
import Struct from '../../codec/Struct';
import Tuple from '../../codec/Tuple';
import Metadata from '../../Metadata';
@@ -83,7 +83,7 @@ export default class Event extends Struct {
const { DataType, value } = Event.decodeEvent(_value);
super({
index: ClassOf('EventId'),
index: 'EventId',
data: DataType
}, value);
}
+3
View File
@@ -8,12 +8,15 @@ import BN from 'bn.js';
import Compact from './codec/Compact';
import U8a from './codec/U8a';
import { InterfaceRegistry } from './interfaceRegistry';
import { FunctionMetadata } from './Metadata/v7/Calls';
import Call from './primitive/Generic/Call';
import Address from './primitive/Generic/Address';
export * from './codec/types';
export type InterfaceTypes = keyof InterfaceRegistry;
export interface CallFunction {
(...args: any[]): Call;
callIndex: Uint8Array;