Inject RPC definitions from typesBundle (#2927)

* Inject RPC definitions from typesBundle

* Augment RPC only, don't clobber
This commit is contained in:
Jaco Greeff
2020-12-08 13:23:41 +01:00
committed by GitHub
parent dba23e3923
commit c29f66c7c5
2 changed files with 30 additions and 19 deletions
+27 -16
View File
@@ -6,7 +6,7 @@ import type { RpcInterface } from '@polkadot/rpc-core/types';
import type { Option, Raw, StorageKey, Text, u64 } from '@polkadot/types';
import type { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import type { StorageEntry } from '@polkadot/types/primitive/types';
import type { AnyFunction, CallFunction, Codec, CodecArg as Arg, InterfaceTypes, Registry, RegistryTypes } from '@polkadot/types/types';
import type { AnyFunction, CallFunction, Codec, CodecArg as Arg, DefinitionRpc, DefinitionRpcSub, InterfaceTypes, Registry, RegistryTypes } from '@polkadot/types/types';
import type { SubmittableExtrinsic } from '../submittable/types';
import type { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecoratedRpcSection, DecorateMethod, PaginationOptions, QueryableConsts, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
@@ -211,7 +211,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
// manner to cater for both old and new:
// - when the number of entries are 0, only remove the ones with isOptional (account & contracts)
// - when non-zero, remove anything that is not in the array (we don't do this)
protected async _filterRpc (): Promise<void> {
protected async _filterRpc (additional: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>): Promise<void> {
let methods: string[];
try {
@@ -222,6 +222,15 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
methods = [];
}
// add any specific user-base RPCs
if (Object.keys(additional).length !== 0) {
this._rpcCore.addUserInterfaces(additional);
// re-decorate, only adding any new additional interfaces
this._decorateRpc(this._rpcCore, this._decorateMethod, this._rpc);
this._decorateRpc(this._rpcCore, this._rxDecorateMethod, this._rx.rpc);
}
this._filterRpcMethods(methods);
}
@@ -267,26 +276,28 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
});
}
protected _decorateRpc<ApiType extends ApiTypes> (rpc: RpcCore, decorateMethod: DecorateMethod<ApiType>): DecoratedRpc<ApiType, RpcInterface> {
protected _decorateRpc<ApiType extends ApiTypes> (rpc: RpcCore, decorateMethod: DecorateMethod<ApiType>, input: Partial<DecoratedRpc<ApiType, RpcInterface>> = {}): DecoratedRpc<ApiType, RpcInterface> {
return rpc.sections.reduce((out, _sectionName): DecoratedRpc<ApiType, RpcInterface> => {
const sectionName = _sectionName as keyof DecoratedRpc<ApiType, RpcInterface>;
// out and section here are horrors to get right from a typing perspective :(
(out as Record<string, unknown>)[sectionName] = Object.entries(rpc[sectionName]).reduce((section, [methodName, method]): DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]> => {
// skip subscriptions where we have a non-subscribe interface
if (this.hasSubscriptions || !(methodName.startsWith('subscribe') || methodName.startsWith('unsubscribe'))) {
(section as Record<string, unknown>)[methodName] = decorateMethod(method, { methodName }) as unknown;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(section as Record<string, { json: unknown }>)[methodName].json = decorateMethod(method.json, { methodName }) as unknown;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(section as Record<string, { raw: unknown }>)[methodName].raw = decorateMethod(method.raw, { methodName }) as unknown;
}
if (!(out as Record<string, unknown>)[sectionName]) {
// out and section here are horrors to get right from a typing perspective :(
(out as Record<string, unknown>)[sectionName] = Object.entries(rpc[sectionName]).reduce((section, [methodName, method]): DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]> => {
// skip subscriptions where we have a non-subscribe interface
if (this.hasSubscriptions || !(methodName.startsWith('subscribe') || methodName.startsWith('unsubscribe'))) {
(section as Record<string, unknown>)[methodName] = decorateMethod(method, { methodName }) as unknown;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(section as Record<string, { json: unknown }>)[methodName].json = decorateMethod(method.json, { methodName }) as unknown;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(section as Record<string, { raw: unknown }>)[methodName].raw = decorateMethod(method.raw, { methodName }) as unknown;
}
return section;
}, {} as DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]>);
return section;
}, {} as DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]>);
}
return out;
}, {} as DecoratedRpc<ApiType, RpcInterface>);
}, input as DecoratedRpc<ApiType, RpcInterface>);
}
protected _decorateMulti<ApiType extends ApiTypes> (decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType> {
+3 -3
View File
@@ -15,7 +15,7 @@ import { map, switchMap } from 'rxjs/operators';
import { Metadata } from '@polkadot/metadata';
import { TypeRegistry } from '@polkadot/types/create';
import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/extrinsic/Extrinsic';
import { getSpecAlias, getSpecTypes, getUpgradeVersion } from '@polkadot/types-known';
import { getSpecAlias, getSpecRpc, getSpecTypes, getUpgradeVersion } from '@polkadot/types-known';
import { assert, BN_ZERO, logger, u8aEq, u8aToU8a } from '@polkadot/util';
import { cryptoWaitReady } from '@polkadot/util-crypto';
@@ -80,7 +80,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
registry.setKnownTypes(this._options);
registry.register(getSpecTypes(registry, chain, version.specName, version.specVersion));
// for bundled types, pull through the aliasses defined
// for bundled types, pull through the aliases defined
if (registry.knownTypes.typesBundle) {
registry.knownTypes.typesAlias = getSpecAlias(registry, chain, version.specName);
}
@@ -246,7 +246,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
this._subscribeUpdates();
// filter the RPC methods (this does an rpc-methods call)
await this._filterRpc();
await this._filterRpc(getSpecRpc(this.registry, chain, runtimeVersion.specName));
// retrieve metadata, either from chain or as pass-in via options
const metadataKey = `${this._genesisHash?.toHex() || '0x'}-${runtimeVersion.specVersion.toString()}`;