Inject RPC definitions from typesBundle (#2927)
* Inject RPC definitions from typesBundle * Augment RPC only, don't clobber
This commit is contained in:
@@ -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> {
|
||||
|
||||
@@ -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()}`;
|
||||
|
||||
Reference in New Issue
Block a user