Skip to content

feat: Add initial support for Metadata V16 view_functions #6135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions packages/api/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import type { HexString } from '@polkadot/util/types';
import type { ApiBase } from '../base/index.js';
import type { SubmittableExtrinsic } from '../types/submittable.js';
import type { AllDerives } from '../util/decorate.js';
import type { Observable } from 'rxjs';
import type { DecoratedMeta } from '@polkadot/types/metadata/decorate/types';
import type { StorageKey } from '@polkadot/types';
import type { Codec, IMethod, AnyTuple, IEventLike } from '@polkadot/types/types';
import type { DecoratedRpc } from './rpc.js';
import type { DecoratedViewFunction } from '@polkadot/types/metadata/decorate/types';

// types
export type { Signer, SignerResult } from '@polkadot/types/types';
Expand All @@ -43,6 +49,14 @@ export * from '@polkadot/api-base/types';
// A smaller interface of ApiRx, used in derive and in SubmittableExtrinsic
export interface ApiInterfaceRx extends ApiInterfaceBase {
derive: AllDerives<'rxjs'>;
readonly query: QueryableStorage<'rxjs'>;
readonly queryAt: QueryableStorageAt<'rxjs'>;
readonly queryMulti: QueryableStorageMulti<'rxjs'>;
readonly registry: Registry;
readonly rpc: DecoratedRpc<'rxjs', RpcInterface>;
readonly runtimeVersion: RuntimeVersion;
readonly tx: SubmittableExtrinsics<'rxjs'>;
readonly view: QueryableViewFunctions<'rxjs'>;
}

export interface ApiOptions extends RegisteredTypes {
Expand Down Expand Up @@ -117,19 +131,36 @@ export interface SignerOptions extends SignatureOptions {
genesisHash: Hash;
}

export interface QueryableCalls<ApiType extends ApiTypes> {
[section: string]: {
[method: string]: AugmentedCall<ApiType>;
};
}

// New Type: Represents a single decorated view function
export interface AugmentedViewFunction<ApiType extends ApiTypes> extends IMethod<AnyTuple> {
(...args: any[]): Observable<Codec>;
meta: DecoratedViewFunction;
}

// New Type: Represents the `api.view` section holding all view functions
export interface QueryableViewFunctions<ApiType extends ApiTypes> {
[section: string]: {
[method: string]: AugmentedViewFunction<ApiType>;
};
}

export interface ApiDecoration<ApiType extends ApiTypes> {
call: QueryableCalls<ApiType>;
consts: QueryableConsts<ApiType>;
errors: DecoratedErrors<ApiType>;
events: DecoratedEvents<ApiType>;
query: QueryableStorage<ApiType>;
registry: Registry;
runtimeVersion: RuntimeVersionPartial;
rx: {
call: QueryableCalls<'rxjs'>;
query: QueryableStorage<'rxjs'>;
};
tx: (extrinsic: Call | Extrinsic | Uint8Array | string) => SubmittableExtrinsic<ApiType>;
runtimeVersion: RuntimeVersion;
rx: ApiInterfaceRx;
tx: SubmittableExtrinsics<ApiType>;
view: QueryableViewFunctions<ApiType>;

findCall (callIndex: Uint8Array | string): CallFunction;
findError (errorIndex: Uint8Array | string): RegistryError;
Expand Down
10 changes: 10 additions & 0 deletions packages/types/src/interfaces/metadata/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
/* eslint-disable */

export * from './definitions.js';
export * from './latest.js';
export * from './types.js';
export * from './v9.js';
export * from './v10.js';
export * from './v11.js';
export * from './v12.js';
export * from './v13.js';
export * from './v14.js';
export * from './v15.js';
export * from './v16.js';
109 changes: 99 additions & 10 deletions packages/types/src/interfaces/metadata/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,13 @@ export interface MetadataAll extends Enum {
readonly asV14: MetadataV14;
readonly isV15: boolean;
readonly asV15: MetadataV15;
readonly type: 'V0' | 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8' | 'V9' | 'V10' | 'V11' | 'V12' | 'V13' | 'V14' | 'V15';
readonly isV16: boolean;
readonly asV16: MetadataV16;
readonly type: 'V0' | 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8' | 'V9' | 'V10' | 'V11' | 'V12' | 'V13' | 'V14' | 'V15' | 'V16';
}

/** @name MetadataLatest */
export interface MetadataLatest extends MetadataV15 {}
export interface MetadataLatest extends MetadataV16 {}

/** @name MetadataV10 */
export interface MetadataV10 extends Struct {
Expand Down Expand Up @@ -219,6 +221,9 @@ export interface MetadataV14 extends Struct {
readonly pallets: Vec<PalletMetadataV14>;
readonly extrinsic: ExtrinsicMetadataV14;
readonly type: SiLookupTypeId;
readonly apis: Vec<RuntimeApiMetadataLatest>;
readonly outerEnums: OuterEnums;
readonly custom: CustomMetadata;
}

/** @name MetadataV15 */
Expand All @@ -228,8 +233,17 @@ export interface MetadataV15 extends Struct {
readonly extrinsic: ExtrinsicMetadataV15;
readonly type: SiLookupTypeId;
readonly apis: Vec<RuntimeApiMetadataV15>;
readonly outerEnums: OuterEnums15;
readonly custom: CustomMetadata15;
readonly custom: CustomMetadata;
}

/** @name MetadataV16 */
export interface MetadataV16 extends Struct {
readonly lookup: PortableRegistry;
readonly pallets: Vec<PalletMetadataV16>;
readonly extrinsic: ExtrinsicMetadataLatest;
readonly type: SiLookupTypeId;
readonly apis: Vec<RuntimeApiMetadataLatest>;
readonly custom: CustomMetadata;
}

/** @name MetadataV9 */
Expand Down Expand Up @@ -312,11 +326,11 @@ export interface ModuleMetadataV9 extends Struct {
/** @name OpaqueMetadata */
export interface OpaqueMetadata extends WrapperOpaque<Bytes> {}

/** @name OuterEnums15 */
export interface OuterEnums15 extends Struct {
readonly callType: SiLookupTypeId;
readonly eventType: SiLookupTypeId;
readonly errorType: SiLookupTypeId;
/** @name OuterEnums */
export interface OuterEnums extends Struct {
readonly callEnumType: SiLookupTypeId;
readonly errorEnumType: SiLookupTypeId;
readonly eventEnumType: SiLookupTypeId;
}

/** @name PalletCallMetadataLatest */
Expand Down Expand Up @@ -355,7 +369,7 @@ export interface PalletEventMetadataV14 extends Struct {
}

/** @name PalletMetadataLatest */
export interface PalletMetadataLatest extends PalletMetadataV15 {}
export interface PalletMetadataLatest extends PalletMetadataV16 {}

/** @name PalletMetadataV14 */
export interface PalletMetadataV14 extends Struct {
Expand Down Expand Up @@ -694,4 +708,79 @@ export interface StorageMetadataV9 extends Struct {
readonly items: Vec<StorageEntryMetadataV9>;
}

/** @name CustomMetadata */
export interface CustomMetadata extends Struct {
readonly map: Vec<CustomMetadataTuple>;
}

/** @name CustomMetadataTuple */
export type CustomMetadataTuple = [Text, CustomValueMetadata];

/** @name CustomValueMetadata */
export interface CustomValueMetadata extends Struct {
readonly type: SiLookupTypeId;
readonly value: Bytes;
}

/** @name PortableRegistry */
export interface PortableRegistry extends Struct {
readonly types: Vec<PortableType>;
}

/** @name PortableType */
export interface PortableType extends Struct {
readonly id: SiLookupTypeId;
readonly type: SiType;
}

/** @name RuntimeApiMetadataLatest */
export interface RuntimeApiMetadataLatest extends RuntimeApiMetadataV15 {}

/** @name RuntimeApiMethodMetadataLatest */
export interface RuntimeApiMethodMetadataLatest extends RuntimeApiMethodMetadataV15 {}

/** @name RuntimeApiMethodParamMetadataLatest */
export interface RuntimeApiMethodParamMetadataLatest extends Struct {
readonly name: Text;
readonly type: SiLookupTypeId;
}

/** @name SignedExtensionMetadataLatest */
export interface SignedExtensionMetadataLatest extends SignedExtensionMetadataV14 {}

/** @name StorageEntryModifierLatest */
export interface StorageEntryModifierLatest extends StorageEntryModifierV14 {}

/** @name StorageEntryTypeLatest */
export interface StorageEntryTypeLatest extends StorageEntryTypeV14 {}

/** @name StorageHasherLatest */
export interface StorageHasherLatest extends StorageHasherV14 {}

/** @name MetadataEnum */
export interface MetadataEnum extends Struct {
readonly V0: MetadataV0;
readonly V1: MetadataV1;
readonly V2: MetadataV2;
readonly V3: MetadataV3;
readonly V4: MetadataV4;
readonly V5: MetadataV5;
readonly V6: MetadataV6;
readonly V7: MetadataV7;
readonly V8: MetadataV8;
readonly V9: MetadataV9;
readonly V10: MetadataV10;
readonly V11: MetadataV11;
readonly V12: MetadataV12;
readonly V13: MetadataV13;
readonly V14: MetadataV14;
readonly V15: MetadataV15;
readonly V16: MetadataV16;
}

/** @name MetadataAll */
export type MetadataAll = MetadataV0 | MetadataV1 | MetadataV2 | MetadataV3 | MetadataV4 | MetadataV5 | MetadataV6 | MetadataV7 | MetadataV8 | MetadataV9 | MetadataV10 | MetadataV11 | MetadataV12 | MetadataV13 | MetadataV14 | MetadataV15 | MetadataV16;

export interface MetadataLatest extends MetadataV16 {}

export type PHANTOM_METADATA = 'metadata';
34 changes: 34 additions & 0 deletions packages/types/src/interfaces/metadata/v16.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2017-2025 @polkadot/types authors & contributors
// SPDX-License-Identifier: Apache-2.0

// import type { SiLookupTypeId } from '../../primitive/types.js';
// import type { PalletCallMetadataV14, PalletConstantMetadataV14, PalletErrorMetadataV14, PalletEventMetadataV14, PalletStorageMetadataV14 } from './v14.js';

// NOTE: The imports above are commented out as they might not be directly needed
// if v16 reuses v15 structures or has its own complete definitions.
// This will need to be adjusted based on the actual V16 spec.

export interface PalletViewFunctionArgumentMetadataV16 extends Struct {
readonly name: Text;
readonly type: SiLookupTypeId; // Assuming it uses SiLookupTypeId like other metadata parts
// readonly typeName: Option<Text>; // Optionally, if type name is directly included
}

export interface PalletViewFunctionMetadataV16 extends Struct {
readonly name: Text;
readonly args: Vec<PalletViewFunctionArgumentMetadataV16>;
readonly returnType: SiLookupTypeId; // Assuming it uses SiLookupTypeId
// readonly returnTypeName: Option<Text>; // Optionally, if type name is directly included
readonly docs: Vec<Text>;
}

export interface PalletMetadataV16 extends Struct {
readonly name: Text;
readonly storage: Option<PalletStorageMetadataV14>; // Assuming V14/V15 structure for now
readonly calls: Option<PalletCallMetadataV14>; // Assuming V14/V15 structure for now
readonly events: Option<PalletEventMetadataV14>; // Assuming V14/V15 structure for now
readonly constants: Vec<PalletConstantMetadataV14>; // Assuming V14/V15 structure for now
readonly errors: Option<PalletErrorMetadataV14>; // Assuming V14/V15 structure for now
readonly viewFunctions: Vec<PalletViewFunctionMetadataV16>; // The new field
readonly index: u8;
}
22 changes: 17 additions & 5 deletions packages/types/src/metadata/MetadataVersioned.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import type { AnyJson } from '@polkadot/types-codec/types';
import type { HexString } from '@polkadot/util/types';
import type { MetadataAll, MetadataLatest, MetadataV9, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15 } from '../interfaces/metadata/index.js';
import type { MetadataAll, MetadataLatest, MetadataV9, MetadataV10, MetadataV11, MetadataV12, MetadataV13, MetadataV14, MetadataV15, MetadataV16 } from '../interfaces/metadata/index.js';
import type { Registry } from '../types/index.js';
import type { MetaVersionAll, MetaVersionAsX } from './versions.js';

Expand All @@ -16,7 +16,8 @@ import { toV12 } from './v11/toV12.js';
import { toV13 } from './v12/toV13.js';
import { toV14 } from './v13/toV14.js';
import { toV15 } from './v14/toV15.js';
import { toLatest } from './v15/toLatest.js';
import { toV16 } from './v15/toV16.js';
import { toLatest } from './v16/toLatest.js';
import { MagicNumber } from './MagicNumber.js';
import { LATEST_VERSION, TO_CALLS_VERSION } from './versions.js';

Expand Down Expand Up @@ -61,8 +62,12 @@ export class MetadataVersioned extends Struct {
const asPrev: MetaVersionAsX = version === 'latest'
? `asV${LATEST_VERSION}`
: `asV${(version - 1) as MetaVersionAll}`;

const prevInput = version === 'latest'
? this.asV16 as F
: this[asPrev] as F;

this.#converted.set(version, fromPrev(this.registry, this[asPrev] as F, this.version));
this.#converted.set(version, fromPrev(this.registry, prevInput, this.version));
}

return this.#converted.get(version) as T;
Expand Down Expand Up @@ -130,17 +135,24 @@ export class MetadataVersioned extends Struct {
}

/**
* @description Returns the wrapped values as a V14 object
* @description Returns the wrapped values as a V15 object
*/
public get asV15 (): MetadataV15 {
return this.#getVersion(15, toV15);
}

/**
* @description Returns the wrapped values as a V16 object
*/
public get asV16 (): MetadataV16 {
return this.#getVersion(16, toV16);
}

/**
* @description Returns the wrapped values as a latest version object
*/
public get asLatest (): MetadataLatest {
return this.#getVersion('latest', toLatest);
return this.#getVersion('latest', toLatest as (registry: Registry, input: MetadataV16, metaVersion: number) => MetadataLatest);
}

/**
Expand Down
35 changes: 30 additions & 5 deletions packages/types/src/metadata/decorate/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import type { AnyTuple, Codec, Registry } from '@polkadot/types-codec/types';
import type { DispatchErrorModule, DispatchErrorModuleU8, DispatchErrorModuleU8a, ErrorMetadataLatest, EventMetadataLatest, PalletConstantMetadataLatest } from '../../interfaces/index.js';
import type { StorageEntry } from '../../primitive/types.js';
import type { CallFunction, IEvent, IEventLike } from '../../types/index.js';
import type { Text } from '@polkadot/types';
import type { TypeDef } from '@polkadot/types/types';
import type { PalletViewFunctionMetadataV16 } from '@polkadot/types/interfaces/metadata/v16';
import type { PalletConstantMeta, PalletErrorMeta, PalletEventMeta, PalletStorageMeta } from '@polkadot/types/interfaces/metadata/types';

export interface ConstantCodec extends Codec {
readonly meta: PalletConstantMetadataLatest;
Expand Down Expand Up @@ -43,10 +47,31 @@ export type Extrinsics = Record<string, ModuleExtrinsics>
export type Storage = Record<string, ModuleStorage>;

export interface DecoratedMeta {
readonly consts: Constants;
readonly errors: Errors;
readonly events: Events;
readonly query: Storage;
readonly consts: Record<string, Record<string, PalletConstantMeta>>;
readonly errors: Record<string, Record<string, PalletErrorMeta>>;
readonly events: Record<string, Record<string, PalletEventMeta>>;
readonly query: Record<string, Record<string, PalletStorageMeta>>;
readonly registry: Registry;
readonly tx: Extrinsics
readonly tx: Record<string, Record<string, CallFunction>>;
readonly view: DecoratedView;
}

// New types for View Functions
export interface DecoratedViewFunctionArg {
name: string;
typeDef: TypeDef;
typeName?: Text; // Optional: May not always be available directly
}

export interface DecoratedViewFunction {
args: DecoratedViewFunctionArg[];
docs: string[];
meta: PalletViewFunctionMetadataV16;
method: string; // camelCase name
name: string; // original name
pallet: string; // camelCase pallet name
returnTypeDef: TypeDef;
section: string; // camelCase pallet name
}

export type DecoratedView = Record<string, Record<string, DecoratedViewFunction>>;
Loading