new EventRecord with topics (#902)
* new EventRecord with topics * Add additional decoding checks (from #612) * Slightly rework storage parsing (future checks) * Split storage result formatting (set vs data) * Allow v3 event parsing * Max Vector length check * assert during Event parsing * Well, HACK-y fallback * Revert "Well, HACK-y fallback" This reverts commit edbf61b99da2753bec3a535126660e71bdcd9861. * Node overrides... * Add implVersion * Register types * Update with polkadot as well * inject compatibility types * EventRecord77 in testing * Conversion with DoubleMap * E2E tested against v3 & v4 * Filter with some * Split archive/remove alex tests * beforeAll -> beforeEach * Remove .only * EventRecordV0 -> 77
This commit is contained in:
@@ -11,9 +11,9 @@ import EnumType from '../../codec/EnumType';
|
||||
import Struct from '../../codec/Struct';
|
||||
import Vector from '../../codec/Vector';
|
||||
import Bytes from '../../primitive/Bytes';
|
||||
import Null from '../../primitive/Null';
|
||||
import Text from '../../primitive/Text';
|
||||
import Type from '../../primitive/Type';
|
||||
import { DoubleMapType } from '../v4/Storage';
|
||||
|
||||
export class StorageFunctionModifier extends Enum {
|
||||
constructor (value?: any) {
|
||||
@@ -33,6 +33,8 @@ export class StorageFunctionModifier extends Enum {
|
||||
}
|
||||
}
|
||||
|
||||
export class DoubleMapType extends Null {}
|
||||
|
||||
export class MapType extends Struct {
|
||||
private _isLinked = false;
|
||||
|
||||
@@ -72,7 +74,7 @@ export class MapType extends Struct {
|
||||
export class PlainType extends Type {
|
||||
}
|
||||
|
||||
export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMapType> {
|
||||
export class StorageFunctionType extends EnumType<PlainType | MapType> {
|
||||
constructor (value?: any, index?: number) {
|
||||
super({
|
||||
PlainType,
|
||||
@@ -82,16 +84,11 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a doublemap
|
||||
*/
|
||||
get isDoubleMap (): boolean {
|
||||
return this.toNumber() === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a double mapped value
|
||||
* @description The value as a mapped value
|
||||
*/
|
||||
get asDoubleMap (): DoubleMapType {
|
||||
assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`);
|
||||
|
||||
return this.value as DoubleMapType;
|
||||
}
|
||||
|
||||
@@ -113,6 +110,13 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
return this.value as PlainType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a double map
|
||||
*/
|
||||
get isDoubleMap (): boolean {
|
||||
return this.toNumber() === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a map
|
||||
*/
|
||||
@@ -132,10 +136,8 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
*/
|
||||
toString (): string {
|
||||
if (this.isDoubleMap) {
|
||||
return this.asDoubleMap.value.toString();
|
||||
}
|
||||
|
||||
if (this.isMap) {
|
||||
return `DoubleMap<${this.asDoubleMap.toString()}>`;
|
||||
} else if (this.isMap) {
|
||||
if (this.asMap.isLinked) {
|
||||
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import Struct from '../../codec/Struct';
|
||||
import Vector from '../../codec/Vector';
|
||||
import Bool from '../../primitive/Bool';
|
||||
import Bytes from '../../primitive/Bytes';
|
||||
import Null from '../../primitive/Null';
|
||||
import Text from '../../primitive/Text';
|
||||
import Type from '../../primitive/Type';
|
||||
import { PlainType, StorageFunctionModifier } from '../v1/Storage';
|
||||
import { DoubleMapType } from './../v4/Storage';
|
||||
|
||||
// Re-export classes that haven't changed between V1 and V2
|
||||
export {
|
||||
@@ -22,6 +22,8 @@ export {
|
||||
StorageFunctionModifier
|
||||
};
|
||||
|
||||
export class DoubleMapType extends Null {}
|
||||
|
||||
export class MapType extends Struct {
|
||||
constructor (value?: any) {
|
||||
super({
|
||||
@@ -53,7 +55,7 @@ export class MapType extends Struct {
|
||||
}
|
||||
}
|
||||
|
||||
export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMapType> {
|
||||
export class StorageFunctionType extends EnumType<PlainType | MapType> {
|
||||
constructor (value?: any, index?: number) {
|
||||
super({
|
||||
PlainType,
|
||||
@@ -63,16 +65,11 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a doublemap
|
||||
*/
|
||||
get isDoubleMap (): boolean {
|
||||
return this.toNumber() === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The value as a double mapped value
|
||||
* @description The value as a mapped value
|
||||
*/
|
||||
get asDoubleMap (): DoubleMapType {
|
||||
assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`);
|
||||
|
||||
return this.value as DoubleMapType;
|
||||
}
|
||||
|
||||
@@ -94,6 +91,13 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
return this.value as PlainType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a double map
|
||||
*/
|
||||
get isDoubleMap (): boolean {
|
||||
return this.toNumber() === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description `true` if the storage entry is a map
|
||||
*/
|
||||
@@ -113,9 +117,8 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
*/
|
||||
toString (): string {
|
||||
if (this.isDoubleMap) {
|
||||
return this.asDoubleMap.value.toString();
|
||||
}
|
||||
if (this.isMap) {
|
||||
return `DoubleMap<${this.asDoubleMap.toString()}>`;
|
||||
} else if (this.isMap) {
|
||||
if (this.asMap.isLinked) {
|
||||
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
|
||||
}
|
||||
|
||||
@@ -126,10 +126,8 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
|
||||
*/
|
||||
toString (): string {
|
||||
if (this.isDoubleMap) {
|
||||
return this.asDoubleMap.value.toString();
|
||||
}
|
||||
|
||||
if (this.isMap) {
|
||||
return `DoubleMap<${this.asDoubleMap.toString()}>`;
|
||||
} else if (this.isMap) {
|
||||
if (this.asMap.isLinked) {
|
||||
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ import { MetadataCall } from '../v1/Calls';
|
||||
import { MetadataEvent } from '../v1/Events';
|
||||
import { StorageFunctionMetadata } from './Storage';
|
||||
|
||||
export {
|
||||
MetadataEvent
|
||||
};
|
||||
|
||||
/**
|
||||
* @name MetadataModule
|
||||
* @description
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { Codec, Constructor, ConstructorDef } from '../types';
|
||||
|
||||
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, u8aConcat, u8aToHex } from '@plugnet/util';
|
||||
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, u8aConcat, u8aToHex } from '@plugnet/util';
|
||||
|
||||
import Null from '../primitive/Null';
|
||||
import Base from './Base';
|
||||
@@ -98,15 +98,19 @@ export default class EnumType<T> extends Base<Codec> implements Codec {
|
||||
const aliasKey = aliasses[keyLower] || keyLower;
|
||||
const index = keys.indexOf(aliasKey);
|
||||
|
||||
assert(index !== -1, `Cannot map input on JSON, unable to find '${key}' in ${keys.join(', ')}`);
|
||||
assert(index !== -1, `Cannot map EnumType JSON, unable to find '${key}' in ${keys.join(', ')}`);
|
||||
|
||||
return EnumType.createValue(def, index, value);
|
||||
}
|
||||
|
||||
private static createValue (def: TypesDef, index: number = 0, value?: any): Decoded {
|
||||
const Clazz = Object.values(def)[index];
|
||||
|
||||
assert(!isUndefined(Clazz), `Unable to create EnumType via index ${index}, in ${Object.keys(def).join(', ')}`);
|
||||
|
||||
return {
|
||||
index,
|
||||
value: new (Object.values(def)[index])(value)
|
||||
value: new Clazz(value)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { u8aToU8a } from '@plugnet/util';
|
||||
import { u8aToU8a, assert } from '@plugnet/util';
|
||||
|
||||
import Compact from './Compact';
|
||||
import { Codec, Constructor } from '../types';
|
||||
import { decodeU8a } from './utils';
|
||||
import AbstractArray from './AbstractArray';
|
||||
|
||||
const MAX_LENGTH = 32768;
|
||||
|
||||
/**
|
||||
* @name Vector
|
||||
* @description
|
||||
@@ -43,10 +45,11 @@ export default class Vector<T extends Codec> extends AbstractArray<T> {
|
||||
}
|
||||
|
||||
const u8a = u8aToU8a(value);
|
||||
const [offset, _length] = Compact.decodeU8a(u8a);
|
||||
const length = _length.toNumber();
|
||||
const [offset, length] = Compact.decodeU8a(u8a);
|
||||
|
||||
return decodeU8a(u8a.subarray(offset), new Array(length).fill(Type)) as T[];
|
||||
assert(length.lten(MAX_LENGTH), `Vector length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
|
||||
return decodeU8a(u8a.subarray(offset), new Array(length.toNumber()).fill(Type)) as T[];
|
||||
}
|
||||
|
||||
static with<O extends Codec> (Type: Constructor<O>): Constructor<Vector<O>> {
|
||||
|
||||
@@ -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 { isString, isU8a, u8aToU8a } from '@plugnet/util';
|
||||
import { assert, isString, isU8a, u8aToU8a } from '@plugnet/util';
|
||||
|
||||
import { AnyU8a } from '../types';
|
||||
import Compact from '../codec/Compact';
|
||||
@@ -46,10 +46,17 @@ export default class Bytes extends U8a {
|
||||
// i.e. new Bytes(new Bytes(...)) will work as expected
|
||||
return value;
|
||||
} else if (isU8a(value)) {
|
||||
if (!value.length) {
|
||||
return new Uint8Array();
|
||||
}
|
||||
|
||||
// handle all other Uint8Array inputs, these do have a length prefix
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
return value.subarray(offset, offset + length.toNumber());
|
||||
assert(total <= value.length, `Bytes: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return value.subarray(offset, total);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@@ -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 { isString, stringToU8a, u8aToString, u8aToHex } from '@plugnet/util';
|
||||
import { assert, isString, stringToU8a, u8aToString, u8aToHex } from '@plugnet/util';
|
||||
|
||||
import { AnyU8a, Codec } from '../types';
|
||||
import Compact from '../codec/Compact';
|
||||
@@ -31,9 +31,16 @@ export default class Text extends String implements Codec {
|
||||
if (isString(value)) {
|
||||
return value.toString();
|
||||
} else if (value instanceof Uint8Array) {
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
if (!value.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return u8aToString(value.subarray(offset, offset + length.toNumber()));
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
assert(total <= value.length, `Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return u8aToString(value.subarray(offset, total));
|
||||
}
|
||||
|
||||
return `${value}`;
|
||||
|
||||
@@ -4,30 +4,40 @@
|
||||
|
||||
import { Constructor } from '../types';
|
||||
|
||||
import { isUndefined, stringCamelCase, u8aToHex } from '@plugnet/util';
|
||||
import { assert, isUndefined, stringCamelCase, u8aToHex } from '@plugnet/util';
|
||||
|
||||
import Struct from '../codec/Struct';
|
||||
import Tuple from '../codec/Tuple';
|
||||
import U8aFixed from '../codec/U8aFixed';
|
||||
import Null from '../primitive/Null';
|
||||
import { TypeDef, getTypeClass, getTypeDef } from '../codec/createType';
|
||||
import MetadataV0 from '../Metadata/v0';
|
||||
import { EventMetadata } from '../Metadata/v0/Events';
|
||||
import Null from '../primitive/Null';
|
||||
import U32 from '../primitive/U32';
|
||||
import Metadata from '../Metadata';
|
||||
import { EventMetadata as EventMetadataV0 } from '../Metadata/v0/Events';
|
||||
import { MetadataEvent as EventMetadataV4 } from '../Metadata/v1/Events';
|
||||
|
||||
const EventTypes: { [index: string]: Constructor<EventData> } = {};
|
||||
|
||||
/**
|
||||
* @name EventIndex
|
||||
* @description
|
||||
* The Substrate EventIndex representation as a [[U32]].
|
||||
*/
|
||||
export class EventIndex extends U32 {
|
||||
}
|
||||
|
||||
/**
|
||||
* @name EventData
|
||||
* @description
|
||||
* Wrapper for the actual data that forms part of an [[Event]]
|
||||
*/
|
||||
export class EventData extends Tuple {
|
||||
private _meta: EventMetadata;
|
||||
private _meta: EventMetadataV0 | EventMetadataV4;
|
||||
private _method: string;
|
||||
private _section: string;
|
||||
private _typeDef: Array<TypeDef>;
|
||||
|
||||
constructor (Types: Array<Constructor>, value: Uint8Array, typeDef: Array<TypeDef>, meta: EventMetadata, section: string, method: string) {
|
||||
constructor (Types: Array<Constructor>, value: Uint8Array, typeDef: Array<TypeDef>, meta: EventMetadataV0 | EventMetadataV4, section: string, method: string) {
|
||||
super(Types, value);
|
||||
|
||||
this._meta = meta;
|
||||
@@ -39,7 +49,7 @@ export class EventData extends Tuple {
|
||||
/**
|
||||
* @description The wrapped [[EventMetadata]]
|
||||
*/
|
||||
get meta (): EventMetadata {
|
||||
get meta (): EventMetadataV0 | EventMetadataV4 {
|
||||
return this._meta;
|
||||
}
|
||||
|
||||
@@ -66,12 +76,12 @@ export class EventData extends Tuple {
|
||||
}
|
||||
|
||||
/**
|
||||
* @name EventIndex
|
||||
* @name EventId
|
||||
* @description
|
||||
* This follows the same approach as in [[Method]], we have the `[sectionIndex, methodIndex]` pairing
|
||||
* that indicates the actual event fired
|
||||
*/
|
||||
export class EventIndex extends U8aFixed {
|
||||
export class EventId extends U8aFixed {
|
||||
constructor (value?: any) {
|
||||
super(value, 16);
|
||||
}
|
||||
@@ -90,23 +100,22 @@ export default class Event extends Struct {
|
||||
const { DataType, value } = Event.decodeEvent(_value);
|
||||
|
||||
super({
|
||||
index: EventIndex,
|
||||
index: EventId,
|
||||
data: DataType
|
||||
}, value);
|
||||
}
|
||||
|
||||
static decodeEvent (value: Uint8Array = new Uint8Array()) {
|
||||
if (!value.length) {
|
||||
return {
|
||||
DataType: Null
|
||||
};
|
||||
}
|
||||
|
||||
const index = value.subarray(0, 2);
|
||||
const DataType = EventTypes[index.toString()];
|
||||
|
||||
if (isUndefined(DataType)) {
|
||||
console.error(`Unable to decode event for index ${u8aToHex(index)}`);
|
||||
|
||||
return {
|
||||
DataType: Null,
|
||||
value: undefined
|
||||
};
|
||||
}
|
||||
assert(!isUndefined(DataType), `Unable to decode event for index ${u8aToHex(index)}`);
|
||||
|
||||
return {
|
||||
DataType,
|
||||
@@ -119,23 +128,48 @@ export default class Event extends Struct {
|
||||
|
||||
// This is called/injected by the API on init, allowing a snapshot of
|
||||
// the available system events to be used in lookups
|
||||
static injectMetadata (metadata: MetadataV0): void {
|
||||
metadata.events.forEach((section, sectionIndex) => {
|
||||
const sectionName = stringCamelCase(section.name.toString());
|
||||
static injectMetadata (metadata: Metadata): void {
|
||||
if (metadata.version === 4) {
|
||||
let sectionIndex = 0;
|
||||
|
||||
section.events.forEach((meta, methodIndex) => {
|
||||
const methodName = meta.name.toString();
|
||||
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
|
||||
const typeDef = meta.arguments.map((arg) => getTypeDef(arg));
|
||||
const Types = typeDef.map(getTypeClass);
|
||||
metadata.asV4.modules.forEach((section) => {
|
||||
const sectionName = stringCamelCase(section.name.toString());
|
||||
|
||||
EventTypes[eventIndex.toString()] = class extends EventData {
|
||||
constructor (value: Uint8Array) {
|
||||
super(Types, value, typeDef, meta, sectionName, methodName);
|
||||
}
|
||||
};
|
||||
if (!section.events.isNone && !section.events.isEmpty) {
|
||||
section.events.unwrap().forEach((meta, methodIndex) => {
|
||||
const methodName = meta.name.toString();
|
||||
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
|
||||
const typeDef = meta.args.map((arg) => getTypeDef(arg));
|
||||
const Types = typeDef.map(getTypeClass);
|
||||
|
||||
EventTypes[eventIndex.toString()] = class extends EventData {
|
||||
constructor (value: Uint8Array) {
|
||||
super(Types, value, typeDef, meta, sectionName, methodName);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
sectionIndex += 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
metadata.asV0.events.forEach((section, sectionIndex) => {
|
||||
const sectionName = stringCamelCase(section.name.toString());
|
||||
|
||||
section.events.forEach((meta, methodIndex) => {
|
||||
const methodName = meta.name.toString();
|
||||
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
|
||||
const typeDef = meta.arguments.map((arg) => getTypeDef(arg));
|
||||
const Types = typeDef.map(getTypeClass);
|
||||
|
||||
EventTypes[eventIndex.toString()] = class extends EventData {
|
||||
constructor (value: Uint8Array) {
|
||||
super(Types, value, typeDef, meta, sectionName, methodName);
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,16 +180,16 @@ export default class Event extends Struct {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[EventIndex]], identifying the raw event
|
||||
* @description The [[EventId]], identifying the raw event
|
||||
*/
|
||||
get index (): EventIndex {
|
||||
return this.get('index') as EventIndex;
|
||||
get index (): EventId {
|
||||
return this.get('index') as EventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[EventMetadata]] with the documentation
|
||||
*/
|
||||
get meta (): EventMetadata {
|
||||
get meta (): EventMetadataV0 | EventMetadataV4 {
|
||||
return this.data.meta;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('EventRecord', () => {
|
||||
describe('v0', () => {
|
||||
beforeEach(() => {
|
||||
Event.injectMetadata(
|
||||
new Metadata(metadataV0).asV0
|
||||
new Metadata(metadataV0)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('EventRecord', () => {
|
||||
describe.skip('v1', () => {
|
||||
beforeEach(() => {
|
||||
Event.injectMetadata(
|
||||
new Metadata(metadataV1).asV0
|
||||
new Metadata(metadataV1)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ import { assert } from '@plugnet/util';
|
||||
|
||||
import EnumType from '../codec/EnumType';
|
||||
import Struct from '../codec/Struct';
|
||||
import Vector from '../codec/Vector';
|
||||
import Null from '../primitive/Null';
|
||||
import U32 from '../primitive/U32';
|
||||
import Hash from './Hash';
|
||||
import Event from './Event';
|
||||
|
||||
/**
|
||||
@@ -73,12 +75,12 @@ export class Phase extends EnumType<ApplyExtrinsic | Finalization> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @name EventRecord
|
||||
* @name EventRecord77
|
||||
* @description
|
||||
* A record for an [[Event]] (as specified by [[Metadata]]) with the specific [[Phase]] of
|
||||
* application.
|
||||
*/
|
||||
export default class EventRecord extends Struct {
|
||||
export class EventRecord77 extends Struct {
|
||||
constructor (value: any) {
|
||||
super({
|
||||
phase: Phase,
|
||||
@@ -99,4 +101,48 @@ export default class EventRecord extends Struct {
|
||||
get phase (): Phase {
|
||||
return this.get('phase') as Phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Hash]] topics for this event (empty, compat)
|
||||
*/
|
||||
get topics (): Vector<Hash> {
|
||||
return new (Vector.with(Hash))();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name EventRecord
|
||||
* @description
|
||||
* A record for an [[Event]] (as specified by [[Metadata]]) with the specific [[Phase]] of
|
||||
* application.
|
||||
*/
|
||||
export default class EventRecord extends Struct {
|
||||
constructor (value: any) {
|
||||
super({
|
||||
phase: Phase,
|
||||
event: Event,
|
||||
topics: Vector.with(Hash)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Event]] this record refers to
|
||||
*/
|
||||
get event (): Event {
|
||||
return this.get('event') as Event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Phase]] where the event was generated
|
||||
*/
|
||||
get phase (): Phase {
|
||||
return this.get('phase') as Phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Hash]] topics for this event
|
||||
*/
|
||||
get topics (): Vector<Hash> {
|
||||
return this.get('topics') as Vector<Hash>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { KeyringPair } from '@plugnet/keyring/types';
|
||||
import { AnyNumber, AnyU8a, ArgsDef, Codec, IExtrinsic, SignatureOptions } from '../types';
|
||||
|
||||
import { isHex, isU8a, u8aToHex, u8aToU8a } from '@plugnet/util';
|
||||
import { assert, isHex, isU8a, u8aToHex, u8aToU8a } from '@plugnet/util';
|
||||
import { blake2AsU8a } from '@plugnet/util-crypto';
|
||||
|
||||
import Compact from '../codec/Compact';
|
||||
@@ -58,9 +58,16 @@ export default class Extrinsic extends Struct implements IExtrinsic {
|
||||
: Compact.addLengthPrefix(u8a)
|
||||
);
|
||||
} else if (isU8a(value)) {
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
if (!value.length) {
|
||||
return new Uint8Array();
|
||||
}
|
||||
|
||||
return value.subarray(offset, offset + length.toNumber());
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
assert(total <= value.length, `Extrinsic: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return value.subarray(offset, total);
|
||||
} else if (value instanceof Method) {
|
||||
return {
|
||||
method: value
|
||||
|
||||
@@ -25,9 +25,8 @@ export { default as BlockNumber } from './BlockNumber';
|
||||
export { default as CodeHash } from './CodeHash';
|
||||
export { default as ContractInfo } from './ContractInfo';
|
||||
export { default as Digest, DigestItem } from './Digest';
|
||||
export { default as Event } from './Event';
|
||||
export { default as EventIndex } from './EventIndex';
|
||||
export { default as EventRecord } from './EventRecord';
|
||||
export { default as Event, EventIndex } from './Event';
|
||||
export { default as EventRecord, EventRecord77 } from './EventRecord';
|
||||
export { default as Exposure } from './Exposure';
|
||||
export { default as Extrinsic } from './Extrinsic';
|
||||
export { default as ExtrinsicEra } from './ExtrinsicEra';
|
||||
|
||||
Reference in New Issue
Block a user