From a7b4fe4dd0a55b26e03ef7526845b500af179bec Mon Sep 17 00:00:00 2001 From: Jaco Date: Fri, 7 May 2021 10:16:10 +0300 Subject: [PATCH] Adjust internal TS definitions for providers (#3503) --- CHANGELOG.md | 12 +++++++++++ packages/api/src/promise/index.spec.ts | 7 ++----- packages/rpc-core/src/index.ts | 28 ++++++++++--------------- packages/rpc-provider/src/http/index.ts | 6 +++--- packages/rpc-provider/src/mock/index.ts | 28 ++++++++++++------------- packages/rpc-provider/src/types.ts | 4 ++-- packages/rpc-provider/src/ws/index.ts | 19 +++++++---------- 7 files changed, 51 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67173b0827..c8ac2855a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # CHANGELOG +## master + +Contributed: + +- Expose RPC definitions via `.meta` (Thanks to https://github.com/jiqiang90) +- Adjust staking derives for chain-specific optional fields (https://github.com/WoeOm) + +Changes: + +- Adjust internal TS definitions for providers + + ## 4.9.1 May 6, 2021 Upgrade priority: Medium. Required for the next v0.9.0 Polkadot/Kusama chain upgrades where parachains are used. diff --git a/packages/api/src/promise/index.spec.ts b/packages/api/src/promise/index.spec.ts index 3e3cd5bcd4..bf8ffd011b 100644 --- a/packages/api/src/promise/index.spec.ts +++ b/packages/api/src/promise/index.spec.ts @@ -50,13 +50,10 @@ describe('ApiPromise', (): void => { describe('initialization', (): void => { it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async (): Promise => { - const rpcData = await provider.send('state_getMetadata', []); + const rpcData = await provider.send('state_getMetadata', []); const genesisHash = registry.createType('Hash', await provider.send('chain_getBlockHash', [])).toHex(); const specVersion = 0; - const metadata = { [`${genesisHash}-${specVersion}`]: rpcData as string }; - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const api = await ApiPromise.create({ metadata, provider, registry }); + const api = await ApiPromise.create({ metadata: { [`${genesisHash}-${specVersion}`]: rpcData }, provider, registry }); expect(api.genesisHash).toBeDefined(); expect(api.runtimeMetadata).toBeDefined(); diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index dd064f53d6..be9fba170c 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -178,12 +178,6 @@ export class RpcCore { this.mapping.set(jsonrpc, { ...def, isSubscription, jsonrpc, method, section }); - // FIXME Remove any here - // To do so, remove `RpcInterfaceMethod` from './types.ts', and refactor - // every method inside this class to take: - // `` - // Not doing so, because it makes this class a little bit less readable, - // and leaving it as-is doesn't harm much (exposed as Record)[method] = isSubscription ? this._createMethodSubscribe(section, method, def as DefinitionRpcSub) : this._createMethodSend(section, method, def); @@ -192,7 +186,7 @@ export class RpcCore { }, {} as RpcInterface[Section]); } - private _memomize (creator: (outputAs: OutputType) => (...values: any[]) => Observable, def: DefinitionRpc): Memoized { + private _memomize (creator: (outputAs: OutputType) => (...values: unknown[]) => Observable, def: DefinitionRpc): Memoized { const memoized = memoize(creator('scale') as RpcInterfaceMethod, { getInstanceId: () => this.#instanceId }); @@ -211,7 +205,7 @@ export class RpcCore { let memoized: null | Memoized = null; // execute the RPC call, doing a registry swap for historic as applicable - const callWithRegistry = async (outputAs: OutputType, values: any[]): Promise => { + const callWithRegistry = async (outputAs: OutputType, values: unknown[]): Promise => { const blockHash = hashIndex === -1 ? null : values[hashIndex] as (Uint8Array | string | null | undefined); @@ -219,17 +213,17 @@ export class RpcCore { ? await this.#getBlockRegistry(u8aToU8a(blockHash)) : { registry: this.#registryDefault }; const params = this._formatInputs(registry, null, def, values); - const data = await this.provider.send(rpcName, params.map((param): AnyJson => param.toJSON())) as AnyJson; + const data = await this.provider.send(rpcName, params.map((param) => param.toJSON())); return outputAs === 'scale' ? this._formatOutput(registry, blockHash, method, def, params, data) : registry.createType(outputAs === 'raw' ? 'Raw' : 'Json', data); }; - const creator = (outputAs: OutputType) => (...values: any[]): Observable => { + const creator = (outputAs: OutputType) => (...values: unknown[]): Observable => { const isDelayed = (hashIndex !== -1 && !!values[hashIndex]) || (cacheIndex !== -1 && !!values[cacheIndex]); - return new Observable((observer: Observer): VoidCallback => { + return new Observable((observer: Observer): VoidCallback => { callWithRegistry(outputAs, values) .then((value): void => { observer.next(value); @@ -279,8 +273,8 @@ export class RpcCore { const subType = `${section}_${updateType}`; let memoized: null | Memoized = null; - const creator = (outputAs: OutputType) => (...values: unknown[]): Observable => { - return new Observable((observer: Observer): VoidCallback => { + const creator = (outputAs: OutputType) => (...values: unknown[]): Observable => { + return new Observable((observer: Observer): VoidCallback => { // Have at least an empty promise, as used in the unsubscribe let subscriptionPromise: Promise = Promise.resolve(null); const registry = this.#registryDefault; @@ -295,7 +289,7 @@ export class RpcCore { const params = this._formatInputs(registry, null, def, values); const paramsJson = params.map((param): AnyJson => param.toJSON()); - const update = (error?: Error | null, result?: any): void => { + const update = (error?: Error | null, result?: Codec | Codec[]): void => { if (error) { logErrorMessage(method, def, error); @@ -340,7 +334,7 @@ export class RpcCore { return memoized; } - private _formatInputs (registry: Registry, blockHash: Uint8Array | string | null | undefined, def: DefinitionRpc, inputs: any[]): Codec[] { + private _formatInputs (registry: Registry, blockHash: Uint8Array | string | null | undefined, def: DefinitionRpc, inputs: unknown[]): Codec[] { const reqArgCount = def.params.filter(({ isOptional }) => !isOptional).length; const optText = reqArgCount === def.params.length ? '' @@ -353,11 +347,11 @@ export class RpcCore { ); } - private _formatOutput (registry: Registry, blockHash: Uint8Array | string | null | undefined, method: string, rpc: DefinitionRpc, params: Codec[], result?: any): Codec | Codec[] { + private _formatOutput (registry: Registry, blockHash: Uint8Array | string | null | undefined, method: string, rpc: DefinitionRpc, params: Codec[], result?: unknown): Codec | Codec[] { if (rpc.type === 'StorageData') { const key = params[0] as StorageKey; - return this._formatStorageData(registry, blockHash, key, result); + return this._formatStorageData(registry, blockHash, key, result as string); } else if (rpc.type === 'StorageChangeSet') { const keys = params[0] as Vec; diff --git a/packages/rpc-provider/src/http/index.ts b/packages/rpc-provider/src/http/index.ts index 76e9484710..12a4f6cfc6 100644 --- a/packages/rpc-provider/src/http/index.ts +++ b/packages/rpc-provider/src/http/index.ts @@ -103,7 +103,7 @@ export class HttpProvider implements ProviderInterface { /** * @summary Send HTTP POST Request with Body to configured HTTP Endpoint. */ - public async send (method: string, params: any[]): Promise { + public async send (method: string, params: unknown[]): Promise { const body = this.#coder.encodeJson(method, params); const response = await fetch(this.#endpoint, { body, @@ -121,14 +121,14 @@ export class HttpProvider implements ProviderInterface { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const result = await response.json(); - return this.#coder.decodeResponse(result); + return this.#coder.decodeResponse(result) as T; } /** * @summary Subscriptions are not supported with the HttpProvider, see [[WsProvider]]. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/require-await - public async subscribe (types: string, method: string, params: any[], cb: ProviderInterfaceCallback): Promise { + public async subscribe (types: string, method: string, params: unknown[], cb: ProviderInterfaceCallback): Promise { l.error(ERROR_SUBSCRIBE); throw new Error(ERROR_SUBSCRIBE); diff --git a/packages/rpc-provider/src/mock/index.ts b/packages/rpc-provider/src/mock/index.ts index 5fdc3b46ad..e3b1445658 100644 --- a/packages/rpc-provider/src/mock/index.ts +++ b/packages/rpc-provider/src/mock/index.ts @@ -53,24 +53,24 @@ export class MockProvider implements ProviderInterface { private requests: Record unknown> = { // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-unsafe-member-access - chain_getBlock: (hash: string): any => this.registry.createType('SignedBlock', rpcSignedBlock.result).toJSON(), + chain_getBlock: () => this.registry.createType('SignedBlock', rpcSignedBlock.result).toJSON(), // eslint-disable-next-line @typescript-eslint/no-unused-vars - chain_getBlockHash: (blockNumber: number): string => '0x1234', + chain_getBlockHash: () => '0x1234', // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access chain_getFinalizedHead: () => this.registry.createType('Header', rpcHeader.result).hash, // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access chain_getHeader: () => this.registry.createType('Header', rpcHeader.result).toJSON(), rpc_methods: () => this.registry.createType('RpcMethods').toJSON(), - state_getKeys: (): string[] => [], - state_getKeysPaged: (): string[] => [], - state_getMetadata: (): string => rpcMetadata, - state_getRuntimeVersion: (): string => this.registry.createType('RuntimeVersion').toHex(), - state_getStorage: (storage: MockStateDb, params: any[]): string => u8aToHex(storage[(params[0] as string)]), - system_chain: (): string => 'mockChain', - system_name: (): string => 'mockClient', - system_properties: (): Record => ({ ss58Format: 42 }), + state_getKeys: () => [], + state_getKeysPaged: () => [], + state_getMetadata: () => rpcMetadata, + state_getRuntimeVersion: () => this.registry.createType('RuntimeVersion').toHex(), + state_getStorage: (storage: MockStateDb, [key]: string[]) => u8aToHex(storage[key]), + system_chain: () => 'mockChain', + system_name: () => 'mockClient', + system_properties: () => ({ ss58Format: 42 }), system_upgradedToTripleRefCount: () => this.registry.createType('bool', true), - system_version: (): string => '9.8.7' + system_version: () => '9.8.7' }; public subscriptions: MockStateSubscriptions = SUBSCRIPTIONS.reduce((subs, name): MockStateSubscriptions => { @@ -121,12 +121,12 @@ export class MockProvider implements ProviderInterface { } // eslint-disable-next-line @typescript-eslint/require-await - public async send (method: string, params: any[]): Promise { + public async send (method: string, params: unknown[]): Promise { l.debug(() => ['send', method, params]); assert(this.requests[method], () => `provider.send: Invalid method '${method}'`); - return this.requests[method](this.db, params); + return this.requests[method](this.db, params) as T; } // eslint-disable-next-line @typescript-eslint/require-await @@ -152,7 +152,7 @@ export class MockProvider implements ProviderInterface { public async unsubscribe (type: string, method: string, id: number): Promise { const sub = this.subscriptionMap[id]; - l.debug((): any => ['unsubscribe', id, sub]); + l.debug(() => ['unsubscribe', id, sub]); assert(sub, () => `Unable to find subscription for ${id}`); diff --git a/packages/rpc-provider/src/types.ts b/packages/rpc-provider/src/types.ts index 92af1cb3cd..2e57d7cdb9 100644 --- a/packages/rpc-provider/src/types.ts +++ b/packages/rpc-provider/src/types.ts @@ -49,7 +49,7 @@ export interface ProviderInterface { connect (): Promise; disconnect (): Promise; on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void; - send (method: string, params: any[]): Promise; - subscribe (type: string, method: string, params: any[], cb: ProviderInterfaceCallback): Promise; + send (method: string, params: unknown[]): Promise; + subscribe (type: string, method: string, params: unknown[], cb: ProviderInterfaceCallback): Promise; unsubscribe (type: string, method: string, id: number | string): Promise; } diff --git a/packages/rpc-provider/src/ws/index.ts b/packages/rpc-provider/src/ws/index.ts index 462cabf468..1ee25f9fef 100644 --- a/packages/rpc-provider/src/ws/index.ts +++ b/packages/rpc-provider/src/ws/index.ts @@ -23,13 +23,13 @@ interface SubscriptionHandler { interface WsStateAwaiting { callback: ProviderInterfaceCallback; method: string; - params: any[]; + params: unknown[]; subscription?: SubscriptionHandler; } interface WsStateSubscription extends SubscriptionHandler { method: string; - params: any[]; + params: unknown[]; } const ALIASES: { [index: string]: string } = { @@ -254,7 +254,7 @@ export class WsProvider implements ProviderInterface { * @param params Encoded parameters as applicable for the method * @param subscription Subscription details (internally used) */ - public send (method: string, params: any[], subscription?: SubscriptionHandler): Promise { + public send (method: string, params: unknown[], subscription?: SubscriptionHandler): Promise { return new Promise((resolve, reject): void => { try { assert(this.isConnected && !isNull(this.#websocket), 'WebSocket is not connected'); @@ -262,10 +262,10 @@ export class WsProvider implements ProviderInterface { const json = this.#coder.encodeJson(method, params); const id = this.#coder.getId(); - const callback = (error?: Error | null, result?: any): void => { + const callback = (error?: Error | null, result?: T): void => { error ? reject(error) - : resolve(result); + : resolve(result as T); }; l.debug(() => ['calling', method, json]); @@ -287,11 +287,6 @@ export class WsProvider implements ProviderInterface { /** * @name subscribe * @summary Allows subscribing to a specific event. - * @param {string} type Subscription type - * @param {string} method Subscription method - * @param {any[]} params Parameters - * @param {ProviderInterfaceCallback} callback Callback - * @return {Promise} Promise resolving to the dd of the subscription you can use with [[unsubscribe]]. * * @example *
@@ -307,7 +302,7 @@ export class WsProvider implements ProviderInterface { * }) * ``` */ - public subscribe (type: string, method: string, params: any[], callback: ProviderInterfaceCallback): Promise { + public subscribe (type: string, method: string, params: unknown[], callback: ProviderInterfaceCallback): Promise { return this.send(method, params, { callback, type }); } @@ -338,7 +333,7 @@ export class WsProvider implements ProviderInterface { } } - #emit = (type: ProviderInterfaceEmitted, ...args: any[]): void => { + #emit = (type: ProviderInterfaceEmitted, ...args: unknown[]): void => { this.#eventemitter.emit(type, ...args); }