SignedExtension injection into payload (#1778)

* Make a start ... V11 definitions

* V11 conversion

* Fix ErrorMetadataV11

* Extension point for signed extensions

* Add V11 to mapped

* Expand toLatest comments

* Make a start at signer extension defs

* exports

* Extract extension definitions

* Add extension registration

* Remove old override

* Get definition on extrinsic creation

* Add missing V4 base

* Optional extrinsic

* Pull extrinsic version from metadata (if available)

* asLatest.extrinsic should now be available

* Don't export non-types for Extrinsic

* Setup registry with default extensions

* Async test really runs async

* Trace test failures (V1 orig, V4 now)

* CHANGELOG

* Add extension data to actual signature

* Cleanups

* Return cleanups

* Mark all type deocde static internal

* Apply extensions fully to payload

* Cleanup duplication

* ExtrinsicSignature* via createType
This commit is contained in:
Jaco Greeff
2020-02-01 14:17:17 +01:00
committed by GitHub
parent 5f8c623179
commit b24a1ff350
59 changed files with 359 additions and 153 deletions
+2
View File
@@ -39,6 +39,7 @@ export default abstract class AbstractInt extends BN implements Codec {
this._isNegative = isNegative;
}
/** @internal */
public static decodeAbstracInt (value: AnyNumber, bitLength: UIntBitLength, isNegative: boolean): string {
// This function returns a string, which will be passed in the BN
// constructor. It would be ideal to actually return a BN, but there's a
@@ -54,6 +55,7 @@ export default abstract class AbstractInt extends BN implements Codec {
return bnToBn(value).toString();
}
/** @internal */
private static decodeAbstracIntU8a (value: Uint8Array, bitLength: UIntBitLength, isNegative: boolean): string {
if (!value.length) {
return '0';
+3
View File
@@ -42,6 +42,7 @@ export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec>
* - Map<any, any>, where both key and value types are either
* constructors or decodeable values for their types.
* @param jsonMap
* @internal
*/
private static decodeBTreeMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Uint8Array | string | Map<any, any>): Map<K, V> {
if (!value) {
@@ -57,6 +58,7 @@ export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec>
throw new Error('BTreeMap: cannot decode type');
}
/** @internal */
private static decodeBTreeMapFromU8a<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, u8a: Uint8Array): Map<K, V> {
const output = new Map<K, V>();
const [offset, length] = Compact.decodeU8a(u8a);
@@ -75,6 +77,7 @@ export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec>
return output;
}
/** @internal */
private static decodeBTreeMapFromMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Map<any, any>): Map<K, V> {
const output = new Map<K, V>();
+3
View File
@@ -37,6 +37,7 @@ export default class BTreeSet<V extends Codec = Codec> extends Set<V> implements
* - Set<any>, where both key and value types are either
* constructors or decodeable values for their types.
* @param jsonSet
* @internal
*/
private static decodeBTreeSet<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, value: Uint8Array | string | Set<any>): Set<V> {
if (!value) {
@@ -52,6 +53,7 @@ export default class BTreeSet<V extends Codec = Codec> extends Set<V> implements
throw new Error('BTreeSet: cannot decode type');
}
/** @internal */
private static decodeBTreeSetFromU8a<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, u8a: Uint8Array): Set<V> {
const output = new Set<V>();
const [offset, length] = Compact.decodeU8a(u8a);
@@ -70,6 +72,7 @@ export default class BTreeSet<V extends Codec = Codec> extends Set<V> implements
return output;
}
/** @internal */
private static decodeBTreeSetFromSet<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, value: Set<any>): Set<V> {
const output = new Set<V>();
+1
View File
@@ -56,6 +56,7 @@ export default class Compact<T extends CompactEncodable> extends Base<T> impleme
return value;
}
/** @internal */
public static decodeCompact<T extends CompactEncodable> (registry: Registry, Type: Constructor<T>, value: Compact<T> | AnyNumber): CompactEncodable {
if (value instanceof Compact) {
return new Type(registry, value.raw);
+1
View File
@@ -35,6 +35,7 @@ export default class CodecDate extends Date implements Codec {
this.raw = this;
}
/** @internal */
public static decodeDate (value: CodecDate | Date | AnyNumber): Date {
if (value instanceof Date) {
return value;
+1
View File
@@ -121,6 +121,7 @@ export default class Enum extends Base<Codec> {
this._index = this._indexes.indexOf(decoded.index) || 0;
}
/** @internal */
private static decodeEnum (registry: Registry, def: TypesDef, value?: any, index?: number): Decoded {
// NOTE We check the index path first, before looking at values - this allows treating
// the optional indexes before anything else, more-specific > less-specific
+2
View File
@@ -29,6 +29,7 @@ export default class Option<T extends Codec> extends Base<T> {
this._Type = Clazz;
}
/** @internal */
public static decodeOption (registry: Registry, Type: Constructor, value?: any): Codec {
if (isNull(value) || isUndefined(value) || value instanceof Null) {
return new Null(registry);
@@ -46,6 +47,7 @@ export default class Option<T extends Codec> extends Base<T> {
return new Type(registry, value);
}
/** @internal */
private static decodeOptionU8a (registry: Registry, Type: Constructor, value: Uint8Array): Codec {
return !value.length || value[0] === 0
? new Null(registry)
+1
View File
@@ -25,6 +25,7 @@ export default class Raw extends Uint8Array implements IU8a {
this.registry = registry;
}
/** @internal */
private static decodeU8a (value?: any): Uint8Array {
if (isU8a(value)) {
return value;
+3
View File
@@ -32,6 +32,7 @@ export default class CodecSet extends Set<string> implements Codec {
this._setValues = setValues;
}
/** @internal */
public static decodeSet (setValues: SetValues, value: string[] | Set<string> | Uint8Array | BN | number | string = 0): string[] {
if (isString(value)) {
return CodecSet.decodeSet(setValues, u8aToU8a(value));
@@ -48,6 +49,7 @@ export default class CodecSet extends Set<string> implements Codec {
return CodecSet.decodeSetNumber(setValues, value);
}
/** @internal */
private static decodeSetArray (setValues: SetValues, value: string[]): string[] {
return value.reduce((result, key): string[] => {
assert(!isUndefined(setValues[key]), `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`);
@@ -58,6 +60,7 @@ export default class CodecSet extends Set<string> implements Codec {
}, [] as string[]);
}
/** @internal */
private static decodeSetNumber (setValues: SetValues, _value: BN | number): string[] {
const bn = bnToBn(_value);
const result = Object.keys(setValues).reduce((result, key): string[] => {
+2
View File
@@ -62,6 +62,7 @@ export default class Struct<
* - array with `[value1, value2]` assuming the array has the same length as
* `Object.keys(Types)`
* @param jsonMap
* @internal
*/
private static decodeStruct <T> (registry: Registry, Types: ConstructorDef, value: any, jsonMap: Map<any, string>): T {
if (isHex(value)) {
@@ -84,6 +85,7 @@ export default class Struct<
return Struct.decodeStructFromObject(registry, Types, value, jsonMap);
}
/** @internal */
private static decodeStructFromObject <T> (registry: Registry, 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
+1
View File
@@ -43,6 +43,7 @@ export default class StructAny extends Map<string, any> implements Codec {
});
}
/** @internal */
private static decodeJson (value?: { [index: string]: any } | null): [string, any][] {
return Object.entries(value || {});
}
+1
View File
@@ -36,6 +36,7 @@ export default class Tuple extends AbstractArray<Codec> {
this._Types = Clazzes;
}
/** @internal */
private static decodeTuple (registry: Registry, _Types: TupleConstructors, value: AnyU8a | string | (AnyU8a | AnyNumber | AnyString | undefined | null)[]): Codec[] {
if (isU8a(value)) {
return decodeU8a(registry, value, _Types);
+1
View File
@@ -24,6 +24,7 @@ export default class U8aFixed extends Raw {
super(registry, U8aFixed.decodeU8aFixed(value, bitLength));
}
/** @internal */
private static decodeU8aFixed (value: AnyU8a, bitLength: BitLength): AnyU8a {
if (Array.isArray(value) || isString(value)) {
return U8aFixed.decodeU8aFixed(u8aToU8a(value), bitLength);
+1
View File
@@ -30,6 +30,7 @@ export default class Vec<T extends Codec> extends AbstractArray<T> {
this._Type = Clazz;
}
/** @internal */
public static decodeVec<T extends Codec> (registry: Registry, Type: Constructor<T>, value: Vec<any> | Uint8Array | string | any[]): T[] {
if (Array.isArray(value)) {
return value.map((entry, index): T => {
+1
View File
@@ -25,6 +25,7 @@ export default class VecFixed<T extends Codec> extends AbstractArray<T> {
this._Type = Clazz;
}
/** @internal */
public static decodeVecFixed<T extends Codec> (registry: Registry, Type: Constructor<T>, allocLength: number, value: VecFixed<any> | Uint8Array | string | any[]): T[] {
const values = Vec.decodeVec(
registry,
+17 -1
View File
@@ -3,13 +3,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { CallFunction, Codec, Constructor, RegistryError, RegistryTypes, Registry, RegistryMetadata, TypeDef } from '../../types';
import { CallFunction, Codec, Constructor, InterfaceTypes, RegistryError, RegistryTypes, Registry, RegistryMetadata, TypeDef } from '../../types';
import extrinsicsFromMeta from '@polkadot/metadata/Decorated/extrinsics/fromMetadata';
import { assert, isFunction, isString, isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util';
import Raw from '../Raw';
import { EventData } from '../../primitive/Generic/Event';
import { defaultExtensions, expandExtensionTypes } from '../../primitive/Extrinsic/SignedExtensions';
import { createClass } from './createClass';
import { getTypeClass } from './getTypeClass';
import { getTypeDef } from './getTypeDef';
@@ -85,6 +86,8 @@ export class TypeRegistry implements Registry {
private _metadataEvents: Record<string, Constructor<EventData>> = {};
private _metadataExtensions: string[] = defaultExtensions;
constructor () {
// we only want to import these on creation, i.e. we want to avoid types
// weird side-effects from circular references. (Since registry is injected
@@ -165,6 +168,14 @@ export class TypeRegistry implements Registry {
return type;
}
public getSignedExtensionExtra (): Record<string, InterfaceTypes> {
return expandExtensionTypes(this._metadataExtensions, 'extra');
}
public getSignedExtensionTypes (): Record<string, InterfaceTypes> {
return expandExtensionTypes(this._metadataExtensions, 'types');
}
public hasClass (name: string): boolean {
return this._classes.has(name);
}
@@ -221,5 +232,10 @@ export class TypeRegistry implements Registry {
decorateExtrinsics(this, metadata, this._metadataCalls);
decorateErrors(this, metadata, this._metadataErrors);
decorateEvents(this, metadata, this._metadataEvents);
// setup the available extensions
this._metadataExtensions = metadata.asLatest.extrinsic.version.gtn(0)
? metadata.asLatest.extrinsic.signedExtensions.map((key): string => key.toString())
: defaultExtensions;
}
}
+52 -40
View File
@@ -3,7 +3,7 @@
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
import { Bytes, Data, Fixed64, H160, H256, H512, IdentityFields, Null, StorageData, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, ChangesTrieConfiguration, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, DispatchInfoTo190, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Percent, Permill, Perquintill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, ChangesTrieConfiguration, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, DispatchInfoTo190, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicSignatureV1, ExtrinsicSignatureV2, ExtrinsicSignatureV3, ExtrinsicSignatureV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Percent, Permill, Perquintill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { InclusionHeight, Uncle, UncleEntryItem } from '@polkadot/types/interfaces/authorship';
import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura';
import { BabeAuthorityWeight, BabeBlockWeight, BabeWeight, MaybeVrf, RawBabePreDigest, RawBabePreDigestCompat, RawBabePreDigestPrimary, RawBabePreDigestPrimaryTo159, RawBabePreDigestSecondary, RawBabePreDigestSecondaryTo159, RawBabePreDigestTo159, SlotNumber, VrfData, VrfProof } from '@polkadot/types/interfaces/babe';
@@ -127,6 +127,57 @@ export interface InterfaceRegistry {
Raw: Raw;
'Option<Raw>': Option<Raw>;
'Vec<Raw>': Vec<Raw>;
Extrinsic: Extrinsic;
'Option<Extrinsic>': Option<Extrinsic>;
'Vec<Extrinsic>': Vec<Extrinsic>;
ExtrinsicEra: ExtrinsicEra;
'Option<ExtrinsicEra>': Option<ExtrinsicEra>;
'Vec<ExtrinsicEra>': Vec<ExtrinsicEra>;
ExtrinsicPayload: ExtrinsicPayload;
'Option<ExtrinsicPayload>': Option<ExtrinsicPayload>;
'Vec<ExtrinsicPayload>': Vec<ExtrinsicPayload>;
ExtrinsicV1: ExtrinsicV1;
'Option<ExtrinsicV1>': Option<ExtrinsicV1>;
'Vec<ExtrinsicV1>': Vec<ExtrinsicV1>;
ExtrinsicPayloadV1: ExtrinsicPayloadV1;
'Option<ExtrinsicPayloadV1>': Option<ExtrinsicPayloadV1>;
'Vec<ExtrinsicPayloadV1>': Vec<ExtrinsicPayloadV1>;
ExtrinsicSignatureV1: ExtrinsicSignatureV1;
'Option<ExtrinsicSignatureV1>': Option<ExtrinsicSignatureV1>;
'Vec<ExtrinsicSignatureV1>': Vec<ExtrinsicSignatureV1>;
ExtrinsicV2: ExtrinsicV2;
'Option<ExtrinsicV2>': Option<ExtrinsicV2>;
'Vec<ExtrinsicV2>': Vec<ExtrinsicV2>;
ExtrinsicPayloadV2: ExtrinsicPayloadV2;
'Option<ExtrinsicPayloadV2>': Option<ExtrinsicPayloadV2>;
'Vec<ExtrinsicPayloadV2>': Vec<ExtrinsicPayloadV2>;
ExtrinsicSignatureV2: ExtrinsicSignatureV2;
'Option<ExtrinsicSignatureV2>': Option<ExtrinsicSignatureV2>;
'Vec<ExtrinsicSignatureV2>': Vec<ExtrinsicSignatureV2>;
ExtrinsicV3: ExtrinsicV3;
'Option<ExtrinsicV3>': Option<ExtrinsicV3>;
'Vec<ExtrinsicV3>': Vec<ExtrinsicV3>;
ExtrinsicPayloadV3: ExtrinsicPayloadV3;
'Option<ExtrinsicPayloadV3>': Option<ExtrinsicPayloadV3>;
'Vec<ExtrinsicPayloadV3>': Vec<ExtrinsicPayloadV3>;
ExtrinsicSignatureV3: ExtrinsicSignatureV3;
'Option<ExtrinsicSignatureV3>': Option<ExtrinsicSignatureV3>;
'Vec<ExtrinsicSignatureV3>': Vec<ExtrinsicSignatureV3>;
ExtrinsicV4: ExtrinsicV4;
'Option<ExtrinsicV4>': Option<ExtrinsicV4>;
'Vec<ExtrinsicV4>': Vec<ExtrinsicV4>;
ExtrinsicPayloadV4: ExtrinsicPayloadV4;
'Option<ExtrinsicPayloadV4>': Option<ExtrinsicPayloadV4>;
'Vec<ExtrinsicPayloadV4>': Vec<ExtrinsicPayloadV4>;
ExtrinsicSignatureV4: ExtrinsicSignatureV4;
'Option<ExtrinsicSignatureV4>': Option<ExtrinsicSignatureV4>;
'Vec<ExtrinsicSignatureV4>': Vec<ExtrinsicSignatureV4>;
ExtrinsicUnknown: ExtrinsicUnknown;
'Option<ExtrinsicUnknown>': Option<ExtrinsicUnknown>;
'Vec<ExtrinsicUnknown>': Vec<ExtrinsicUnknown>;
ExtrinsicPayloadUnknown: ExtrinsicPayloadUnknown;
'Option<ExtrinsicPayloadUnknown>': Option<ExtrinsicPayloadUnknown>;
'Vec<ExtrinsicPayloadUnknown>': Vec<ExtrinsicPayloadUnknown>;
AccountId: AccountId;
'Option<AccountId>': Option<AccountId>;
'Vec<AccountId>': Vec<AccountId>;
@@ -183,45 +234,6 @@ export interface InterfaceRegistry {
DispatchInfoTo190: DispatchInfoTo190;
'Option<DispatchInfoTo190>': Option<DispatchInfoTo190>;
'Vec<DispatchInfoTo190>': Vec<DispatchInfoTo190>;
Extrinsic: Extrinsic;
'Option<Extrinsic>': Option<Extrinsic>;
'Vec<Extrinsic>': Vec<Extrinsic>;
ExtrinsicEra: ExtrinsicEra;
'Option<ExtrinsicEra>': Option<ExtrinsicEra>;
'Vec<ExtrinsicEra>': Vec<ExtrinsicEra>;
ExtrinsicPayload: ExtrinsicPayload;
'Option<ExtrinsicPayload>': Option<ExtrinsicPayload>;
'Vec<ExtrinsicPayload>': Vec<ExtrinsicPayload>;
ExtrinsicPayloadUnknown: ExtrinsicPayloadUnknown;
'Option<ExtrinsicPayloadUnknown>': Option<ExtrinsicPayloadUnknown>;
'Vec<ExtrinsicPayloadUnknown>': Vec<ExtrinsicPayloadUnknown>;
ExtrinsicPayloadV1: ExtrinsicPayloadV1;
'Option<ExtrinsicPayloadV1>': Option<ExtrinsicPayloadV1>;
'Vec<ExtrinsicPayloadV1>': Vec<ExtrinsicPayloadV1>;
ExtrinsicPayloadV2: ExtrinsicPayloadV2;
'Option<ExtrinsicPayloadV2>': Option<ExtrinsicPayloadV2>;
'Vec<ExtrinsicPayloadV2>': Vec<ExtrinsicPayloadV2>;
ExtrinsicPayloadV3: ExtrinsicPayloadV3;
'Option<ExtrinsicPayloadV3>': Option<ExtrinsicPayloadV3>;
'Vec<ExtrinsicPayloadV3>': Vec<ExtrinsicPayloadV3>;
ExtrinsicPayloadV4: ExtrinsicPayloadV4;
'Option<ExtrinsicPayloadV4>': Option<ExtrinsicPayloadV4>;
'Vec<ExtrinsicPayloadV4>': Vec<ExtrinsicPayloadV4>;
ExtrinsicUnknown: ExtrinsicUnknown;
'Option<ExtrinsicUnknown>': Option<ExtrinsicUnknown>;
'Vec<ExtrinsicUnknown>': Vec<ExtrinsicUnknown>;
ExtrinsicV1: ExtrinsicV1;
'Option<ExtrinsicV1>': Option<ExtrinsicV1>;
'Vec<ExtrinsicV1>': Vec<ExtrinsicV1>;
ExtrinsicV2: ExtrinsicV2;
'Option<ExtrinsicV2>': Option<ExtrinsicV2>;
'Vec<ExtrinsicV2>': Vec<ExtrinsicV2>;
ExtrinsicV3: ExtrinsicV3;
'Option<ExtrinsicV3>': Option<ExtrinsicV3>;
'Vec<ExtrinsicV3>': Vec<ExtrinsicV3>;
ExtrinsicV4: ExtrinsicV4;
'Option<ExtrinsicV4>': Option<ExtrinsicV4>;
'Vec<ExtrinsicV4>': Vec<ExtrinsicV4>;
Hash: Hash;
'Option<Hash>': Option<Hash>;
'Vec<Hash>': Vec<Hash>;
@@ -2,8 +2,30 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Extrinsic definitions, extracted for readability
const extrinsic = {
Extrinsic: 'GenericExtrinsic',
ExtrinsicEra: 'GenericExtrinsicEra',
ExtrinsicPayload: 'GenericExtrinsicPayload',
ExtrinsicV1: 'GenericExtrinsicV1',
ExtrinsicPayloadV1: 'GenericExtrinsicPayloadV1',
ExtrinsicSignatureV1: 'GenericExtrinsicSignatureV1',
ExtrinsicV2: 'GenericExtrinsicV2',
ExtrinsicPayloadV2: 'GenericExtrinsicPayloadV2',
ExtrinsicSignatureV2: 'GenericExtrinsicSignatureV2',
ExtrinsicV3: 'GenericExtrinsicV3',
ExtrinsicPayloadV3: 'GenericExtrinsicPayloadV3',
ExtrinsicSignatureV3: 'GenericExtrinsicSignatureV3',
ExtrinsicV4: 'GenericExtrinsicV4',
ExtrinsicPayloadV4: 'GenericExtrinsicPayloadV4',
ExtrinsicSignatureV4: 'GenericExtrinsicSignatureV4',
ExtrinsicUnknown: 'GenericExtrinsicUnknown',
ExtrinsicPayloadUnknown: 'GenericExtrinsicPayloadUnknown'
};
export default {
types: {
...extrinsic,
AccountId: 'GenericAccountId',
AccountIdOf: 'AccountId',
AccountIndex: 'GenericAccountIndex',
@@ -33,19 +55,6 @@ export default {
weight: 'Weight',
class: 'DispatchClass'
},
Extrinsic: 'GenericExtrinsic',
ExtrinsicEra: 'GenericExtrinsicEra',
ExtrinsicPayload: 'GenericExtrinsicPayload',
ExtrinsicPayloadUnknown: 'GenericExtrinsicPayloadUnknown',
ExtrinsicPayloadV1: 'GenericExtrinsicPayloadV1',
ExtrinsicPayloadV2: 'GenericExtrinsicPayloadV2',
ExtrinsicPayloadV3: 'GenericExtrinsicPayloadV3',
ExtrinsicPayloadV4: 'GenericExtrinsicPayloadV4',
ExtrinsicUnknown: 'GenericExtrinsicUnknown',
ExtrinsicV1: 'GenericExtrinsicV1',
ExtrinsicV2: 'GenericExtrinsicV2',
ExtrinsicV3: 'GenericExtrinsicV3',
ExtrinsicV4: 'GenericExtrinsicV4',
Hash: 'H256',
Header: {
parentHash: 'Hash',
+13 -1
View File
@@ -3,7 +3,7 @@
import { Codec, ITuple } from '@polkadot/types/types';
import { Compact, Enum, Struct } from '@polkadot/types/codec';
import { Bytes, Fixed64, GenericAccountId, GenericAccountIndex, GenericAddress, GenericBlock, GenericCall, GenericConsensusEngineId, GenericDigest, GenericDigestItem, GenericExtrinsic, GenericExtrinsicEra, GenericExtrinsicPayload, GenericExtrinsicPayloadUnknown, GenericExtrinsicPayloadV1, GenericExtrinsicPayloadV2, GenericExtrinsicPayloadV3, GenericExtrinsicPayloadV4, GenericExtrinsicUnknown, GenericExtrinsicV1, GenericExtrinsicV2, GenericExtrinsicV3, GenericExtrinsicV4, GenericImmortalEra, GenericMortalEra, GenericOrigin, GenericSignerPayload, H256, H512, Null, StorageData, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
import { Bytes, Fixed64, GenericAccountId, GenericAccountIndex, GenericAddress, GenericBlock, GenericCall, GenericConsensusEngineId, GenericDigest, GenericDigestItem, GenericExtrinsic, GenericExtrinsicEra, GenericExtrinsicPayload, GenericExtrinsicPayloadUnknown, GenericExtrinsicPayloadV1, GenericExtrinsicPayloadV2, GenericExtrinsicPayloadV3, GenericExtrinsicPayloadV4, GenericExtrinsicSignatureV1, GenericExtrinsicSignatureV2, GenericExtrinsicSignatureV3, GenericExtrinsicSignatureV4, GenericExtrinsicUnknown, GenericExtrinsicV1, GenericExtrinsicV2, GenericExtrinsicV3, GenericExtrinsicV4, GenericImmortalEra, GenericMortalEra, GenericOrigin, GenericSignerPayload, H256, H512, Null, StorageData, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
/** @name AccountId */
export interface AccountId extends GenericAccountId {}
@@ -102,6 +102,18 @@ export interface ExtrinsicPayloadV3 extends GenericExtrinsicPayloadV3 {}
/** @name ExtrinsicPayloadV4 */
export interface ExtrinsicPayloadV4 extends GenericExtrinsicPayloadV4 {}
/** @name ExtrinsicSignatureV1 */
export interface ExtrinsicSignatureV1 extends GenericExtrinsicSignatureV1 {}
/** @name ExtrinsicSignatureV2 */
export interface ExtrinsicSignatureV2 extends GenericExtrinsicSignatureV2 {}
/** @name ExtrinsicSignatureV3 */
export interface ExtrinsicSignatureV3 extends GenericExtrinsicSignatureV3 {}
/** @name ExtrinsicSignatureV4 */
export interface ExtrinsicSignatureV4 extends GenericExtrinsicSignatureV4 {}
/** @name ExtrinsicUnknown */
export interface ExtrinsicUnknown extends GenericExtrinsicUnknown {}
+1
View File
@@ -25,6 +25,7 @@ export default class Bool extends Boolean implements Codec {
this.registry = registry;
}
/** @internal */
private static decodeBool (value: any): boolean {
if (value instanceof Boolean) {
return value.valueOf();
+2
View File
@@ -21,6 +21,7 @@ export default class Bytes extends Raw {
super(registry, Bytes.decodeBytes(value));
}
/** @internal */
private static decodeBytes (value?: AnyU8a): Uint8Array | undefined {
if (Array.isArray(value) || isString(value)) {
return u8aToU8a(value);
@@ -33,6 +34,7 @@ export default class Bytes extends Raw {
return value;
}
/** @internal */
private static decodeBytesU8a (value: Uint8Array): Uint8Array {
if (!value.length) {
return new Uint8Array();
@@ -39,7 +39,7 @@ const VERSIONS: InterfaceTypes[] = [
export { TRANSACTION_VERSION as LATEST_EXTRINSIC_VERSION } from './v4/Extrinsic';
/**
* @name Extrinsic
* @name GenericExtrinsic
* @description
* Representation of an Extrinsic in the system. It contains the actual call,
* (optional) signature and encodes with an actual length prefix
@@ -55,6 +55,7 @@ export default class Extrinsic extends Base<ExtrinsicVx | ExtrinsicUnknown> impl
super(registry, Extrinsic.decodeExtrinsic(registry, value, version));
}
/** @internal */
private static newFromValue (registry: Registry, value: any, version: number): ExtrinsicVx | ExtrinsicUnknown {
if (value instanceof Extrinsic) {
return value.raw;
@@ -68,6 +69,7 @@ export default class Extrinsic extends Base<ExtrinsicVx | ExtrinsicUnknown> impl
return createType(registry, type, value, { isSigned, version }) as ExtrinsicVx;
}
/** @internal */
public static decodeExtrinsic (registry: Registry, value: Extrinsic | ExtrinsicValue | AnyU8a | Call | undefined, version: number = DEFAULT_VERSION): ExtrinsicVx | ExtrinsicUnknown {
if (Array.isArray(value) || isHex(value)) {
return Extrinsic.decodeU8aLike(registry, value, version);
@@ -80,6 +82,7 @@ export default class Extrinsic extends Base<ExtrinsicVx | ExtrinsicUnknown> impl
return Extrinsic.newFromValue(registry, value, version);
}
/** @internal */
private static decodeU8aLike (registry: Registry, value: string | number[], version: number): ExtrinsicVx | ExtrinsicUnknown {
// Instead of the block below, it should simply be:
// return Extrinsic.decodeExtrinsic(hexToU8a(value as string));
@@ -100,6 +103,7 @@ export default class Extrinsic extends Base<ExtrinsicVx | ExtrinsicUnknown> impl
);
}
/** @internal */
private static decodeU8a (registry: Registry, value: Uint8Array, version: number): ExtrinsicVx | ExtrinsicUnknown {
if (!value.length) {
return Extrinsic.newFromValue(registry, new Uint8Array(), version);
@@ -55,6 +55,7 @@ export class MortalEra extends Tuple {
}, MortalEra.decodeMortalEra(registry, value));
}
/** @internal */
private static decodeMortalEra (registry: Registry, value?: MortalMethod | Uint8Array | number[] | string): MortalEraValue {
if (isHex(value)) {
return MortalEra.decodeMortalU8a(registry, hexToU8a(value));
@@ -71,6 +72,7 @@ export class MortalEra extends Tuple {
throw new Error('Invalid data passed to Mortal era');
}
/** @internal */
private static decodeMortalObject (registry: Registry, value: MortalMethod): MortalEraValue {
const { current, period } = value;
let calPeriod = Math.pow(2, Math.ceil(Math.log2(period)));
@@ -82,6 +84,7 @@ export class MortalEra extends Tuple {
return [new U64(registry, calPeriod), new U64(registry, quantizedPhase)];
}
/** @internal */
private static decodeMortalU8a (registry: Registry, value: Uint8Array): MortalEraValue {
if (value.length === 0) {
return [new U64(registry), new U64(registry)];
@@ -186,7 +189,7 @@ export class MortalEra extends Tuple {
}
/**
* @name ExtrinsicEra
* @name GenericExtrinsicEra
* @description
* The era for an extrinsic, indicating either a mortal or immortal extrinsic
*/
@@ -198,6 +201,7 @@ export default class ExtrinsicEra extends Enum implements IExtrinsicEra {
}, ExtrinsicEra.decodeExtrinsicEra(value));
}
/** @internal */
// eslint-disable-next-line @typescript-eslint/ban-types
private static decodeExtrinsicEra (value: IExtrinsicEra | MortalMethod | MortalEnumDef | ImmortalEnumDef | Uint8Array | string = new Uint8Array()): Uint8Array | Object | undefined {
if (!value) {
@@ -1,4 +1,4 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// Copyright 2017-2020 @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.
@@ -31,7 +31,7 @@ const VERSIONS: InterfaceTypes[] = [
];
/**
* @name ExtrinsicPayload
* @name GenericExtrinsicPayload
* @description
* A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
* on the contents included
@@ -41,6 +41,7 @@ export default class ExtrinsicPayload extends Base<ExtrinsicPayloadVx> {
super(registry, ExtrinsicPayload.decodeExtrinsicPayload(registry, value as ExtrinsicPayloadValue, version));
}
/** @internal */
public static decodeExtrinsicPayload (registry: Registry, value: ExtrinsicPayload | ExtrinsicPayloadValue | Uint8Array | string | undefined, version: number = DEFAULT_VERSION): ExtrinsicPayloadVx {
if (value instanceof ExtrinsicPayload) {
return value.raw;
@@ -8,7 +8,7 @@ import { ExtrinsicPayloadOptions } from './types';
import Struct from '../../codec/Struct';
/**
* @name ExtrinsicPayloadUnknown
* @name GenericExtrinsicPayloadUnknown
* @description
* A default handler for payloads where the version is not known (default throw)
*/
@@ -9,7 +9,7 @@ import Struct from '../../codec/Struct';
import { UNMASK_VERSION } from './constants';
/**
* @name ExtrinsicUnknown
* @name GenericExtrinsicUnknown
* @description
* A default handler for extrinsics where the version is not known (default throw)
*/
@@ -0,0 +1,86 @@
// Copyright 2017-2020 @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 { InterfaceTypes } from '../../types';
type ExtTypes = Record<string, InterfaceTypes>;
type ExtInfo = {
extra: ExtTypes;
types: ExtTypes;
}
// A mapping of the known signed extensions to the extra fields that they contain. Unlike in the actual extensions,
// we define the extra fields not as a Tuple, but rather as a struct so they can be named. These will be expanded
// into the various fields when added to the payload (we only support V4 onwards with these, V3 and earlier are
// deemded fixed and non-changeable)
const allExtensions: Record<string, ExtInfo> = {
ChargeTransactionPayment: {
extra: {},
types: {
tip: 'Compact<Balance>'
}
},
CheckBlockGasLimit: {
extra: {},
types: {}
},
CheckEra: {
extra: {
blockHash: 'Hash'
},
types: {
era: 'ExtrinsicEra'
}
},
CheckGenesis: {
extra: {
genesisHash: 'Hash'
},
types: {}
},
CheckNonce: {
extra: {},
types: {
nonce: 'Compact<Index>'
}
},
CheckVersion: {
extra: {
specVersion: 'u32'
},
types: {}
},
CheckWeight: {
extra: {},
types: {}
}
};
// the v4 signed extensions (the order is important here)
const defaultExtensions: Array<keyof typeof allExtensions> = [
'CheckVersion',
'CheckGenesis',
'CheckEra',
'CheckNonce',
'CheckWeight',
'ChargeTransactionPayment',
'CheckBlockGasLimit'
];
function expandExtensionTypes (extensions: string[], type: keyof ExtInfo): ExtTypes {
return extensions
.map((key): ExtInfo => {
const info = allExtensions[key];
if (!info) {
console.warn(`Unknown signed extension ${key} found, treating it as empty with no extra data`);
}
return info;
})
.filter((info): boolean => !!info)
.reduce((result, info): ExtTypes => ({ ...result, ...info[type] }), {});
}
export { allExtensions, defaultExtensions, expandExtensionTypes };
@@ -1,4 +1,4 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// Copyright 2017-2020 @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.
@@ -1,4 +1,4 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// Copyright 2017-2020 @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.
@@ -38,6 +38,11 @@ const _Payload: Constructor<SignerPayloadType> = Struct.with({
version: 'u8'
}) as any;
/**
* @name SignerPayload
* @description
* A generic signer payload that can be used for serialization between API and signer
*/
export default class SignerPayload extends _Payload implements ISignerPayload {
/**
* @description Creates an representation of the structure as an ISignerPayload JSON
@@ -2,7 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// generic
export { default as GenericExtrinsic } from './Extrinsic';
export { default as GenericExtrinsicEra, MortalEra as GenericMortalEra, ImmortalEra as GenericImmortalEra } from './ExtrinsicEra';
export { default as GenericExtrinsicPayload } from './ExtrinsicPayload';
@@ -10,15 +9,7 @@ export { default as GenericExtrinsicPayloadUnknown } from './ExtrinsicPayloadUnk
export { default as GenericExtrinsicUnknown } from './ExtrinsicUnknown';
export { default as GenericSignerPayload } from './SignerPayload';
// versioned
export { default as GenericExtrinsicV1 } from './v1/Extrinsic';
export { default as GenericExtrinsicPayloadV1 } from './v1/ExtrinsicPayload';
export { default as GenericExtrinsicV2 } from './v2/Extrinsic';
export { default as GenericExtrinsicPayloadV2 } from './v2/ExtrinsicPayload';
export { default as GenericExtrinsicV3 } from './v3/Extrinsic';
export { default as GenericExtrinsicPayloadV3 } from './v3/ExtrinsicPayload';
export { default as GenericExtrinsicV4 } from './v4/Extrinsic';
export { default as GenericExtrinsicPayloadV4 } from './v4/ExtrinsicPayload';
export * from './v1';
export * from './v2';
export * from './v3';
export * from './v4';
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Address, Call } from '../../../interfaces/runtime';
import { Address, Call, ExtrinsicSignatureV1 } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, Registry, SignatureOptions } from '../../../types';
import { ExtrinsicOptions } from '../types';
@@ -10,7 +10,6 @@ import { isU8a } from '@polkadot/util';
import { createType } from '../../../codec/create';
import Struct from '../../../codec/Struct';
import ExtrinsicSignatureV1 from './ExtrinsicSignature';
export interface ExtrinsicValueV1 {
method?: Call;
@@ -20,26 +19,25 @@ export interface ExtrinsicValueV1 {
const TRANSACTION_VERSION = 1;
/**
* @name ExtrinsicV1
* @name GenericExtrinsicV1
* @description
* The first generation of compact extrinsics
*/
export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
constructor (registry: Registry, value?: Uint8Array | ExtrinsicValueV1, { isSigned }: Partial<ExtrinsicOptions> = {}) {
super(registry, {
signature: ExtrinsicSignatureV1,
signature: 'ExtrinsicSignatureV1',
method: 'Call'
}, ExtrinsicV1.decodeExtrinsic(registry, value, isSigned));
}
/** @internal */
public static decodeExtrinsic (registry: Registry, value?: Uint8Array | ExtrinsicValueV1, isSigned = false): ExtrinsicValueV1 {
if (!value) {
return {};
} else if (value instanceof ExtrinsicV1) {
if (value instanceof ExtrinsicV1) {
return value;
} else if (isU8a(value)) {
// here we decode manually since we need to pull through the version information
const signature = new ExtrinsicSignatureV1(registry, value, { isSigned });
const signature = createType(registry, 'ExtrinsicSignatureV1', value, { isSigned });
const method = createType(registry, 'Call', value.subarray(signature.encodedLength));
return {
@@ -48,7 +46,7 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
};
}
return value;
return value || {};
}
/**
@@ -11,7 +11,7 @@ import Bytes from '../../../primitive/Bytes';
import { sign } from '../util';
/**
* @name ExtrinsicPayloadV1
* @name GenericExtrinsicPayloadV1
* @description
* A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
* on the contents included
@@ -13,7 +13,7 @@ import { EMPTY_U8A, IMMORTAL_ERA } from '../constants';
import ExtrinsicPayloadV1 from './ExtrinsicPayload';
/**
* @name ExtrinsicSignatureV1
* @name GenericExtrinsicSignatureV1
* @description
* A container for the [[Signature]] associated with a specific [[Extrinsic]]
*/
@@ -32,6 +32,7 @@ export default class ExtrinsicSignatureV1 extends Struct implements IExtrinsicSi
}, ExtrinsicSignatureV1.decodeExtrinsicSignature(value, isSigned));
}
/** @internal */
public static decodeExtrinsicSignature (value: ExtrinsicSignatureV1 | Uint8Array | undefined, isSigned = false): ExtrinsicSignatureV1 | Uint8Array {
if (!value) {
return EMPTY_U8A;
@@ -0,0 +1,7 @@
// Copyright 2017-2020 @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.
export { default as GenericExtrinsicV1 } from './Extrinsic';
export { default as GenericExtrinsicPayloadV1 } from './ExtrinsicPayload';
export { default as GenericExtrinsicSignatureV1 } from './ExtrinsicSignature';
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Address, Call } from '../../../interfaces/runtime';
import { Address, Call, ExtrinsicSignatureV2 } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, Registry, SignatureOptions } from '../../../types';
import { ExtrinsicOptions } from '../types';
@@ -10,7 +10,6 @@ import { isU8a } from '@polkadot/util';
import { createType, ClassOf } from '../../../codec/create';
import Struct from '../../../codec/Struct';
import ExtrinsicSignatureV2 from './ExtrinsicSignature';
const TRANSACTION_VERSION = 2;
@@ -20,28 +19,27 @@ export interface ExtrinsicValueV2 {
}
/**
* @name ExtrinsicV2
* @name GenericExtrinsicV2
* @description
* The second generation of compact extrinsics
*/
export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
constructor (registry: Registry, value?: Uint8Array | ExtrinsicValueV2 | Call, { isSigned }: Partial<ExtrinsicOptions> = {}) {
super(registry, {
signature: ExtrinsicSignatureV2,
signature: 'ExtrinsicSignatureV2',
method: 'Call'
}, ExtrinsicV2.decodeExtrinsic(registry, value, isSigned));
}
/** @internal */
public static decodeExtrinsic (registry: Registry, value?: Call | Uint8Array | ExtrinsicValueV2, isSigned = false): ExtrinsicValueV2 {
if (!value) {
return {};
} else if (value instanceof ExtrinsicV2) {
if (value instanceof ExtrinsicV2) {
return value;
} else if (value instanceof ClassOf(registry, 'Call')) {
return { method: value };
} else if (isU8a(value)) {
// here we decode manually since we need to pull through the version information
const signature = new ExtrinsicSignatureV2(registry, value, { isSigned });
const signature = createType(registry, 'ExtrinsicSignatureV2', value, { isSigned });
const method = createType(registry, 'Call', value.subarray(signature.encodedLength));
return {
@@ -50,7 +48,7 @@ export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
};
}
return value;
return value || {};
}
/**
@@ -3,23 +3,15 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { Balance, ExtrinsicEra, Hash, Index } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IKeyringPair, InterfaceTypes, Registry } from '../../../types';
import { ExtrinsicPayloadValue, IKeyringPair, Registry } from '../../../types';
import Compact from '../../../codec/Compact';
import Struct from '../../../codec/Struct';
import Bytes from '../../../primitive/Bytes';
import { sign } from '../util';
// the base definition (excluding extras)
export const SignedPayloadBaseV2: Record<string, InterfaceTypes> = {
method: 'Bytes',
era: 'ExtrinsicEra',
nonce: 'Compact<Index>',
tip: 'Compact<Balance>'
};
/**
* @name ExtrinsicPayloadV2
* @name GenericExtrinsicPayloadV2
* @description
* A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
* on the contents included
@@ -27,7 +19,10 @@ export const SignedPayloadBaseV2: Record<string, InterfaceTypes> = {
export default class ExtrinsicPayloadV2 extends Struct {
constructor (registry: Registry, value?: ExtrinsicPayloadValue | Uint8Array | string) {
super(registry, {
...SignedPayloadBaseV2,
method: 'Bytes',
era: 'ExtrinsicEra',
nonce: 'Compact<Index>',
tip: 'Compact<Balance>',
blockHash: 'Hash'
}, value);
}
@@ -13,7 +13,7 @@ import { EMPTY_U8A, IMMORTAL_ERA } from '../constants';
import ExtrinsicPayloadV2 from './ExtrinsicPayload';
/**
* @name ExtrinsicSignatureV2
* @name GenericExtrinsicSignatureV2
* @description
* A container for the [[Signature]] associated with a specific [[Extrinsic]]
*/
@@ -28,6 +28,7 @@ export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSi
}, ExtrinsicSignatureV2.decodeExtrinsicSignature(value, isSigned));
}
/** @internal */
public static decodeExtrinsicSignature (value: ExtrinsicSignatureV2 | Uint8Array | undefined, isSigned = false): ExtrinsicSignatureV2 | Uint8Array {
if (!value) {
return EMPTY_U8A;
@@ -0,0 +1,7 @@
// Copyright 2017-2020 @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.
export { default as GenericExtrinsicV2 } from './Extrinsic';
export { default as GenericExtrinsicPayloadV2 } from './ExtrinsicPayload';
export { default as GenericExtrinsicSignatureV2 } from './ExtrinsicSignature';
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Address, Call } from '../../../interfaces/runtime';
import { Address, Call, ExtrinsicSignatureV3 } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, Registry, SignatureOptions } from '../../../types';
import { ExtrinsicOptions } from '../types';
@@ -10,7 +10,6 @@ import { isU8a } from '@polkadot/util';
import { createType, ClassOf } from '../../../codec/create';
import Struct from '../../../codec/Struct';
import ExtrinsicSignatureV3 from './ExtrinsicSignature';
const TRANSACTION_VERSION = 3;
@@ -20,28 +19,27 @@ export interface ExtrinsicValueV3 {
}
/**
* @name ExtrinsicV3
* @name GenericExtrinsicV3
* @description
* The third generation of compact extrinsics
*/
export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
constructor (registry: Registry, value?: Uint8Array | ExtrinsicValueV3 | Call, { isSigned }: Partial<ExtrinsicOptions> = {}) {
super(registry, {
signature: ExtrinsicSignatureV3,
signature: 'ExtrinsicSignatureV3',
method: 'Call'
}, ExtrinsicV3.decodeExtrinsic(registry, value, isSigned));
}
/** @internal */
public static decodeExtrinsic (registry: Registry, value?: Call | Uint8Array | ExtrinsicValueV3, isSigned = false): ExtrinsicValueV3 {
if (!value) {
return {};
} else if (value instanceof ExtrinsicV3) {
if (value instanceof ExtrinsicV3) {
return value;
} else if (value instanceof ClassOf(registry, 'Call')) {
return { method: value };
} else if (isU8a(value)) {
// here we decode manually since we need to pull through the version information
const signature = new ExtrinsicSignatureV3(registry, value, { isSigned });
const signature = createType(registry, 'ExtrinsicSignatureV3', value, { isSigned });
const method = createType(registry, 'Call', value.subarray(signature.encodedLength));
return {
@@ -50,7 +48,7 @@ export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
};
}
return value;
return value || {};
}
/**
@@ -10,10 +10,9 @@ import Struct from '../../../codec/Struct';
import Bytes from '../../../primitive/Bytes';
import u32 from '../../../primitive/U32';
import { sign } from '../util';
import { SignedPayloadBaseV2 as SignedPayloadBaseV3 } from '../v2/ExtrinsicPayload';
/**
* @name ExtrinsicPayloadV3
* @name GenericExtrinsicPayloadV3
* @description
* A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
* on the contents included
@@ -21,8 +20,12 @@ import { SignedPayloadBaseV2 as SignedPayloadBaseV3 } from '../v2/ExtrinsicPaylo
export default class ExtrinsicPayloadV3 extends Struct {
constructor (registry: Registry, value?: ExtrinsicPayloadValue | Uint8Array | string) {
super(registry, {
...SignedPayloadBaseV3,
// signed extensions
method: 'Bytes',
// extensions
era: 'ExtrinsicEra',
nonce: 'Compact<Index>',
tip: 'Compact<Balance>',
// extensions (additional)
specVersion: 'u32',
genesisHash: 'Hash',
blockHash: 'Hash'
@@ -11,7 +11,7 @@ import ExtrinsicSignatureV2 from '../v2/ExtrinsicSignature';
import ExtrinsicPayloadV3 from './ExtrinsicPayload';
/**
* @name ExtrinsicSignatureV3
* @name GenericExtrinsicSignatureV3
* @description
* A container for the [[Signature]] associated with a specific [[Extrinsic]]
*/
@@ -0,0 +1,7 @@
// Copyright 2017-2020 @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.
export { default as GenericExtrinsicV3 } from './Extrinsic';
export { default as GenericExtrinsicPayloadV3 } from './ExtrinsicPayload';
export { default as GenericExtrinsicSignatureV3 } from './ExtrinsicSignature';
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Address, Call } from '../../../interfaces/runtime';
import { Address, Call, ExtrinsicSignatureV4 } from '../../../interfaces/runtime';
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, Registry, SignatureOptions } from '../../../types';
import { ExtrinsicOptions } from '../types';
@@ -10,7 +10,6 @@ import { isU8a } from '@polkadot/util';
import { createType, ClassOf } from '../../../codec/create';
import Struct from '../../../codec/Struct';
import ExtrinsicSignatureV4 from './ExtrinsicSignature';
export const TRANSACTION_VERSION = 4;
@@ -20,28 +19,27 @@ export interface ExtrinsicValueV4 {
}
/**
* @name ExtrinsicV4
* @name GenericExtrinsicV4
* @description
* The third generation of compact extrinsics
*/
export default class ExtrinsicV4 extends Struct implements IExtrinsicImpl {
constructor (registry: Registry, value?: Uint8Array | ExtrinsicValueV4 | Call, { isSigned }: Partial<ExtrinsicOptions> = {}) {
super(registry, {
signature: ExtrinsicSignatureV4,
signature: 'ExtrinsicSignatureV4',
method: 'Call'
}, ExtrinsicV4.decodeExtrinsic(registry, value, isSigned));
}
/** @internal */
public static decodeExtrinsic (registry: Registry, value?: Call | Uint8Array | ExtrinsicValueV4, isSigned = false): ExtrinsicValueV4 {
if (!value) {
return {};
} else if (value instanceof ExtrinsicV4) {
if (value instanceof ExtrinsicV4) {
return value;
} else if (value instanceof ClassOf(registry, 'Call')) {
return { method: value };
} else if (isU8a(value)) {
// here we decode manually since we need to pull through the version information
const signature = new ExtrinsicSignatureV4(registry, value, { isSigned });
const signature = createType(registry, 'ExtrinsicSignatureV4', value, { isSigned });
const method = createType(registry, 'Call', value.subarray(signature.encodedLength));
return {
@@ -50,7 +48,7 @@ export default class ExtrinsicV4 extends Struct implements IExtrinsicImpl {
};
}
return value;
return value || {};
}
/**
@@ -10,10 +10,9 @@ import Struct from '../../../codec/Struct';
import Bytes from '../../../primitive/Bytes';
import u32 from '../../../primitive/U32';
import { sign } from '../util';
import { SignedPayloadBaseV2 as SignedPayloadBaseV4 } from '../v2/ExtrinsicPayload';
/**
* @name ExtrinsicPayloadV4
* @name GenericExtrinsicPayloadV4
* @description
* A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
* on the contents included
@@ -21,19 +20,9 @@ import { SignedPayloadBaseV2 as SignedPayloadBaseV4 } from '../v2/ExtrinsicPaylo
export default class ExtrinsicPayloadV4 extends Struct {
constructor (registry: Registry, value?: ExtrinsicPayloadValue | Uint8Array | string) {
super(registry, {
...SignedPayloadBaseV4,
// TODO get the signed extensions from the registry and apply
...{
// system::CheckVersion<Runtime>
specVersion: 'u32',
// system::CheckGenesis<Runtime>
genesisHash: 'Hash',
// system::CheckEra<Runtime>
blockHash: 'Hash'
// system::CheckNonce<Runtime>
// system::CheckWeight<Runtime>
// balances::TakeFees<Runtime>
}
method: 'Bytes',
...registry.getSignedExtensionTypes(),
...registry.getSignedExtensionExtra()
}, value);
}
@@ -15,7 +15,7 @@ import { EMPTY_U8A, IMMORTAL_ERA } from '../constants';
import ExtrinsicPayloadV4 from './ExtrinsicPayload';
/**
* @name ExtrinsicSignatureV4
* @name GenericExtrinsicSignatureV4
* @description
* A container for the [[Signature]] associated with a specific [[Extrinsic]]
*/
@@ -24,12 +24,11 @@ export default class ExtrinsicSignatureV4 extends Struct implements IExtrinsicSi
super(registry, {
signer: 'Address',
signature: 'MultiSignature',
era: 'ExtrinsicEra',
nonce: 'Compact<Index>',
tip: 'Compact<Balance>'
...registry.getSignedExtensionTypes()
}, ExtrinsicSignatureV4.decodeExtrinsicSignature(value, isSigned));
}
/** @internal */
public static decodeExtrinsicSignature (value: ExtrinsicSignatureV4 | Uint8Array | undefined, isSigned = false): ExtrinsicSignatureV4 | Uint8Array {
if (!value) {
return EMPTY_U8A;
@@ -0,0 +1,7 @@
// Copyright 2017-2020 @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.
export { default as GenericExtrinsicV4 } from './Extrinsic';
export { default as GenericExtrinsicPayloadV4 } from './ExtrinsicPayload';
export { default as GenericExtrinsicSignatureV4 } from './ExtrinsicSignature';
@@ -25,6 +25,7 @@ export default class AccountId extends U8aFixed {
return encodeAddress(value);
}
/** @internal */
private static decodeAccountId (value: AnyU8a | AnyString): Uint8Array {
if (isU8a(value) || Array.isArray(value)) {
return u8aToU8a(value);
@@ -32,6 +32,7 @@ export default class AccountIndex extends U32 {
super(registry, AccountIndex.decodeAccountIndex(value));
}
/** @internal */
public static decodeAccountIndex (value: AnyNumber): BN | Uint8Array | number | string {
if (value instanceof AccountIndex) {
// `value.toBn()` on AccountIndex returns a pure BN (i.e. not an
@@ -30,6 +30,7 @@ export default class Address extends Base<AccountId | AccountIndex> {
super(registry, Address.decodeAddress(registry, value));
}
/** @internal */
public static decodeAddress (registry: Registry, value: AnyAddress): AccountId | AccountIndex {
if (value instanceof AccountId || value instanceof AccountIndex) {
return value;
@@ -44,6 +45,7 @@ export default class Address extends Base<AccountId | AccountIndex> {
return Address.decodeString(registry, value);
}
/** @internal */
private static decodeString (registry: Registry, value: string): AccountId | AccountIndex {
const decoded = decodeAddress(value);
@@ -52,6 +54,7 @@ export default class Address extends Base<AccountId | AccountIndex> {
: createType(registry, 'AccountIndex', u8aToBn(decoded, true));
}
/** @internal */
private static decodeU8a (registry: Registry, value: Uint8Array): AccountId | AccountIndex {
// This allows us to instantiate an address with a raw publicKey. Do this first before
// we checking the first byte, otherwise we may split an already-existent valid address
@@ -61,6 +61,7 @@ export default class Call extends Struct implements IMethod {
* - {@see DecodeMethodInput}
* @param _meta - Metadata to use, so that `injectMethods` lookup is not
* necessary.
* @internal
*/
private static decodeCall (registry: Registry, value: DecodedMethod | Uint8Array | string = new Uint8Array(), _meta?: FunctionMetadataLatest): DecodedMethod {
if (isHex(value) || isU8a(value)) {
@@ -72,6 +73,7 @@ export default class Call extends Struct implements IMethod {
throw new Error(`Call: Cannot decode value '${value}' of type ${typeof value}`);
}
/** @internal */
private static decodeCallViaObject (registry: Registry, value: DecodedMethod, _meta?: FunctionMetadataLatest): DecodedMethod {
// we only pass args/methodsIndex out
const { args, callIndex } = value;
@@ -92,6 +94,7 @@ export default class Call extends Struct implements IMethod {
};
}
/** @internal */
private static decodeCallViaU8a (registry: Registry, value: Uint8Array, _meta?: FunctionMetadataLatest): DecodedMethod {
// We need 2 bytes for the callIndex
const callIndex = new Uint8Array(2);
@@ -124,6 +127,7 @@ export default class Call extends Struct implements IMethod {
* its metadata.
*
* @param meta - The function metadata used to get the definition.
* @internal
*/
private static getArgsDef (registry: Registry, meta: FunctionMetadataLatest): ArgsDef {
return Call.filterOrigin(meta).reduce((result, { name, type }): ArgsDef => {
@@ -81,6 +81,7 @@ export default class Event extends Struct {
}, value);
}
/** @internal */
public static decodeEvent (registry: Registry, value: Uint8Array = new Uint8Array()): { DataType: Constructor<Null> | Constructor<EventData>; value?: { index: Uint8Array; data: Uint8Array } } {
if (!value.length) {
return {
@@ -45,6 +45,7 @@ export default class Vote extends U8aFixed {
this._conviction = createType(this.registry, 'Conviction', decoded[0] & CON_MASK);
}
/** @internal */
private static decodeVote (registry: Registry, value?: InputTypes): Uint8Array {
if (isUndefined(value)) {
return Vote.decodeVoteBool(false);
@@ -62,12 +63,14 @@ export default class Vote extends U8aFixed {
return new Uint8Array([vote | conviction.index]);
}
/** @internal */
private static decodeVoteBool (value: boolean): Uint8Array {
return value
? new Uint8Array([AYE_BITS | DEF_CONV])
: new Uint8Array([NAY_BITS]);
}
/** @internal */
private static decodeVoteU8a (value: Uint8Array): Uint8Array {
return value.length
? value.subarray(0, 1)
@@ -74,6 +74,7 @@ export default class StorageKey extends Bytes {
this._section = override.section || section;
}
/** @internal */
public static decodeStorageKey (value?: AnyU8a | StorageKey | StorageEntry | [StorageEntry, any]): Decoded {
if (value instanceof StorageKey) {
return {
+1
View File
@@ -31,6 +31,7 @@ export default class Text extends String implements Codec {
this.registry = registry;
}
/** @internal */
private static decodeText (value: Text | string | AnyU8a | { toString: () => string }): string {
if (isHex(value)) {
return u8aToString(hexToU8a(value.toString()));
+9
View File
@@ -372,6 +372,12 @@ export interface RegistryMetadataEvents {
unwrap (): RegistryMetadataEvent[];
}
export interface RegistryMetadataExtrinsic {
version: BN;
// eslint-disable-next-line @typescript-eslint/ban-types
signedExtensions: String[];
}
export interface RegistryMetadataModule {
calls: RegistryMetadataCalls;
errors: RegistryMetadataErrors;
@@ -381,6 +387,7 @@ export interface RegistryMetadataModule {
export interface RegistryMetadataLatest {
modules: RegistryMetadataModule[];
extrinsic: RegistryMetadataExtrinsic;
}
export interface RegistryMetadata {
@@ -396,6 +403,8 @@ export interface Registry {
get <T extends Codec = Codec> (name: string): Constructor<T> | undefined;
getOrThrow <T extends Codec = Codec> (name: string, msg?: string): Constructor<T>;
getSignedExtensionExtra (): Record<string, InterfaceTypes>;
getSignedExtensionTypes (): Record<string, InterfaceTypes>;
hasClass (name: string): boolean;
hasDef (name: string): boolean;
hasType (name: string): boolean;