Skip to content

Commit

Permalink
Merge bd97130 into 62ed0a7
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr committed Sep 28, 2018
2 parents 62ed0a7 + bd97130 commit 43ac4e3
Show file tree
Hide file tree
Showing 29 changed files with 283 additions and 264 deletions.
1 change: 0 additions & 1 deletion packages/api-codec/src/Metadata.rpc.json

This file was deleted.

9 changes: 9 additions & 0 deletions packages/api-codec/src/Metadata.rpc.ts

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions packages/api-codec/src/Metadata.spec.js
Expand Up @@ -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());

Expand Down
3 changes: 3 additions & 0 deletions packages/api-codec/src/types.d.ts
Expand Up @@ -3,10 +3,13 @@
// 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';

export type AnyNumber = UInt | BN | Uint8Array | number | string;

export type AnyU8a = U8a | Uint8Array | Array<number> | string;

export type CodecTypes = keyof typeof Classes;
33 changes: 12 additions & 21 deletions packages/api-provider/src/mock/mocks.ts
Expand Up @@ -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;
Expand Down Expand Up @@ -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(() => {
Expand All @@ -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);
}
4 changes: 2 additions & 2 deletions packages/api-provider/src/mock/send.ts
Expand Up @@ -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);
}
10 changes: 5 additions & 5 deletions packages/api-provider/src/mock/state.ts
Expand Up @@ -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';
Expand All @@ -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
)
Expand All @@ -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)]
);
Expand All @@ -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: {},
Expand All @@ -50,7 +50,7 @@ export default function state (): MockState {
emitter: new E3.EventEmitter(),
l,
requests: Object.assign({}, REQUESTS),
storage,
db,
subscriptionId: 0,
subscriptionMap: {},
subscriptions
Expand Down
6 changes: 3 additions & 3 deletions packages/api-provider/src/mock/types.d.ts
Expand Up @@ -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
Expand Down
13 changes: 5 additions & 8 deletions packages/api-rx/src/index.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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))
Expand Down
6 changes: 3 additions & 3 deletions packages/api-rx/src/types.d.ts
Expand Up @@ -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>;

Expand All @@ -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 & {
Expand Down
1 change: 0 additions & 1 deletion packages/api/package.json
Expand Up @@ -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"
}
}
57 changes: 33 additions & 24 deletions packages/api/src/index.ts
Expand Up @@ -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
Expand All @@ -41,35 +38,47 @@ 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];

assert(!isUndefined(definition), `Unable to find section '${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(', ');

// @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);

return exposed;
}, {} 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 {
Expand All @@ -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);

Expand All @@ -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> => {
Expand All @@ -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);

Expand All @@ -122,15 +131,15 @@ 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) =>
createType(type as string, inputs[index])
);
}

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') {
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/types.d.ts
Expand Up @@ -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>;
Expand All @@ -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 change: 0 additions & 1 deletion packages/type-jsonrpc/package.json
Expand Up @@ -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"
}
}

0 comments on commit 43ac4e3

Please sign in to comment.