diff --git a/.changeset/sharp-ladybugs-move.md b/.changeset/sharp-ladybugs-move.md new file mode 100644 index 00000000..453504fb --- /dev/null +++ b/.changeset/sharp-ladybugs-move.md @@ -0,0 +1,5 @@ +--- +"@reactive-dot/core": patch +--- + +Fix query crashing when specifying the `at` option. diff --git a/packages/core/src/actions/query.ts b/packages/core/src/actions/query.ts index c68ca50d..ff90dd8c 100644 --- a/packages/core/src/actions/query.ts +++ b/packages/core/src/actions/query.ts @@ -46,15 +46,21 @@ export function query< // eslint-disable-next-line @typescript-eslint/no-explicit-any return (api.apis[instruction.pallet]![instruction.api] as any)( ...instruction.args, - { signal: options?.signal }, + { signal: options?.signal, at: instruction.at }, ); - case "read-storage": - return ( + case "read-storage": { + const storageEntry = api.query[instruction.pallet]![ + instruction.storage // eslint-disable-next-line @typescript-eslint/no-explicit-any - (api.query[instruction.pallet]![instruction.storage] as any).watchValue( - ...instruction.args, - ) - ); + ] as any; + + return instruction.at?.startsWith("0x") + ? storageEntry.getValue(...instruction.args, { at: instruction.at }) + : storageEntry.watchValue( + ...instruction.args, + ...[instruction.at].filter((x) => x !== undefined), + ); + } case "read-storage-entries": return ( // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -62,6 +68,7 @@ export function query< ...instruction.args, { signal: options?.signal, + at: instruction.at, }, ) ); diff --git a/packages/core/src/query-builder.ts b/packages/core/src/query-builder.ts index 517f5e76..d438b679 100644 --- a/packages/core/src/query-builder.ts +++ b/packages/core/src/query-builder.ts @@ -8,8 +8,6 @@ type PapiCallOptions = Partial<{ signal: AbortSignal; }>; -type CallOptions = Omit; - type OmitCallOptions = T extends [ infer Head, ...infer Tail, @@ -20,20 +18,20 @@ type OmitCallOptions = T extends [ : []; type InferPapiStorageEntry = T extends { - watchValue: (...args: [...infer Args, infer At]) => infer Response; + watchValue: (...args: [...infer Args, infer _]) => infer Response; } - ? { args: Args; options: { at: At }; response: Response } - : { args: unknown[]; options: unknown; response: unknown }; + ? { args: Args; response: Response } + : { args: unknown[]; response: unknown }; type InferPapiStorageEntries = T extends { getEntries: (...args: infer Args) => infer Response; } - ? { args: OmitCallOptions; options: CallOptions; response: Response } - : { args: unknown[]; options: unknown; response: unknown }; + ? { args: OmitCallOptions; response: Response } + : { args: unknown[]; response: unknown }; type InferPapiRuntimeCall = T extends (...args: infer Args) => infer Response - ? { args: OmitCallOptions; options: CallOptions; response: Response } - : { args: unknown[]; options: unknown; response: unknown }; + ? { args: OmitCallOptions; response: Response } + : { args: unknown[]; response: unknown }; type InferPapiConstantEntry = T extends { (): Promise; @@ -42,6 +40,8 @@ type InferPapiConstantEntry = T extends { ? Promise : unknown; +type At = "best" | "finalized" | `0x${string}`; + type BaseInstruction = { instruction: T; }; @@ -66,6 +66,7 @@ export type StorageReadInstruction< pallet: TPallet; storage: TStorage; args: TArguments; + at: At | undefined; }; export type StorageEntriesReadInstruction< @@ -79,6 +80,7 @@ export type StorageEntriesReadInstruction< pallet: TPallet; storage: TStorage; args: TArguments; + at: At | undefined; }; export type ApiCallInstruction< @@ -92,6 +94,7 @@ export type ApiCallInstruction< pallet: TPallet; api: TApi; args: TArguments; + at: At | undefined; }; export type MultiInstruction> = @@ -253,15 +256,18 @@ export class Query< TArguments extends InferPapiStorageEntry< TypedApi["query"][TPallet][TStorage] >["args"], - TOptions extends InferPapiStorageEntry< - TypedApi["query"][TPallet][TStorage] - >["options"], - >(pallet: TPallet, storage: TStorage, args: TArguments, options?: TOptions) { + >( + pallet: TPallet, + storage: TStorage, + args: TArguments, + options?: { at?: At }, + ) { return this.#append({ instruction: "read-storage", pallet, storage, - args: options === undefined ? args : [...args, options], + args, + at: options?.at, }); } @@ -271,21 +277,18 @@ export class Query< TArguments extends InferPapiStorageEntry< TypedApi["query"][TPallet][TStorage] >["args"], - TOptions extends InferPapiStorageEntry< - TypedApi["query"][TPallet][TStorage] - >["options"], >( pallet: TPallet, storage: TStorage, args: TArguments[], - options?: TOptions, + options?: { at?: At }, ) { return this.#append({ instruction: "read-storage", pallet, storage, - args: - options === undefined ? args : args.map((args) => [...args, options]), + args, + at: options?.at, multi: true, }); } @@ -296,17 +299,18 @@ export class Query< TArguments extends InferPapiStorageEntries< TypedApi["query"][TPallet][TStorage] >["args"], - TOptions extends Array< - InferPapiStorageEntries< - TypedApi["query"][TPallet][TStorage] - >["options"] - >, - >(pallet: TPallet, storage: TStorage, args: TArguments, options?: TOptions) { + >( + pallet: TPallet, + storage: TStorage, + args: TArguments, + options?: { at?: At }, + ) { return this.#append({ instruction: "read-storage-entries", pallet, storage, - args: options === undefined ? args : [...args, options], + args, + at: options?.at, }); } @@ -316,15 +320,13 @@ export class Query< TArguments extends InferPapiRuntimeCall< TypedApi["apis"][TPallet][TApi] >["args"], - TOptions extends InferPapiRuntimeCall< - TypedApi["apis"][TPallet][TApi] - >["options"], - >(pallet: TPallet, api: TApi, args: TArguments, options?: TOptions) { + >(pallet: TPallet, api: TApi, args: TArguments, options?: { at?: At }) { return this.#append({ instruction: "call-api", pallet, api, - args: options === undefined ? args : [...args, options], + args, + at: options?.at, }); } @@ -334,16 +336,13 @@ export class Query< TArguments extends InferPapiRuntimeCall< TypedApi["apis"][TPallet][TApi] >["args"], - TOptions extends InferPapiRuntimeCall< - TypedApi["apis"][TPallet][TApi] - >["options"], - >(pallet: TPallet, api: TApi, args: TArguments[], options?: TOptions) { + >(pallet: TPallet, api: TApi, args: TArguments[], options?: { at?: At }) { return this.#append({ instruction: "call-api", pallet, api, - args: - options === undefined ? args : args.map((args) => [...args, options]), + args, + at: options?.at, multi: true, }); }