diff --git a/CHANGELOG.md b/CHANGELOG.md index bbfc08727f..eb840ade4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGELOG +## master + +Changes: + +- Support for `state_call` definitions via API config (exposed on `api.runtime.*`) +- Type generation for runtime call definitions (not exposed by default) + + ## 8.10.1 Jun 26, 2022 Contributed: diff --git a/packages/api-augment/src/kusama/runtime.ts b/packages/api-augment/src/kusama/runtime.ts new file mode 100644 index 0000000000..a8654bf50f --- /dev/null +++ b/packages/api-augment/src/kusama/runtime.ts @@ -0,0 +1,47 @@ +// Auto-generated via `yarn polkadot-types-from-chain`, do not edit +/* eslint-disable */ + +import type { ApiTypes } from '@polkadot/api-base/types'; +import type { AuthorityList, SetId } from '@polkadot/types/interfaces/grandpa'; +import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata'; +import type { AccountId, Index } from '@polkadot/types/interfaces/runtime'; +import type { Observable } from '@polkadot/types/types'; + +declare module '@polkadot/api-base/types/calls' { + export interface AugmentedCalls { + accountNonceApi: { + /** + * The API to query account nonce (aka transaction index) + **/ + accountNonce: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + grandpaApi: { + /** + * Get current GRANDPA authority set id. + **/ + currentSetId: AugmentedCall Observable>; + /** + * Get the current GRANDPA authorities and weights. This should not change except for when changes are scheduled and the corresponding delay has passed. + **/ + grandpaAuthorities: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + metadata: { + /** + * Returns the metadata of a runtime + **/ + metadata: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + } // AugmentedCalls +} // declare module diff --git a/packages/api-augment/src/polkadot/runtime.ts b/packages/api-augment/src/polkadot/runtime.ts new file mode 100644 index 0000000000..a8654bf50f --- /dev/null +++ b/packages/api-augment/src/polkadot/runtime.ts @@ -0,0 +1,47 @@ +// Auto-generated via `yarn polkadot-types-from-chain`, do not edit +/* eslint-disable */ + +import type { ApiTypes } from '@polkadot/api-base/types'; +import type { AuthorityList, SetId } from '@polkadot/types/interfaces/grandpa'; +import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata'; +import type { AccountId, Index } from '@polkadot/types/interfaces/runtime'; +import type { Observable } from '@polkadot/types/types'; + +declare module '@polkadot/api-base/types/calls' { + export interface AugmentedCalls { + accountNonceApi: { + /** + * The API to query account nonce (aka transaction index) + **/ + accountNonce: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + grandpaApi: { + /** + * Get current GRANDPA authority set id. + **/ + currentSetId: AugmentedCall Observable>; + /** + * Get the current GRANDPA authorities and weights. This should not change except for when changes are scheduled and the corresponding delay has passed. + **/ + grandpaAuthorities: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + metadata: { + /** + * Returns the metadata of a runtime + **/ + metadata: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + } // AugmentedCalls +} // declare module diff --git a/packages/api-augment/src/substrate/runtime.ts b/packages/api-augment/src/substrate/runtime.ts new file mode 100644 index 0000000000..a8654bf50f --- /dev/null +++ b/packages/api-augment/src/substrate/runtime.ts @@ -0,0 +1,47 @@ +// Auto-generated via `yarn polkadot-types-from-chain`, do not edit +/* eslint-disable */ + +import type { ApiTypes } from '@polkadot/api-base/types'; +import type { AuthorityList, SetId } from '@polkadot/types/interfaces/grandpa'; +import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata'; +import type { AccountId, Index } from '@polkadot/types/interfaces/runtime'; +import type { Observable } from '@polkadot/types/types'; + +declare module '@polkadot/api-base/types/calls' { + export interface AugmentedCalls { + accountNonceApi: { + /** + * The API to query account nonce (aka transaction index) + **/ + accountNonce: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + grandpaApi: { + /** + * Get current GRANDPA authority set id. + **/ + currentSetId: AugmentedCall Observable>; + /** + * Get the current GRANDPA authorities and weights. This should not change except for when changes are scheduled and the corresponding delay has passed. + **/ + grandpaAuthorities: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + metadata: { + /** + * Returns the metadata of a runtime + **/ + metadata: AugmentedCall Observable>; + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + }; + } // AugmentedCalls +} // declare module diff --git a/packages/api-base/src/types/base.ts b/packages/api-base/src/types/base.ts index dab1b36173..2fe8ce5a7a 100644 --- a/packages/api-base/src/types/base.ts +++ b/packages/api-base/src/types/base.ts @@ -65,3 +65,9 @@ export interface PaginationOptions { // eslint-disable-next-line @typescript-eslint/no-unused-vars export type DecorateMethod = Observable>(method: M, options?: DecorateMethodOptions) => T; + +type AsCodec = R extends Codec + ? R + : Codec; + +export type ReturnCodec = AsCodec>>; diff --git a/packages/api-base/src/types/calls.ts b/packages/api-base/src/types/calls.ts new file mode 100644 index 0000000000..b33871a129 --- /dev/null +++ b/packages/api-base/src/types/calls.ts @@ -0,0 +1,37 @@ +// Copyright 2017-2022 @polkadot/api-base authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Observable } from 'rxjs'; +import type { AnyFunction, Codec, DefinitionCall } from '@polkadot/types/types'; +import type { ApiTypes, ReturnCodec } from './base'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-interface +export interface AugmentedCalls { + // augmented +} + +export interface QueryableCalls extends AugmentedCalls { + // when non-augmented, we need to at least have Codec results + [key: string]: QueryableModuleCalls; +} + +export interface QueryableModuleCalls { + [key: string]: DecoratedCallBase; +} + +export type DecoratedCallBase Observable> = + ApiType extends 'rxjs' + ? > (...args: Parameters) => Observable + : > (...args: Parameters) => Promise; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export type AugmentedCall Observable> = +DecoratedCallBase & { meta: DefinitionCallNamed }; + +export interface DefinitionCallNamed extends DefinitionCall { + method: string; + name: string; + section: string; + sectionHash: Uint8Array; + version: number; +} diff --git a/packages/api-base/src/types/index.ts b/packages/api-base/src/types/index.ts index ec8fe83548..80f0c9b73f 100644 --- a/packages/api-base/src/types/index.ts +++ b/packages/api-base/src/types/index.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // These are augmented, do an augmentation export +export * from '@polkadot/api-base/types/calls'; export * from '@polkadot/api-base/types/consts'; export * from '@polkadot/api-base/types/errors'; export * from '@polkadot/api-base/types/events'; diff --git a/packages/api-base/src/types/storage.ts b/packages/api-base/src/types/storage.ts index c849b6438d..ba8bfe7c83 100644 --- a/packages/api-base/src/types/storage.ts +++ b/packages/api-base/src/types/storage.ts @@ -6,7 +6,7 @@ import type { StorageKey, u64 } from '@polkadot/types'; import type { Hash } from '@polkadot/types/interfaces'; import type { StorageEntry } from '@polkadot/types/primitive/types'; import type { AnyFunction, AnyTuple, Callback, Codec, IStorageKey } from '@polkadot/types/types'; -import type { ApiTypes, DropLast, MethodResult, ObsInnerType, PaginationOptions, PromiseOrObs, UnsubscribePromise } from './base'; +import type { ApiTypes, DropLast, MethodResult, PaginationOptions, PromiseOrObs, ReturnCodec, UnsubscribePromise } from './base'; // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-interface export interface AugmentedQueries { @@ -22,12 +22,6 @@ export interface QueryableStorageAt extends AugmentedQ [key: string]: QueryableModuleStorageAt; } -type AsCodec = R extends Codec - ? R - : Codec; - -type ReturnCodec = AsCodec>>; - interface StorageEntryObservableMulti { (args: (unknown[] | unknown)[]): Observable; } diff --git a/packages/api/src/base/Decorate.ts b/packages/api/src/base/Decorate.ts index 8518b44032..8a15ae9626 100644 --- a/packages/api/src/base/Decorate.ts +++ b/packages/api/src/base/Decorate.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { Observable } from 'rxjs'; -import type { DeriveCustom } from '@polkadot/api-base/types'; +import type { AugmentedCall, DefinitionCallNamed, DeriveCustom, QueryableCalls } from '@polkadot/api-base/types'; 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'; @@ -19,7 +19,8 @@ import { getAvailableDerives } from '@polkadot/api-derive'; import { memo, RpcCore } from '@polkadot/rpc-core'; import { WsProvider } from '@polkadot/rpc-provider'; import { expandMetadata, Metadata, TypeRegistry, unwrapStorageType } from '@polkadot/types'; -import { arrayChunk, arrayFlatten, assert, assertReturn, BN, compactStripLength, lazyMethod, lazyMethods, logger, nextTick, objectSpread, u8aToHex } from '@polkadot/util'; +import { arrayChunk, arrayFlatten, assert, assertReturn, BN, compactStripLength, lazyMethod, lazyMethods, logger, nextTick, objectSpread, stringCamelCase, u8aConcatStrict, u8aToHex } from '@polkadot/util'; +import { blake2AsU8a } from '@polkadot/util-crypto'; import { createSubmittable } from '../submittable'; import { augmentObject } from '../util/augmentObject'; @@ -66,6 +67,8 @@ export abstract class Decorate extends Events { // HACK Use BN import so decorateDerive works... yes, wtf. protected __phantom = new BN(0); + protected _runtime: QueryableCalls = {} as QueryableCalls; + protected _consts: QueryableConsts = {} as QueryableConsts; protected _derive?: ReturnType['_decorateDerive']>; @@ -211,6 +214,7 @@ export abstract class Decorate extends Events { events: {}, query: {}, registry, + runtime: {}, rx: { query: {} }, @@ -227,14 +231,18 @@ export abstract class Decorate extends Events { registry.decoratedMeta = expandMetadata(registry.registry, registry.metadata); } + const runtime = this._decorateCalls(registry, this._decorateMethod, blockHash); const storage = this._decorateStorage(registry.decoratedMeta, this._decorateMethod, blockHash); const storageRx = this._decorateStorage(registry.decoratedMeta, this._rxDecorateMethod, blockHash); + // TODO Once we actually have metadata, we would like to decorate the actual calls object + augmentObject('consts', registry.decoratedMeta.consts, decoratedApi.consts, fromEmpty); augmentObject('errors', registry.decoratedMeta.errors, decoratedApi.errors, fromEmpty); augmentObject('events', registry.decoratedMeta.events, decoratedApi.events, fromEmpty); augmentObject('query', storage, decoratedApi.query, fromEmpty); augmentObject('query', storageRx, decoratedApi.rx.query, fromEmpty); + augmentObject('runtime', runtime, decoratedApi.runtime, fromEmpty); decoratedApi.findCall = (callIndex: Uint8Array | string): CallFunction => findCall(registry.registry, callIndex); @@ -259,6 +267,7 @@ export abstract class Decorate extends Events { const { decoratedApi, decoratedMeta } = this._createDecorated(registry, fromEmpty, registry.decoratedApi); + this._runtime = decoratedApi.runtime; this._consts = decoratedApi.consts; this._errors = decoratedApi.errors; this._events = decoratedApi.events; @@ -404,6 +413,88 @@ export abstract class Decorate extends Events { return out as DecoratedRpc; } + // pre-metadata decoration + protected _decorateCalls ({ registry, runtimeVersion: { apis } }: VersionedRegistry, decorateMethod: DecorateMethod, blockHash?: Uint8Array | string | null): QueryableCalls { + const result = {} as QueryableCalls; + + if (!this._options.runtime) { + return result; + } + + const named: Record> = {}; + const sections = Object.entries(this._options.runtime); + + for (let i = 0; i < sections.length; i++) { + const [_section, secs] = sections[i]; + const sectionHash = blake2AsU8a(_section, 64); + const rtApi = apis.find(([a]) => a.eq(sectionHash)); + + if (rtApi) { + const sec = secs.find(({ version = 1 }) => rtApi[1].eq(version)); + + if (sec) { + const section = stringCamelCase(_section); + + if (!named[section]) { + named[section] = {}; + } + + const methods = Object.entries(sec.methods); + + for (let m = 0; m < methods.length; m++) { + const [_method, def] = methods[m]; + const method = stringCamelCase(_method); + + named[section][method] = objectSpread({ method, name: `${_section}_${_method}`, section, sectionHash, version: 1 }, def); + } + } else { + l.warn(`Not decorating runtime ${_section}, unable to find version ${rtApi[1].toString()}`); + } + } else { + l.warn(`Not decorating runtime ${_section}, not found in available apis`); + } + } + + const stateCall = blockHash + ? (name: string, bytes: Uint8Array) => this._rpcCore.state.call(name, bytes, blockHash) + : (name: string, bytes: Uint8Array) => this._rpcCore.state.call(name, bytes); + + const lazySection = (section: string) => + lazyMethods({}, Object.keys(named[section]), (method: string) => + this._decorateCall(registry, named[section][method], stateCall, decorateMethod) + ); + + const modules = Object.keys(named); + + for (let i = 0; i < modules.length; i++) { + lazyMethod(result, modules[i], lazySection); + } + + return result; + } + + protected _decorateCall (registry: Registry, def: DefinitionCallNamed, stateCall: (method: string, bytes: Uint8Array) => Observable, decorateMethod: DecorateMethod): AugmentedCall { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const decorated = decorateMethod((...args: unknown[]): Observable => { + if (args.length !== def.params.length) { + throw new Error(`${def.name}:: Expected ${def.params.length} arguments, found ${args.length}`); + } + + const bytes = registry.createType('Raw', u8aConcatStrict( + args.map((a, i) => registry.createTypeUnsafe(def.params[i].type, [a]).toU8a()) + )); + + return stateCall(def.name, bytes).pipe( + map((r) => registry.createTypeUnsafe(def.type, [r])) + ); + }); + + (decorated as AugmentedCall).meta = def; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return decorated; + } + // only be called if supportMulti is true protected _decorateMulti (decorateMethod: DecorateMethod): QueryableStorageMulti { // eslint-disable-next-line @typescript-eslint/no-unsafe-return diff --git a/packages/api/src/base/Getters.ts b/packages/api/src/base/Getters.ts index cb309e4aaf..0a2144e5b3 100644 --- a/packages/api/src/base/Getters.ts +++ b/packages/api/src/base/Getters.ts @@ -7,7 +7,7 @@ import type { Text } from '@polkadot/types'; import type { Hash, RuntimeVersion } from '@polkadot/types/interfaces'; import type { Metadata } from '@polkadot/types/metadata'; import type { CallFunction, RegistryError } from '@polkadot/types/types'; -import type { ApiDecoration, ApiInterfaceRx, ApiTypes, DecoratedErrors, DecoratedEvents, DecoratedRpc, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types'; +import type { ApiDecoration, ApiInterfaceRx, ApiTypes, DecoratedErrors, DecoratedEvents, DecoratedRpc, QueryableCalls, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types'; import { assertReturn } from '@polkadot/util'; @@ -25,6 +25,13 @@ function assertResult (value: T | undefined): T { } export abstract class Getters extends Init implements ApiDecoration { + /** + * @description Runtime call interfaces (currently untyped, only decorated via API options) + */ + public get runtime (): QueryableCalls { + return assertResult(this._runtime); + } + /** * @description Contains the parameter types (constants) of all modules. * diff --git a/packages/api/src/checkTypes.manual.ts b/packages/api/src/checkTypes.manual.ts index 1890a1a140..893dfee716 100644 --- a/packages/api/src/checkTypes.manual.ts +++ b/packages/api/src/checkTypes.manual.ts @@ -4,6 +4,7 @@ // Simple non-runnable checks to test type definitions in the editor itself import '@polkadot/api-augment'; +import '@polkadot/api-augment/substrate/runtime'; import type { HeaderExtended } from '@polkadot/api-derive/types'; import type { StorageKey } from '@polkadot/types'; @@ -18,6 +19,19 @@ import { SubmittableResult } from './'; const registry = new TypeRegistry(); +async function calls (api: ApiPromise): Promise { + // it allows defaults + const testSetId = await api.runtime.grandpaApi.currentSetId(); + + // it allows type overrides (generally shouldn't be used, but available) + const testSetIdO = await api.runtime.grandpaApi.currentSetId(); + + // it allows actual params + const nonce = await api.runtime.accountNonceApi.accountNonce('5Test'); + + console.log(testSetId.toNumber(), testSetIdO.isAscii, nonce.toNumber()); +} + function consts (api: ApiPromise): void { // constants has actual value & metadata console.log( @@ -215,12 +229,13 @@ function types (api: ApiPromise): void { const compact = registry.createType('Compact', 2); const f32 = registry.createType('f32'); const u32 = registry.createType('u32'); + const raw = registry.createType('Raw'); // const random = registry.createType('RandomType', 2); // This one should deliberately show a TS error const gasUnsafe = createTypeUnsafe(registry, 'Gas', [2]); const overriddenUnsafe = createTypeUnsafe
(registry, 'Gas', [2]); - console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe, u32.toNumber(), f32.toNumber(), api.createType('AccountData')); + console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe, u32.toNumber(), f32.toNumber(), api.createType('AccountData'), raw.subarray(0, 10)); } async function tx (api: ApiPromise, pairs: TestKeyringMap): Promise { @@ -289,6 +304,7 @@ async function main (): Promise { // eslint-disable-next-line @typescript-eslint/no-floating-promises Promise.all([ + calls(api), consts(api), derive(api), errors(api), diff --git a/packages/api/src/types/calls.ts b/packages/api/src/types/calls.ts new file mode 100644 index 0000000000..285168968b --- /dev/null +++ b/packages/api/src/types/calls.ts @@ -0,0 +1,4 @@ +// Copyright 2017-2022 @polkadot/api authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +export * from '@polkadot/api-base/types/calls'; diff --git a/packages/api/src/types/index.ts b/packages/api/src/types/index.ts index 2dcde3ead5..2395fc71b2 100644 --- a/packages/api/src/types/index.ts +++ b/packages/api/src/types/index.ts @@ -3,6 +3,7 @@ import type { ApiTypes, DeriveCustom, QueryableStorageMulti } from '@polkadot/api-base/types'; import type { ApiInterfaceRx as ApiInterfaceBase } from '@polkadot/api-base/types/api'; +import type { QueryableCalls } from '@polkadot/api-base/types/calls'; import type { QueryableConsts } from '@polkadot/api-base/types/consts'; import type { DecoratedErrors } from '@polkadot/api-base/types/errors'; import type { DecoratedEvents } from '@polkadot/api-base/types/events'; @@ -10,7 +11,7 @@ import type { QueryableStorage } from '@polkadot/api-base/types/storage'; import type { ProviderInterface, ProviderInterfaceEmitted } from '@polkadot/rpc-provider/types'; import type { ExtDef } from '@polkadot/types/extrinsic/signedExtensions/types'; import type { Call, Extrinsic, Hash, RuntimeVersionPartial } from '@polkadot/types/interfaces'; -import type { CallFunction, DefinitionRpc, DefinitionRpcSub, RegisteredTypes, Registry, RegistryError, SignatureOptions, Signer } from '@polkadot/types/types'; +import type { CallFunction, DefinitionRpc, DefinitionRpcSub, DefinitionsCall, RegisteredTypes, Registry, RegistryError, SignatureOptions, Signer } from '@polkadot/types/types'; import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; import type { ApiBase } from '../base'; @@ -18,6 +19,7 @@ import type { SubmittableExtrinsic } from '../types/submittable'; import type { AllDerives } from '../util/decorate'; export * from '@polkadot/api-base/types'; +export * from '@polkadot/api/types/calls'; export * from '@polkadot/api/types/consts'; export * from '@polkadot/api/types/errors'; export * from '@polkadot/api/types/events'; @@ -60,6 +62,10 @@ export interface ApiOptions extends RegisteredTypes { * @description User-defined RPC methods */ rpc?: Record>; + /** + * @description Overrides for state_call usage (this will be removed in some future version) + */ + runtime?: DefinitionsCall; /** * @description Any chain-specific signed extensions that are now well-known */ @@ -94,6 +100,7 @@ export interface ApiDecoration { errors: DecoratedErrors; events: DecoratedEvents; query: QueryableStorage; + runtime: QueryableCalls; registry: Registry; runtimeVersion: RuntimeVersionPartial; rx: { diff --git a/packages/typegen/package.json b/packages/typegen/package.json index ad8e22d779..01741a8cf6 100644 --- a/packages/typegen/package.json +++ b/packages/typegen/package.json @@ -35,6 +35,7 @@ "@babel/runtime": "^7.18.3", "@polkadot/api": "8.10.1", "@polkadot/api-augment": "8.10.1", + "@polkadot/api-base": "8.10.1", "@polkadot/rpc-augment": "8.10.1", "@polkadot/rpc-provider": "8.10.1", "@polkadot/types": "8.10.1", diff --git a/packages/typegen/src/fromChain.ts b/packages/typegen/src/fromChain.ts index 7ec75aedd8..6ca333a3d6 100644 --- a/packages/typegen/src/fromChain.ts +++ b/packages/typegen/src/fromChain.ts @@ -9,7 +9,7 @@ import yargs from 'yargs'; import { Definitions } from '@polkadot/types/types'; import { formatNumber } from '@polkadot/util'; -import { generateDefaultConsts, generateDefaultErrors, generateDefaultEvents, generateDefaultQuery, generateDefaultRpc, generateDefaultTx } from './generate'; +import { generateDefaultCalls, generateDefaultConsts, generateDefaultErrors, generateDefaultEvents, generateDefaultQuery, generateDefaultRpc, generateDefaultTx } from './generate'; import { assertDir, assertFile, getMetadataViaWs, HEADER, writeFile } from './util'; function generate (metaHex: HexString, pkg: string | undefined, output: string, isStrict?: boolean): void { @@ -46,12 +46,15 @@ function generate (metaHex: HexString, pkg: string | undefined, output: string, generateDefaultQuery(path.join(outputPath, 'augment-api-query.ts'), metaHex, extraTypes, isStrict, customLookupDefinitions); generateDefaultRpc(path.join(outputPath, 'augment-api-rpc.ts'), extraTypes); generateDefaultTx(path.join(outputPath, 'augment-api-tx.ts'), metaHex, extraTypes, isStrict, customLookupDefinitions); + generateDefaultCalls(path.join(outputPath, 'augment-api-runtime.ts'), metaHex, extraTypes, isStrict, customLookupDefinitions); writeFile(path.join(outputPath, 'augment-api.ts'), (): string => [ HEADER('chain'), ...[ - ...['consts', 'errors', 'events', 'query', 'tx', 'rpc'].filter((key) => !!key).map((key) => `./augment-api-${key}`) + ...['consts', 'errors', 'events', 'query', 'tx', 'rpc'] + .filter((key) => !!key) + .map((key) => `./augment-api-${key}`) ].map((path) => `import '${path}';\n`) ].join('') ); diff --git a/packages/typegen/src/generate/index.ts b/packages/typegen/src/generate/index.ts index 8e3d2f2170..8e268d3247 100644 --- a/packages/typegen/src/generate/index.ts +++ b/packages/typegen/src/generate/index.ts @@ -8,5 +8,6 @@ export { generateDefaultInterface } from './interfaceRegistry'; export { generateDefaultLookup } from './lookup'; export { generateDefaultQuery } from './query'; export { generateDefaultRpc } from './rpc'; +export { generateDefaultCalls } from './runtime'; export { generateDefaultTsDef } from './tsDef'; export { generateDefaultTx } from './tx'; diff --git a/packages/typegen/src/generate/rpc.ts b/packages/typegen/src/generate/rpc.ts index 4a2428053d..fff5e9ccd4 100644 --- a/packages/typegen/src/generate/rpc.ts +++ b/packages/typegen/src/generate/rpc.ts @@ -30,7 +30,7 @@ const StorageKeyType = 'StorageKey | string | Uint8Array | any'; const generateRpcTypesTemplate = Handlebars.compile(readTemplate('rpc')); /** @internal */ -export function generateRpcTypes (registry: TypeRegistry, importDefinitions: Record, dest: string, extraTypes: ExtraTypes = {}): void { +export function generateRpcTypes (registry: TypeRegistry, importDefinitions: Record, dest: string, extraTypes: ExtraTypes): void { writeFile(dest, (): string => { const allTypes: ExtraTypes = { '@polkadot/types/interfaces': importDefinitions, ...extraTypes }; const imports = createImports(allTypes); @@ -46,7 +46,7 @@ export function generateRpcTypes (registry: TypeRegistry, importDefinitions: Rec const additional: Record = {}; const modules = rpcKeys.map((sectionFullName) => { - const rpc = definitions[sectionFullName].rpc; + const rpc = definitions[sectionFullName].rpc || {}; const section = sectionFullName.split('/').pop(); const allMethods = Object.keys(rpc).sort().map((methodName) => { diff --git a/packages/typegen/src/generate/runtime.ts b/packages/typegen/src/generate/runtime.ts new file mode 100644 index 0000000000..82136e4760 --- /dev/null +++ b/packages/typegen/src/generate/runtime.ts @@ -0,0 +1,137 @@ +// Copyright 2017-2022 @polkadot/typegen authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { DefinitionCallNamed } from '@polkadot/api-base/types'; +import type { TypeRegistry } from '@polkadot/types/create'; +import type { Definitions } from '@polkadot/types/types'; +import type { HexString } from '@polkadot/util/types'; +import type { ExtraTypes } from './types'; + +import Handlebars from 'handlebars'; + +import * as defaultDefs from '@polkadot/types/interfaces/definitions'; +import lookupDefinitions from '@polkadot/types-augment/lookup/definitions'; +import { objectSpread, stringCamelCase } from '@polkadot/util'; + +import { createImports, formatType, getSimilarTypes, initMeta, readTemplate, setImports, writeFile } from '../util'; + +const generateCallsTypesTemplate = Handlebars.compile(readTemplate('calls')); + +/** @internal */ +function getDefs (defs: Record): Record> { + const named: Record> = {}; + const all = Object.values(defs); + + for (let j = 0; j < all.length; j++) { + const set = all[j].runtime; + + if (set) { + const sections = Object.entries(set); + + for (let i = 0; i < sections.length; i++) { + const [_section, sec] = sections[i]; + const methods = Object.entries(sec[0].methods); + + if (methods.length) { + const section = stringCamelCase(_section); + + if (!named[section]) { + named[section] = {}; + } + + for (let m = 0; m < methods.length; m++) { + const [_method, def] = methods[m]; + const method = stringCamelCase(_method); + + named[section][method] = objectSpread({ method, name: `${_section}_${method}`, section }, def); + } + } + } + } + } + + return named; +} + +/** @internal */ +export function generateCallTypes (registry: TypeRegistry, dest: string, extraTypes: ExtraTypes, isStrict: boolean, customLookupDefinitions?: Definitions): void { + writeFile(dest, (): string => { + const allTypes: ExtraTypes = { + '@polkadot/types-augment': { + lookup: { + ...lookupDefinitions, + ...customLookupDefinitions + } + }, + '@polkadot/types/interfaces': defaultDefs, + ...extraTypes + }; + const imports = createImports(allTypes); + const allDefs = Object.entries(allTypes).reduce((defs, [path, obj]) => { + return Object.entries(obj).reduce((defs, [key, value]) => ({ ...defs, [`${path}/${key}`]: value }), defs); + }, {}); + const definitions = getDefs(imports.definitions as Record); + const callKeys = Object.keys(definitions); + + const modules = callKeys.map((section) => { + const calls = definitions[section]; + + const allMethods = Object.keys(calls).sort().map((methodName) => { + const def = calls[methodName]; + + setImports(allDefs, imports, [def.type]); + + const args = def.params.map((param) => { + const similarTypes = getSimilarTypes(registry, imports.definitions, param.type, imports); + + setImports(allDefs, imports, [param.type, ...similarTypes]); + + return `${param.name}: ${similarTypes.join(' | ')}`; + }); + + return { + args: args.join(', '), + docs: [def.description], + name: methodName, + type: formatType(registry, allDefs, def.type, imports) + }; + }).sort((a, b) => a.name.localeCompare(b.name)); + + return { + items: allMethods, + name: section || 'unknown' + }; + }).sort((a, b) => a.name.localeCompare(b.name)); + + imports.typesTypes.Observable = true; + + return generateCallsTypesTemplate({ + headerType: 'chain', + imports, + isStrict, + modules, + types: [ + ...Object.keys(imports.localTypes).sort().map((packagePath): { file: string; types: string[] } => ({ + file: packagePath.replace('@polkadot/types-augment', '@polkadot/types'), + types: Object.keys(imports.localTypes[packagePath]) + })), + { + file: '@polkadot/api-base/types', + types: ['ApiTypes'] + } + ] + }); + }); +} + +export function generateDefaultCalls (dest: string, data: HexString, extraTypes: ExtraTypes = {}, isStrict = false, customLookupDefinitions?: Definitions): void { + const { registry } = initMeta(data, extraTypes); + + generateCallTypes( + registry, + dest, + extraTypes, + isStrict, + customLookupDefinitions + ); +} diff --git a/packages/typegen/src/generate/types.ts b/packages/typegen/src/generate/types.ts index 8cf45dc8d3..12bb73b257 100644 --- a/packages/typegen/src/generate/types.ts +++ b/packages/typegen/src/generate/types.ts @@ -1,4 +1,4 @@ // Copyright 2017-2022 @polkadot/typegen authors & contributors // SPDX-License-Identifier: Apache-2.0 -export type ExtraTypes = Record }>>; +export type ExtraTypes = Record, types: Record }>>; diff --git a/packages/typegen/src/interfacesTs.ts b/packages/typegen/src/interfacesTs.ts index 97ed2364fb..b411b199f2 100644 --- a/packages/typegen/src/interfacesTs.ts +++ b/packages/typegen/src/interfacesTs.ts @@ -7,7 +7,7 @@ import kusama from '@polkadot/types-support/metadata/static-kusama'; import polkadot from '@polkadot/types-support/metadata/static-polkadot'; import substrate from '@polkadot/types-support/metadata/static-substrate'; -import { generateDefaultConsts, generateDefaultErrors, generateDefaultEvents, generateDefaultInterface, generateDefaultLookup, generateDefaultQuery, generateDefaultRpc, generateDefaultTsDef, generateDefaultTx } from './generate'; +import { generateDefaultCalls, generateDefaultConsts, generateDefaultErrors, generateDefaultEvents, generateDefaultInterface, generateDefaultLookup, generateDefaultQuery, generateDefaultRpc, generateDefaultTsDef, generateDefaultTx } from './generate'; const BASE = 'packages/api-augment/src'; const METAS = Object.entries({ kusama, polkadot, substrate }) as [string, HexString][]; @@ -27,5 +27,6 @@ export function main (): void { generateDefaultEvents(`${BASE}/${name}/events.ts`, staticMeta); generateDefaultQuery(`${BASE}/${name}/query.ts`, staticMeta); generateDefaultTx(`${BASE}/${name}/tx.ts`, staticMeta); + generateDefaultCalls(`${BASE}/${name}/runtime.ts`, staticMeta); } } diff --git a/packages/typegen/src/metadataMd.ts b/packages/typegen/src/metadataMd.ts index 829773531e..0a0bebd16f 100644 --- a/packages/typegen/src/metadataMd.ts +++ b/packages/typegen/src/metadataMd.ts @@ -138,10 +138,10 @@ function addRpc (): string { .reduce((all: Section[], _sectionName): Section[] => { const section = definitions[_sectionName as 'babe']; - Object.keys(section.rpc) + Object.keys(section.rpc || {}) .sort() .forEach((methodName) => { - const method = section.rpc[methodName]; + const method = (section.rpc || {})[methodName]; const sectionName = method.aliasSection || _sectionName; const topName = method.aliasSection ? `${_sectionName}/${method.aliasSection}` : _sectionName; let container = all.find(({ name }) => name === topName); diff --git a/packages/typegen/src/templates/calls.hbs b/packages/typegen/src/templates/calls.hbs new file mode 100644 index 0000000000..3074b6e0d3 --- /dev/null +++ b/packages/typegen/src/templates/calls.hbs @@ -0,0 +1,22 @@ +{{> header }} + +{{{ importsAll }}} + +declare module '@polkadot/api-base/types/calls' { + export interface AugmentedCalls { + {{#each modules}} + {{{name}}}: { + {{#each items}} + {{> docs}} + {{{name}}}: AugmentedCall Observable<{{{type}}}>>; + {{/each}} + {{#unless @root.isStrict}} + /** + * Generic call + **/ + [key: string]: DecoratedCallBase; + {{/unless}} + }; + {{/each}} + } // AugmentedCalls +} // declare module diff --git a/packages/typegen/tsconfig.build.json b/packages/typegen/tsconfig.build.json index 490403db50..ab8eb5b5ff 100644 --- a/packages/typegen/tsconfig.build.json +++ b/packages/typegen/tsconfig.build.json @@ -8,6 +8,7 @@ "references": [ { "path": "../api/tsconfig.build.json" }, { "path": "../api-augment/tsconfig.build.json" }, + { "path": "../api-base/tsconfig.build.json" }, { "path": "../rpc-augment/tsconfig.build.json" }, { "path": "../rpc-provider/tsconfig.build.json" }, { "path": "../types/tsconfig.build.json" }, diff --git a/packages/types-augment/src/registry/interfaces.ts b/packages/types-augment/src/registry/interfaces.ts index dee9e0fa40..efd83898f8 100644 --- a/packages/types-augment/src/registry/interfaces.ts +++ b/packages/types-augment/src/registry/interfaces.ts @@ -34,7 +34,7 @@ import type { AuthorityIndex, AuthorityList, AuthoritySet, AuthoritySetChange, A import type { IdentityFields, IdentityInfo, IdentityInfoAdditional, IdentityInfoTo198, IdentityJudgement, RegistrarIndex, RegistrarInfo, Registration, RegistrationJudgement, RegistrationTo198 } from '@polkadot/types/interfaces/identity'; import type { AuthIndex, AuthoritySignature, Heartbeat, HeartbeatTo244, OpaqueMultiaddr, OpaqueNetworkState, OpaquePeerId } from '@polkadot/types/interfaces/imOnline'; import type { CallIndex, LotteryConfig } from '@polkadot/types/interfaces/lottery'; -import type { ErrorMetadataLatest, ErrorMetadataV10, ErrorMetadataV11, ErrorMetadataV12, ErrorMetadataV13, ErrorMetadataV14, ErrorMetadataV9, EventMetadataLatest, EventMetadataV10, EventMetadataV11, EventMetadataV12, EventMetadataV13, EventMetadataV14, EventMetadataV9, ExtrinsicMetadataLatest, ExtrinsicMetadataV11, ExtrinsicMetadataV12, ExtrinsicMetadataV13, ExtrinsicMetadataV14, FunctionArgumentMetadataLatest, FunctionArgumentMetadataV10, FunctionArgumentMetadataV11, FunctionArgumentMetadataV12, FunctionArgumentMetadataV13, FunctionArgumentMetadataV14, FunctionArgumentMetadataV9, FunctionMetadataLatest, FunctionMetadataV10, FunctionMetadataV11, FunctionMetadataV12, FunctionMetadataV13, FunctionMetadataV14, FunctionMetadataV9, MetadataAll, MetadataLatest, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV9, ModuleConstantMetadataV10, ModuleConstantMetadataV11, ModuleConstantMetadataV12, ModuleConstantMetadataV13, ModuleConstantMetadataV9, ModuleMetadataV10, ModuleMetadataV11, ModuleMetadataV12, ModuleMetadataV13, ModuleMetadataV9, PalletCallMetadataLatest, PalletCallMetadataV14, PalletConstantMetadataLatest, PalletConstantMetadataV14, PalletErrorMetadataLatest, PalletErrorMetadataV14, PalletEventMetadataLatest, PalletEventMetadataV14, PalletMetadataLatest, PalletMetadataV14, PalletStorageMetadataLatest, PalletStorageMetadataV14, PortableType, PortableTypeV14, SignedExtensionMetadataLatest, SignedExtensionMetadataV14, StorageEntryMetadataLatest, StorageEntryMetadataV10, StorageEntryMetadataV11, StorageEntryMetadataV12, StorageEntryMetadataV13, StorageEntryMetadataV14, StorageEntryMetadataV9, StorageEntryModifierLatest, StorageEntryModifierV10, StorageEntryModifierV11, StorageEntryModifierV12, StorageEntryModifierV13, StorageEntryModifierV14, StorageEntryModifierV9, StorageEntryTypeLatest, StorageEntryTypeV10, StorageEntryTypeV11, StorageEntryTypeV12, StorageEntryTypeV13, StorageEntryTypeV14, StorageEntryTypeV9, StorageHasher, StorageHasherV10, StorageHasherV11, StorageHasherV12, StorageHasherV13, StorageHasherV14, StorageHasherV9, StorageMetadataV10, StorageMetadataV11, StorageMetadataV12, StorageMetadataV13, StorageMetadataV9 } from '@polkadot/types/interfaces/metadata'; +import type { ErrorMetadataLatest, ErrorMetadataV10, ErrorMetadataV11, ErrorMetadataV12, ErrorMetadataV13, ErrorMetadataV14, ErrorMetadataV9, EventMetadataLatest, EventMetadataV10, EventMetadataV11, EventMetadataV12, EventMetadataV13, EventMetadataV14, EventMetadataV9, ExtrinsicMetadataLatest, ExtrinsicMetadataV11, ExtrinsicMetadataV12, ExtrinsicMetadataV13, ExtrinsicMetadataV14, FunctionArgumentMetadataLatest, FunctionArgumentMetadataV10, FunctionArgumentMetadataV11, FunctionArgumentMetadataV12, FunctionArgumentMetadataV13, FunctionArgumentMetadataV14, FunctionArgumentMetadataV9, FunctionMetadataLatest, FunctionMetadataV10, FunctionMetadataV11, FunctionMetadataV12, FunctionMetadataV13, FunctionMetadataV14, FunctionMetadataV9, MetadataAll, MetadataLatest, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV9, ModuleConstantMetadataV10, ModuleConstantMetadataV11, ModuleConstantMetadataV12, ModuleConstantMetadataV13, ModuleConstantMetadataV9, ModuleMetadataV10, ModuleMetadataV11, ModuleMetadataV12, ModuleMetadataV13, ModuleMetadataV9, OpaqueMetadata, PalletCallMetadataLatest, PalletCallMetadataV14, PalletConstantMetadataLatest, PalletConstantMetadataV14, PalletErrorMetadataLatest, PalletErrorMetadataV14, PalletEventMetadataLatest, PalletEventMetadataV14, PalletMetadataLatest, PalletMetadataV14, PalletStorageMetadataLatest, PalletStorageMetadataV14, PortableType, PortableTypeV14, SignedExtensionMetadataLatest, SignedExtensionMetadataV14, StorageEntryMetadataLatest, StorageEntryMetadataV10, StorageEntryMetadataV11, StorageEntryMetadataV12, StorageEntryMetadataV13, StorageEntryMetadataV14, StorageEntryMetadataV9, StorageEntryModifierLatest, StorageEntryModifierV10, StorageEntryModifierV11, StorageEntryModifierV12, StorageEntryModifierV13, StorageEntryModifierV14, StorageEntryModifierV9, StorageEntryTypeLatest, StorageEntryTypeV10, StorageEntryTypeV11, StorageEntryTypeV12, StorageEntryTypeV13, StorageEntryTypeV14, StorageEntryTypeV9, StorageHasher, StorageHasherV10, StorageHasherV11, StorageHasherV12, StorageHasherV13, StorageHasherV14, StorageHasherV9, StorageMetadataV10, StorageMetadataV11, StorageMetadataV12, StorageMetadataV13, StorageMetadataV9 } from '@polkadot/types/interfaces/metadata'; import type { MmrLeafBatchProof, MmrLeafProof } from '@polkadot/types/interfaces/mmr'; import type { StorageKind } from '@polkadot/types/interfaces/offchain'; import type { DeferredOffenceOf, Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences'; @@ -657,6 +657,7 @@ declare module '@polkadot/types/types/registry' { OffenceDetails: OffenceDetails; Offender: Offender; OpaqueCall: OpaqueCall; + OpaqueMetadata: OpaqueMetadata; OpaqueMultiaddr: OpaqueMultiaddr; OpaqueNetworkState: OpaqueNetworkState; OpaquePeerId: OpaquePeerId; diff --git a/packages/types/src/interfaces/grandpa/definitions.ts b/packages/types/src/interfaces/grandpa/definitions.ts index e41d6956ad..9a147cb068 100644 --- a/packages/types/src/interfaces/grandpa/definitions.ts +++ b/packages/types/src/interfaces/grandpa/definitions.ts @@ -6,34 +6,12 @@ import type { Definitions } from '../../types'; +import { rpc } from './rpc'; +import { runtime } from './runtime'; + export default { - rpc: { - proveFinality: { - description: 'Prove finality for the given block number, returning the Justification for the last block in the set.', - params: [ - { - name: 'blockNumber', - type: 'BlockNumber' - } - ], - type: 'Option' - }, - roundState: { - description: 'Returns the state of the current best round state as well as the ongoing background rounds', - params: [], - type: 'ReportedRoundStates' - }, - subscribeJustifications: { - description: 'Subscribes to grandpa justifications', - params: [], - pubsub: [ - 'justifications', - 'subscribeJustifications', - 'unsubscribeJustifications' - ], - type: 'JustificationNotification' - } - }, + rpc, + runtime, types: { AuthorityIndex: 'u64', AuthorityList: 'Vec', diff --git a/packages/types/src/interfaces/grandpa/rpc.ts b/packages/types/src/interfaces/grandpa/rpc.ts new file mode 100644 index 0000000000..0fb75a6cc0 --- /dev/null +++ b/packages/types/src/interfaces/grandpa/rpc.ts @@ -0,0 +1,32 @@ +// Copyright 2017-2022 @polkadot/types authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { DefinitionsRpc } from '../../types'; + +export const rpc: DefinitionsRpc = { + proveFinality: { + description: 'Prove finality for the given block number, returning the Justification for the last block in the set.', + params: [ + { + name: 'blockNumber', + type: 'BlockNumber' + } + ], + type: 'Option' + }, + roundState: { + description: 'Returns the state of the current best round state as well as the ongoing background rounds', + params: [], + type: 'ReportedRoundStates' + }, + subscribeJustifications: { + description: 'Subscribes to grandpa justifications', + params: [], + pubsub: [ + 'justifications', + 'subscribeJustifications', + 'unsubscribeJustifications' + ], + type: 'JustificationNotification' + } +}; diff --git a/packages/types/src/interfaces/grandpa/runtime.ts b/packages/types/src/interfaces/grandpa/runtime.ts new file mode 100644 index 0000000000..9fcef70f8d --- /dev/null +++ b/packages/types/src/interfaces/grandpa/runtime.ts @@ -0,0 +1,24 @@ +// Copyright 2017-2022 @polkadot/types authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { DefinitionsCall } from '../../types'; + +export const runtime: DefinitionsCall = { + GrandpaApi: [ + { + methods: { + current_set_id: { + description: 'Get current GRANDPA authority set id.', + params: [], + type: 'SetId' + }, + grandpa_authorities: { + description: 'Get the current GRANDPA authorities and weights. This should not change except for when changes are scheduled and the corresponding delay has passed.', + params: [], + type: 'AuthorityList' + } + }, + version: 3 + } + ] +}; diff --git a/packages/types/src/interfaces/metadata/definitions.ts b/packages/types/src/interfaces/metadata/definitions.ts index 14be27f199..2ccebbc76d 100644 --- a/packages/types/src/interfaces/metadata/definitions.ts +++ b/packages/types/src/interfaces/metadata/definitions.ts @@ -9,6 +9,7 @@ import type { Definitions } from '../../types'; import { objectSpread } from '@polkadot/util'; import { AllHashers } from './hashers'; +import { runtime } from './runtime'; import { v9 } from './v9'; import { v10 } from './v10'; import { v11 } from './v11'; @@ -20,6 +21,7 @@ export { AllHashers }; export default { rpc: {}, + runtime, types: objectSpread({}, v9, v10, v11, v12, v13, v14, { // latest mappings ErrorMetadataLatest: 'ErrorMetadataV14', @@ -41,6 +43,9 @@ export default { StorageEntryTypeLatest: 'StorageEntryTypeV14', StorageHasher: 'StorageHasherV14', + // additional types + OpaqueMetadata: 'Bytes', + // the enum containing all the mappings MetadataAll: { _enum: { diff --git a/packages/types/src/interfaces/metadata/runtime.ts b/packages/types/src/interfaces/metadata/runtime.ts new file mode 100644 index 0000000000..4a64ba9d74 --- /dev/null +++ b/packages/types/src/interfaces/metadata/runtime.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2022 @polkadot/types authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { DefinitionsCall } from '../../types'; + +export const runtime: DefinitionsCall = { + Metadata: [ + { + methods: { + metadata: { + description: 'Returns the metadata of a runtime', + params: [], + type: 'OpaqueMetadata' + } + } + } + ] +}; diff --git a/packages/types/src/interfaces/metadata/types.ts b/packages/types/src/interfaces/metadata/types.ts index 8126f70137..55a9925c70 100644 --- a/packages/types/src/interfaces/metadata/types.ts +++ b/packages/types/src/interfaces/metadata/types.ts @@ -275,6 +275,9 @@ export interface ModuleMetadataV9 extends Struct { readonly errors: Vec; } +/** @name OpaqueMetadata */ +export interface OpaqueMetadata extends Bytes {} + /** @name PalletCallMetadataLatest */ export interface PalletCallMetadataLatest extends PalletCallMetadataV14 {} diff --git a/packages/types/src/interfaces/state/definitions.ts b/packages/types/src/interfaces/state/definitions.ts index e95e6e3b6f..24a52be6df 100644 --- a/packages/types/src/interfaces/state/definitions.ts +++ b/packages/types/src/interfaces/state/definitions.ts @@ -454,7 +454,8 @@ export default { }, RuntimeVersionPartial: { specName: 'Text', - specVersion: 'u32' + specVersion: 'u32', + apis: 'Vec' }, SpecVersion: 'u32', StorageChangeSet: { diff --git a/packages/types/src/interfaces/state/types.ts b/packages/types/src/interfaces/state/types.ts index 97a8c925bf..3f0b8c2e04 100644 --- a/packages/types/src/interfaces/state/types.ts +++ b/packages/types/src/interfaces/state/types.ts @@ -73,6 +73,7 @@ export interface RuntimeVersionApi extends ITuple<[ApiId, u32]> {} export interface RuntimeVersionPartial extends Struct { readonly specName: Text; readonly specVersion: u32; + readonly apis: Vec; } /** @name SpecVersion */ diff --git a/packages/types/src/interfaces/system/definitions.ts b/packages/types/src/interfaces/system/definitions.ts index f191f21acd..046c3c6367 100644 --- a/packages/types/src/interfaces/system/definitions.ts +++ b/packages/types/src/interfaces/system/definitions.ts @@ -7,9 +7,11 @@ import type { Definitions } from '../../types'; import { rpc } from './rpc'; +import { runtime } from './runtime'; export default { rpc, + runtime, types: { AccountInfo: 'AccountInfoWithTripleRefCount', AccountInfoWithRefCountU8: { diff --git a/packages/types/src/interfaces/system/rpc.ts b/packages/types/src/interfaces/system/rpc.ts index 1af32b5986..183d05ccd2 100644 --- a/packages/types/src/interfaces/system/rpc.ts +++ b/packages/types/src/interfaces/system/rpc.ts @@ -1,8 +1,6 @@ // Copyright 2017-2022 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -// As per frontier - import type { DefinitionsRpc } from '../../types'; export const rpc: DefinitionsRpc = { diff --git a/packages/types/src/interfaces/system/runtime.ts b/packages/types/src/interfaces/system/runtime.ts new file mode 100644 index 0000000000..c377a9dd21 --- /dev/null +++ b/packages/types/src/interfaces/system/runtime.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2022 @polkadot/types authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { DefinitionsCall } from '../../types'; + +export const runtime: DefinitionsCall = { + AccountNonceApi: [ + { + methods: { + account_nonce: { + description: 'The API to query account nonce (aka transaction index)', + params: [ + { + name: 'accountId', + type: 'AccountId' + } + ], + type: 'Index' + } + } + } + ] +}; diff --git a/packages/types/src/types/definitions.ts b/packages/types/src/types/definitions.ts index 17cc78a253..58238e0331 100644 --- a/packages/types/src/types/definitions.ts +++ b/packages/types/src/types/definitions.ts @@ -42,15 +42,32 @@ export interface DefinitionRpcExt extends DefinitionRpc { section: string; } +export interface DefinitionCallParam { + name: string; + type: DefinitionTypeType; +} + +export interface DefinitionCall { + description: string; + params: DefinitionCallParam[]; + type: DefinitionTypeType; +} + export interface DefinitionRpcSub extends DefinitionRpc { pubsub: [string, string, string]; } export type DefinitionsRpc = Record; +export type DefinitionsCall = Record; + version?: number; +}[]>; + export type DefinitionsTypes = Record; export interface Definitions { - rpc: DefinitionsRpc; + rpc?: DefinitionsRpc; + runtime?: DefinitionsCall; types: DefinitionsTypes; } diff --git a/yarn.lock b/yarn.lock index 00adcbf811..200f20d3c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2213,6 +2213,7 @@ __metadata: "@babel/runtime": ^7.18.3 "@polkadot/api": 8.10.1 "@polkadot/api-augment": 8.10.1 + "@polkadot/api-base": 8.10.1 "@polkadot/rpc-augment": 8.10.1 "@polkadot/rpc-provider": 8.10.1 "@polkadot/types": 8.10.1