Skip to content

Commit 0967dbb

Browse files
authored
Add api.{errors, events, query, tx}.<method>.<section>.is(...) (#2984)
* api.{event, error}.<section>.is<Type> * Full generation, with checkTypes * .is * Extrinsic with arg type definition * decorate is * Call is * Remove hasOrigin * Renames * Query is * Fix extrinsic is * Backwards compatibility for generated types * event with optional AnyTuple * Cleanups * Cleanups * Adjust * Cleanup
1 parent 025a745 commit 0967dbb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2987
-524
lines changed

packages/api/src/augment/errors.ts

Lines changed: 1162 additions & 0 deletions
Large diffs are not rendered by default.

packages/api/src/augment/events.ts

Lines changed: 842 additions & 0 deletions
Large diffs are not rendered by default.

packages/api/src/augment/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import './consts';
5+
import './errors';
6+
import './events';
57
import './query';
68
import './rpc';
79
import './tx';

packages/api/src/augment/query.ts

Lines changed: 181 additions & 181 deletions
Large diffs are not rendered by default.

packages/api/src/augment/tx.ts

Lines changed: 205 additions & 205 deletions
Large diffs are not rendered by default.

packages/api/src/base/Decorate.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import type { RpcInterface } from '@polkadot/rpc-core/types';
66
import type { Option, Raw, StorageKey, Text, u64 } from '@polkadot/types';
77
import type { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
88
import type { StorageEntry } from '@polkadot/types/primitive/types';
9-
import type { AnyFunction, CallFunction, Codec, CodecArg as Arg, DefinitionRpc, DefinitionRpcSub, InterfaceTypes, Registry, RegistryTypes } from '@polkadot/types/types';
9+
import type { AnyFunction, AnyTuple, CallFunction, Codec, CodecArg as Arg, DefinitionRpc, DefinitionRpcSub, IMethod, InterfaceTypes, IStorageKey, Registry, RegistryTypes } from '@polkadot/types/types';
1010
import type { SubmittableExtrinsic } from '../submittable/types';
11-
import type { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecoratedRpcSection, DecorateMethod, PaginationOptions, QueryableConsts, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
11+
import type { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedErrors, DecoratedEvents, DecoratedRpc, DecoratedRpcSection, DecorateMethod, PaginationOptions, QueryableConsts, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
1212

1313
import BN from 'bn.js';
1414

@@ -57,6 +57,10 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
5757

5858
protected _derive?: ReturnType<Decorate<ApiType>['_decorateDerive']>;
5959

60+
protected _errors: DecoratedErrors<ApiType> = {} as DecoratedErrors<ApiType>;
61+
62+
protected _events: DecoratedEvents<ApiType> = {} as DecoratedEvents<ApiType>;
63+
6064
protected _extrinsics?: SubmittableExtrinsics<ApiType>;
6165

6266
protected _extrinsicType: number = EXTRINSIC_DEFAULT_VERSION;
@@ -195,6 +199,8 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
195199
// this API
196200
augmentObject('query', this._decorateStorage(decoratedMeta, this._decorateMethod), this._query, fromEmpty);
197201
augmentObject('consts', decoratedMeta.consts, this._consts, fromEmpty);
202+
augmentObject('errors', decoratedMeta.errors, this._errors, fromEmpty);
203+
augmentObject('events', decoratedMeta.events, this._events, fromEmpty);
198204

199205
// rx
200206
augmentObject(null, this._decorateStorage(decoratedMeta, this._rxDecorateMethod), this._rx.query, fromEmpty);
@@ -338,6 +344,10 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
338344
const decorated = (...params: Arg[]): SubmittableExtrinsic<ApiType> =>
339345
creator(method(...params));
340346

347+
// pass through the `.is`
348+
decorated.is = (other: IMethod<AnyTuple>) =>
349+
method.is(other);
350+
341351
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
342352
return this._decorateFunctionMeta(method as any, decorated as any) as unknown as SubmittableExtrinsicFunction<ApiType>;
343353
}
@@ -371,6 +381,9 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
371381
decorated.hash = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<Hash> =>
372382
this._rpcCore.state.getStorageHash(getArgs(arg1, arg2)));
373383

384+
decorated.is = <A extends AnyTuple> (key: IStorageKey<AnyTuple>): key is IStorageKey<A> =>
385+
key.section === creator.section && key.method === creator.method;
386+
374387
decorated.key = (arg1?: Arg, arg2?: Arg): string =>
375388
u8aToHex(compactStripLength(creator(creator.meta.type.isDoubleMap ? [arg1, arg2] : arg1))[1]);
376389

packages/api/src/base/Getters.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Metadata } from '@polkadot/metadata';
55
import type { RpcInterface } from '@polkadot/rpc-core/types';
66
import type { Text } from '@polkadot/types';
77
import type { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
8-
import type { ApiInterfaceRx, ApiTypes, DecoratedRpc, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types';
8+
import type { ApiInterfaceRx, ApiTypes, DecoratedErrors, DecoratedEvents, DecoratedRpc, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types';
99

1010
import { assertReturn } from '@polkadot/util';
1111

@@ -54,6 +54,20 @@ export abstract class Getters<ApiType extends ApiTypes> extends Init<ApiType> {
5454
return assertResult(this._derive);
5555
}
5656

57+
/**
58+
* @description Errors from metadata
59+
*/
60+
public get errors (): DecoratedErrors<ApiType> {
61+
return assertResult(this._errors);
62+
}
63+
64+
/**
65+
* @description Events from metadata
66+
*/
67+
public get events (): DecoratedEvents<ApiType> {
68+
return assertResult(this._events);
69+
}
70+
5771
/**
5872
* @description Returns the version of extrinsics in-use on this chain
5973
*/

packages/api/src/checkTypes.manual.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
// Simple non-runnable checks to test type definitions in the editor itself
55

6-
import type { AccountId, Balance, Header, Index } from '@polkadot/types/interfaces';
7-
import type { IExtrinsic, IMethod } from '@polkadot/types/types';
6+
import type { StorageKey } from '@polkadot/types';
7+
import type { AccountId, Balance, DispatchError, EventRecord, Header, Index } from '@polkadot/types/interfaces';
8+
import type { AnyTuple, IExtrinsic, IMethod } from '@polkadot/types/types';
89

910
import { ApiPromise } from '@polkadot/api';
1011
import { HeaderExtended } from '@polkadot/api-derive';
@@ -34,6 +35,39 @@ async function derive (api: ApiPromise): Promise<void> {
3435
console.log('fees', fees);
3536
}
3637

38+
function errors (api: ApiPromise): void {
39+
const someError = {} as DispatchError;
40+
41+
// existing
42+
console.log(api.errors.vesting.AmountLow.is(someError));
43+
44+
// non-existing error, existing module
45+
console.log(api.errors.vesting.Something.is(someError));
46+
47+
// something random
48+
console.log(api.errors.something.Random.is(someError));
49+
}
50+
51+
function events (api: ApiPromise): void {
52+
const eventRecord = {} as EventRecord;
53+
54+
// existing
55+
if (api.events.balances.Transfer.is(eventRecord)) {
56+
// the types are correctly expanded
57+
const [from, to, amount] = eventRecord.event.data;
58+
59+
console.log(from.toHuman(), to.toHuman(), amount.toBn());
60+
}
61+
62+
// something random
63+
if (api.events.something.Random.is(eventRecord)) {
64+
// the types are just codec
65+
const [a, b] = eventRecord.event.data;
66+
67+
console.log(a.toHuman(), b.toHuman());
68+
}
69+
}
70+
3771
async function query (api: ApiPromise, pairs: TestKeyringMap): Promise<void> {
3872
const intentions = await api.query.staking.bonded();
3973

@@ -102,6 +136,16 @@ async function queryExtra (api: ApiPromise, pairs: TestKeyringMap): Promise<void
102136
const entries = await api.query.system.events.range(['0x12345', '0x7890']);
103137

104138
console.log(`Received ${entries.length} entries, ${entries.map(([hash, events]) => `${hash.toHex()}: ${events.length} events`).join(', ')}`);
139+
140+
// is
141+
const key = {} as StorageKey;
142+
143+
if (api.query.balances.account.is(key)) {
144+
const [accountId] = key.args;
145+
146+
// should be AccountId type
147+
console.log(accountId.toHuman());
148+
}
105149
}
106150

107151
async function rpc (api: ApiPromise): Promise<void> {
@@ -143,7 +187,7 @@ async function tx (api: ApiPromise, pairs: TestKeyringMap): Promise<void> {
143187
// transfer, also allows for BigInt inputs here
144188
const transfer = api.tx.balances.transfer(pairs.bob.address, 123456789n);
145189

146-
console.log('transfer casted', transfer as IMethod, transfer as IExtrinsic);
190+
console.log('transfer casted', transfer as IMethod<AnyTuple>, transfer as IExtrinsic<AnyTuple>);
147191

148192
// simple "return the hash" variant
149193
console.log('hash:', (await transfer.signAndSend(pairs.alice)).toHex());
@@ -179,6 +223,14 @@ async function tx (api: ApiPromise, pairs: TestKeyringMap): Promise<void> {
179223

180224
// it handles enum inputs correctly
181225
await api.tx.democracy.proxyVote(123, { Split: { nay: 456, yay: 123 } }).signAndSend(pairs.alice);
226+
227+
// is
228+
if (api.tx.balances.transfer.is(second)) {
229+
const [recipientId, balance] = second.args;
230+
231+
// should be LookupSource & Balance types
232+
console.log(recipientId.toHuman(), balance.toNumber());
233+
}
182234
}
183235

184236
async function main (): Promise<void> {
@@ -189,6 +241,8 @@ async function main (): Promise<void> {
189241
Promise.all([
190242
consts(api),
191243
derive(api),
244+
errors(api),
245+
events(api),
192246
query(api, pairs),
193247
queryExtra(api, pairs),
194248
rpc(api),

packages/api/src/types/errors.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017-2020 @polkadot/api authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import type { IsError } from '@polkadot/metadata/decorate/types';
5+
import type { ApiTypes } from './base';
6+
7+
// In errors we don't need the ApiType, however add it for consistency
8+
// eslint-disable-next-line @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars
9+
export interface AugmentedErrors<ApiType extends ApiTypes> { }
10+
11+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
12+
export type AugmentedError<ApiType extends ApiTypes> = IsError;
13+
14+
export interface ModuleErrors<ApiType extends ApiTypes> {
15+
[key: string]: AugmentedError<ApiType>;
16+
}

packages/api/src/types/events.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017-2020 @polkadot/api authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import type { IsEvent } from '@polkadot/metadata/decorate/types';
5+
import type { AnyTuple } from '@polkadot/types/types';
6+
import type { ApiTypes } from './base';
7+
8+
// In events we don't need the ApiType, however add it for consistency
9+
// eslint-disable-next-line @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars
10+
export interface AugmentedEvents<ApiType extends ApiTypes> { }
11+
12+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
13+
export type AugmentedEvent<ApiType extends ApiTypes, T extends AnyTuple = AnyTuple> = IsEvent<T>;
14+
15+
export interface ModuleEvents<ApiType extends ApiTypes> {
16+
[key: string]: AugmentedEvent<ApiType, AnyTuple>;
17+
}

0 commit comments

Comments
 (0)