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:
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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[] {
|
||||
|
||||
@@ -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] {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user