Cleanup jsonrpc, refer to api-codec (#174)

* Cleanup jsonrpc, refer to api-codec

* Move storagekey legacy into type-params (legacy)

* Remove misplaced debug log

* Remove header encoding, use api-codec/Header

* Remove legacy types

* Add metadat array (hack around json import)

* Move json metadata to ts
This commit is contained in:
Jaco Greeff
2018-09-28 18:35:39 +02:00
committed by GitHub
parent 62ed0a7b3f
commit b3a95b58ed
29 changed files with 282 additions and 263 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -4
View File
@@ -3,13 +3,11 @@
// of the ISC license. See the LICENSE file for details.
import Metadata from './Metadata';
import rpcdata from './Metadata.rpc.json';
import rpcdata from './Metadata.rpc';
describe('Metadata', () => {
it('decodes properly', () => {
const decoded = new Metadata().fromJSON(
rpcdata.result
);
const decoded = new Metadata().fromJSON(rpcdata);
const str = JSON.stringify(decoded.toJSON());
+3
View File
@@ -3,6 +3,7 @@
// of the ISC license. See the LICENSE file for details.
import BN from 'bn.js';
import * as Classes from './index';
import U8a from './codec/U8a';
import UInt from './codec/UInt';
@@ -10,3 +11,5 @@ import UInt from './codec/UInt';
export type AnyNumber = UInt | BN | Uint8Array | number | string;
export type AnyU8a = U8a | Uint8Array | Array<number> | string;
export type CodecTypes = keyof typeof Classes;
+12 -21
View File
@@ -4,26 +4,20 @@
// FIXME: This file is way too long and way too messy
import { Storages } from '@polkadot/storage/types';
import { SectionItem } from '@polkadot/params/types';
import { StorageFunction } from '@polkadot/api-codec/StorageKey';
import { KeyringPair } from '@polkadot/util-keyring/types';
import { ProviderInterface$Emitted } from '../types';
import { MockState, MockState$Storage, MockState$Subscriptions } from './types';
import { MockState, MockState$Db, MockState$Subscriptions } from './types';
import BN from 'bn.js';
import headerEncode from '@polkadot/primitives/json/header/encode';
import createKey from '@polkadot/storage/key';
import state from '@polkadot/storage/index';
import Header from '@polkadot/api-codec/Header';
import storage from '@polkadot/storage/testing';
import bnToU8a from '@polkadot/util/bn/toU8a';
import u8aToHex from '@polkadot/util/u8a/toHex';
import randomAsU8a from '@polkadot/util-crypto/random/asU8a';
import testKeyring from '@polkadot/util-keyring/testing';
const keyring = testKeyring();
// FIXME No more .public
const stateStaking = state.staking.public;
const stateSystem = state.staking.public;
const stateTimestamp = state.timestamp.public;
const emitEvents: Array<ProviderInterface$Emitted> = ['connected', 'disconnected'];
let emitIndex = 0;
@@ -58,15 +52,15 @@ function updateSubs (subscriptions: MockState$Subscriptions, method: string, val
});
}
function setStorageBn (storage: MockState$Storage, key: SectionItem<Storages>, value: BN | number, ...keyParams: Array<Uint8Array>): void {
function setStorageBn (db: MockState$Db, createKey: StorageFunction, value: BN | number, ...keyParams: Array<Uint8Array>): void {
const keyValue = u8aToHex(
createKey(key).apply(null, keyParams)
createKey(...keyParams)
);
storage[keyValue] = bnToU8a(value, 64, true);
db[keyValue] = bnToU8a(value, 64, true);
}
export default function mocks ({ emitter, storage, subscriptions }: MockState): void {
export default function mocks ({ emitter, db, subscriptions }: MockState): void {
let newHead = makeBlockHeader(new BN(-1));
setInterval(() => {
@@ -79,15 +73,12 @@ export default function mocks ({ emitter, storage, subscriptions }: MockState):
newHead = makeBlockHeader(newHead.number);
keyring.getPairs().forEach(({ publicKey }: KeyringPair, index: number) => {
// @ts-ignore FIXME This does not exist anymore
setStorageBn(storage, stateStaking.freeBalanceOf, newHead.number.muln(3).iaddn(index), publicKey());
// @ts-ignore FIXME This does not exist anymore
setStorageBn(storage, stateSystem.accountIndexOf, newHead.number.addn(index), publicKey());
setStorageBn(db, storage.balances.freeBalance, newHead.number.muln(3).iaddn(index), publicKey());
setStorageBn(db, storage.system.accountNonce, newHead.number.addn(index), publicKey());
});
// @ts-ignore FIXME This does not exist anymore
setStorageBn(storage, stateTimestamp.current, Math.floor(Date.now() / 1000));
setStorageBn(db, storage.timestamp.now, Math.floor(Date.now() / 1000));
updateSubs(subscriptions, 'chain_newHead', headerEncode(newHead));
updateSubs(subscriptions, 'chain_newHead', new Header(newHead).toJSON());
}, 5000);
}
+2 -2
View File
@@ -4,10 +4,10 @@
import { MockState } from './types';
export default async function send ({ requests, storage }: MockState, method: string, params: Array<any>): Promise<any> {
export default async function send ({ requests, db }: MockState, method: string, params: Array<any>): Promise<any> {
if (!requests[method]) {
throw new Error(`provider.send: Invalid method '${method}'`);
}
return requests[method](storage, params);
return requests[method](db, params);
}
+5 -5
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { MockState, MockState$Storage, MockState$Subscriptions } from './types';
import { MockState, MockState$Db, MockState$Subscriptions } from './types';
import E3 from 'eventemitter3';
import interfaces from '@polkadot/jsonrpc/index';
@@ -14,7 +14,7 @@ const l = logger('api-mock');
const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply(
[], Object.values(interfaces).map((area) =>
Object
.values(area.public)
.values(area.methods)
.filter((method) =>
method.isSubscription
)
@@ -25,7 +25,7 @@ const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply(
);
const REQUESTS = {
'state_getStorage': (storage: MockState$Storage, params: Array<any>): string => {
'state_getStorage': (storage: MockState$Db, params: Array<any>): string => {
return u8aToHex(
storage[(params[0] as string)]
);
@@ -36,7 +36,7 @@ const REQUESTS = {
};
export default function state (): MockState {
const storage = {};
const db = {};
const subscriptions: MockState$Subscriptions = SUBSCRIPTIONS.reduce((subs, name) => {
subs[name] = {
callbacks: {},
@@ -50,7 +50,7 @@ export default function state (): MockState {
emitter: new E3.EventEmitter(),
l,
requests: Object.assign({}, REQUESTS),
storage,
db,
subscriptionId: 0,
subscriptionMap: {},
subscriptions
+3 -3
View File
@@ -16,19 +16,19 @@ export type MockState$Subscriptions = {
}
};
export type MockState$Storage = {
export type MockState$Db = {
[index: string]: Uint8Array
};
export type MockState$Requests = {
[index: string]: (storage: MockState$Storage, params: Array<any>) => string
[index: string]: (db: MockState$Db, params: Array<any>) => string
};
export type MockState = {
emitter: EventEmitter,
l: Logger,
requests: MockState$Requests,
storage: MockState$Storage,
db: MockState$Db,
subscriptionId: number,
subscriptionMap: {
[index: number]: string
+5 -8
View File
@@ -4,7 +4,6 @@
import { ApiInterface, ApiInterface$Section } from '@polkadot/api/types';
import { ProviderInterface } from '@polkadot/api-provider/types';
import { Interface$Sections } from '@polkadot/jsonrpc/types';
import { RxApiInterface, RxApiInterface$Section } from './types';
import { BehaviorSubject, Observable, Subscriber, from } from 'rxjs';
@@ -51,19 +50,17 @@ export default class RxApi implements RxApiInterface {
provider.on('connected', () => this._isConnected.next(true));
provider.on('disconnected', () => this._isConnected.next(false));
this.author = this.createInterface('author');
this.chain = this.createInterface('chain');
this.state = this.createInterface('state');
this.system = this.createInterface('system');
this.author = this.createInterface('author', this._api.author);
this.chain = this.createInterface('chain', this._api.chain);
this.state = this.createInterface('state', this._api.state);
this.system = this.createInterface('system', this._api.system);
}
isConnected (): BehaviorSubject<boolean> {
return this._isConnected;
}
private createInterface (sectionName: Interface$Sections): RxApiInterface$Section {
const section: ApiInterface$Section = this._api[sectionName];
private createInterface (sectionName: string, section: ApiInterface$Section): RxApiInterface$Section {
return Object
.keys(section)
.filter((name) => !['subscribe', 'unsubscribe'].includes(name))
+3 -3
View File
@@ -2,9 +2,9 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { Interfaces } from '@polkadot/jsonrpc/types';
import { BehaviorSubject, Observable } from 'rxjs';
import { Interface$Sections } from '@polkadot/jsonrpc/types';
import interfaces from '@polkadot/jsonrpc/types';
export type RxApiInterface$Method = (...params: Array<any>) => Observable<any> | BehaviorSubject<any>;
@@ -13,7 +13,7 @@ export type RxApiInterface$Section = {
};
type RxApiInterface$Keys = {
readonly [key in keyof Interfaces]: RxApiInterface$Section;
readonly [key in keyof typeof interfaces]: RxApiInterface$Section;
};
export type RxApiInterface = RxApiInterface$Keys & {
-1
View File
@@ -32,7 +32,6 @@
"@babel/runtime": "^7.0.0",
"@polkadot/api-provider": "^0.30.2",
"@polkadot/jsonrpc": "^0.30.2",
"@polkadot/params": "^0.30.2",
"@polkadot/util": "^0.30.7"
}
}
+33 -24
View File
@@ -3,18 +3,15 @@
// of the ISC license. See the LICENSE file for details.
import { ProviderInterface, ProviderInterface$Callback } from '@polkadot/api-provider/types';
import { Interfaces, Interface$Sections } from '@polkadot/jsonrpc/types';
import { SectionItem } from '@polkadot/params/types';
import { Section, Method } from '@polkadot/jsonrpc/types';
import { ApiInterface, ApiInterface$Section, ApiInterface$Section$Method } from './types';
import { Base, Vector, createType } from '@polkadot/api-codec/codec';
import { StorageChangeSet, StorageKey } from '@polkadot/api-codec/index';
import interfaces from '@polkadot/jsonrpc/index';
import signature from '@polkadot/params/signature';
import assert from '@polkadot/util/assert';
import ExtError from '@polkadot/util/ext/error';
import isFunction from '@polkadot/util/is/function';
import isUndefined from '@polkadot/util/is/undefined';
/**
* @example
@@ -41,27 +38,39 @@ export default class Api implements ApiInterface {
this._provider = provider;
this.author = this.createInterface('author');
this.chain = this.createInterface('chain');
this.state = this.createInterface('state');
this.system = this.createInterface('system');
this.author = this.createInterface(interfaces.author);
this.chain = this.createInterface(interfaces.chain);
this.state = this.createInterface(interfaces.state);
this.system = this.createInterface(interfaces.system);
}
private createInterface (section: Interface$Sections): ApiInterface$Section {
const definition = interfaces[section];
/**
* @name signature
* @signature jsonrpcSignature (method: InterfaceMethodDefinition): string
* @summary Returns a string representation of the method with inputs and outputs.
* @description
* Formats the name, inputs and outputs into a human-readable string. This contains the input parameter names input types and output type.
* @example
* import Api from '@polkadot/Api';
*
* Api.signature({ name: 'test_method', params: [ { name: 'dest', type: 'Address' } ], type: 'Address' }); // => test_method (dest: Address): Address
*/
static signature ({ name, params, type }: Method): string {
const inputs = params.map(({ name, type }) =>
`${name}: ${type}`
).join(', ');
assert(!isUndefined(definition), `Unable to find section '${section}`);
// @ts-ignore undefined check done in assert
const methods = definition.public;
return `${name} (${inputs}): ${type}`;
}
private createInterface ({ methods, name }: Section<any>): ApiInterface$Section {
return Object
.keys(methods)
.reduce((exposed, name) => {
const rpcName = `${section}_${name}`;
const def = methods[name];
.reduce((exposed, method) => {
const rpcName = `${name}_${method}`;
const def = methods[method];
exposed[name] = def.isSubscription
exposed[method] = def.isSubscription
? this.createMethodSubscribe(rpcName, def)
: this.createMethodSend(rpcName, def);
@@ -69,7 +78,7 @@ export default class Api implements ApiInterface {
}, {} as ApiInterface$Section);
}
private createMethodSend (rpcName: string, method: SectionItem<Interfaces>): ApiInterface$Section$Method {
private createMethodSend (rpcName: string, method: Method): ApiInterface$Section$Method {
const call = async (...values: Array<any>): Promise<any> => {
// TODO Warn on deprecated methods
try {
@@ -79,7 +88,7 @@ export default class Api implements ApiInterface {
return this.formatOutput(method, params, result);
} catch (error) {
const message = `${signature(method)}:: ${error.message}`;
const message = `${Api.signature(method)}:: ${error.message}`;
console.error(message, error);
@@ -90,7 +99,7 @@ export default class Api implements ApiInterface {
return call as ApiInterface$Section$Method;
}
private createMethodSubscribe (rpcName: string, method: SectionItem<Interfaces>): ApiInterface$Section$Method {
private createMethodSubscribe (rpcName: string, method: Method): ApiInterface$Section$Method {
const unsubscribe = (subscriptionId: any): Promise<any> =>
this._provider.unsubscribe(rpcName, method.subscribe[1], subscriptionId);
const _call = async (...values: Array<any>): Promise<any> => {
@@ -107,7 +116,7 @@ export default class Api implements ApiInterface {
return this._provider.subscribe(rpcName, method.subscribe[0], paramsJson, update);
} catch (error) {
const message = `${signature(method)}:: ${error.message}`;
const message = `${Api.signature(method)}:: ${error.message}`;
console.error(message, error);
@@ -122,7 +131,7 @@ export default class Api implements ApiInterface {
return call;
}
private formatInputs (method: SectionItem<Interfaces>, inputs: Array<any>): Array<Base> {
private formatInputs (method: Method, inputs: Array<any>): Array<Base> {
assert(method.params.length === inputs.length, `Expected ${method.params.length} parameters, ${inputs.length} found instead`);
return method.params.map(({ type }, index) =>
@@ -130,7 +139,7 @@ export default class Api implements ApiInterface {
);
}
private formatOutput (method: SectionItem<Interfaces>, params: Array<Base>, result?: any): Base {
private formatOutput (method: Method, params: Array<Base>, result?: any): Base {
const base = createType(method.type as string, result);
if (method.type === 'StorageData') {
+2 -2
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { Interfaces, Interface$Sections } from '@polkadot/jsonrpc/types';
import interfaces from '@polkadot/jsonrpc/index';
export interface ApiInterface$Section$Method {
(...params: Array<any>): Promise<any>;
@@ -16,5 +16,5 @@ export type ApiInterface$Section = {
};
export type ApiInterface = {
readonly [key in keyof Interfaces]: ApiInterface$Section
readonly [key in keyof typeof interfaces]: ApiInterface$Section
}
-1
View File
@@ -29,7 +29,6 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-jsonrpc#readme",
"dependencies": {
"@polkadot/params": "^0.30.2",
"babel-runtime": "^6.26.0"
}
}
+18 -20
View File
@@ -2,45 +2,43 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { CreateItems, CreateItemOptions, CreateItemOptionsMap, Section, SectionItems } from '@polkadot/params/types';
import { Interfaces, Interface$Sections } from './types';
import { MethodOpt, Section, SectionMethods } from './types';
import param from '@polkadot/params/param';
import createSection from '@polkadot/params/section';
import createMethod from './create/method';
import createParam from './create/param';
const pendingExtrinsics: CreateItemOptions = {
const pendingExtrinsics: MethodOpt = {
description: 'Returns all pending extrinsics, potentially grouped by sender',
params: [],
type: 'PendingExtrinsics'
};
const submitExtrinsic: CreateItemOptions = {
const submitExtrinsic: MethodOpt = {
isSigned: true,
description: 'Submit a fully formatted extrinsic for block inclusion',
params: [
param('extrinsic', 'Bytes')
createParam('extrinsic', 'Bytes')
],
type: 'Hash'
};
const privateMethods: CreateItemOptionsMap = {};
const publicMethods: CreateItemOptionsMap = {
const methods: { [index: string]: MethodOpt } = {
pendingExtrinsics, submitExtrinsic
};
export type PrivateMethods = typeof privateMethods;
export type PublicMethods = typeof publicMethods;
export type Methods = typeof methods;
/**
* @summary Methods to work with authors & contributors.
*/
export default (name: Interface$Sections): Section<Interfaces, PrivateMethods, PublicMethods> =>
createSection(name)((createMethod: CreateItems<Interfaces>) => ({
description: 'Authoring of network items',
public: Object.keys(publicMethods).reduce((result, key) => {
result[key] = createMethod(key)(publicMethods[key]);
export default {
isDeprecated: false,
isHidden: false,
description: 'Authoring of network items',
name: 'author',
methods: Object.keys(methods).reduce((result, key) => {
result[key] = createMethod('author', key, methods[key]);
return result;
}, {} as SectionItems<Interfaces, PublicMethods>)
}));
return result;
}, {} as SectionMethods<Methods>)
} as Section<Methods>;
+24 -26
View File
@@ -2,49 +2,48 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { CreateItems, CreateItemOptions, CreateItemOptionsMap, Section, SectionItems } from '@polkadot/params/types';
import { Interfaces, Interface$Sections } from './types';
import { MethodOpt, Section, SectionMethods } from './types';
import param from '@polkadot/params/param';
import createSection from '@polkadot/params/section';
import createMethod from './create/method';
import createParam from './create/param';
const getBlock: CreateItemOptions = {
const getBlock: MethodOpt = {
description: 'Get header and body of a relay chain block',
params: [
param('hash', 'Hash')
createParam('hash', 'Hash')
],
type: 'SignedBlock'
};
const getHead: CreateItemOptions = {
const getHead: MethodOpt = {
description: 'Retrieves the best headerHash',
params: [],
type: 'Hash'
};
const getHeader: CreateItemOptions = {
const getHeader: MethodOpt = {
description: 'Retrieves the header for a specific block',
params: [
param('hash', 'Hash')
createParam('hash', 'Hash')
],
type: 'Header'
};
const getRuntimeVersion: CreateItemOptions = {
const getRuntimeVersion: MethodOpt = {
description: ' Get the runtime version',
params: [],
type: 'RuntimeVersion'
};
const getRuntimeVersionAt: CreateItemOptions = {
const getRuntimeVersionAt: MethodOpt = {
description: ' Get the runtime version at a specific block',
params: [
param('hash', 'Hash')
createParam('hash', 'Hash')
],
type: 'RuntimeVersion'
};
const newHead: CreateItemOptions = {
const newHead: MethodOpt = {
description: 'Retrieves the best header via subscription',
subscribe: [
'chain_subscribeNewHead',
@@ -54,24 +53,23 @@ const newHead: CreateItemOptions = {
type: 'Header'
};
const privateMethods: CreateItemOptionsMap = {};
const publicMethods: CreateItemOptionsMap = {
const methods: { [index: string]: MethodOpt } = {
getBlock, getHead, getHeader, getRuntimeVersion, getRuntimeVersionAt, newHead
};
export type PublicMethods = typeof publicMethods;
export type PrivateMethods = typeof privateMethods;
export type Methods = typeof methods;
/**
* @summary Methods to retrieve chain data.
*/
export default (name: Interface$Sections): Section<Interfaces, PrivateMethods, PublicMethods> =>
createSection(name)((createMethod: CreateItems<Interfaces>) => ({
description: 'Retrieval of chain data',
public: Object.keys(publicMethods).reduce((result, key) => {
result[key] = createMethod(key)(publicMethods[key]);
export default {
isDeprecated: false,
isHidden: false,
description: 'Retrieval of chain data',
name: 'chain',
methods: Object.keys(methods).reduce((result, key) => {
result[key] = createMethod('chain', key, methods[key]);
return result;
}, {} as SectionItems<Interfaces, PublicMethods>)
}));
return result;
}, {} as SectionMethods<Methods>)
} as Section<Methods>;
@@ -0,0 +1,22 @@
// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { MethodOpt, Method } from '../types';
import isUndefined from '@polkadot/util/is/undefined';
export default function createMethod (section: string, name: string, { description, params, type, isDeprecated = false, isHidden = false, isSigned = false, subscribe }: MethodOpt): Method {
return {
description,
isDeprecated,
isHidden,
isSigned,
isSubscription: !isUndefined(subscribe),
name,
params,
section,
subscribe: subscribe || ['', ''],
type
};
}
+18
View File
@@ -0,0 +1,18 @@
// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { CodecTypes } from '@polkadot/api-codec/types';
import { Param } from '../types';
type ParamOptions = {
isOptional?: boolean
};
export default function createParam (name: string, type: CodecTypes, { isOptional = false }: ParamOptions = { isOptional: false }): Param {
return {
isOptional,
name,
type
};
}
+5 -7
View File
@@ -2,18 +2,16 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { Interfaces } from './types';
import author from './author';
import chain from './chain';
import state from './state';
import system from './system';
const interfaces: Interfaces = {
author: author('author'),
chain: chain('chain'),
state: state('state'),
system: system('system')
const interfaces = {
author,
chain,
state,
system
};
export default interfaces;
+45 -65
View File
@@ -2,145 +2,125 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { CreateItems, CreateItemOptions, CreateItemOptionsMap, Section } from '@polkadot/params/types';
import { Interfaces, Interface$Sections } from './types';
import { MethodOpt, Section, SectionMethods } from './types';
import param from '@polkadot/params/param';
import createSection from '@polkadot/params/section';
import createMethod from './create/method';
import createParam from './create/param';
const call: CreateItemOptions = {
const call: MethodOpt = {
description: 'Perform a call to a builtin on the chain',
params: [
param('method', 'String'),
param('data', 'Bytes')
createParam('method', 'Text'),
createParam('data', 'Bytes')
],
type: 'Bytes'
};
const callAt: CreateItemOptions = {
const callAt: MethodOpt = {
description: 'Perform a call to a builtin on the chain (At block)',
params: [
param('method', 'String'),
param('data', 'Bytes'),
param('block', 'Hash')
createParam('method', 'Text'),
createParam('data', 'Bytes'),
createParam('block', 'Hash')
],
type: 'Bytes'
};
const getMetadata: CreateItemOptions = {
const getMetadata: MethodOpt = {
description: 'Returns the runtime metadata',
params: [],
type: 'Metadata'
};
const getMetadataAt: CreateItemOptions = {
const getMetadataAt: MethodOpt = {
description: 'Returns the runtime metadata',
params: [
param('block', 'Hash')
createParam('block', 'Hash')
],
type: 'Metadata'
};
const getStorage: CreateItemOptions = {
const getStorage: MethodOpt = {
description: 'Retrieves the storage for a key',
params: [
param('key', 'StorageKey')
createParam('key', 'StorageKey')
],
type: 'StorageData'
};
const getStorageAt: CreateItemOptions = {
const getStorageAt: MethodOpt = {
description: 'Retrieves the storage for a key at a specific block',
params: [
param('key', 'Bytes'),
param('block', 'Hash')
createParam('key', 'Bytes'),
createParam('block', 'Hash')
],
type: 'Bytes'
};
const getStorageHash: CreateItemOptions = {
const getStorageHash: MethodOpt = {
description: 'Retrieves the storage hash',
params: [
param('key', 'Bytes')
createParam('key', 'Bytes')
],
type: 'Hash'
};
const getStorageHashAt: CreateItemOptions = {
const getStorageHashAt: MethodOpt = {
description: 'Retrieves the storage hash at a specific block',
params: [
param('key', 'Bytes'),
param('block', 'Hash')
createParam('key', 'Bytes'),
createParam('block', 'Hash')
],
type: 'Hash'
};
const getStorageSize: CreateItemOptions = {
const getStorageSize: MethodOpt = {
description: 'Retrieves the storage size',
params: [
param('key', 'Bytes')
createParam('key', 'Bytes')
],
type: 'u64'
};
const getStorageSizeAt: CreateItemOptions = {
const getStorageSizeAt: MethodOpt = {
description: 'Retrieves the storage size at a specific block',
params: [
param('key', 'Bytes'),
param('block', 'Hash')
createParam('key', 'Bytes'),
createParam('block', 'Hash')
],
type: 'u64'
};
const storage: CreateItemOptions = {
const storage: MethodOpt = {
description: 'Subscribes to storage changes for the provided keys',
subscribe: [
'state_subscribeStorage',
'state_unsubscribeStorage'
],
params: [
param('keys', 'Vec<StorageKey>')
// @ts-ignore The Vec<> wrap is fine
createParam('keys', 'Vec<StorageKey>')
],
type: 'StorageChangeSet'
};
const privateMethods: CreateItemOptionsMap = {};
const publicMethods: CreateItemOptionsMap = {
call, callAt, getStorage, getStorageAt, getStorageHash, getStorageHashAt, getStorageSize, getStorageSizeAt, storage
const methods: { [index: string]: MethodOpt } = {
call, callAt, getMetadata, getMetadataAt, getStorage, getStorageAt, getStorageHash, getStorageHashAt, getStorageSize, getStorageSizeAt, storage
};
export type PrivateMethods = typeof privateMethods;
export type PublicMethods = typeof publicMethods;
export type Methods = typeof methods;
/**
* @summary Query the state and state storage.
*/
export default (name: Interface$Sections): Section<Interfaces, PrivateMethods, PublicMethods> =>
createSection(name)((createMethod: CreateItems<Interfaces>) => ({
description: 'Query of state',
public: {
call:
createMethod('call')(call),
callAt:
createMethod('callAt')(callAt),
getMetadata:
createMethod('getMetadata')(getMetadata),
getMetadataAt:
createMethod('getMetadataAt')(getMetadataAt),
getStorage:
createMethod('getStorage')(getStorage),
getStorageAt:
createMethod('getStorageAt')(getStorageAt),
getStorageHash:
createMethod('getStorageHash')(getStorageHash),
getStorageHashAt:
createMethod('getStrorageHashAt')(getStorageHashAt),
getStorageSize:
createMethod('getStorageSize')(getStorageSize),
getStorageSizeAt:
createMethod('getStorageSizeAt')(getStorageSizeAt),
storage:
createMethod('storage')(storage)
}
}));
export default {
isDeprecated: false,
isHidden: false,
description: 'Query of state',
name: 'state',
methods: Object.keys(methods).reduce((result, key) => {
result[key] = createMethod('state', key, methods[key]);
return result;
}, {} as SectionMethods<Methods>)
} as Section<Methods>;
+21 -26
View File
@@ -2,50 +2,45 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { CreateItems, CreateItemOptions, CreateItemOptionsMap, Section } from '@polkadot/params/types';
import { Interfaces, Interface$Sections } from './types';
import { MethodOpt, Section, SectionMethods } from './types';
import createSection from '@polkadot/params/section';
import createMethod from './create/method';
const chain: CreateItemOptions = {
const chain: MethodOpt = {
description: 'Retrieves the chain',
params: [],
type: 'String'
type: 'Text'
};
const name: CreateItemOptions = {
const name: MethodOpt = {
description: 'Retrieves the node name',
params: [],
type: 'String'
type: 'Text'
};
const version: CreateItemOptions = {
const version: MethodOpt = {
description: 'Retrieves the version of the node',
params: [],
type: 'String'
type: 'Text'
};
const privateMethods: CreateItemOptionsMap = {};
const publicMethods: CreateItemOptionsMap = {
const methods: { [index: string]: MethodOpt } = {
chain, name, version
};
export type PrivateMethods = typeof privateMethods;
export type PublicMethods = typeof publicMethods;
export type Methods = typeof methods;
/**
* @summary Methods to retrieve system info.
*/
export default (sname: Interface$Sections): Section<Interfaces, PrivateMethods, PublicMethods> =>
createSection(sname)((createMethod: CreateItems<Interfaces>) => ({
description: 'Methods to retrieve system info',
public: {
chain:
createMethod('chain')(chain),
name:
createMethod('name')(name),
version:
createMethod('version')(version)
}
}));
export default {
isDeprecated: false,
isHidden: false,
description: 'Methods to retrieve system info',
name: 'system',
methods: Object.keys(methods).reduce((result, key) => {
result[key] = createMethod('system', key, methods[key]);
return result;
}, {} as SectionMethods<Methods>)
} as Section<Methods>;
+41 -12
View File
@@ -2,17 +2,46 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { Section } from '@polkadot/params/types';
import { PrivateMethods as AuthorPrivate, PublicMethods as AuthorPublic} from './author';
import { PrivateMethods as ChainPrivate, PublicMethods as ChainPublic} from './chain';
import { PrivateMethods as StatePrivate, PublicMethods as StatePublic} from './state';
import { PrivateMethods as SystemPrivate, PublicMethods as SystemPublic} from './system';
import { CodecTypes } from '@polkadot/api-codec/types';
export type Interfaces = {
author: Section<Interfaces, AuthorPrivate, AuthorPrivate>,
chain: Section<Interfaces, ChainPrivate, ChainPublic>,
state: Section<Interfaces, StatePrivate, StatePublic>,
system: Section<Interfaces, SystemPrivate, SystemPublic>
}
export type Param = {
isOptional: boolean,
name: string,
type: CodecTypes
};
export type Interface$Sections = keyof Interfaces;
export type MethodOpt = {
description: string,
isDeprecated?: boolean,
isHidden?: boolean,
isSigned?: boolean,
isSubscription?: boolean,
params: Array<Param>,
subscribe?: [string, string],
type: CodecTypes
};
export type Method = {
description: string,
isDeprecated: boolean,
isHidden: boolean,
isSigned: boolean,
isSubscription: boolean,
name: string,
params: Array<Param>,
section: string,
subscribe: [string, string],
type: CodecTypes
};
export type SectionMethods<M> = {
[key in keyof M]: Method
};
export type Section<M> = {
isDeprecated: boolean,
isHidden: boolean,
description: string,
name: string,
methods: SectionMethods<M>
};
@@ -3,10 +3,9 @@
// of the ISC license. See the LICENSE file for details.
import { SectionItem } from '@polkadot/params/types';
import { Storages } from '@polkadot/storage/types';
import createStorageKey from '@polkadot/storage/key';
import createStorageKey from '../../key';
export default function storageKey ([key, ...params]: [SectionItem<Storages>, any]): Uint8Array {
export default function storageKey ([key, ...params]: [SectionItem<any>, any]): Uint8Array {
return createStorageKey(key).apply(null, params);
}
@@ -3,7 +3,6 @@
// of the ISC license. See the LICENSE file for details.
import { SectionItem } from '@polkadot/params/types';
import { Storage$Key$Value } from '../types';
import u8aConcat from '@polkadot/util/u8a/concat';
import u8aFromString from '@polkadot/util/u8a/fromString';
@@ -11,12 +10,12 @@ import xxhash from '@polkadot/util-crypto/xxhash/asU8a';
import formatParams from './params';
export type Keygen = (...keyParams: Array<Storage$Key$Value>) => Uint8Array;
export type Keygen = (...keyParams: Array<any>) => Uint8Array;
export default function bindKey <T> ({ isUnhashed, key, params }: SectionItem<T>): Keygen {
const prefix = u8aFromString(key);
return (...keyParams: Array<Storage$Key$Value>): Uint8Array => {
return (...keyParams: Array<any>): Uint8Array => {
const postfix = keyParams.length !== 0
? u8aConcat.apply(null, formatParams(params, keyParams))
: new Uint8Array([]);
@@ -4,7 +4,6 @@
import BN from 'bn.js';
import { Param, Params } from '@polkadot/params/types';
import { Storage$Key$Value } from '../types';
import sizes from '@polkadot/primitives/sizes';
import bnToU8a from '@polkadot/util/bn/toU8a';
@@ -12,7 +11,7 @@ import u8aToU8a from '@polkadot/util/u8a/toU8a';
import u8aFromString from '@polkadot/util/u8a/fromString';
import addressDecode from '@polkadot/util-keyring/address/decode';
export default function formatParams (params: Params, values: Storage$Key$Value[] = []): Array<Uint8Array> {
export default function formatParams (params: Params, values: Array<any> = []): Array<Uint8Array> {
const paramTypes = Object.values(params).map(({ type }: Param) => type);
return values.map((value: any, index: number): Uint8Array => {
@@ -3,12 +3,12 @@
// of the ISC license. See the LICENSE file for details.
import Metadata from '@polkadot/api-codec/Metadata';
import json from '@polkadot/api-codec/Metadata.rpc.json';
import json from '@polkadot/api-codec/Metadata.rpc';
import fromMetadata from './fromMetadata';
// Use the pre-generated metadata
const metadata = new Metadata().fromJSON(json.result);
const metadata = new Metadata().fromJSON(json);
const newStorage = fromMetadata({}, metadata);
describe('fromMetadata', () => {
-3
View File
@@ -1,3 +0,0 @@
# Legacy
This whole folder is legacy code, and only used because other packages (api-provider, api-format, type-params) use this folder.
+2 -2
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import metadataJson from '@polkadot/api-codec/Metadata.rpc.json';
import metadataRpc from '@polkadot/api-codec/Metadata.rpc';
import Metadata from '@polkadot/api-codec/Metadata';
import storage from './index';
@@ -10,5 +10,5 @@ import fromMetadata from './fromMetadata';
export default fromMetadata(
storage,
new Metadata().fromJSON(metadataJson.result)
new Metadata().fromJSON(metadataRpc)
);
-17
View File
@@ -18,20 +18,3 @@ export interface Storage {
[key: string]: ModuleStorage; // Will hold modules returned by state_getMetadata
substrate: { [key in Substrate]: StorageFunction };
}
// TODO Below is legacy code, used in:
// - api-provider
export type Storage$Key$Value = number | BN | Uint8Array | string;
export type Storages = {
consensus: Section<Storages, any, any>;
// contract: Section<Storages, any, any>,
council: Section<Storages, any, any>;
councilVoting: Section<Storages, any, any>;
democracy: Section<Storages, any, any>;
parachains: Section<Storages, any, any>;
session: Section<Storages, any, any>;
staking: Section<Storages, any, any>;
system: Section<Storages, any, any>;
timestamp: Section<Storages, any, any>;
};
export type Storage$Sections = keyof Storages;