eslint rules (#1099)
* Off to the races - 3760 problems (1794 errors, 1966 warnings)
* Convert Array<T> -> T[] (not all correct, eg. extends)
* () => { -> (): void => {
* get is/as -> public get is/as
* public for getters, constructors & base Codec
* Some cleanups from previous overzealous search & replace
* Under 2k, 1874 problems (649 errors, 1225 warnings)
* ^^^ check that commit for details ;)
* Minor.
* rm config header
* Minor cleanups
* Default to tslint, eslint as option
* Trigger
* Update jsonrpc
* 1494 problems (433 errors, 1061 warnings)
* 1103 problems (135 errors, 968 warnings)
* 899 problems (9 errors, 890 warnings)
* 483 problems (9 errors, 474 warnings) (ignore any... for now)
* 366 problems (9 errors, 357 warnings)
* 336 problems (9 errors, 327 warnings)
* 148 problems (9 errors, 139 warnings)
* 31 problems (8 errors, 23 warnings)
* 0, 0
This commit is contained in:
@@ -8,43 +8,43 @@ import { AccountId } from '@polkadot/types';
|
||||
|
||||
import Rpc from '.';
|
||||
|
||||
describe('Cached Observables', () => {
|
||||
describe('Cached Observables', (): void => {
|
||||
let rpc: Rpc;
|
||||
const keyring = testingPairs();
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
rpc = new Rpc(new MockProvider());
|
||||
});
|
||||
|
||||
it('creates a single observable for subscriptions (multiple calls)', () => {
|
||||
it('creates a single observable for subscriptions (multiple calls)', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead(123);
|
||||
const observable2 = rpc.chain.subscribeNewHead(123);
|
||||
|
||||
expect(observable2).toBe(observable1);
|
||||
});
|
||||
|
||||
it('creates a single observable for subscriptions (multiple calls, no arguments)', () => {
|
||||
it('creates a single observable for subscriptions (multiple calls, no arguments)', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead();
|
||||
const observable2 = rpc.chain.subscribeNewHead();
|
||||
|
||||
expect(observable2).toBe(observable1);
|
||||
});
|
||||
|
||||
it('creates a single observable (multiple calls, different arguments that should be cached together)', () => {
|
||||
it('creates a single observable (multiple calls, different arguments that should be cached together)', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead(keyring.alice.address);
|
||||
const observable2 = rpc.chain.subscribeNewHead(new AccountId(keyring.alice.address));
|
||||
|
||||
expect(observable2).toBe(observable1);
|
||||
});
|
||||
|
||||
it('creates multiple observables for different values', () => {
|
||||
it('creates multiple observables for different values', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead(123);
|
||||
const observable2 = rpc.chain.subscribeNewHead(456);
|
||||
|
||||
expect(observable2).not.toBe(observable1);
|
||||
});
|
||||
|
||||
it('clears cache if there are no more subscribers', () => {
|
||||
it('clears cache if there are no more subscribers', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead();
|
||||
const observable2 = rpc.chain.subscribeNewHead();
|
||||
|
||||
@@ -62,14 +62,14 @@ describe('Cached Observables', () => {
|
||||
expect(observable3).not.toBe(observable1);
|
||||
});
|
||||
|
||||
it('creates different observables for different methods but same arguments', () => {
|
||||
it('creates different observables for different methods but same arguments', (): void => {
|
||||
const observable1 = rpc.chain.subscribeNewHead(123);
|
||||
const observable2 = rpc.state.subscribeStorage(123);
|
||||
|
||||
expect(observable2).not.toBe(observable1);
|
||||
});
|
||||
|
||||
it('creates multiple observables for one-shots', () => {
|
||||
it('creates multiple observables for one-shots', (): void => {
|
||||
const observable1 = rpc.system.chain(123);
|
||||
const observable2 = rpc.system.chain(123);
|
||||
|
||||
|
||||
@@ -22,23 +22,23 @@ const BALANCE_KEYS = [
|
||||
];
|
||||
const OPTION_BYTES_HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce';
|
||||
|
||||
function formattingTests (version: string, storage: Storage, encodedValues: [string, string, string]) {
|
||||
function formattingTests (version: string, storage: Storage, encodedValues: [string, string, string]): void {
|
||||
const [ENC_ONE, ENC_TWO, CONTRACT_KEY] = encodedValues;
|
||||
|
||||
describe(`formatting with Metadata ${version}`, () => {
|
||||
describe(`formatting with Metadata ${version}`, (): void => {
|
||||
let api: Api;
|
||||
let provider: any;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
provider = {
|
||||
send: jest.fn((method, [key]) =>
|
||||
send: jest.fn((method, [key]): Promise<any> =>
|
||||
Promise.resolve(
|
||||
BALANCE_KEYS.includes(key)
|
||||
? '0x01020000000000000000000000000000'
|
||||
: null
|
||||
)
|
||||
),
|
||||
subscribe: jest.fn((type, method, params, cb) => {
|
||||
subscribe: jest.fn((type, method, params, cb): void => {
|
||||
// this emulates https://github.com/polkadot-js/api/issues/1051
|
||||
params[0][0] === CONTRACT_KEY
|
||||
? cb(null, {
|
||||
@@ -60,10 +60,10 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str
|
||||
api = new Api(provider);
|
||||
});
|
||||
|
||||
it('encodes key (with params), decoding response', (done) => {
|
||||
it('encodes key (with params), decoding response', (done): void => {
|
||||
api.state
|
||||
.getStorage([storage.balances.freeBalance, ADDR_ONE])
|
||||
.subscribe((value) => {
|
||||
.subscribe((value): void => {
|
||||
expect(
|
||||
provider.send
|
||||
).toHaveBeenCalledWith(
|
||||
@@ -75,22 +75,22 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the fallback result on not-found values', (done) => {
|
||||
it('returns the fallback result on not-found values', (done): void => {
|
||||
api.state
|
||||
.getStorage([storage.system.accountNonce, ADDR_ONE])
|
||||
.subscribe((value) => {
|
||||
.subscribe((value): void => {
|
||||
expect(value.toHex()).toEqual('0x0000000000000000');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes multiple keys, decoding multiple results', (done) => {
|
||||
it('encodes multiple keys, decoding multiple results', (done): void => {
|
||||
api.state.subscribeStorage(
|
||||
[
|
||||
[storage.balances.freeBalance, ADDR_ONE],
|
||||
[storage.balances.freeBalance, ADDR_TWO]
|
||||
]
|
||||
).subscribe((value: any) => {
|
||||
).subscribe((value: any): void => {
|
||||
console.error(value);
|
||||
|
||||
expect(
|
||||
@@ -102,7 +102,7 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str
|
||||
expect.anything()
|
||||
);
|
||||
expect(
|
||||
value.map((balance: BN) =>
|
||||
value.map((balance: BN): number =>
|
||||
balance.toNumber()
|
||||
)
|
||||
).toEqual([0x0201, 0x0102]);
|
||||
@@ -111,11 +111,15 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str
|
||||
});
|
||||
});
|
||||
|
||||
it('handles the case where Option<Bytes> are retrieved', (done) => {
|
||||
let call = Number(version.slice(1)) <= 5 ? storage.contract.pristineCode : storage.contracts.pristineCode;
|
||||
it('handles the case where Option<Bytes> are retrieved', (done): void => {
|
||||
const call = Number(version.slice(1)) <= 5
|
||||
? storage.contract.pristineCode
|
||||
: storage.contracts.pristineCode;
|
||||
|
||||
api.state
|
||||
.subscribeStorage([[call, '0x00']])
|
||||
.subscribe((value: any) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
.subscribe((value: any): void => {
|
||||
// console.error(value);
|
||||
|
||||
// expect(value.toHex()).toBe(OPTION_BYTES_HEX);
|
||||
|
||||
@@ -6,18 +6,18 @@ import MockProvider from '@polkadot/rpc-provider/mock';
|
||||
|
||||
import Rpc from '.';
|
||||
|
||||
describe('Api', () => {
|
||||
it('requires a provider with a send method', () => {
|
||||
describe('Api', (): void => {
|
||||
it('requires a provider with a send method', (): void => {
|
||||
expect(
|
||||
() => new Rpc({} as any)
|
||||
(): Rpc => new Rpc({} as any)
|
||||
).toThrow(/Expected Provider/);
|
||||
});
|
||||
|
||||
it('creates an instance with all sections', () => {
|
||||
it('creates an instance with all sections', (): void => {
|
||||
const rpc = new Rpc(new MockProvider());
|
||||
|
||||
expect(
|
||||
Object.keys(rpc).filter((key) => !key.startsWith('_'))
|
||||
Object.keys(rpc).filter((key): boolean => !key.startsWith('_'))
|
||||
).toEqual([
|
||||
'provider',
|
||||
'author', 'chain', 'state', 'system'
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
||||
import { RpcSection, RpcMethod } from '@polkadot/jsonrpc/types';
|
||||
import { RpcInterface, RpcInterface$Method, RpcInterface$Section } from './types';
|
||||
import { AnyJson, Codec } from '@polkadot/types/types';
|
||||
import { RpcInterface, RpcInterfaceMethod, RpcInterfaceSection } from './types';
|
||||
|
||||
import memoize from 'memoizee';
|
||||
import { combineLatest, from, Observable, Observer, of, throwError } from 'rxjs';
|
||||
import { catchError, map, publishReplay, refCount, switchMap } from 'rxjs/operators';
|
||||
import interfaces from '@polkadot/jsonrpc';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
import { Option, StorageChangeSet, StorageData, StorageKey, Vector, createClass, createType } from '@polkadot/types';
|
||||
import { ExtError, assert, isFunction, isNull, logger } from '@polkadot/util';
|
||||
|
||||
@@ -50,18 +50,23 @@ const EMPTY_META = {
|
||||
*/
|
||||
export default class Rpc implements RpcInterface {
|
||||
private _storageCache = new Map<string, Option<StorageData>>();
|
||||
readonly provider: ProviderInterface;
|
||||
readonly author: RpcInterface$Section;
|
||||
readonly chain: RpcInterface$Section;
|
||||
readonly state: RpcInterface$Section;
|
||||
readonly system: RpcInterface$Section;
|
||||
|
||||
public readonly provider: ProviderInterface;
|
||||
|
||||
public readonly author: RpcInterfaceSection;
|
||||
|
||||
public readonly chain: RpcInterfaceSection;
|
||||
|
||||
public readonly state: RpcInterfaceSection;
|
||||
|
||||
public readonly system: RpcInterfaceSection;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* Default constructor for the Api Object
|
||||
* @param {ProviderInterface} provider An API provider using HTTP or WebSocket
|
||||
*/
|
||||
constructor (provider: ProviderInterface) {
|
||||
public constructor (provider: ProviderInterface) {
|
||||
assert(provider && isFunction(provider.send), 'Expected Provider to API create');
|
||||
|
||||
this.provider = provider;
|
||||
@@ -87,8 +92,8 @@ export default class Rpc implements RpcInterface {
|
||||
* Api.signature({ name: 'test_method', params: [ { name: 'dest', type: 'Address' } ], type: 'Address' }); // => test_method (dest: Address): Address
|
||||
* ```
|
||||
*/
|
||||
static signature ({ method, params, type }: RpcMethod): string {
|
||||
const inputs = params.map(({ name, type }) =>
|
||||
public static signature ({ method, params, type }: RpcMethod): string {
|
||||
const inputs = params.map(({ name, type }): string =>
|
||||
`${name}: ${type}`
|
||||
).join(', ');
|
||||
|
||||
@@ -98,19 +103,18 @@ export default class Rpc implements RpcInterface {
|
||||
/**
|
||||
* @description Manually disconnect from the attached provider
|
||||
*/
|
||||
disconnect (): void {
|
||||
public disconnect (): void {
|
||||
this.provider.disconnect();
|
||||
}
|
||||
|
||||
private createErrorMessage (method: RpcMethod, error: Error) {
|
||||
private createErrorMessage (method: RpcMethod, error: Error): string {
|
||||
return `${Rpc.signature(method)}:: ${error.message}`;
|
||||
}
|
||||
|
||||
private createInterface ({ methods }: RpcSection): RpcInterface$Section {
|
||||
private createInterface ({ methods }: RpcSection): RpcInterfaceSection {
|
||||
return Object
|
||||
.keys(methods)
|
||||
.reduce((exposed, methodName) => {
|
||||
|
||||
.reduce((exposed, methodName): RpcInterfaceSection => {
|
||||
const def = methods[methodName];
|
||||
|
||||
exposed[methodName] = def.isSubscription
|
||||
@@ -118,13 +122,13 @@ export default class Rpc implements RpcInterface {
|
||||
: this.createMethodSend(def);
|
||||
|
||||
return exposed;
|
||||
}, {} as RpcInterface$Section);
|
||||
}, {} as unknown as RpcInterfaceSection);
|
||||
}
|
||||
|
||||
private createMethodSend (method: RpcMethod): RpcInterface$Method {
|
||||
private createMethodSend (method: RpcMethod): RpcInterfaceMethod {
|
||||
const rpcName = `${method.section}_${method.method}`;
|
||||
|
||||
const call = (...values: Array<any>): Observable<any> => {
|
||||
const call = (...values: any[]): Observable<any> => {
|
||||
// TODO Warn on deprecated methods
|
||||
|
||||
// Here, logically, it should be `of(this.formatInputs(method, values))`.
|
||||
@@ -135,15 +139,15 @@ export default class Rpc implements RpcInterface {
|
||||
// - then do `map(()=>this.formatInputs)` - might throw, but inside Observable.
|
||||
return of(1)
|
||||
.pipe(
|
||||
map(() => this.formatInputs(method, values)),
|
||||
switchMap((params) =>
|
||||
map((): Codec[] => this.formatInputs(method, values)),
|
||||
switchMap((params): Observable<[Codec[], any]> =>
|
||||
combineLatest([
|
||||
of(params),
|
||||
from(this.provider.send(rpcName, params.map((param) => param.toJSON())))
|
||||
from(this.provider.send(rpcName, params.map((param): AnyJson => param.toJSON())))
|
||||
])
|
||||
),
|
||||
map(([params, result]) => this.formatOutput(method, params, result)),
|
||||
catchError((error) => {
|
||||
map(([params, result]): any => this.formatOutput(method, params, result)),
|
||||
catchError((error): any => {
|
||||
const message = this.createErrorMessage(method, error);
|
||||
|
||||
l.error(message);
|
||||
@@ -158,23 +162,23 @@ export default class Rpc implements RpcInterface {
|
||||
// We voluntarily don't cache the "one-shot" RPC calls. For example,
|
||||
// `getStorage('123')` returns the current value, but this value can change
|
||||
// over time, so we wouldn't want to cache the Observable.
|
||||
return call as RpcInterface$Method;
|
||||
return call as RpcInterfaceMethod;
|
||||
}
|
||||
|
||||
private createMethodSubscribe (method: RpcMethod): RpcInterface$Method {
|
||||
private createMethodSubscribe (method: RpcMethod): RpcInterfaceMethod {
|
||||
const [updateType, subMethod, unsubMethod] = method.pubsub;
|
||||
const subName = `${method.section}_${subMethod}`;
|
||||
const unsubName = `${method.section}_${unsubMethod}`;
|
||||
const subType = `${method.section}_${updateType}`;
|
||||
|
||||
const call = (...values: Array<any>): Observable<any> => {
|
||||
return new Observable((observer: Observer<any>) => {
|
||||
const call = (...values: any[]): Observable<any> => {
|
||||
return new Observable((observer: Observer<any>): VoidCallback => {
|
||||
let subscriptionPromise: Promise<number>;
|
||||
|
||||
try {
|
||||
const params = this.formatInputs(method, values);
|
||||
const paramsJson = params.map((param) => param.toJSON());
|
||||
const update = (error?: Error, result?: any) => {
|
||||
const paramsJson = params.map((param): AnyJson => param.toJSON());
|
||||
const update = (error?: Error, result?: any): void => {
|
||||
if (error) {
|
||||
l.error(this.createErrorMessage(method, error));
|
||||
return;
|
||||
@@ -193,7 +197,7 @@ export default class Rpc implements RpcInterface {
|
||||
}
|
||||
|
||||
// Teardown logic
|
||||
return () => {
|
||||
return (): void => {
|
||||
// Delete from cache
|
||||
// Reason:
|
||||
// ```
|
||||
@@ -203,11 +207,14 @@ export default class Rpc implements RpcInterface {
|
||||
// api.query.system.accountNonce(addr1).subscribe(); // will output 6 instead of 7 if we don't clear cache
|
||||
// // that's because all our observables are replay(1)
|
||||
// ```
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
memoized.delete(...values);
|
||||
// Unsubscribe from provider
|
||||
subscriptionPromise
|
||||
.then((subscriptionId) => this.provider.unsubscribe(subType, unsubName, subscriptionId))
|
||||
.catch((error: Error) => {
|
||||
.then((subscriptionId): Promise<boolean> =>
|
||||
this.provider.unsubscribe(subType, unsubName, subscriptionId)
|
||||
)
|
||||
.catch((error: Error): void => {
|
||||
const message = this.createErrorMessage(method, error);
|
||||
|
||||
l.error(message);
|
||||
@@ -231,20 +238,20 @@ export default class Rpc implements RpcInterface {
|
||||
return memoized;
|
||||
}
|
||||
|
||||
private formatInputs (method: RpcMethod, inputs: Array<any>): Array<Codec> {
|
||||
const reqArgCount = method.params.filter(({ isOptional }) => !isOptional).length;
|
||||
private formatInputs (method: RpcMethod, inputs: any[]): Codec[] {
|
||||
const reqArgCount = method.params.filter(({ isOptional }): boolean => !isOptional).length;
|
||||
const optText = reqArgCount === method.params.length
|
||||
? ''
|
||||
: ` (${method.params.length - reqArgCount} optional)`;
|
||||
|
||||
assert(inputs.length >= reqArgCount && inputs.length <= method.params.length, `Expected ${method.params.length} parameters${optText}, ${inputs.length} found instead`);
|
||||
|
||||
return inputs.map((input, index) =>
|
||||
return inputs.map((input, index): Codec =>
|
||||
createType(method.params[index].type, input)
|
||||
);
|
||||
}
|
||||
|
||||
private formatOutput (method: RpcMethod, params: Array<Codec>, result?: any): Codec | Array<Codec | null | undefined> {
|
||||
private formatOutput (method: RpcMethod, params: Codec[], result?: any): Codec | (Codec | null | undefined)[] {
|
||||
const base = createType(method.type as string, result);
|
||||
|
||||
if (method.type === 'StorageData') {
|
||||
@@ -263,7 +270,7 @@ export default class Rpc implements RpcInterface {
|
||||
// - Base - There is a valid value, non-empty
|
||||
// - null - The storage key is empty (but in the resultset)
|
||||
// - undefined - The storage value is not in the resultset
|
||||
return (params[0] as Vector<StorageKey>).reduce((results, key: StorageKey) => {
|
||||
return (params[0] as Vector<StorageKey>).reduce((results, key: StorageKey): (Codec | undefined)[] => {
|
||||
try {
|
||||
results.push(this.formatStorageSet(key, base as StorageChangeSet));
|
||||
} catch (error) {
|
||||
@@ -273,7 +280,7 @@ export default class Rpc implements RpcInterface {
|
||||
}
|
||||
|
||||
return results;
|
||||
}, [] as Array<Codec | undefined>);
|
||||
}, [] as (Codec | undefined)[]);
|
||||
}
|
||||
|
||||
return base;
|
||||
@@ -305,7 +312,7 @@ export default class Rpc implements RpcInterface {
|
||||
|
||||
// see if we have a result value for this specific key, fallback to the cache value
|
||||
// when the value in the set is not available, or is null/empty.
|
||||
const { value } = base.changes.find(({ key, value }) =>
|
||||
const { value } = base.changes.find(({ key, value }): boolean =>
|
||||
value.isSome && key.toHex() === hexKey
|
||||
) || { value: this._storageCache.get(hexKey) || new Option<StorageData>(StorageData, null) };
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
import Rpc from '.';
|
||||
|
||||
describe('methodSend', () => {
|
||||
describe('methodSend', (): void => {
|
||||
let rpc: Rpc;
|
||||
let methods: any;
|
||||
let provider: any;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
methods = {
|
||||
blah: {
|
||||
method: 'blah',
|
||||
@@ -28,7 +28,7 @@ describe('methodSend', () => {
|
||||
};
|
||||
|
||||
provider = {
|
||||
send: jest.fn((method, params) => {
|
||||
send: jest.fn((method, params): Promise<any> => {
|
||||
return Promise.resolve(params[0]);
|
||||
})
|
||||
};
|
||||
@@ -36,37 +36,37 @@ describe('methodSend', () => {
|
||||
rpc = new Rpc(provider);
|
||||
});
|
||||
|
||||
it('wraps errors with the call signature', (done) => {
|
||||
it('wraps errors with the call signature', (done): void => {
|
||||
// @ts-ignore private method
|
||||
const method = rpc.createMethodSend(methods.blah);
|
||||
|
||||
method().subscribe(
|
||||
() => { /* noop */ },
|
||||
(error) => {
|
||||
(): void => { /* noop */ },
|
||||
(error): void => {
|
||||
expect(error.message).toMatch(/blah \(foo: Bytes\): Bytes/);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('checks for mismatched parameters', (done) => {
|
||||
it('checks for mismatched parameters', (done): void => {
|
||||
// @ts-ignore private method
|
||||
const method = rpc.createMethodSend(methods.bleh);
|
||||
|
||||
method(1).subscribe(
|
||||
() => { /* noop */ },
|
||||
(error) => {
|
||||
(): void => { /* noop */ },
|
||||
(error): void => {
|
||||
expect(error.message).toMatch(/parameters, 1 found instead/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls the provider with the correct parameters', (done) => {
|
||||
it('calls the provider with the correct parameters', (done): void => {
|
||||
// @ts-ignore private method
|
||||
const method = rpc.createMethodSend(methods.blah);
|
||||
|
||||
// Args are length-prefixed, because it's a Bytes
|
||||
method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe(() => {
|
||||
method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe((): void => {
|
||||
expect(provider.send).toHaveBeenCalledWith('test_blah', ['0x1234']);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import MockProvider from '@polkadot/rpc-provider/mock';
|
||||
|
||||
import Rpc from '.';
|
||||
|
||||
describe('replay', () => {
|
||||
describe('replay', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
rpc = new Rpc(new MockProvider());
|
||||
});
|
||||
|
||||
it('subscribes via the rpc section', (done) => {
|
||||
rpc.chain.getBlockHash = jest.fn(() => of(1));
|
||||
it('subscribes via the rpc section', (done): void => {
|
||||
rpc.chain.getBlockHash = jest.fn((): Observable<number> => of(1));
|
||||
|
||||
rpc.chain.getBlockHash(123, false).subscribe(() => {
|
||||
rpc.chain.getBlockHash(123, false).subscribe((): void => {
|
||||
expect(
|
||||
rpc.chain.getBlockHash
|
||||
).toHaveBeenCalledWith(123, false);
|
||||
@@ -26,8 +26,8 @@ describe('replay', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the observable value', (done) => {
|
||||
rpc.system.chain().subscribe((value) => {
|
||||
it('returns the observable value', (done): void => {
|
||||
rpc.system.chain().subscribe((value: any): void => {
|
||||
if (value) {
|
||||
expect(value).toEqual('mockChain'); // Defined in MockProvider
|
||||
done();
|
||||
@@ -35,27 +35,28 @@ describe('replay', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('replay(1) works as expected', (done) => {
|
||||
it('replay(1) works as expected', (done): void => {
|
||||
const observable = rpc.system.chain();
|
||||
let a: string | undefined;
|
||||
observable.subscribe((value) => { a = value; });
|
||||
observable.subscribe((value: any): void => { a = value; });
|
||||
|
||||
setTimeout(() => {
|
||||
setTimeout((): void => {
|
||||
// Subscribe again to the same observable, it should fire value immediately
|
||||
observable.subscribe((value) => {
|
||||
observable.subscribe((value: any): void => {
|
||||
expect(value).toEqual(a);
|
||||
done();
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
it('unsubscribes as required', (done) => {
|
||||
it('unsubscribes as required', (done): void => {
|
||||
rpc.provider.unsubscribe = jest.fn();
|
||||
|
||||
const subscription = rpc.chain.subscribeNewHead().subscribe(() => {
|
||||
const subscription = rpc.chain.subscribeNewHead().subscribe((): void => {
|
||||
subscription.unsubscribe();
|
||||
|
||||
// There's a promise inside .unsubscribe(), wait a bit
|
||||
setTimeout(() => {
|
||||
setTimeout((): void => {
|
||||
expect(rpc.provider.unsubscribe).toHaveBeenCalled();
|
||||
done();
|
||||
}, 200);
|
||||
|
||||
@@ -4,17 +4,15 @@
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface RpcInterface$Method {
|
||||
(...params: Array<any>): Observable<any>;
|
||||
export interface RpcInterfaceMethod {
|
||||
(...params: any[]): Observable<any>;
|
||||
}
|
||||
|
||||
export type RpcInterface$Section = {
|
||||
[index: string]: RpcInterface$Method
|
||||
};
|
||||
export type RpcInterfaceSection = Record<string, RpcInterfaceMethod>;
|
||||
|
||||
export interface RpcInterface {
|
||||
readonly author: RpcInterface$Section;
|
||||
readonly chain: RpcInterface$Section;
|
||||
readonly state: RpcInterface$Section;
|
||||
readonly system: RpcInterface$Section;
|
||||
readonly author: RpcInterfaceSection;
|
||||
readonly chain: RpcInterfaceSection;
|
||||
readonly state: RpcInterfaceSection;
|
||||
readonly system: RpcInterfaceSection;
|
||||
}
|
||||
|
||||
@@ -10,21 +10,21 @@ import Rpc from '../../src';
|
||||
|
||||
const randomAccount = '5HTqyWJHAVUieZnpb1V8gK4T1E4mnhkrUVSSzWBQd6kYgsVJ';
|
||||
|
||||
describe.skip('e2e Alexander - Polkadot', () => {
|
||||
describe.skip('e2e Alexander - Polkadot', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
jest.setTimeout(30000);
|
||||
rpc = new Rpc(new WsProvider('wss://poc3-rpc.polkadot.io/'));
|
||||
});
|
||||
|
||||
it('subscribes to storage', (done) => {
|
||||
it('subscribes to storage', (done): void => {
|
||||
rpc.state
|
||||
.subscribeStorage([
|
||||
[storage.system.accountNonce, randomAccount],
|
||||
[storage.session.currentIndex]
|
||||
])
|
||||
.subscribe((data: StorageChangeSet) => {
|
||||
.subscribe((data: StorageChangeSet): void => {
|
||||
expect(data).toHaveLength(2);
|
||||
expect(data).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -37,20 +37,20 @@ describe.skip('e2e Alexander - Polkadot', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves a block by hash (krumme lanke #1)', (done) => {
|
||||
it('retrieves a block by hash (krumme lanke #1)', (done): void => {
|
||||
rpc.chain
|
||||
.getBlock('0x627847bffdf5f3e01ac440d057dec6a37a12a6f329db7ef8367665574b76b5df')
|
||||
.subscribe((block: SignedBlock) => {
|
||||
.subscribe((block: SignedBlock): void => {
|
||||
expect(block).toBeDefined();
|
||||
expect(block).toBeInstanceOf(SignedBlock);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves a block by hash (krumme lanke #2)', (done) => {
|
||||
it('retrieves a block by hash (krumme lanke #2)', (done): void => {
|
||||
rpc.chain
|
||||
.getBlock('0x53416d53a4b1dfcae9165a89d193608e4aa770414f02267f5b2c4015a2e66091')
|
||||
.subscribe((block: SignedBlock) => {
|
||||
.subscribe((block: SignedBlock): void => {
|
||||
expect(block).toBeDefined();
|
||||
expect(block).toBeInstanceOf(SignedBlock);
|
||||
done();
|
||||
|
||||
@@ -7,27 +7,27 @@ import WsProvider from '@polkadot/rpc-provider/ws';
|
||||
|
||||
import Rpc from '../../src';
|
||||
|
||||
describe.skip('e2e basics', () => {
|
||||
describe.skip('e2e basics', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
jest.setTimeout(30000);
|
||||
rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944'));
|
||||
});
|
||||
|
||||
it('retrieves the pending extrinsics', (done) => {
|
||||
it('retrieves the pending extrinsics', (done): void => {
|
||||
rpc.author
|
||||
.pendingExtrinsics()
|
||||
.subscribe((extrinsics: PendingExtrinsics) => {
|
||||
.subscribe((extrinsics: PendingExtrinsics): void => {
|
||||
expect(extrinsics).toBeInstanceOf(PendingExtrinsics);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves the system properties', (done) => {
|
||||
it('retrieves the system properties', (done): void => {
|
||||
rpc.system
|
||||
.properties()
|
||||
.subscribe((properties: ChainProperties) => {
|
||||
.subscribe((properties: ChainProperties): void => {
|
||||
expect(properties).toBeInstanceOf(ChainProperties);
|
||||
console.log('properties', properties);
|
||||
done();
|
||||
|
||||
@@ -7,20 +7,20 @@ import WsProvider from '@polkadot/rpc-provider/ws';
|
||||
|
||||
import Rpc from '../../src';
|
||||
|
||||
describe.skip('e2e chain', () => {
|
||||
describe.skip('e2e chain', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
jest.setTimeout(30000);
|
||||
rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944'));
|
||||
});
|
||||
|
||||
it('subscribes via subscribeNewHead', (done) => {
|
||||
let count: number = 0;
|
||||
it('subscribes via subscribeNewHead', (done): void => {
|
||||
let count = 0;
|
||||
|
||||
rpc.chain
|
||||
.subscribeNewHead()
|
||||
.subscribe((header: Header) => {
|
||||
.subscribe((header: Header): void => {
|
||||
expect(header).toBeInstanceOf(Header);
|
||||
|
||||
if (++count === 3) {
|
||||
@@ -29,10 +29,10 @@ describe.skip('e2e chain', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves the runtime version', (done) => {
|
||||
it('retrieves the runtime version', (done): void => {
|
||||
rpc.chain
|
||||
.getRuntimeVersion()
|
||||
.subscribe((version: RuntimeVersion) => {
|
||||
.subscribe((version: RuntimeVersion): void => {
|
||||
expect(version).toBeInstanceOf(RuntimeVersion);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -21,50 +21,50 @@ const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
|
||||
const CODE = '0x3a636f6465'; // :code
|
||||
const CHILD_STORAGE = '0x3a6368696c645f73746f726167653a'; // :child_storage:
|
||||
|
||||
describe.skip('e2e state', () => {
|
||||
describe.skip('e2e state', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
jest.setTimeout(30000);
|
||||
rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944'));
|
||||
});
|
||||
|
||||
it('getMetadata(): retrieves the wasm metadata', (done) => {
|
||||
it('getMetadata(): retrieves the wasm metadata', (done): void => {
|
||||
rpc.state
|
||||
.getMetadata()
|
||||
.subscribe((meta: Metadata) => {
|
||||
.subscribe((meta: Metadata): void => {
|
||||
console.error(JSON.stringify(meta.toJSON()));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('getKeys(): retrieves storage keys for ":code"', (done) => {
|
||||
it('getKeys(): retrieves storage keys for ":code"', (done): void => {
|
||||
rpc.state
|
||||
.getKeys(CODE)
|
||||
.subscribe((keys: Array<StorageKey>) => {
|
||||
.subscribe((keys: StorageKey[]): void => {
|
||||
expect(keys.length).toEqual(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('test-suite getStorage()', () => {
|
||||
it('retrieves code', (done) => {
|
||||
describe('test-suite getStorage()', (): void => {
|
||||
it('retrieves code', (done): void => {
|
||||
rpc.state
|
||||
.getStorage([
|
||||
storage.substrate.code
|
||||
])
|
||||
.subscribe((code: Bytes) => {
|
||||
.subscribe((code: Bytes): void => {
|
||||
console.error(code.toHex().substr(0, 256), '...');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves balances', (done) => {
|
||||
it('retrieves balances', (done): void => {
|
||||
rpc.state
|
||||
.getStorage([
|
||||
storage.balances.freeBalance, ALICE
|
||||
])
|
||||
.subscribe((balance: Balance) => {
|
||||
.subscribe((balance: Balance): void => {
|
||||
console.error(balance);
|
||||
|
||||
expect(balance.isZero()).not.toEqual(true);
|
||||
@@ -72,12 +72,12 @@ describe.skip('e2e state', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('retrieves timestamp', (done) => {
|
||||
it('retrieves timestamp', (done): void => {
|
||||
rpc.state
|
||||
.getStorage([
|
||||
storage.timestamp.now
|
||||
])
|
||||
.subscribe((moment: Moment) => {
|
||||
.subscribe((moment: Moment): void => {
|
||||
console.error(moment);
|
||||
|
||||
expect(moment.toNumber()).not.toEqual(0);
|
||||
@@ -86,22 +86,20 @@ describe.skip('e2e state', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('e2e state child methods', () => {
|
||||
describe('e2e state child methods', (): void => {
|
||||
// `child_storage` is currently not used anywhere in substrate, that's why we need to
|
||||
// add a Smart Contract that is using `child_storage` before being able to test it.
|
||||
let codeHash: Hash;
|
||||
|
||||
beforeAll(async (done) => {
|
||||
beforeAll(async (done): Promise<Hash> => {
|
||||
const code: string = fs.readFileSync(path.join(__dirname, '../../../api-contract/test/contracts/flipper-pruned.wasm')).toString('hex');
|
||||
const abi = new Abi(flipperAbi);
|
||||
const apiPromise: ApiPromise = await ApiPromise.create(new WsProvider('ws://127.0.0.1:9944'));
|
||||
const keyring: {
|
||||
[index: string]: KeyringPair
|
||||
} = testingPairs({ type: 'sr25519' });
|
||||
const keyring: Record<string, KeyringPair> = testingPairs({ type: 'sr25519' });
|
||||
|
||||
const putCode = apiPromise.tx.contract
|
||||
.putCode(50000, `0x${code}`)
|
||||
.signAndSend(keyring.eve, (result: SubmittableResult) => {
|
||||
.signAndSend(keyring.eve, (result: SubmittableResult): void => {
|
||||
if (result.status.isFinalized) {
|
||||
const record = result.findRecord('contract', 'CodeStored');
|
||||
|
||||
@@ -109,58 +107,60 @@ describe.skip('e2e state', () => {
|
||||
codeHash = record.event.data[0] as Hash;
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
return putCode.then(() => {
|
||||
return putCode.then((): Promise<Hash> => {
|
||||
return apiPromise.tx.contract
|
||||
.create(12345, 50000, codeHash, abi.deploy())
|
||||
.signAndSend(keyring.bob);
|
||||
});
|
||||
});
|
||||
|
||||
it('getChildKeys(): retrieves :child_storage: keys for one deployed flipper contract', async (done) => {
|
||||
it('getChildKeys(): retrieves :child_storage: keys for one deployed flipper contract', async (done):
|
||||
Promise<void> => {
|
||||
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
|
||||
|
||||
rpc.state
|
||||
.getChildKeys(storageKeys[0], '0x')
|
||||
.subscribe((keys: Array<StorageKey>) => {
|
||||
.subscribe((keys: StorageKey[]): void => {
|
||||
expect(keys.length).toBeGreaterThanOrEqual(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('getChildStorage(): retrieves the default value of the flipper smart contract', async (done) => {
|
||||
it('getChildStorage(): retrieves the default value of the flipper smart contract', async (done): Promise<void> => {
|
||||
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
|
||||
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise();
|
||||
|
||||
rpc.state
|
||||
.getChildStorage(storageKeys[0], childStorageKeys[0])
|
||||
.subscribe((storage: StorageData) => {
|
||||
.subscribe((storage: StorageData): void => {
|
||||
expect(storage.toString()).toBe('0x00');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('getChildStorageHash(): retrieves the Hash of the flipper smart contract', async (done) => {
|
||||
it('getChildStorageHash(): retrieves the Hash of the flipper smart contract', async (done): Promise<void> => {
|
||||
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
|
||||
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise();
|
||||
|
||||
rpc.state
|
||||
.getChildStorageHash(storageKeys[0], childStorageKeys[0])
|
||||
.subscribe((storage: StorageData) => {
|
||||
.subscribe((storage: StorageData): void => {
|
||||
expect(storage.toString()).toBe('0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('getChildStorageSize(): retrieves the size of the flipper smart contract', async (done) => {
|
||||
it('getChildStorageSize(): retrieves the size of the flipper smart contract', async (done): Promise<void> => {
|
||||
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
|
||||
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise();
|
||||
|
||||
rpc.state
|
||||
.getChildStorageSize(storageKeys[0], childStorageKeys[0])
|
||||
.subscribe((storage: StorageData) => {
|
||||
.subscribe((storage: StorageData): void => {
|
||||
expect(storage.toString()).toBe('1');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -8,20 +8,20 @@ import storage from '@polkadot/api-metadata/storage/static';
|
||||
|
||||
import Rpc from '../../src';
|
||||
|
||||
describe.skip('e2e subscriptions', () => {
|
||||
describe.skip('e2e subscriptions', (): void => {
|
||||
let rpc: Rpc;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach((): void => {
|
||||
jest.setTimeout(30000);
|
||||
rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944'));
|
||||
});
|
||||
|
||||
it('retrieves current timestamp', (done) => {
|
||||
let count: number = 0;
|
||||
it('retrieves current timestamp', (done): void => {
|
||||
let count = 0;
|
||||
|
||||
rpc.state
|
||||
.subscribeStorage([[storage.timestamp.now]])
|
||||
.subscribe((data: StorageChangeSet) => {
|
||||
.subscribe((data: StorageChangeSet): void => {
|
||||
expect(data).toBeDefined();
|
||||
|
||||
if (++count === 3) {
|
||||
|
||||
Reference in New Issue
Block a user