diff --git a/packages/types/src/AccountId.ts b/packages/types/src/AccountId.ts index fa3ba51947..fb642e79a0 100644 --- a/packages/types/src/AccountId.ts +++ b/packages/types/src/AccountId.ts @@ -2,12 +2,11 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { AnyU8a } from './types'; +import { AnyString, AnyU8a } from './types'; import { decodeAddress, encodeAddress } from '@polkadot/keyring'; -import { hexToU8a, isHex, isU8a, u8aToU8a } from '@polkadot/util'; +import { hexToU8a, isHex, isString, isU8a, u8aToU8a } from '@polkadot/util'; -import U8a from './codec/U8a'; import U8aFixed from './codec/U8aFixed'; // A wrapper around an AccountId/PublicKey representation. Since we are dealing with @@ -25,16 +24,16 @@ export default class AccountId extends U8aFixed { return encodeAddress(value); } - static decodeAccountId (value: AnyU8a): Uint8Array { - if (value instanceof U8a) { - return value.raw; - } else if (isU8a(value) || Array.isArray(value)) { + private static decodeAccountId (value: AnyU8a | AnyString): Uint8Array { + if (isU8a(value) || Array.isArray(value)) { return u8aToU8a(value); } else if (isHex(value)) { - return hexToU8a(value); + return hexToU8a(value.toString()); + } else if (isString(value)) { + return decodeAddress((value as AnyString).toString()); } - return decodeAddress(value); + return value; } toJSON (): any { @@ -42,6 +41,6 @@ export default class AccountId extends U8aFixed { } toString (): string { - return AccountId.encode(this.raw); + return AccountId.encode(this); } } diff --git a/packages/types/src/AccountIndex.ts b/packages/types/src/AccountIndex.ts index 9ed0e01750..3b9ad6b836 100644 --- a/packages/types/src/AccountIndex.ts +++ b/packages/types/src/AccountIndex.ts @@ -7,7 +7,6 @@ import { decodeAddress, encodeAddress } from '@polkadot/keyring'; import { bnToBn, bnToU8a, isBn, isNumber, isU8a, isHex, hexToU8a, u8aToHex } from '@polkadot/util'; import { AnyNumber } from './types'; -import U8a from './codec/U8a'; import UInt from './codec/UInt'; import U32 from './U32'; @@ -34,8 +33,6 @@ export default class AccountIndex extends U32 { static decodeAccountIndex (value: AnyNumber): BN | Uint8Array | number | string { if (value instanceof UInt) { return value.raw; - } else if (value instanceof U8a) { - return AccountIndex.decodeAccountIndex(value.raw); } else if (isBn(value) || isNumber(value) || isU8a(value)) { return value; } else if (isHex(value)) { diff --git a/packages/types/src/Address.ts b/packages/types/src/Address.ts index fb566c82e3..c5e2b8aab9 100644 --- a/packages/types/src/Address.ts +++ b/packages/types/src/Address.ts @@ -7,7 +7,6 @@ import { decodeAddress } from '@polkadot/keyring'; import { hexToU8a, isBn, isHex, isNumber, isU8a, u8aConcat, u8aToHex, u8aToU8a, u8aToBn } from '@polkadot/util'; import Base from './codec/Base'; -import U8a from './codec/U8a'; import AccountId from './AccountId'; import AccountIndex from './AccountIndex'; @@ -34,8 +33,6 @@ export default class Address extends Base { return value.raw; } else if (value instanceof AccountId || value instanceof AccountIndex) { return value; - } else if (value instanceof U8a) { - return Address.decodeAddress(value.raw); } else if (Array.isArray(value)) { return Address.decodeAddress(u8aToU8a(value)); } else if (isU8a(value)) { diff --git a/packages/types/src/Bool.ts b/packages/types/src/Bool.ts index 4b4f243c43..0ffafddf9a 100644 --- a/packages/types/src/Bool.ts +++ b/packages/types/src/Bool.ts @@ -5,10 +5,9 @@ import { isU8a } from '@polkadot/util'; import Base from './codec/Base'; -import U8a from './codec/U8a'; export default class Bool extends Base { - constructor (value: Bool | U8a | Boolean | Uint8Array | boolean = false) { + constructor (value: Bool | Boolean | Uint8Array | boolean = false) { super( Bool.decodeBool(value) ); @@ -17,8 +16,6 @@ export default class Bool extends Base { static decodeBool (value: any): boolean { if (value instanceof Bool || value instanceof Boolean) { return value.valueOf(); - } else if (value instanceof U8a) { - return Bool.decodeBool(value.raw); } else if (isU8a(value)) { return value[0] === 1; } diff --git a/packages/types/src/Bytes.ts b/packages/types/src/Bytes.ts index 79b3b242c7..951ad5dbe7 100644 --- a/packages/types/src/Bytes.ts +++ b/packages/types/src/Bytes.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { hexToU8a, isHex, isU8a, u8aConcat, u8aToU8a } from '@polkadot/util'; +import { hexToU8a, isHex, isString, isU8a, u8aConcat, u8aToU8a } from '@polkadot/util'; import { AnyU8a } from './types'; import Compact, { DEFAULT_LENGTH_BITS } from './codec/Compact'; @@ -16,10 +16,8 @@ export default class Bytes extends U8a { super(Bytes.decodeBytes(value)); } - static decodeBytes (value: AnyU8a): Uint8Array { - if (value instanceof U8a) { - return value.raw; - } else if (isHex(value)) { + private static decodeBytes (value: AnyU8a): Uint8Array { + if (isHex(value)) { // FIXME We manually add the length prefix for hex for now // https://github.com/paritytech/substrate/issues/889 const u8a = hexToU8a(value); @@ -31,13 +29,11 @@ export default class Bytes extends U8a { const [offset, length] = Compact.decodeU8a(value, DEFAULT_LENGTH_BITS); return value.subarray(offset, offset + length.toNumber()); + } else if (Array.isArray(value) || isString(value)) { + return Bytes.decodeBytes(u8aToU8a(value)); } - return Bytes.decodeBytes(u8aToU8a(value)); - } - - get length (): number { - return this.raw.length; + return value; } get encodedLength (): number { @@ -46,10 +42,10 @@ export default class Bytes extends U8a { toU8a (isBare?: boolean): Uint8Array { return isBare - ? this.raw + ? this : u8aConcat( Compact.encodeU8a(this.length, DEFAULT_LENGTH_BITS), - this.raw + this ); } } diff --git a/packages/types/src/Event.ts b/packages/types/src/Event.ts index dc08367f14..82f5c65773 100644 --- a/packages/types/src/Event.ts +++ b/packages/types/src/Event.ts @@ -8,7 +8,6 @@ import { isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util'; import Struct from './codec/Struct'; import Tuple from './codec/Tuple'; -import U8a from './codec/U8a'; import U8aFixed from './codec/U8aFixed'; import { TypeDef, getTypeClass, getTypeDef } from './codec/createType'; import Metadata, { EventMetadata } from './Metadata'; @@ -57,7 +56,7 @@ class EventIndex extends U8aFixed { export default class Event extends Struct { // Currently we _only_ decode from Uint8Array, since we expect it to // be used via EventRecord - constructor (_value: Uint8Array | U8a) { + constructor (_value: Uint8Array) { const { DataType, value } = Event.decodeEvent(_value); super({ @@ -66,10 +65,7 @@ export default class Event extends Struct { }, value); } - static decodeEvent (_value: U8a | Uint8Array) { - const value = _value instanceof U8a - ? _value.raw - : _value; + static decodeEvent (value: Uint8Array) { const index = value.subarray(0, 2); const DataType = EventTypes[index.toString()]; diff --git a/packages/types/src/Extrinsic.ts b/packages/types/src/Extrinsic.ts index 54ea21ea38..0f86dd6077 100644 --- a/packages/types/src/Extrinsic.ts +++ b/packages/types/src/Extrinsic.ts @@ -11,7 +11,6 @@ import { blake2AsU8a } from '@polkadot/util-crypto'; import Base from './codec/Base'; import Compact, { DEFAULT_LENGTH_BITS } from './codec/Compact'; import Struct from './codec/Struct'; -import U8a from './codec/U8a'; import ExtrinsicSignature from './ExtrinsicSignature'; import Hash from './Hash'; import { FunctionMetadata } from './Metadata'; @@ -45,8 +44,6 @@ export default class Extrinsic extends Struct { return {}; } else if (value instanceof Extrinsic) { return value.raw; - } else if (value instanceof U8a) { - return Extrinsic.decodeExtrinsic(value.raw); } else if (isHex(value)) { // FIXME We manually add the length prefix for hex for now // https://github.com/paritytech/substrate/issues/889 diff --git a/packages/types/src/ExtrinsicEra.ts b/packages/types/src/ExtrinsicEra.ts index 830c0fd28d..416cbda11b 100644 --- a/packages/types/src/ExtrinsicEra.ts +++ b/packages/types/src/ExtrinsicEra.ts @@ -16,9 +16,7 @@ export default class ExtrinsicEra extends U8a { } static decodeExtrinsicEra (value?: AnyU8a): Uint8Array { - if (value instanceof U8a) { - return value.raw; - } else if (value) { + if (value) { const u8a = u8aToU8a(value); // If we have a zero byte, it is immortal (1 byte in length), otherwise we have diff --git a/packages/types/src/ExtrinsicSignature.ts b/packages/types/src/ExtrinsicSignature.ts index 27b09fbb61..7eb274b3c7 100644 --- a/packages/types/src/ExtrinsicSignature.ts +++ b/packages/types/src/ExtrinsicSignature.ts @@ -8,7 +8,6 @@ import { AnyNumber, AnyU8a } from './types'; import { isU8a, u8aConcat } from '@polkadot/util'; import Struct from './codec/Struct'; -import U8a from './codec/U8a'; import Address from './Address'; import ExtrinsicEra from './ExtrinsicEra'; import Method from './Method'; @@ -35,7 +34,7 @@ const BIT_VERSION = 0b0000001; // 8 bytes: The Transaction Index of the signing account // 1/2 bytes: The Transaction Era export default class ExtrinsicSignature extends Struct { - constructor (value?: ExtrinsicSignatureValue | U8a | Uint8Array) { + constructor (value?: ExtrinsicSignatureValue | Uint8Array) { super({ signer: Address, signature: Signature, @@ -49,8 +48,6 @@ export default class ExtrinsicSignature extends Struct { return {}; } else if (value instanceof Struct) { return value.raw; - } else if (value instanceof U8a) { - return ExtrinsicSignature.decodeExtrinsicSignature(value.raw); } else if (isU8a(value)) { const version = value[0]; diff --git a/packages/types/src/Method.ts b/packages/types/src/Method.ts index 550b329f88..0a7feb837f 100644 --- a/packages/types/src/Method.ts +++ b/packages/types/src/Method.ts @@ -6,7 +6,6 @@ import { ExtrinsicFunction, Extrinsics } from '@polkadot/extrinsics/types'; import { assert, isHex, isObject, isU8a } from '@polkadot/util'; import Base from './codec/Base'; -import U8a from './codec/U8a'; import { AnyU8a, Constructor } from './types'; import { FunctionMetadata, FunctionArgumentMetadata } from './Metadata'; import { getTypeDef, getTypeClass } from './codec/createType'; @@ -68,10 +67,8 @@ export default class Method extends Struct { * @param _meta - Metadata to use, so that `injectExtrinsics` lookup is not * necessary. */ - private static decodeMethod (value: DecodedMethod | U8a | Uint8Array | string, _meta?: FunctionMetadata): DecodedMethod { - if (value instanceof U8a) { - return Method.decodeMethod(value.raw); - } else if (isHex(value)) { + private static decodeMethod (value: DecodedMethod | Uint8Array | string, _meta?: FunctionMetadata): DecodedMethod { + if (isHex(value)) { return Method.decodeMethod(value, _meta); } else if (isU8a(value)) { // The first 2 bytes are the callIndex diff --git a/packages/types/src/Moment.ts b/packages/types/src/Moment.ts index 3f87953152..fbc6cf6224 100644 --- a/packages/types/src/Moment.ts +++ b/packages/types/src/Moment.ts @@ -6,7 +6,6 @@ import BN from 'bn.js'; import { bnToBn, bnToHex, bnToU8a, isString, isU8a, u8aToBn } from '@polkadot/util'; import Base from './codec/Base'; -import U8a from './codec/U8a'; import UInt, { UIntBitLength } from './codec/UInt'; import { AnyNumber } from './types'; @@ -30,8 +29,6 @@ export default class Moment extends Base { return new Date(Math.ceil(value.getTime() / 1000) * 1000); } else if (value instanceof UInt) { value = value.toBn(); - } else if (value instanceof U8a) { - return Moment.decodeMoment(value.raw); } else if (isU8a(value)) { value = u8aToBn(value.subarray(0, BITLENGTH / 8), true); } else if (isString(value)) { diff --git a/packages/types/src/StorageKey.ts b/packages/types/src/StorageKey.ts index 1eeaaae47b..f53ce1fd74 100644 --- a/packages/types/src/StorageKey.ts +++ b/packages/types/src/StorageKey.ts @@ -6,7 +6,6 @@ import { AnyU8a } from './types'; import { isFunction } from '@polkadot/util'; -import U8a from './codec/U8a'; import Bytes from './Bytes'; import { StorageFunctionMetadata } from './Metadata'; @@ -38,8 +37,6 @@ export default class StorageKey extends Bytes { if (isFunction(fn)) { return fn(arg); } - } else if (value instanceof U8a) { - return StorageKey.decodeStorageKey(value.raw); } return value as Uint8Array; diff --git a/packages/types/src/Text.ts b/packages/types/src/Text.ts index 003507ab8e..72ac20cb59 100644 --- a/packages/types/src/Text.ts +++ b/packages/types/src/Text.ts @@ -7,7 +7,6 @@ import { isFunction, isString, stringToU8a, u8aToString, u8aConcat } from '@polk import { AnyU8a } from '@polkadot/types/types'; import Base from './codec/Base'; import Compact, { DEFAULT_LENGTH_BITS } from './codec/Compact'; -import U8a from './codec/U8a'; // This is a string wrapper, along with the length. It is used both for strings as well // as stuff like documentation. @@ -33,8 +32,6 @@ export default class Text extends Base { const [offset, length] = Compact.decodeU8a(value, DEFAULT_LENGTH_BITS); return u8aToString(value.subarray(offset, offset + length.toNumber())); - } else if (value instanceof U8a) { - return Text.decodeText(value.raw); } else if (isFunction(value.toString)) { return value.toString(); } diff --git a/packages/types/src/codec/Compact.ts b/packages/types/src/codec/Compact.ts index d1ab1cef32..8fef4a395f 100644 --- a/packages/types/src/codec/Compact.ts +++ b/packages/types/src/codec/Compact.ts @@ -7,7 +7,6 @@ import { bnToBn, bnToU8a, hexToBn, isBn, isHex, isNumber, isString, isU8a, u8aTo import { AnyNumber, Constructor } from '../types'; import Base from './Base'; -import U8a from './U8a'; import UInt, { UIntBitLength } from './UInt'; import Moment from '../Moment'; @@ -64,9 +63,7 @@ export default class Compact extends Base { } static decodeCompact (Type: Constructor, value: AnyNumber): Moment | UInt { - if (value instanceof U8a) { - return Compact.decodeCompact(Type, value.raw); - } else if (isString(value)) { + if (isString(value)) { return new Type( isHex(value) ? hexToBn(value) diff --git a/packages/types/src/codec/Enum.ts b/packages/types/src/codec/Enum.ts index da5659ad93..53582ed55e 100644 --- a/packages/types/src/codec/Enum.ts +++ b/packages/types/src/codec/Enum.ts @@ -5,7 +5,6 @@ import { isU8a } from '@polkadot/util'; import Base from './Base'; -import U8a from './U8a'; type EnumDef = { [index: number]: string @@ -21,7 +20,7 @@ type EnumDef = { export default class Enum extends Base { private _enum: EnumDef; - constructor (def: EnumDef, value: Enum | U8a | Uint8Array | number = 0) { + constructor (def: EnumDef, value: Enum | Uint8Array | number = 0) { super( Enum.decodeEnum(value) ); @@ -29,11 +28,9 @@ export default class Enum extends Base { this._enum = def; } - static decodeEnum (value: Enum | U8a | Uint8Array | number = 0): number { + static decodeEnum (value: Enum | Uint8Array | number = 0): number { if (value instanceof Enum) { return value.raw; - } else if (value instanceof U8a) { - return Enum.decodeEnum(value.raw); } else if (isU8a(value)) { return value[0]; } else { diff --git a/packages/types/src/codec/EnumType.ts b/packages/types/src/codec/EnumType.ts index d8734fe2b6..56cace92ba 100644 --- a/packages/types/src/codec/EnumType.ts +++ b/packages/types/src/codec/EnumType.ts @@ -5,7 +5,6 @@ import { isNumber, isObject, isU8a, isUndefined, u8aConcat } from '@polkadot/util'; import Base from './Base'; -import U8a from './U8a'; import Null from '../Null'; import { Constructor } from '../types'; @@ -52,9 +51,7 @@ export default class EnumType extends Base> { } // Or else, we just look at `value` - if (value instanceof U8a) { - return EnumType.decodeEnumType(def, value.raw, index); - } else if (isU8a(value)) { + if (isU8a(value)) { return { index: value[0], value: new def[value[0]](value.subarray(1)) }; } else if (isNumber(value) && !isUndefined(def[value])) { return { index: value, value: new def[value]() }; diff --git a/packages/types/src/codec/Set.ts b/packages/types/src/codec/Set.ts index bae8cca29f..bc56361bca 100644 --- a/packages/types/src/codec/Set.ts +++ b/packages/types/src/codec/Set.ts @@ -5,7 +5,6 @@ import { isU8a, isUndefined } from '@polkadot/util'; import Base from './Base'; -import U8a from './U8a'; type SetValues = { [index: string]: number @@ -18,7 +17,7 @@ type SetValues = { export default class Set extends Base> { private _setValues: SetValues; - constructor (setValues: SetValues, value?: U8a | Array | Uint8Array | number) { + constructor (setValues: SetValues, value?: Array | Uint8Array | number) { super( Set.decodeSet(setValues, value) ); @@ -26,10 +25,8 @@ export default class Set extends Base> { this._setValues = setValues; } - static decodeSet (setValues: SetValues, value: U8a | Array | Uint8Array | number = 0): Array { - if (value instanceof U8a) { - return Set.decodeSet(setValues, value.raw); - } else if (isU8a(value)) { + static decodeSet (setValues: SetValues, value: Array | Uint8Array | number = 0): Array { + if (isU8a(value)) { return Set.decodeSet(setValues, value[0]); } else if (Array.isArray(value)) { return value.reduce((result, value) => { diff --git a/packages/types/src/codec/Struct.ts b/packages/types/src/codec/Struct.ts index 2444297d8d..f2144d6a18 100644 --- a/packages/types/src/codec/Struct.ts +++ b/packages/types/src/codec/Struct.ts @@ -5,7 +5,6 @@ import { hexToU8a, isHex, isObject, isU8a, u8aConcat, u8aToHex } from '@polkadot/util'; import Base from './Base'; -import U8a from './U8a'; import { Codec, Constructor, ConstructorDef } from '../types'; // A Struct defines an Object with key/values - where the values are Base values. It removes @@ -22,7 +21,7 @@ export default class Struct< V extends { [K in keyof S]: any } = { [K in keyof S]: any }, // type names, mapped by key, name of Class in S E extends { [K in keyof S]: string } = { [K in keyof S]: string } -> extends Map implements Codec { + > extends Map implements Codec { public raw: Map; // FIXME Remove this once we convert all types out of Base protected _jsonMap: Map; protected _Types: E; @@ -66,12 +65,10 @@ export default class Struct< S extends ConstructorDef, _, T extends { [K in keyof S]: Base } - > (Types: S, value: any, jsonMap: Map): T { + > (Types: S, value: any, jsonMap: Map): T { // l.debug(() => ['Struct.decode', { Types, value }]); - if (value instanceof U8a) { - return Struct.decodeStruct(Types, value.raw, jsonMap); - } else if (isHex(value)) { + if (isHex(value)) { return Struct.decodeStruct(Types, hexToU8a(value as string), jsonMap); } else if (!value) { return {} as T; @@ -115,7 +112,7 @@ export default class Struct< static with< S extends ConstructorDef - > (Types: S): Constructor> { + > (Types: S): Constructor> { return class extends Struct { constructor (value?: any, jsonMap?: Map) { super(Types, value, jsonMap); diff --git a/packages/types/src/codec/U8a.spec.js b/packages/types/src/codec/U8a.spec.ts similarity index 69% rename from packages/types/src/codec/U8a.spec.js rename to packages/types/src/codec/U8a.spec.ts index 332f4541bc..c35d5d97fd 100644 --- a/packages/types/src/codec/U8a.spec.js +++ b/packages/types/src/codec/U8a.spec.ts @@ -2,28 +2,29 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. +import { CodecTo } from '../types'; import U8a from './U8a'; -const testDecode = (type, input, expected) => +const testDecode = (type: string, input: any, expected: string) => it(`can decode from ${type}`, () => { const e = new U8a(input); expect(e.toString()).toBe(expected); }); -const testEncode = (to, expected) => +const testEncode = (to: CodecTo, expected: any) => it(`can encode ${to}`, () => { const e = new U8a([1, 2, 3, 4, 5]); expect(e[to]()).toEqual(expected); }); describe('U8a', () => { - let u8a; + let u8a: U8a; beforeEach(() => { u8a = new U8a([1, 2, 3, 4, 5]); }); - testDecode('Array', [1, 2, 3, 4, 5], '0x0102030405') + testDecode('Array', [1, 2, 3, 4, 5], '0x0102030405'); testDecode('hex', '0x0102030405', '0x0102030405'); testDecode('U8a', new Uint8Array([1, 2, 3, 4, 5]), '0x0102030405'); testDecode('Uint8Array', Uint8Array.from([1, 2, 3, 4, 5]), '0x0102030405'); @@ -34,12 +35,20 @@ describe('U8a', () => { testEncode('toU8a', Uint8Array.from([1, 2, 3, 4, 5])); it('contains the length of the elements', () => { - expect(u8a.length).toEqual(5); // eslint-disable-line + expect(u8a.length).toEqual(5); + }); + + it('correctly encodes length', () => { + expect(u8a.encodedLength).toEqual(5); }); it('allows wrapping of a pre-existing instance', () => { expect( new U8a(u8a).length - ).toEqual(5); // eslint-disable-line + ).toEqual(5); + }); + + it('implements subarray correctly', () => { + expect(u8a.subarray(1, 3).toString()).toEqual('0x0203'); }); }); diff --git a/packages/types/src/codec/U8a.ts b/packages/types/src/codec/U8a.ts index deefac328b..04ff2a2c44 100644 --- a/packages/types/src/codec/U8a.ts +++ b/packages/types/src/codec/U8a.ts @@ -4,40 +4,44 @@ import { isU8a, u8aToHex, u8aToU8a } from '@polkadot/util'; -import { AnyU8a } from '../types'; -import Base from './Base'; +import { AnyU8a, Codec } from '../types'; // A U8a. A basic wrapper around Uint8Array, with no frills and no fuss. It // wraps a Uint8Array. It does differ from other implementations wher it will // consume the full u8a as passed to it in U8a. As such it is meant to be // subclassed where the wrapper takes care of the actual lengths. -export default class U8a extends Base { - constructor (value: AnyU8a = new Uint8Array()) { - super( - U8a.decodeU8a(value) - ); +export default class U8a extends Uint8Array implements Codec { + public raw: Uint8Array; // FIXME Remove this once we convert all types out of Base + + constructor (value: AnyU8a | ArrayBuffer, byteOffset: number = 0, length?: number) { + // Uint8Array can be constructed with ArrayBuffer, in which case it has 1 + // or 2 more optional arguments. We handle this special case here. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array + if (value instanceof ArrayBuffer) { + super(value, byteOffset, length); + } else { + super( + U8a.decodeU8a(value) + ); + } + + this.raw = this; } - static decodeU8a (value: any): Uint8Array { + private static decodeU8a (value: any): Uint8Array { if (isU8a(value)) { return value; - } else if (value instanceof U8a) { - return value.raw; } else { return u8aToU8a(value); } } - get length (): number { - return this.raw.length; - } - get encodedLength (): number { return this.length; } toHex (): string { - return u8aToHex(this.raw); + return u8aToHex(this); } toJSON (): any { @@ -45,7 +49,7 @@ export default class U8a extends Base { } toU8a (isBare?: boolean): Uint8Array { - return this.raw; + return Uint8Array.from(this); } toString (): string { diff --git a/packages/types/src/codec/U8aFixed.spec.js b/packages/types/src/codec/U8aFixed.spec.ts similarity index 80% rename from packages/types/src/codec/U8aFixed.spec.js rename to packages/types/src/codec/U8aFixed.spec.ts index 912b9378dd..6d633e1973 100644 --- a/packages/types/src/codec/U8aFixed.spec.js +++ b/packages/types/src/codec/U8aFixed.spec.ts @@ -5,14 +5,18 @@ import U8aFixed from './U8aFixed'; describe('U8aFixed', () => { - let u8a; + let u8a: U8aFixed; beforeEach(() => { u8a = new U8aFixed([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 32); }); it('limits the length', () => { - expect(u8a.length).toEqual(4); // eslint-disable-line + expect(u8a.length).toEqual(4); + }); + + it('exposes the correct bitLength', () => { + expect(u8a.bitLength).toEqual(32); }); it('allows wrapping of a pre-existing instance', () => { diff --git a/packages/types/src/codec/U8aFixed.ts b/packages/types/src/codec/U8aFixed.ts index d40ce5627b..1d8d2e7f56 100644 --- a/packages/types/src/codec/U8aFixed.ts +++ b/packages/types/src/codec/U8aFixed.ts @@ -2,6 +2,8 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. +import { isString, isU8a, u8aToU8a } from '@polkadot/util'; + import { AnyU8a } from '../types'; import U8a from './U8a'; @@ -11,25 +13,23 @@ type BitLength = 8 | 16 | 32 | 64 | 128 | 256 | 512; // A U8a that manages a a sequence of bytes up to the specified bitLength. Not meant // to be used directly, rather is should be subclassed with the specific lengths. export default class U8aFixed extends U8a { - protected _bitLength: number; - constructor (value: AnyU8a = new Uint8Array(), bitLength: BitLength = 256) { - super(value); - - this._bitLength = bitLength; - - this._trim(); + super( + U8aFixed.decodeU8aFixed(value, bitLength) + ); } - private _trimLength (): number { - return this._bitLength / 8; + private static decodeU8aFixed (value: AnyU8a, bitLength: BitLength = 256): AnyU8a { + if (isU8a(value)) { + return value.subarray(0, bitLength / 8); + } else if (Array.isArray(value) || isString(value)) { + return U8aFixed.decodeU8aFixed(u8aToU8a(value), bitLength); + } + + return value; } - private _trim (): void { - this.raw = this.raw.subarray(0, this._trimLength()); - } - - get encodedLength (): number { - return this._trimLength(); + get bitLength () { + return this.length * 8; } } diff --git a/packages/types/src/codec/UInt.ts b/packages/types/src/codec/UInt.ts index f2e6fbfed5..12a4adf307 100644 --- a/packages/types/src/codec/UInt.ts +++ b/packages/types/src/codec/UInt.ts @@ -8,7 +8,6 @@ import BN from 'bn.js'; import { bnToBn, bnToHex, bnToU8a, hexToBn, isHex, isString, isU8a, u8aToBn } from '@polkadot/util'; import Base from './Base'; -import U8a from './U8a'; export type UIntBitLength = 8 | 16 | 32 | 64 | 128 | 256; @@ -36,8 +35,6 @@ export default class UInt extends Base { static decodeUInt (value: AnyNumber, bitLength: UIntBitLength): BN { if (value instanceof UInt) { return value.raw; - } else if (value instanceof U8a) { - return UInt.decodeUInt(value.raw, bitLength); } else if (isHex(value)) { return hexToBn(value); } else if (isU8a(value)) { diff --git a/packages/types/src/codec/Vector.ts b/packages/types/src/codec/Vector.ts index 3405459115..b8d2d02232 100644 --- a/packages/types/src/codec/Vector.ts +++ b/packages/types/src/codec/Vector.ts @@ -6,7 +6,6 @@ import { u8aConcat, u8aToU8a } from '@polkadot/util'; import Base from './Base'; import Compact, { DEFAULT_LENGTH_BITS } from './Compact'; -import U8a from './U8a'; import { Constructor } from '../types'; // This manages codec arrays. Intrernally it keeps track of the length (as decoded) and allows @@ -19,7 +18,7 @@ export default class Vector< > extends Base> { private _Type: Constructor; - constructor (Type: Constructor, value: Vector | U8a | Uint8Array | string | Array = [] as Array) { + constructor (Type: Constructor, value: Vector | Uint8Array | string | Array = [] as Array) { super( Vector.decodeVector(Type, value) ); @@ -27,7 +26,7 @@ export default class Vector< this._Type = Type; } - static decodeVector (Type: Constructor, value: Vector | U8a | Uint8Array | string | Array): Array { + static decodeVector (Type: Constructor, value: Vector | Uint8Array | string | Array): Array { if (Array.isArray(value)) { return value.map((entry) => entry instanceof Type @@ -38,9 +37,7 @@ export default class Vector< return Vector.decodeVector(Type, value.raw); } - const u8a = value instanceof U8a - ? value.raw - : u8aToU8a(value); + const u8a = u8aToU8a(value); let [offset, _length] = Compact.decodeU8a(u8a, DEFAULT_LENGTH_BITS); const length = _length.toNumber(); diff --git a/packages/types/src/types.d.ts b/packages/types/src/types.d.ts index a3c9ecddcf..9779261ee2 100644 --- a/packages/types/src/types.d.ts +++ b/packages/types/src/types.d.ts @@ -6,11 +6,13 @@ import BN from 'bn.js'; import * as Classes from './index'; import Base from './codec/Base'; -import { U8a, UInt } from './codec'; +import { UInt } from './codec'; -export type AnyNumber = U8a | UInt | BN | Uint8Array | number | string; +export type AnyNumber = UInt | BN | Uint8Array | number | string; -export type AnyU8a = U8a | Uint8Array | Array | string; +export type AnyString = string | String; + +export type AnyU8a = Uint8Array | Array | string; export interface Codec { encodedLength: number;