refactor: Metadata overhaul (#913)

* Replace part1

* Replace part2

* Replace part3

* Replace part5

* Replace part6

* Fix small bugs

* Fix double map toString

* Small fixes

* Update to v4

* Fix docs script

* Grumbles

* Alphabetical

* Reads better

* comment

* module to modul
This commit is contained in:
Amaury Martiny
2019-06-12 16:45:45 +12:00
committed by Ian He
parent 194077033a
commit 2699dcfc9c
77 changed files with 1198 additions and 4550 deletions
@@ -2,8 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { MetadataInterface } from './types';
import { assert, isUndefined } from '@plugnet/util';
import EnumType from '../codec/EnumType';
@@ -15,10 +13,10 @@ import MetadataV1 from './v1';
import MetadataV2 from './v2';
import MetadataV3 from './v3';
import MetadataV4 from './v4';
import v1ToV0 from './v1/toV0';
import v2ToV1 from './v2/toV1';
import v3ToV2 from './v3/toV2';
import v4ToV3 from './v4/toV3';
import v0ToV1 from './v0/toV1';
import v1ToV2 from './v1/toV2';
import v2ToV3 from './v2/toV3';
import v3ToV4 from './v3/toV4';
class MetadataDeprecated extends Null {
}
@@ -134,11 +132,11 @@ class MetadataEnum extends EnumType<MetadataDeprecated | MetadataV0 | MetadataV1
* @description
* The versioned runtime metadata as a decoded structure
*/
export default class MetadataVersioned extends Struct implements MetadataInterface {
private _convertedV0?: MetadataV0;
export default class MetadataVersioned extends Struct {
private _convertedV1?: MetadataV1;
private _convertedV2?: MetadataV2;
private _convertedV3?: MetadataV3;
private _convertedV4?: MetadataV4;
constructor (value?: any) {
super({
@@ -172,29 +170,23 @@ export default class MetadataVersioned extends Struct implements MetadataInterfa
* @description Returns the wrapped metadata as a V0 object
*/
get asV0 (): MetadataV0 {
if (this.metadata.version === 0) {
return this.metadata.asV0;
}
assert(this.metadata.version === 0, `Cannot convert metadata from v${this.metadata.version} to v0`);
if (isUndefined(this._convertedV0)) {
this._convertedV0 = v1ToV0(this.asV1);
}
return this._convertedV0;
return this.metadata.asV0;
}
/**
* @description Returns the wrapped values as a V1 object
*/
get asV1 (): MetadataV1 {
assert(this.metadata.version <= 1, `Cannot convert metadata from v${this.metadata.version} to v1`);
if (this.metadata.version === 1) {
return this.metadata.asV1;
}
assert([2, 3, 4].includes(this.metadata.version), `Cannot convert metadata from v${this.metadata.version} to v1`);
if (isUndefined(this._convertedV1)) {
this._convertedV1 = v2ToV1(this.asV2);
this._convertedV1 = v0ToV1(this.asV0);
}
return this._convertedV1;
@@ -204,14 +196,14 @@ export default class MetadataVersioned extends Struct implements MetadataInterfa
* @description Returns the wrapped values as a V2 object
*/
get asV2 (): MetadataV2 {
assert(this.metadata.version <= 2, `Cannot convert metadata from v${this.metadata.version} to v2`);
if (this.metadata.version === 2) {
return this.metadata.asV2;
}
assert([3, 4].includes(this.metadata.version), `Cannot convert metadata from v${this.metadata.version} to v2`);
if (isUndefined(this._convertedV2)) {
this._convertedV2 = v3ToV2(this.asV3);
this._convertedV2 = v1ToV2(this.asV1);
}
return this._convertedV2;
@@ -221,29 +213,37 @@ export default class MetadataVersioned extends Struct implements MetadataInterfa
* @description Returns the wrapped values as a V3 object
*/
get asV3 (): MetadataV3 {
assert(this.metadata.version <= 3, `Cannot convert metadata from v${this.metadata.version} to v3`);
if (this.metadata.version === 3) {
return this.metadata.asV3;
}
assert([4].includes(this.metadata.version), `Cannot convert metadata from v${this.metadata.version} to v3`);
if (isUndefined(this._convertedV3)) {
this._convertedV3 = v4ToV3(this.asV4);
this._convertedV3 = v2ToV3(this.asV2);
}
return this._convertedV3;
}
getUniqTypes (throwError: boolean): Array<string> {
return (this.metadata.value as any as MetadataInterface).getUniqTypes(throwError);
return this.asV4.getUniqTypes(throwError);
}
/**
* @description Returns the wrapped values as a V3 object
* @description Returns the wrapped values as a V4 object
*/
get asV4 (): MetadataV4 {
assert(this.metadata.version === 4, `Cannot convert metadata from v${this.metadata.version} to v4`);
assert(this.metadata.version <= 4, `Cannot convert metadata from v${this.metadata.version} to v3`);
return this.metadata.asV4;
if (this.metadata.version === 4) {
return this.metadata.asV4;
}
if (isUndefined(this._convertedV4)) {
this._convertedV4 = v3ToV4(this.asV3);
}
return this._convertedV4;
}
}
+1 -1
View File
@@ -2,6 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import metadata from './v3/static';
import metadata from './v4/static';
export default metadata;
+5 -1
View File
@@ -2,6 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export interface MetadataInterface {
import { Vector } from '../codec';
import { Codec } from '../types';
export interface MetadataInterface<Modules extends Codec> extends Codec {
modules: Vector<Modules>;
getUniqTypes (throwError: boolean): Array<string>;
}
@@ -0,0 +1,68 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import extrinsicsFromMeta from '@polkadot/extrinsics/fromMetadata';
import createType from '../../codec/createType';
import Metadata from '../Metadata';
import Method from '../../primitive/Method';
import { MetadataInterface } from '../types';
import { Codec } from '../../types';
/**
* Given the static `rpcData` and the `latestSubstrate` JSON file, Metadata
* should decode `rpcData` and output `latestSubstrate`.
*/
export function decodeLatestSubstrate<Modules extends Codec> (
version: number,
rpcData: string,
latestSubstrate: object
) {
it('decodes latest substrate properly', () => {
const metadata = new Metadata(rpcData);
console.error(JSON.stringify(metadata.toJSON()));
expect(metadata.version).toBe(version);
expect((metadata[`asV${version}` as keyof Metadata] as unknown as MetadataInterface<Modules>).modules.length).not.toBe(0);
expect(metadata.toJSON()).toEqual(latestSubstrate);
});
}
/**
* Given a `version`, MetadataV4 and MetadataV{version} should output the same
* unique types.
*/
export function toV4<Modules extends Codec> (version: number, rpcData: string) {
it('converts to V4', () => {
const metadata = new Metadata(rpcData)[`asV${version}` as keyof Metadata];
const metadataV4 = new Metadata(rpcData).asV4;
expect(
(metadata as unknown as MetadataInterface<Modules>).getUniqTypes(true)
).toEqual(metadataV4.getUniqTypes(true));
});
}
/**
* Given a Metadata, no type should throw when given its fallback value.
*/
export function defaultValues (rpcData: string) {
describe('storage with default values', () => {
const metadata = new Metadata(rpcData);
Method.injectMethods(extrinsicsFromMeta(metadata));
metadata.asV4.modules
.filter(({ storage }) => storage.isSome)
.map((mod) =>
mod.storage.unwrap().forEach(({ fallback, name, type }) => {
it(`creates default types for ${mod.prefix}.${name}, type ${type}`, () => {
expect(
() => createType(type.toString(), fallback)
).not.toThrow();
});
})
);
});
}
+15 -7
View File
@@ -12,7 +12,7 @@ export class EventMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
arguments: Vector.with(Type),
args: Vector.with(Type),
documentation: Vector.with(Text)
}, value);
}
@@ -20,8 +20,16 @@ export class EventMetadata extends Struct {
/**
* @description The arguments of [[Type]]
*/
get args (): Vector<Type> {
return this.get('args') as Vector<Type>;
}
/**
* @description The arguments of [[Type]]
* @deprecated Use `.args` instead
*/
get arguments (): Vector<Type> {
return this.get('arguments') as Vector<Type>;
return this.args;
}
/**
@@ -47,7 +55,7 @@ export class EventMetadata extends Struct {
}
}
export class OuterEventMetadataEvent extends Tuple {
export class OuterEventEventMetadata extends Tuple {
constructor (value?: any) {
super({
Text,
@@ -74,15 +82,15 @@ export class OuterEventMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
events: Vector.with(OuterEventMetadataEvent)
events: Vector.with(OuterEventEventMetadata)
}, value);
}
/**
* @description The [[OuterEventMetadataEvent]]
* @description The [[OuterEventEventMetadata]]
*/
get events (): Vector<OuterEventMetadataEvent> {
return this.get('events') as Vector<OuterEventMetadataEvent>;
get events (): Vector<OuterEventEventMetadata> {
return this.get('events') as Vector<OuterEventEventMetadata>;
}
/**
+17 -26
View File
@@ -2,41 +2,32 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import extrinsicsFromMeta from '@plugnet/extrinsics/fromMetadata';
import createType from '../../codec/createType';
import Method from '../../primitive/Method';
import Metadata from './Metadata';
import latestParsed from './latest.substrate.json';
import MetadataV0 from './';
import Metadata from '../';
import latestSubstrateV0 from './latest.substrate.v0.json';
import rpcData from './static';
import { defaultValues, toV4 } from '../util/testUtil';
describe('Metadata', () => {
it('decodes latest properly', () => {
it('works with fallback', () => {
const metadata = new Metadata(rpcData);
const str = JSON.stringify(metadata.toJSON());
const metadataV0 = new MetadataV0(rpcData);
expect(metadata.events.length).not.toBe(0);
expect(str).toEqual(JSON.stringify(latestParsed));
expect(metadata.asV0.toString()).toEqual(metadataV0.toString());
});
describe('storage with default values', () => {
it('decodes latest substrate properly', () => {
const metadata = new Metadata(rpcData);
const json = metadata.asV0.toJSON();
Method.injectMethods(extrinsicsFromMeta(metadata));
console.error(JSON.stringify(json));
metadata.modules.forEach((mod) => {
if (mod.storage.isNone) {
return;
}
mod.storage.unwrap().functions.forEach((fn) => {
it(`creates default types for ${mod.prefix}.${fn.name}, type ${fn.type}`, () => {
expect(
() => createType(fn.type.toString(), fn.fallback)
).not.toThrow();
});
});
});
expect(metadata.version).toBe(0);
expect(metadata.asV0.modules.length).not.toBe(0);
expect(json).toEqual(latestSubstrateV0);
});
toV4(0, rpcData);
defaultValues(rpcData);
});
+14 -16
View File
@@ -11,19 +11,17 @@ import Struct from '../../codec/Struct';
import Vector from '../../codec/Vector';
import { flattenUniq, validateTypes } from '../util';
import { OuterDispatchMetadata, OuterDispatchCall } from './Calls';
import { OuterEventMetadata, OuterEventMetadataEvent } from './Events';
import { OuterEventMetadata, OuterEventEventMetadata } from './Events';
import { RuntimeModuleMetadata } from './Modules';
// Decodes the runtime metadata as passed through from the `state_getMetadata` call. This
// file is probably best understood from the bottom-up, i.e. start reading right at the
// end and work up. (Just so we don't use before definition)
// Decodes the runtime metadata as passed through from the `state_getMetadata` call.
/**
* @name MetadataV0
* @description
* The runtime metadata as a decoded structure
*/
export default class MetadataV0 extends Struct implements MetadataInterface {
export default class MetadataV0 extends Struct implements MetadataInterface<RuntimeModuleMetadata> {
constructor (value?: any) {
super({
outerEvent: OuterEventMetadata,
@@ -62,9 +60,9 @@ export default class MetadataV0 extends Struct implements MetadataInterface {
}
/**
* @description Wrapped [[OuterEventMetadataEvent]]
* @description Wrapped [[OuterEventEventMetadata]]
*/
get events (): Vector<OuterEventMetadataEvent> {
get events (): Vector<OuterEventEventMetadata> {
return (this.get('outerEvent') as OuterEventMetadata).events;
}
@@ -76,25 +74,25 @@ export default class MetadataV0 extends Struct implements MetadataInterface {
}
private get argNames () {
return this.modules.map((module) =>
module.module.call.functions.map((fn) =>
fn.arguments.map((argument) => argument.type.toString())
return this.modules.map((modul) =>
modul.module.call.functions.map((fn) =>
fn.args.map((argument) => argument.type.toString())
)
);
}
private get eventNames () {
return this.events.map((module) =>
module.events.map((event) =>
event.arguments.map((argument) => argument.toString())
return this.events.map((modul) =>
modul.events.map((event) =>
event.args.map((argument) => argument.toString())
)
);
}
private get storageNames () {
return this.modules.map((module) =>
module.storage.isSome
? module.storage.unwrap().functions.map((fn) =>
return this.modules.map((modul) =>
modul.storage.isSome
? modul.storage.unwrap().functions.map((fn) =>
fn.type.isMap
? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]
: [fn.type.asType.toString()]
+10 -3
View File
@@ -39,13 +39,21 @@ export class FunctionMetadata extends Struct {
super({
id: U16,
name: Text,
arguments: Vector.with(FunctionArgumentMetadata),
args: Vector.with(FunctionArgumentMetadata),
documentation: Vector.with(Text)
}, value);
}
/**
* @description The arguments of [[Type]]
*/
get args (): Vector<FunctionArgumentMetadata> {
return this.get('args') as Vector<FunctionArgumentMetadata>;
}
/**
* @description The [[FunctionArgumentMetadata]] for arguments
* @deprecated Use `.args` instead
*/
get arguments (): Vector<FunctionArgumentMetadata> {
return this.get('arguments') as Vector<FunctionArgumentMetadata>;
@@ -103,7 +111,6 @@ export class CallMetadata extends Struct {
return this.get('name') as Text;
}
}
export class ModuleMetadata extends Struct {
constructor (value?: any) {
super({
@@ -113,7 +120,7 @@ export class ModuleMetadata extends Struct {
}
/**
* @description The calls as [[CallMetadata]]
* @description The calls as [[FunctionMetadata]]
*/
get call (): CallMetadata {
return this.get('call') as CallMetadata;
+2 -24
View File
@@ -11,7 +11,6 @@ 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';
@@ -33,8 +32,6 @@ export class StorageFunctionModifier extends Enum {
}
}
export class DoubleMapType extends Null {}
export class MapType extends Struct {
private _isLinked = false;
@@ -78,20 +75,10 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
constructor (value?: any, index?: number) {
super({
PlainType,
MapType,
DoubleMapType
MapType
}, value, index);
}
/**
* @description The value as a mapped value
*/
get asDoubleMap (): DoubleMapType {
assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`);
return this.value as DoubleMapType;
}
/**
* @description The value as a mapped value
*/
@@ -110,13 +97,6 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
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
*/
@@ -135,9 +115,7 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
* @description Returns the string representation of the value
*/
toString (): string {
if (this.isDoubleMap) {
return `DoubleMap<${this.asDoubleMap.toString()}>`;
} else if (this.isMap) {
if (this.isMap) {
if (this.asMap.isLinked) {
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
}
@@ -7,14 +7,14 @@
[
{
"name": "ExtrinsicSuccess",
"arguments": [],
"args": [],
"documentation": [
" An extrinsic completed successfully."
]
},
{
"name": "ExtrinsicFailed",
"arguments": [],
"args": [],
"documentation": [
" An extrinsic failed."
]
@@ -26,7 +26,7 @@
[
{
"name": "NewAccount",
"arguments": [
"args": [
"AccountId",
"AccountIndex",
"NewAccountOutcome"
@@ -37,7 +37,7 @@
},
{
"name": "ReapedAccount",
"arguments": [
"args": [
"AccountId"
],
"documentation": [
@@ -46,7 +46,7 @@
},
{
"name": "Transfer",
"arguments": [
"args": [
"AccountId",
"AccountId",
"Balance",
@@ -63,7 +63,7 @@
[
{
"name": "NewSession",
"arguments": [
"args": [
"BlockNumber"
],
"documentation": [
@@ -78,7 +78,7 @@
[
{
"name": "Reward",
"arguments": [
"args": [
"Balance"
],
"documentation": [
@@ -87,7 +87,7 @@
},
{
"name": "OfflineWarning",
"arguments": [
"args": [
"AccountId",
"u32"
],
@@ -98,7 +98,7 @@
},
{
"name": "OfflineSlash",
"arguments": [
"args": [
"AccountId",
"Balance"
],
@@ -113,7 +113,7 @@
[
{
"name": "Tabled",
"arguments": [
"args": [
"PropIndex",
"Balance",
"Vec<AccountId>"
@@ -122,7 +122,7 @@
},
{
"name": "Started",
"arguments": [
"args": [
"ReferendumIndex",
"VoteThreshold"
],
@@ -130,28 +130,28 @@
},
{
"name": "Passed",
"arguments": [
"args": [
"ReferendumIndex"
],
"documentation": []
},
{
"name": "NotPassed",
"arguments": [
"args": [
"ReferendumIndex"
],
"documentation": []
},
{
"name": "Cancelled",
"arguments": [
"args": [
"ReferendumIndex"
],
"documentation": []
},
{
"name": "Executed",
"arguments": [
"args": [
"ReferendumIndex",
"bool"
],
@@ -164,7 +164,7 @@
[
{
"name": "NewAuthorities",
"arguments": [
"args": [
"Vec<(SessionKey,u64)>"
],
"documentation": [
@@ -178,7 +178,7 @@
[
{
"name": "VoterReaped",
"arguments": [
"args": [
"AccountId",
"AccountId"
],
@@ -188,7 +188,7 @@
},
{
"name": "BadReaperSlashed",
"arguments": [
"args": [
"AccountId"
],
"documentation": [
@@ -197,7 +197,7 @@
},
{
"name": "TallyStarted",
"arguments": [
"args": [
"u32"
],
"documentation": [
@@ -206,7 +206,7 @@
},
{
"name": "TallyFinalised",
"arguments": [
"args": [
"Vec<AccountId>",
"Vec<AccountId>"
],
@@ -221,7 +221,7 @@
[
{
"name": "TallyCancelation",
"arguments": [
"args": [
"Hash",
"u32",
"u32",
@@ -234,7 +234,7 @@
},
{
"name": "TallyReferendum",
"arguments": [
"args": [
"Hash",
"u32",
"u32",
@@ -252,7 +252,7 @@
[
{
"name": "Proposed",
"arguments": [
"args": [
"AccountId",
"ProposalIndex",
"Hash",
@@ -264,7 +264,7 @@
},
{
"name": "Voted",
"arguments": [
"args": [
"AccountId",
"Hash",
"bool",
@@ -278,7 +278,7 @@
},
{
"name": "Approved",
"arguments": [
"args": [
"Hash"
],
"documentation": [
@@ -287,7 +287,7 @@
},
{
"name": "Disapproved",
"arguments": [
"args": [
"Hash"
],
"documentation": [
@@ -296,7 +296,7 @@
},
{
"name": "Executed",
"arguments": [
"args": [
"Hash",
"bool"
],
@@ -311,7 +311,7 @@
[
{
"name": "Proposed",
"arguments": [
"args": [
"ProposalIndex"
],
"documentation": [
@@ -320,7 +320,7 @@
},
{
"name": "Spending",
"arguments": [
"args": [
"Balance"
],
"documentation": [
@@ -329,7 +329,7 @@
},
{
"name": "Awarded",
"arguments": [
"args": [
"ProposalIndex",
"Balance",
"AccountId"
@@ -340,7 +340,7 @@
},
{
"name": "Burnt",
"arguments": [
"args": [
"Balance"
],
"documentation": [
@@ -349,7 +349,7 @@
},
{
"name": "Rollover",
"arguments": [
"args": [
"Balance"
],
"documentation": [
@@ -468,7 +468,7 @@
{
"id": 0,
"name": "set",
"arguments": [
"args": [
{
"name": "now",
"type": "Compact<Moment>"
@@ -528,7 +528,7 @@
{
"id": 0,
"name": "report_misbehavior",
"arguments": [
"args": [
{
"name": "_report",
"type": "Bytes"
@@ -541,7 +541,7 @@
{
"id": 1,
"name": "note_offline",
"arguments": [
"args": [
{
"name": "offline",
"type": "InherentOfflineReport"
@@ -554,7 +554,7 @@
{
"id": 2,
"name": "remark",
"arguments": [
"args": [
{
"name": "_remark",
"type": "Bytes"
@@ -567,7 +567,7 @@
{
"id": 3,
"name": "set_heap_pages",
"arguments": [
"args": [
{
"name": "pages",
"type": "u64"
@@ -580,7 +580,7 @@
{
"id": 4,
"name": "set_code",
"arguments": [
"args": [
{
"name": "new",
"type": "Bytes"
@@ -593,7 +593,7 @@
{
"id": 5,
"name": "set_storage",
"arguments": [
"args": [
{
"name": "items",
"type": "Vec<KeyValue>"
@@ -628,7 +628,7 @@
{
"id": 0,
"name": "transfer",
"arguments": [
"args": [
{
"name": "dest",
"type": "Address"
@@ -645,7 +645,7 @@
{
"id": 1,
"name": "set_balance",
"arguments": [
"args": [
{
"name": "who",
"type": "Address"
@@ -800,7 +800,7 @@
{
"id": 0,
"name": "set_key",
"arguments": [
"args": [
{
"name": "key",
"type": "SessionKey"
@@ -814,7 +814,7 @@
{
"id": 1,
"name": "set_length",
"arguments": [
"args": [
{
"name": "new",
"type": "Compact<BlockNumber>"
@@ -827,7 +827,7 @@
{
"id": 2,
"name": "force_new_session",
"arguments": [
"args": [
{
"name": "apply_rewards",
"type": "bool"
@@ -924,7 +924,7 @@
{
"id": 0,
"name": "stake",
"arguments": [],
"args": [],
"documentation": [
" Declare the desire to stake for the transactor.",
"",
@@ -934,7 +934,7 @@
{
"id": 1,
"name": "unstake",
"arguments": [
"args": [
{
"name": "intentions_index",
"type": "Compact<u32>"
@@ -949,7 +949,7 @@
{
"id": 2,
"name": "nominate",
"arguments": [
"args": [
{
"name": "target",
"type": "Address"
@@ -960,7 +960,7 @@
{
"id": 3,
"name": "unnominate",
"arguments": [
"args": [
{
"name": "target_index",
"type": "Compact<u32>"
@@ -974,7 +974,7 @@
{
"id": 4,
"name": "register_preferences",
"arguments": [
"args": [
{
"name": "intentions_index",
"type": "Compact<u32>"
@@ -993,7 +993,7 @@
{
"id": 5,
"name": "set_sessions_per_era",
"arguments": [
"args": [
{
"name": "new",
"type": "Compact<BlockNumber>"
@@ -1006,7 +1006,7 @@
{
"id": 6,
"name": "set_bonding_duration",
"arguments": [
"args": [
{
"name": "new",
"type": "Compact<BlockNumber>"
@@ -1019,7 +1019,7 @@
{
"id": 7,
"name": "set_validator_count",
"arguments": [
"args": [
{
"name": "new",
"type": "Compact<u32>"
@@ -1032,7 +1032,7 @@
{
"id": 8,
"name": "force_new_era",
"arguments": [
"args": [
{
"name": "apply_rewards",
"type": "bool"
@@ -1046,7 +1046,7 @@
{
"id": 9,
"name": "set_offline_slash_grace",
"arguments": [
"args": [
{
"name": "new",
"type": "Compact<u32>"
@@ -1261,7 +1261,7 @@
{
"id": 0,
"name": "propose",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Proposal"
@@ -1278,7 +1278,7 @@
{
"id": 1,
"name": "second",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Compact<PropIndex>"
@@ -1291,7 +1291,7 @@
{
"id": 2,
"name": "vote",
"arguments": [
"args": [
{
"name": "ref_index",
"type": "Compact<ReferendumIndex>"
@@ -1309,7 +1309,7 @@
{
"id": 3,
"name": "start_referendum",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Proposal"
@@ -1330,7 +1330,7 @@
{
"id": 4,
"name": "cancel_referendum",
"arguments": [
"args": [
{
"name": "ref_index",
"type": "Compact<ReferendumIndex>"
@@ -1343,7 +1343,7 @@
{
"id": 5,
"name": "cancel_queued",
"arguments": [
"args": [
{
"name": "when",
"type": "BlockNumber"
@@ -1506,7 +1506,7 @@
{
"id": 0,
"name": "report_misbehavior",
"arguments": [
"args": [
{
"name": "_report",
"type": "Bytes"
@@ -1541,7 +1541,7 @@
{
"id": 0,
"name": "set_approvals",
"arguments": [
"args": [
{
"name": "votes",
"type": "Vec<bool>"
@@ -1559,7 +1559,7 @@
{
"id": 1,
"name": "reap_inactive_voter",
"arguments": [
"args": [
{
"name": "reporter_index",
"type": "Compact<u32>"
@@ -1588,7 +1588,7 @@
{
"id": 2,
"name": "retract_voter",
"arguments": [
"args": [
{
"name": "index",
"type": "Compact<u32>"
@@ -1601,7 +1601,7 @@
{
"id": 3,
"name": "submit_candidacy",
"arguments": [
"args": [
{
"name": "slot",
"type": "Compact<u32>"
@@ -1616,7 +1616,7 @@
{
"id": 4,
"name": "present_winner",
"arguments": [
"args": [
{
"name": "candidate",
"type": "Address"
@@ -1639,7 +1639,7 @@
{
"id": 5,
"name": "set_desired_seats",
"arguments": [
"args": [
{
"name": "count",
"type": "Compact<u32>"
@@ -1654,7 +1654,7 @@
{
"id": 6,
"name": "remove_member",
"arguments": [
"args": [
{
"name": "who",
"type": "Address"
@@ -1669,7 +1669,7 @@
{
"id": 7,
"name": "set_presentation_duration",
"arguments": [
"args": [
{
"name": "count",
"type": "Compact<BlockNumber>"
@@ -1683,7 +1683,7 @@
{
"id": 8,
"name": "set_term_duration",
"arguments": [
"args": [
{
"name": "count",
"type": "Compact<BlockNumber>"
@@ -1883,7 +1883,7 @@
{
"id": 0,
"name": "propose",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Proposal"
@@ -1894,7 +1894,7 @@
{
"id": 1,
"name": "vote",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Hash"
@@ -1909,7 +1909,7 @@
{
"id": 2,
"name": "veto",
"arguments": [
"args": [
{
"name": "proposal_hash",
"type": "Hash"
@@ -1920,7 +1920,7 @@
{
"id": 3,
"name": "set_cooloff_period",
"arguments": [
"args": [
{
"name": "blocks",
"type": "Compact<BlockNumber>"
@@ -1931,7 +1931,7 @@
{
"id": 4,
"name": "set_voting_period",
"arguments": [
"args": [
{
"name": "blocks",
"type": "Compact<BlockNumber>"
@@ -2020,7 +2020,7 @@
{
"id": 0,
"name": "propose",
"arguments": [
"args": [
{
"name": "threshold",
"type": "Compact<u32>"
@@ -2035,7 +2035,7 @@
{
"id": 1,
"name": "vote",
"arguments": [
"args": [
{
"name": "proposal",
"type": "Hash"
@@ -2108,7 +2108,7 @@
{
"id": 0,
"name": "propose_spend",
"arguments": [
"args": [
{
"name": "value",
"type": "Compact<Balance>"
@@ -2127,7 +2127,7 @@
{
"id": 1,
"name": "set_pot",
"arguments": [
"args": [
{
"name": "new_pot",
"type": "Compact<Balance>"
@@ -2140,7 +2140,7 @@
{
"id": 2,
"name": "configure",
"arguments": [
"args": [
{
"name": "proposal_bond",
"type": "Permill"
@@ -2165,7 +2165,7 @@
{
"id": 3,
"name": "reject_proposal",
"arguments": [
"args": [
{
"name": "proposal_id",
"type": "Compact<ProposalIndex>"
@@ -2178,7 +2178,7 @@
{
"id": 4,
"name": "approve_proposal",
"arguments": [
"args": [
{
"name": "proposal_id",
"type": "Compact<ProposalIndex>"
@@ -2276,7 +2276,7 @@
{
"id": 0,
"name": "set_heads",
"arguments": [
"args": [
{
"name": "heads",
"type": "Vec<AttestedCandidate>"
@@ -2289,7 +2289,7 @@
{
"id": 1,
"name": "register_parachain",
"arguments": [
"args": [
{
"name": "id",
"type": "Id"
@@ -2311,7 +2311,7 @@
{
"id": 2,
"name": "deregister_parachain",
"arguments": [
"args": [
{
"name": "id",
"type": "Id"
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { stringUpperFirst } from '@polkadot/util';
import { Option, Vector } from '../../codec';
import MetadataV0 from './Metadata';
import { RuntimeModuleMetadata } from './Modules';
import { Text } from '../../primitive';
import { FunctionMetadata } from '../v1/Calls';
import { EventMetadata } from '../v1/Events';
import MetadataV1, { ModuleMetadata } from '../v1/Metadata';
import { StorageFunctionMetadata } from '../v1/Storage';
function toV1Calls (modul: RuntimeModuleMetadata) {
return modul.module.call.functions.length === 0
? new Option(Vector.with(FunctionMetadata))
: new Option(Vector.with(FunctionMetadata), modul.module.call.functions);
}
function toV1Events (metadataV0: MetadataV0, prefix: Text) {
const events = metadataV0.events.find((event) => event.name.eq(prefix));
return events
? new Option(Vector.with(EventMetadata), events.events)
: new Option(Vector.with(EventMetadata));
}
function toV1Storage (modul: RuntimeModuleMetadata) {
return modul.storage.isNone
? new Option(Vector.with(StorageFunctionMetadata))
: new Option(
Vector.with(StorageFunctionMetadata),
modul.storage.unwrap().functions
);
}
/**
* Function that converts MetadataV0 to MetadataV1
*/
export default function toV1 (metadataV0: MetadataV0): MetadataV1 {
return new MetadataV1({
modules: metadataV0.modules.map((modul) => {
// The prefix of this module (capitalized)
const prefix = modul.storage.isSome
? modul.storage.unwrap().prefix.toString()
: stringUpperFirst(modul.prefix.toString()); // If this module doesn't have storage, we just assume the prefix is the name capitalized
return new ModuleMetadata({
name: modul.prefix, // Not capitalized
prefix, // Capitalized
storage: toV1Storage(modul),
calls: toV1Calls(modul),
events: toV1Events(metadataV0, modul.prefix)
});
})
});
}
+7 -17
View File
@@ -7,7 +7,7 @@ import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import Type from '../../primitive/Type';
export class MetadataCallArg extends Struct {
export class FunctionArgumentMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
@@ -31,27 +31,24 @@ export class MetadataCallArg extends Struct {
}
/**
* @name MetadataCall
* @name FunctionMetadata
* @description
* The definition of a call
*/
export class MetadataCall extends Struct {
export class FunctionMetadata extends Struct {
constructor (value?: any) {
super({
// NOTE Just commented out, it is not available in current, but an open question
// around the usefulness of supplying this remains (could be re-added)
// id: u16,
name: Text,
args: Vector.with(MetadataCallArg),
args: Vector.with(FunctionArgumentMetadata),
documentation: Vector.with(Text)
}, value);
}
/**
* @description The [[MetadataCallArg]] for arguments
* @description The [[FunctionArgumentMetadata]] for arguments
*/
get args (): Vector<MetadataCallArg> {
return this.get('args') as Vector<MetadataCallArg>;
get args (): Vector<FunctionArgumentMetadata> {
return this.get('args') as Vector<FunctionArgumentMetadata>;
}
/**
@@ -69,13 +66,6 @@ export class MetadataCall extends Struct {
return this.documentation;
}
// /**
// * @description The call function id
// */
// get id (): u16 {
// return this.get('id') as u16;
// }
/**
* @description The call name
*/
+2 -48
View File
@@ -2,51 +2,5 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Struct from '../../codec/Struct';
import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import Type from '../../primitive/Type';
/**
* @name MetadataEvent
* @description
* The definition of an event
*/
export class MetadataEvent extends Struct {
constructor (value?: any) {
super({
name: Text,
args: Vector.with(Type),
documentation: Vector.with(Text)
}, value);
}
/**
* @description The [[Type]] for args
*/
get args (): Vector<Type> {
return this.get('args') as Vector<Type>;
}
/**
* @description The [[Text]] documentation
*/
get documentation (): Vector<Text> {
return this.get('documentation') as Vector<Text>;
}
/**
* @description The [[Text]] documentation
* @deprecated Use `.documentation` instead.
*/
get docs (): Vector<Text> {
return this.documentation;
}
/**
* @description The call name
*/
get name (): Text {
return this.get('name') as Text;
}
}
// Re-export classes that haven't changed between V0 and V1
export { EventMetadata } from '../v0/Events';
@@ -2,45 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import extrinsicsFromMeta from '@plugnet/extrinsics/fromMetadata';
import createType from '../../codec/createType';
import Method from '../../primitive/Method';
import Metadata from '../Metadata';
import latestParsed from './latest.substrate.v1.json';
import latestSubstrate from './latest.substrate.v1.json';
import rpcData from './static';
import { decodeLatestSubstrate, defaultValues, toV4 } from '../util/testUtil';
describe('MetadataV1', () => {
const metadata = new Metadata(rpcData);
decodeLatestSubstrate(1, rpcData, latestSubstrate);
it('decodes latest properly', () => {
const str = JSON.stringify(metadata.toJSON());
toV4(1, rpcData);
expect(metadata.version).toBe(1);
expect(metadata.asV1.modules.length).not.toBe(0);
expect(str).toEqual(JSON.stringify(latestParsed));
});
it('converts v1 to V0', () => {
const v0 = metadata.asV0;
expect(metadata.getUniqTypes(true)).toEqual(v0.getUniqTypes(true));
});
describe('storage with default values', () => {
Method.injectMethods(extrinsicsFromMeta(metadata.asV0));
metadata.asV1.modules
.filter(({ storage }) => storage.isSome)
.map((mod) =>
mod.storage.unwrap().forEach(({ fallback, name, type }) => {
it(`creates default types for ${mod.prefix}.${name}, type ${type}`, () => {
expect(
() => createType(type.toString(), fallback)
).not.toThrow();
});
})
);
});
defaultValues(rpcData);
});
+14 -14
View File
@@ -10,38 +10,38 @@ import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import { flattenUniq, validateTypes } from '../util';
import { MetadataCall } from './Calls';
import { MetadataEvent } from './Events';
import { FunctionMetadata } from './Calls';
import { EventMetadata } from './Events';
import { StorageFunctionMetadata } from './Storage';
/**
* @name MetadataModule
* @name ModuleMetadata
* @description
* The definition of a module in the system
*/
export class MetadataModule extends Struct {
export class ModuleMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
prefix: Text,
storage: Option.with(Vector.with(StorageFunctionMetadata)),
calls: Option.with(Vector.with(MetadataCall)),
events: Option.with(Vector.with(MetadataEvent))
calls: Option.with(Vector.with(FunctionMetadata)),
events: Option.with(Vector.with(EventMetadata))
}, value);
}
/**
* @description the module calls
*/
get calls (): Option<Vector<MetadataCall>> {
return this.get('calls') as Option<Vector<MetadataCall>>;
get calls (): Option<Vector<FunctionMetadata>> {
return this.get('calls') as Option<Vector<FunctionMetadata>>;
}
/**
* @description the module events
*/
get events (): Option<Vector<MetadataEvent>> {
return this.get('events') as Option<Vector<MetadataEvent>>;
get events (): Option<Vector<EventMetadata>> {
return this.get('events') as Option<Vector<EventMetadata>>;
}
/**
@@ -71,18 +71,18 @@ export class MetadataModule extends Struct {
* @description
* The runtime metadata as a decoded structure
*/
export default class MetadataV1 extends Struct implements MetadataInterface {
export default class MetadataV1 extends Struct implements MetadataInterface<ModuleMetadata> {
constructor (value?: any) {
super({
modules: Vector.with(MetadataModule)
modules: Vector.with(ModuleMetadata)
}, value);
}
/**
* @description The associated modules for this structure
*/
get modules (): Vector<MetadataModule> {
return this.get('modules') as Vector<MetadataModule>;
get modules (): Vector<ModuleMetadata> {
return this.get('modules') as Vector<ModuleMetadata>;
}
private get callNames () {
+2 -2
View File
@@ -2,10 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { default as MetadataV1, MetadataModule as MetadataModuleV1 } from './Metadata';
import { default as MetadataV1, ModuleMetadata as ModuleMetadataV1 } from './Metadata';
export default MetadataV1;
export {
MetadataModuleV1
ModuleMetadataV1
};
-103
View File
@@ -1,103 +0,0 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { OuterDispatchCall, OuterDispatchMetadata } from '../v0/Calls';
import { EventMetadata, OuterEventMetadata, OuterEventMetadataEvent } from '../v0/Events';
import { CallMetadata, FunctionMetadata, RuntimeModuleMetadata, ModuleMetadata } from '../v0/Modules';
import { StorageFunctionMetadata, StorageMetadata, StorageFunctionType } from '../v0/Storage';
import MetadataV0 from '../v0/Metadata';
import MetadataV1, { MetadataModuleV1 } from '.';
function storageV0 (mod: MetadataModuleV1): StorageMetadata | null {
if (mod.storage.isNone) {
return null;
}
return new StorageMetadata({
prefix: mod.prefix,
functions: mod.storage.unwrap().map(({ documentation, fallback, modifier, name, type }) =>
new StorageFunctionMetadata({
name,
modifier: modifier.toNumber(),
type: new StorageFunctionType(type),
fallback,
documentation
})
)
});
}
function moduleV0 (mod: MetadataModuleV1): ModuleMetadata {
return new ModuleMetadata({
name: 'Module',
call: new CallMetadata({
name: 'Call',
functions: mod.calls.isNone
? []
: mod.calls.unwrap().map(({ args, documentation, name }, id) =>
new FunctionMetadata({
id,
name,
arguments: args,
documentation
})
)
})
});
}
function modulesV0 (v1: MetadataV1): Array<RuntimeModuleMetadata> {
return v1.modules.map((mod) =>
new RuntimeModuleMetadata({
prefix: mod.name, // passed from name, compact with casing
module: moduleV0(mod),
storage: storageV0(mod)
})
);
}
function outerDispatchV0 (v1: MetadataV1): OuterDispatchMetadata {
return new OuterDispatchMetadata({
name: 'Call',
calls: v1.modules
.filter(({ calls }) => calls.isSome)
.map((mod, index) =>
new OuterDispatchCall({
// name and prefix are swapped in the actual V0 data, i.e. name is UpperCase
name: mod.prefix,
prefix: mod.name,
index
})
)
});
}
function outerEventV0 (v1: MetadataV1): OuterEventMetadata {
return new OuterEventMetadata({
name: 'Event',
events: v1.modules
.filter(({ events }) => events.isSome)
.map((mod) =>
new OuterEventMetadataEvent([
mod.name,
mod.events.unwrap().map(({ args, documentation, name }) =>
new EventMetadata({
name,
arguments: args,
documentation
})
)
])
)
});
}
export default function toV0 (v1: MetadataV1): MetadataV0 {
return new MetadataV0({
outerEvent: outerEventV0(v1),
modules: modulesV0(v1),
outerDispatch: outerDispatchV0(v1)
});
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import MetadataV1 from './Metadata';
import MetadataV2 from '../v2';
export default function toV2 (metadataV1: MetadataV1): MetadataV2 {
return new MetadataV2(metadataV1);
}
@@ -2,9 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import MetadataV2 from '../v2/Metadata';
import MetadataV3 from '.';
export default function toV2 (v2: MetadataV3): MetadataV2 {
return new MetadataV2(v2);
}
// Re-export classes that haven't changed between V1 and V2
export {
FunctionArgumentMetadata,
FunctionMetadata
} from '../v1/Calls';
@@ -2,9 +2,5 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import MetadataV3 from '../v3/Metadata';
import MetadataV4 from '.';
export default function toV3 (v4: MetadataV4): MetadataV3 {
return new MetadataV3(v4);
}
// Re-export classes that haven't changed between V1 and V2
export { EventMetadata } from '../v1/Events';
@@ -2,51 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import extrinsicsFromMeta from '@plugnet/extrinsics/fromMetadata';
import createType from '../../codec/createType';
import Method from '../../primitive/Method';
import Metadata from '../Metadata';
import latestParsed from './latest.substrate.v2.json';
import latestSubstrate from './latest.substrate.v2.json';
import rpcData from './static';
import { decodeLatestSubstrate, defaultValues, toV4 } from '../util/testUtil';
describe('MetadataV2', () => {
const metadata = new Metadata(rpcData);
decodeLatestSubstrate(2, rpcData, latestSubstrate);
it('decodes latest properly', () => {
const str = JSON.stringify(metadata.toJSON());
toV4(2, rpcData);
expect(metadata.version).toBe(2);
expect(metadata.asV2.modules.length).not.toBe(0);
expect(str).toEqual(JSON.stringify(latestParsed));
});
it('converts v2 to V1', () => {
const v1 = metadata.asV1;
expect(metadata.getUniqTypes(true)).toEqual(v1.getUniqTypes(true));
});
it('converts v2 to V0', () => {
const v1 = metadata.asV0;
expect(metadata.getUniqTypes(true)).toEqual(v1.getUniqTypes(true));
});
describe('storage with default values', () => {
Method.injectMethods(extrinsicsFromMeta(metadata.asV0));
metadata.asV2.modules
.filter(({ storage }) => storage.isSome)
.map((mod) =>
mod.storage.unwrap().forEach(({ fallback, name, type }) => {
it(`creates default types for ${mod.prefix}.${name}, type ${type}`, () => {
expect(
() => createType(type.toString(), fallback)
).not.toThrow();
});
})
);
});
defaultValues(rpcData);
});
+14 -14
View File
@@ -10,38 +10,38 @@ import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import { flattenUniq, validateTypes } from '../util';
import { MetadataCall } from '../v1/Calls';
import { MetadataEvent } from '../v1/Events';
import { FunctionMetadata } from './Calls';
import { EventMetadata } from './Events';
import { StorageFunctionMetadata } from './Storage';
/**
* @name MetadataModule
* @name ModuleMetadata
* @description
* The definition of a module in the system
*/
export class MetadataModule extends Struct {
export class ModuleMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
prefix: Text,
storage: Option.with(Vector.with(StorageFunctionMetadata)),
calls: Option.with(Vector.with(MetadataCall)),
events: Option.with(Vector.with(MetadataEvent))
calls: Option.with(Vector.with(FunctionMetadata)),
events: Option.with(Vector.with(EventMetadata))
}, value);
}
/**
* @description the module calls
*/
get calls (): Option<Vector<MetadataCall>> {
return this.get('calls') as Option<Vector<MetadataCall>>;
get calls (): Option<Vector<FunctionMetadata>> {
return this.get('calls') as Option<Vector<FunctionMetadata>>;
}
/**
* @description the module events
*/
get events (): Option<Vector<MetadataEvent>> {
return this.get('events') as Option<Vector<MetadataEvent>>;
get events (): Option<Vector<EventMetadata>> {
return this.get('events') as Option<Vector<EventMetadata>>;
}
/**
@@ -71,18 +71,18 @@ export class MetadataModule extends Struct {
* @description
* The runtime metadata as a decoded structure
*/
export default class MetadataV2 extends Struct implements MetadataInterface {
export default class MetadataV2 extends Struct implements MetadataInterface<ModuleMetadata> {
constructor (value?: any) {
super({
modules: Vector.with(MetadataModule)
modules: Vector.with(ModuleMetadata)
}, value);
}
/**
* @description The associated modules for this structure
*/
get modules (): Vector<MetadataModule> {
return this.get('modules') as Vector<MetadataModule>;
get modules (): Vector<ModuleMetadata> {
return this.get('modules') as Vector<ModuleMetadata>;
}
private get callNames () {
+3 -25
View File
@@ -11,7 +11,6 @@ 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';
@@ -22,8 +21,6 @@ export {
StorageFunctionModifier
};
export class DoubleMapType extends Null {}
export class MapType extends Struct {
constructor (value?: any) {
super({
@@ -59,20 +56,10 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
constructor (value?: any, index?: number) {
super({
PlainType,
MapType,
DoubleMapType
MapType
}, value, index);
}
/**
* @description The value as a mapped value
*/
get asDoubleMap (): DoubleMapType {
assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`);
return this.value as DoubleMapType;
}
/**
* @description The value as a mapped value
*/
@@ -91,13 +78,6 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
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
*/
@@ -116,9 +96,7 @@ export class StorageFunctionType extends EnumType<PlainType | MapType> {
* @description Returns the string representation of the value
*/
toString (): string {
if (this.isDoubleMap) {
return `DoubleMap<${this.asDoubleMap.toString()}>`;
} else if (this.isMap) {
if (this.isMap) {
if (this.asMap.isLinked) {
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
}
@@ -139,7 +117,7 @@ export type StorageFunctionMetadataValue = {
};
/**
* @name MetadataModule
* @name ModuleMetadata
* @description
* The definition of a storage function
*/
+2 -2
View File
@@ -2,10 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { default as MetadataV2, MetadataModule as MetadataModuleV2 } from './Metadata';
import { default as MetadataV2, ModuleMetadata as ModuleMetadataV2 } from './Metadata';
export default MetadataV2;
export {
MetadataModuleV2
ModuleMetadataV2
};
+10
View File
@@ -0,0 +1,10 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import MetadataV2 from './Metadata';
import MetadataV3 from '../v3';
export default function toV3 (metadataV2: MetadataV2): MetadataV3 {
return new MetadataV3(metadataV2);
}
@@ -2,9 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import MetadataV1 from '../v1/Metadata';
import MetadataV2 from '.';
export default function toV1 (v2: MetadataV2): MetadataV1 {
return new MetadataV1(v2);
}
// Re-export classes that haven't changed between V2 and V3
export {
FunctionArgumentMetadata,
FunctionMetadata
} from '../v2/Calls';
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Re-export classes that haven't changed between V2 and V3
export { EventMetadata } from '../v2/Events';
@@ -2,21 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Metadata from '../Metadata';
import latestParsed from './latest.substrate.v3.json';
import latestSubstrate from './latest.substrate.v3.json';
import rpcData from './static';
import { decodeLatestSubstrate, defaultValues, toV4 } from '../util/testUtil';
describe('MetadataV3', () => {
const metadata = new Metadata(rpcData);
decodeLatestSubstrate(3, rpcData, latestSubstrate);
it('decodes latest properly', () => {
const str = JSON.stringify(metadata.toJSON());
toV4(3, rpcData);
console.error(str);
console.error(metadata.getUniqTypes(true));
expect(metadata.version).toBe(3);
expect(metadata.asV3.modules.length).not.toBe(0);
expect(str).toEqual(JSON.stringify(latestParsed));
});
defaultValues(rpcData);
});
+14 -14
View File
@@ -10,38 +10,38 @@ import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import { flattenUniq, validateTypes } from '../util';
import { MetadataCall } from '../v1/Calls';
import { MetadataEvent } from '../v1/Events';
import { FunctionMetadata } from './Calls';
import { EventMetadata } from './Events';
import { StorageFunctionMetadata } from './Storage';
/**
* @name MetadataModule
* @name ModuleMetadata
* @description
* The definition of a module in the system
*/
export class MetadataModule extends Struct {
export class ModuleMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
prefix: Text,
storage: Option.with(Vector.with(StorageFunctionMetadata)),
calls: Option.with(Vector.with(MetadataCall)),
events: Option.with(Vector.with(MetadataEvent))
calls: Option.with(Vector.with(FunctionMetadata)),
events: Option.with(Vector.with(EventMetadata))
}, value);
}
/**
* @description the module calls
*/
get calls (): Option<Vector<MetadataCall>> {
return this.get('calls') as Option<Vector<MetadataCall>>;
get calls (): Option<Vector<FunctionMetadata>> {
return this.get('calls') as Option<Vector<FunctionMetadata>>;
}
/**
* @description the module events
*/
get events (): Option<Vector<MetadataEvent>> {
return this.get('events') as Option<Vector<MetadataEvent>>;
get events (): Option<Vector<EventMetadata>> {
return this.get('events') as Option<Vector<EventMetadata>>;
}
/**
@@ -71,18 +71,18 @@ export class MetadataModule extends Struct {
* @description
* The runtime metadata as a decoded structure
*/
export default class MetadataV3 extends Struct implements MetadataInterface {
export default class MetadataV3 extends Struct implements MetadataInterface<ModuleMetadata> {
constructor (value?: any) {
super({
modules: Vector.with(MetadataModule)
modules: Vector.with(ModuleMetadata)
}, value);
}
/**
* @description The associated modules for this structure
*/
get modules (): Vector<MetadataModule> {
return this.get('modules') as Vector<MetadataModule>;
get modules (): Vector<ModuleMetadata> {
return this.get('modules') as Vector<ModuleMetadata>;
}
private get callNames () {
+3 -1
View File
@@ -127,7 +127,9 @@ export class StorageFunctionType extends EnumType<PlainType | MapType | DoubleMa
toString (): string {
if (this.isDoubleMap) {
return `DoubleMap<${this.asDoubleMap.toString()}>`;
} else if (this.isMap) {
}
if (this.isMap) {
if (this.asMap.isLinked) {
return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`;
}
+2 -2
View File
@@ -2,10 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { default as MetadataV3, MetadataModule as MetadataModuleV3 } from './Metadata';
import { default as MetadataV3, ModuleMetadata as ModuleMetadataV3 } from './Metadata';
export default MetadataV3;
export {
MetadataModuleV3
ModuleMetadataV3
};
+68
View File
@@ -0,0 +1,68 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Option, Vector } from '../../codec';
import MetadataV3 from './Metadata';
import StorageHasher from '../../primitive/StorageHasher';
import MetadataV4 from '../v4';
import { StorageFunctionMetadata as StorageFunctionMetadataV3 } from '../v3/Storage';
import { DoubleMapType, MapType, StorageFunctionMetadata, StorageFunctionType } from '../v4/Storage';
/**
* Convert V3 StorageFunction to V4 StorageFunction
*/
function toV4StorageFunction (storageFn: StorageFunctionMetadataV3): StorageFunctionMetadata {
const { documentation, fallback, modifier, name, type } = storageFn;
// Convert the old type to the new type: there is one new field
// called `hasher`, which we initialize to xxHash (the default in
// v3).
const [newType, index] = type.isPlainType
? [type, 0]
: type.isMap
? [new MapType({
hasher: new StorageHasher('Twox128'),
key: type.asMap.key,
value: type.asMap.value,
isLinked: type.asMap.isLinked
}), 1]
: [new DoubleMapType({
hasher: new StorageHasher('Twox128'),
key1: type.asDoubleMap.key1,
key2: type.asDoubleMap.key2,
value: type.asDoubleMap.value,
key2Hasher: type.asDoubleMap.key2Hasher
}), 2];
return new StorageFunctionMetadata({
name: name,
modifier: modifier,
type: new StorageFunctionType(newType, index),
fallback: fallback,
documentation: documentation
});
}
/**
* Convert from MetadataV3 to MetadataV4
* See https://github.com/paritytech/substrate/pull/2268 for details
*/
export default function toV4 (metadataV3: MetadataV3): MetadataV4 {
return new MetadataV4({
modules: metadataV3.modules.map((modul) => {
return {
name: modul.name,
prefix: modul.prefix,
storage: modul.storage.isSome
? new Option(
Vector.with(StorageFunctionMetadata),
modul.storage.unwrap().map(toV4StorageFunction)
)
: undefined,
calls: modul.calls,
events: modul.events
};
})
});
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Re-export classes that haven't changed between V3 and V4
export {
FunctionArgumentMetadata,
FunctionMetadata
} from '../v3/Calls';
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Re-export classes that haven't changed between V3 and V4
export { EventMetadata } from '../v3/Events';
@@ -2,29 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
<<<<<<< HEAD
import extrinsicsFromMeta from '@plugnet/extrinsics/fromMetadata';
import createType from '../../codec/createType';
import Method from '../../primitive/Method';
=======
>>>>>>> 57715c50c0... Revert "Update extrinsics FromMetadata. Drop storages with doublemap type when converting v3 to v2 (#888)" (#903)
import Metadata from '../Metadata';
import latestParsed from './latest.substrate.v4.json';
import latestSubstrate from './latest.substrate.v4.json';
import rpcData from './static';
import { decodeLatestSubstrate, defaultValues, toV4 } from '../util/testUtil';
describe('MetadataV4', () => {
const metadata = new Metadata(rpcData);
decodeLatestSubstrate(4, rpcData, latestSubstrate);
it('decodes latest properly', () => {
const str = JSON.stringify(metadata.toJSON());
toV4(4, rpcData);
console.error(str);
console.error(metadata.getUniqTypes(true));
expect(metadata.version).toBe(4);
expect(metadata.asV4.modules.length).not.toBe(0);
expect(str).toEqual(JSON.stringify(latestParsed));
});
defaultValues(rpcData);
});
+14 -18
View File
@@ -10,42 +10,38 @@ import Vector from '../../codec/Vector';
import Text from '../../primitive/Text';
import { flattenUniq, validateTypes } from '../util';
import { MetadataCall } from '../v1/Calls';
import { MetadataEvent } from '../v1/Events';
import { FunctionMetadata } from './Calls';
import { EventMetadata } from './Events';
import { StorageFunctionMetadata } from './Storage';
export {
MetadataEvent
};
/**
* @name MetadataModule
* @name ModuleMetadata
* @description
* The definition of a module in the system
*/
export class MetadataModule extends Struct {
export class ModuleMetadata extends Struct {
constructor (value?: any) {
super({
name: Text,
prefix: Text,
storage: Option.with(Vector.with(StorageFunctionMetadata)),
calls: Option.with(Vector.with(MetadataCall)),
events: Option.with(Vector.with(MetadataEvent))
calls: Option.with(Vector.with(FunctionMetadata)),
events: Option.with(Vector.with(EventMetadata))
}, value);
}
/**
* @description the module calls
*/
get calls (): Option<Vector<MetadataCall>> {
return this.get('calls') as Option<Vector<MetadataCall>>;
get calls (): Option<Vector<FunctionMetadata>> {
return this.get('calls') as Option<Vector<FunctionMetadata>>;
}
/**
* @description the module events
*/
get events (): Option<Vector<MetadataEvent>> {
return this.get('events') as Option<Vector<MetadataEvent>>;
get events (): Option<Vector<EventMetadata>> {
return this.get('events') as Option<Vector<EventMetadata>>;
}
/**
@@ -75,18 +71,18 @@ export class MetadataModule extends Struct {
* @description
* The runtime metadata as a decoded structure
*/
export default class MetadataV4 extends Struct implements MetadataInterface {
export default class MetadataV4 extends Struct implements MetadataInterface<ModuleMetadata> {
constructor (value?: any) {
super({
modules: Vector.with(MetadataModule)
modules: Vector.with(ModuleMetadata)
}, value);
}
/**
* @description The associated modules for this structure
*/
get modules (): Vector<MetadataModule> {
return this.get('modules') as Vector<MetadataModule>;
get modules (): Vector<ModuleMetadata> {
return this.get('modules') as Vector<ModuleMetadata>;
}
private get callNames () {
+2 -2
View File
@@ -2,10 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { default as MetadataV4, MetadataModule as MetadataModuleV4 } from './Metadata';
import { default as MetadataV4, ModuleMetadata as ModuleMetadataV4 } from './Metadata';
export default MetadataV4;
export {
MetadataModuleV4
ModuleMetadataV4
};
+10 -34
View File
@@ -11,8 +11,7 @@ import Tuple from '../codec/Tuple';
import U8aFixed from '../codec/U8aFixed';
import { TypeDef, getTypeClass, getTypeDef } from '../codec/createType';
import Metadata from '../Metadata';
import { EventMetadata as EventMetadataV0 } from '../Metadata/v0/Events';
import { MetadataEvent as EventMetadataV4 } from '../Metadata/v1/Events';
import { EventMetadata as EventMetadataV4 } from '../Metadata/v4/Events';
import Null from './Null';
import U32 from './U32';
@@ -32,12 +31,12 @@ export class EventIndex extends U32 {
* Wrapper for the actual data that forms part of an [[Event]]
*/
export class EventData extends Tuple {
private _meta: EventMetadataV0 | EventMetadataV4;
private _meta: EventMetadataV4;
private _method: string;
private _section: string;
private _typeDef: Array<TypeDef>;
constructor (Types: Array<Constructor>, value: Uint8Array, typeDef: Array<TypeDef>, meta: EventMetadataV0 | EventMetadataV4, section: string, method: string) {
constructor (Types: Array<Constructor>, value: Uint8Array, typeDef: Array<TypeDef>, meta: EventMetadataV4, section: string, method: string) {
super(Types, value);
this._meta = meta;
@@ -49,7 +48,7 @@ export class EventData extends Tuple {
/**
* @description The wrapped [[EventMetadata]]
*/
get meta (): EventMetadataV0 | EventMetadataV4 {
get meta (): EventMetadataV4 {
return this._meta;
}
@@ -129,37 +128,15 @@ 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: Metadata): void {
if (metadata.version === 4) {
let sectionIndex = 0;
metadata.asV4.modules.forEach((section) => {
metadata.asV4.modules
.filter((section) => section.events.isSome)
.forEach((section, sectionIndex) => {
const sectionName = stringCamelCase(section.name.toString());
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) => {
section.events.unwrap().forEach((meta, methodIndex) => {
const methodName = meta.name.toString();
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
const typeDef = meta.arguments.map((arg) => getTypeDef(arg));
const typeDef = meta.args.map((arg) => getTypeDef(arg));
const Types = typeDef.map(getTypeClass);
EventTypes[eventIndex.toString()] = class extends EventData {
@@ -169,7 +146,6 @@ export default class Event extends Struct {
};
});
});
}
}
/**
@@ -189,7 +165,7 @@ export default class Event extends Struct {
/**
* @description The [[EventMetadata]] with the documentation
*/
get meta (): EventMetadataV0 | EventMetadataV4 {
get meta (): EventMetadataV4 {
return this.data.meta;
}
+3 -3
View File
@@ -34,19 +34,19 @@ describe('Method', () => {
it('is false with no arguments', () => {
expect(
new Method(test, { arguments: [] } as any).hasOrigin
new Method(test, { args: [] } as any).hasOrigin
).toEqual(false);
});
it('is false with first argument as non-Origin', () => {
expect(
new Method(test, { arguments: [{ name: 'a', type: 'u32' }] } as any).hasOrigin
new Method(test, { args: [{ name: 'a', type: 'u32' }] } as any).hasOrigin
).toEqual(false);
});
it('is false with first argument as non-Origin', () => {
expect(
new Method(test, { arguments: [{ name: 'a', type: 'Origin' }] } as any).hasOrigin
new Method(test, { args: [{ name: 'a', type: 'Origin' }] } as any).hasOrigin
).toEqual(true);
});
});
+12 -12
View File
@@ -9,7 +9,7 @@ import { assert, isHex, isObject, isU8a, hexToU8a } from '@plugnet/util';
import { getTypeDef, getTypeClass } from '../codec/createType';
import Struct from '../codec/Struct';
import U8aFixed from '../codec/U8aFixed';
import { FunctionMetadata, FunctionArgumentMetadata } from '../Metadata/v0/Modules';
import { FunctionMetadata as FunctionMetadataV4, FunctionArgumentMetadata } from '../Metadata/v4/Calls';
interface DecodeMethodInput {
args: any;
@@ -18,13 +18,13 @@ interface DecodeMethodInput {
interface DecodedMethod extends DecodeMethodInput {
argsDef: ArgsDef;
meta: FunctionMetadata;
meta: FunctionMetadataV4;
}
export interface MethodFunction {
(...args: any[]): Method;
callIndex: Uint8Array;
meta: FunctionMetadata;
meta: FunctionMetadataV4;
method: string;
section: string;
toJSON: () => any;
@@ -63,9 +63,9 @@ export class MethodIndex extends U8aFixed {
* {@link https://github.com/paritytech/wiki/blob/master/Extrinsic.md#the-extrinsic-format-for-node}.
*/
export default class Method extends Struct implements IMethod {
protected _meta: FunctionMetadata;
protected _meta: FunctionMetadataV4;
constructor (value: any, meta?: FunctionMetadata) {
constructor (value: any, meta?: FunctionMetadataV4) {
const decoded = Method.decodeMethod(value, meta);
super({
@@ -86,7 +86,7 @@ export default class Method extends Struct implements IMethod {
* @param _meta - Metadata to use, so that `injectMethods` lookup is not
* necessary.
*/
private static decodeMethod (value: DecodedMethod | Uint8Array | string, _meta?: FunctionMetadata): DecodedMethod {
private static decodeMethod (value: DecodedMethod | Uint8Array | string, _meta?: FunctionMetadataV4): DecodedMethod {
if (isHex(value)) {
return Method.decodeMethod(hexToU8a(value), _meta);
} else if (isU8a(value)) {
@@ -127,16 +127,16 @@ export default class Method extends Struct implements IMethod {
return {
args: new Uint8Array(),
argsDef: {},
meta: new FunctionMetadata(),
meta: new FunctionMetadataV4(),
callIndex: new Uint8Array([255, 255])
};
}
// If the extrinsic function has an argument of type `Origin`, we ignore it
static filterOrigin (meta?: FunctionMetadata): Array<FunctionArgumentMetadata> {
static filterOrigin (meta?: FunctionMetadataV4): Array<FunctionArgumentMetadata> {
// FIXME should be `arg.type !== Origin`, but doesn't work...
return meta
? meta.arguments.filter(({ type }) =>
? meta.args.filter(({ type }) =>
type.toString() !== 'Origin'
)
: [];
@@ -161,7 +161,7 @@ export default class Method extends Struct implements IMethod {
*
* @param meta - The function metadata used to get the definition.
*/
private static getArgsDef (meta: FunctionMetadata): ArgsDef {
private static getArgsDef (meta: FunctionMetadataV4): ArgsDef {
return Method.filterOrigin(meta).reduce((result, { name, type }) => {
const Type = getTypeClass(
getTypeDef(type)
@@ -215,7 +215,7 @@ export default class Method extends Struct implements IMethod {
* @description `true` if the `Origin` type is on the method (extrinsic method)
*/
get hasOrigin (): boolean {
const firstArg = this.meta.arguments[0];
const firstArg = this.meta.args[0];
return !!firstArg && firstArg.type.toString() === 'Origin';
}
@@ -223,7 +223,7 @@ export default class Method extends Struct implements IMethod {
/**
* @description The [[FunctionMetadata]]
*/
get meta (): FunctionMetadata {
get meta (): FunctionMetadataV4 {
return this._meta;
}
}
+60 -22
View File
@@ -3,33 +3,71 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { hexToU8a } from '@plugnet/util';
import storage from '@plugnet/storage/static';
import fromMetadata from '@plugnet/storage/fromMetadata';
import rpcDataV3 from '@plugnet/types/Metadata/v3/static';
import rpcDataV4 from '@plugnet/types/Metadata/v4/static';
import Metadata from '../Metadata';
import StorageKey from './StorageKey';
describe('StorageKey', () => {
it(`should correctly get Alice's freeBalance storage key (hex)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toHex()
).toBe('0xc99f5446efa57788f39ab529311f4550'); // FIXME OK this should be length-prefixed in reality
describe('with MetadataV3 (uses xxHash by default)', () => {
const storage = fromMetadata(new Metadata(rpcDataV3));
it(`should correctly get Alice's freeBalance storage key (hex)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toHex()
).toBe('0xc99f5446efa57788f39ab529311f4550'); // FIXME OK this should be length-prefixed in reality
});
it(`should correctly get Alice's freeBalance storage key (u8a)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toU8a()
).toEqual(
// length prefix attached
hexToU8a('0x40c99f5446efa57788f39ab529311f4550')
);
});
});
it(`should correctly get Alice's freeBalance storage key (u8a)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toU8a()
).toEqual(
// length prefix attached
hexToU8a('0x40c99f5446efa57788f39ab529311f4550')
);
describe('with MetadataV4 (uses xxHash by default)', () => {
const storage = fromMetadata(new Metadata(rpcDataV4));
it(`should correctly get Alice's freeBalance storage key (hex)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toHex()
).toBe('0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587bb');
});
it(`should correctly get Alice's freeBalance storage key (u8a)`, () => {
expect(
new StorageKey(
storage
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
.toU8a()
).toEqual(
// length prefix attached
Uint8Array.from([
128, 127, 134, 78, 24, 227, 221, 139, 88, 56, 99, 16, 210, 254, 9, 25, 238, 242, 124, 110, 85, 133, 100, 183, 246, 127, 34, 217, 157, 32, 245, 135, 187
])
);
});
});
});
+9 -10
View File
@@ -7,12 +7,11 @@ import { AnyU8a } from '../types';
import { assert, isFunction, isString, isU8a } from '@plugnet/util';
import Bytes from './Bytes';
import { StorageFunctionMetadata as MetaV0 } from '../Metadata/v0/Storage';
import { StorageFunctionMetadata as MetaV4 } from '../Metadata/v4/Storage';
export interface StorageFunction {
(arg?: any): Uint8Array;
meta: MetaV0 | MetaV4;
meta: MetaV4;
method: string;
section: string;
toJSON: () => any;
@@ -26,8 +25,8 @@ export interface StorageFunction {
* constructed by passing in a raw key or a StorageFunction with (optional) arguments.
*/
export default class StorageKey extends Bytes {
private _meta: MetaV0 | MetaV4 | null;
private _outputType: string | null;
private _meta?: MetaV4;
private _outputType?: string;
constructor (value?: AnyU8a | StorageKey | StorageFunction | [StorageFunction, any]) {
super(StorageKey.decodeStorageKey(value));
@@ -53,7 +52,7 @@ export default class StorageKey extends Bytes {
throw new Error(`Unable to convert input ${value} to StorageKey`);
}
static getMeta (value: StorageKey | StorageFunction | [StorageFunction, any]): MetaV0 | MetaV4 | null {
static getMeta (value: StorageKey | StorageFunction | [StorageFunction, any]): MetaV4 | undefined {
if (value instanceof StorageKey) {
return value.meta;
} else if (isFunction(value)) {
@@ -64,10 +63,10 @@ export default class StorageKey extends Bytes {
return fn.meta;
}
return null;
return undefined;
}
static getType (value: StorageKey | StorageFunction | [StorageFunction, any]): string | null {
static getType (value: StorageKey | StorageFunction | [StorageFunction, any]): string | undefined {
if (value instanceof StorageKey) {
return value.outputType;
} else if (isFunction(value)) {
@@ -78,20 +77,20 @@ export default class StorageKey extends Bytes {
return fn.meta.type.toString();
}
return null;
return undefined;
}
/**
* @description The metadata or `null` when not available
*/
get meta (): MetaV0 | MetaV4 | null {
get meta (): MetaV4 | undefined {
return this._meta;
}
/**
* @description The output type, `null` when not available
*/
get outputType (): string | null {
get outputType (): string | undefined {
return this._outputType;
}
}
+26 -19
View File
@@ -9,7 +9,7 @@ import interfaces from '../../../type-jsonrpc/src';
import Method from '../primitive/Method';
import Metadata from '../Metadata';
import rpcdata from '../Metadata/static';
import MetadataV0 from '../Metadata/v0';
import MetadataV4 from '../Metadata/v4';
const ANCHOR_TOP = '';
const LINK_BACK_TO_TOP = '';
@@ -56,7 +56,10 @@ function addRpc () {
}, renderHeading + renderAnchors);
}
function sortExtrinsicsSectionMethods (a: any, b: any) {
/**
* Sort object by their `.name`
*/
function sortByName<T extends { name: any }> (a: T, b: T): number {
// ignore upper and lowercase
const nameA = a.name.toString().toUpperCase();
const nameB = b.name.toString().toUpperCase();
@@ -64,26 +67,28 @@ function sortExtrinsicsSectionMethods (a: any, b: any) {
return nameA.localeCompare(nameB);
}
function addEvents (metadata: MetadataV0) {
function addEvents (metadata: MetadataV4) {
const renderHeading = `## ${ANCHOR_TOP}Events${DESC_EVENTS}`;
const orderedSections = metadata.events.map((i) => i).sort();
const orderedSections = metadata.modules.sort(sortByName);
let renderAnchors = '';
const sections = orderedSections.reduce((md, meta) => {
if (!meta.events || !meta.events.length) {
if (meta.events.isNone || !meta.events.unwrap().length) {
return md;
}
const events = meta.events.unwrap();
const sectionName = stringCamelCase(meta.name.toString());
renderAnchors += sectionLink(sectionName);
const renderSection = generateSectionHeader(md, sectionName);
const orderedMethods = meta.events.sort(sortExtrinsicsSectionMethods);
const orderedMethods = events.sort(sortByName);
return orderedMethods.reduce((md, func) => {
const methodName = func.name.toString();
const args = func.arguments.map((type) => '`' + type + '`').join(', ');
const args = func.args.map((type) => '`' + type + '`').join(', ');
const doc = func.documentation.reduce((md, doc) => `${md} ${doc}`, '');
const renderSignature = `${md}\n▸ **${methodName}**(${args})`;
const renderSummary = `${doc ? `\n- **summary**: ${doc}\n` : '\n'}`;
@@ -95,21 +100,23 @@ function addEvents (metadata: MetadataV0) {
return renderHeading + renderAnchors + sections;
}
function addExtrinsics (metadata: MetadataV0) {
function addExtrinsics (metadata: MetadataV4) {
const renderHeading = `## ${ANCHOR_TOP}Extrinsics${DESC_EXTRINSICS}`;
const orderedSections = metadata.modules.map((i) => i).sort();
const orderedSections = metadata.modules.map((i) => i).sort(sortByName);
let renderAnchors = '';
const sections = orderedSections.reduce((md, meta) => {
if (!meta.module.call || !meta.module.call.functions.length) {
if (meta.calls.isNone || !meta.calls.unwrap().length) {
return md;
}
const calls = meta.calls.unwrap();
const sectionName = stringCamelCase(meta.prefix.toString());
renderAnchors += sectionLink(sectionName);
const renderSection = generateSectionHeader(md, sectionName);
const orderedMethods = meta.module.call.functions.sort(sortExtrinsicsSectionMethods);
const orderedMethods = calls.sort(sortByName);
return orderedMethods.reduce((md, func) => {
const methodName = stringCamelCase(func.name.toString());
@@ -125,21 +132,21 @@ function addExtrinsics (metadata: MetadataV0) {
return renderHeading + renderAnchors + sections;
}
function addStorage (metadata: MetadataV0) {
function addStorage (metadata: MetadataV4) {
const renderHeading = `## ${ANCHOR_TOP}Storage${DESC_STORAGE}`;
const orderedSections = metadata.modules.sort();
const orderedSections = metadata.modules.sort(sortByName);
let renderAnchors = '';
const sections = orderedSections.reduce((md, moduleMetadata) => {
if (moduleMetadata.storage.isNone) {
return md;
}
const sectionName = stringLowerFirst(moduleMetadata.storage.unwrap().prefix.toString());
const sectionName = stringLowerFirst(moduleMetadata.prefix.toString());
renderAnchors += sectionLink(sectionName);
const renderSection = generateSectionHeader(md, sectionName);
const orderedMethods = moduleMetadata.storage.unwrap().functions.sort();
const orderedMethods = moduleMetadata.storage.unwrap().sort(sortByName);
return orderedMethods.reduce((md, func) => {
const methodName = stringLowerFirst(func.name.toString());
@@ -177,22 +184,22 @@ function writeToRpcMd () {
writeFile('docs/METHODS_RPC.md', addRpc());
}
function writeToStorageMd (metadata: MetadataV0) {
function writeToStorageMd (metadata: MetadataV4) {
const options = { flags: 'r', encoding: 'utf8' };
const data = fs.readFileSync('packages/types/src/scripts/METHODS_STORAGE_SUBSTRATE.md', options);
writeFile('docs/METHODS_STORAGE.md', addStorage(metadata), data);
}
function writeToExtrinsicsMd (metadata: MetadataV0) {
function writeToExtrinsicsMd (metadata: MetadataV4) {
writeFile('docs/METHODS_EXTRINSICS.md', addExtrinsics(metadata));
}
function writeToEventsMd (metadata: MetadataV0) {
function writeToEventsMd (metadata: MetadataV4) {
writeFile('docs/METHODS_EVENTS.md', addEvents(metadata));
}
const metadata = new Metadata(rpcdata).asV0;
const metadata = new Metadata(rpcdata).asV4;
writeToRpcMd();
writeToStorageMd(metadata);
+1 -1
View File
@@ -10,7 +10,7 @@ import { blake2AsU8a } from '@plugnet/util-crypto';
import Compact from '../codec/Compact';
import Struct from '../codec/Struct';
import { FunctionMetadata } from '../Metadata/v0/Modules';
import { FunctionMetadata } from '../Metadata/v4/Calls';
import Method from '../primitive/Method';
import Address from '../primitive/Address';
import Hash from '../primitive/Hash';
+3 -3
View File
@@ -7,13 +7,13 @@ import { KeyringPair } from '@plugnet/keyring/types';
import BN from 'bn.js';
import U8a from './codec/U8a';
import { FunctionMetadata } from './Metadata/v4/Calls';
import Method from './primitive/Method';
import Address from './primitive/Address';
import { FunctionMetadata } from './Metadata/v0/Modules';
export type CodecArg = Codec | BN | Boolean | String | Uint8Array | boolean | number | string | undefined | CodecArgArray | CodecArgObject;
export type CodecCallback <T extends Codec = any> = (result: T) => any;
export type CodecCallback<T extends Codec = any> = (result: T) => any;
interface CodecArgObject {
[index: string]: CodecArg;
@@ -106,7 +106,7 @@ export interface ArgsDef {
[index: string]: Constructor;
}
export interface IHash extends U8a {}
export interface IHash extends U8a { }
export interface IMethod extends Codec {
readonly args: Array<Codec>;