@d9-network/ink 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Binary, PolkadotClient, PolkadotSigner, SS58String } from "polkadot-api";
1
+ import { Binary, Enum, HexString, PolkadotClient, PolkadotSigner, SS58String } from "polkadot-api";
2
2
  import { Event, InkCallableDescriptor, InkDescriptors, InkMetadata, InkStorageDescriptor } from "@polkadot-api/ink-contracts";
3
3
  import { Bytes } from "@subsquid/scale-codec";
4
4
  import * as _polkadot_api_substrate_bindings0 from "@polkadot-api/substrate-bindings";
@@ -104,8 +104,8 @@ declare function isContractError(error: unknown): error is ContractError;
104
104
  /**
105
105
  * Type guard to check for specific error types
106
106
  */
107
- declare function isErrorType<T extends ContractErrorType>(error: unknown, type: T): error is ContractError & {
108
- type: T;
107
+ declare function isErrorType<T$1 extends ContractErrorType>(error: unknown, type: T$1): error is ContractError & {
108
+ type: T$1;
109
109
  };
110
110
  //#endregion
111
111
  //#region src/event-types.d.ts
@@ -127,13 +127,42 @@ interface RawContractEvent {
127
127
  topics: Uint8Array[];
128
128
  }
129
129
  /**
130
- * Decoded contract event
130
+ * Extract the definition object from an Enum type or InkEvent type
131
+ * e.g. ExtractEnumDef<Enum<{A: X, B: Y}>> = {A: X, B: Y}
132
+ *
133
+ * For non-Enum types (e.g., InkEvent { type: string; value: unknown }),
134
+ * returns a generic event definition.
135
+ */
136
+ type ExtractEnumDef<E> = E extends Enum<infer T> ? T : E extends Event ? Record<string, unknown> : never;
137
+ /**
138
+ * Extract event labels as a union type from an Enum type
139
+ * e.g. ExtractEventLabels<Enum<{Transfer: X, Approval: Y}>> = "Transfer" | "Approval"
140
+ */
141
+ type ExtractEventLabels<E extends Event> = keyof ExtractEnumDef<E> & string;
142
+ /**
143
+ * Type-safe contract event with discriminated union
144
+ * Enables type narrowing: `if (event.type === "Transfer") { event.value.from }`
131
145
  */
132
- interface DecodedContractEvent<T = unknown> {
146
+ type TypedContractEvent<E extends Event> = E extends Enum<infer T> ? { [K in keyof T & string]: {
147
+ /** Event type (discriminant for type narrowing) */
148
+ type: K;
149
+ /** Decoded event data (type-safe based on event type) */
150
+ value: T[K];
151
+ /** Original raw event */
152
+ raw: RawContractEvent;
153
+ } }[keyof T & string] : {
154
+ type: string;
155
+ value: unknown;
156
+ raw: RawContractEvent;
157
+ };
158
+ /**
159
+ * Decoded contract event (legacy, use TypedContractEvent for type safety)
160
+ */
161
+ interface DecodedContractEvent<T$1 = unknown> {
133
162
  /** Event label from metadata (e.g., "Transfer", "Approval") */
134
163
  label: string;
135
164
  /** Decoded event data */
136
- data: T;
165
+ data: T$1;
137
166
  /** Original raw event */
138
167
  raw: RawContractEvent;
139
168
  }
@@ -150,6 +179,29 @@ interface EventFilterOptions {
150
179
  /** To block number (inclusive) */
151
180
  toBlock?: number;
152
181
  }
182
+ /**
183
+ * Type-safe event filter options with literal event labels
184
+ * Provides compile-time validation of event label names
185
+ *
186
+ * @typeParam E - The event type representing all possible events
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * const options: TypedEventFilterOptions<typeof contracts.usdt.__types.event> = {
191
+ * eventLabels: ["Transfer", "Approval"], // Must be valid event names
192
+ * };
193
+ * ```
194
+ */
195
+ interface TypedEventFilterOptions<E extends Event> {
196
+ /** Contract address to filter by */
197
+ contractAddress?: SS58String;
198
+ /** Event labels to include (type-safe) */
199
+ eventLabels?: Array<ExtractEventLabels<E>>;
200
+ /** From block number (inclusive) */
201
+ fromBlock?: number;
202
+ /** To block number (inclusive) */
203
+ toBlock?: number;
204
+ }
153
205
  /**
154
206
  * Event subscription options
155
207
  */
@@ -177,6 +229,196 @@ interface EventSubscriptionOptions {
177
229
  getEvents: (blockHash: string) => Promise<unknown[]>;
178
230
  }
179
231
  //#endregion
232
+ //#region src/call-types.d.ts
233
+ /**
234
+ * Raw call data from a transaction
235
+ */
236
+ interface RawContractCall {
237
+ /** The call data (SCALE encoded selector + args) */
238
+ data: Uint8Array;
239
+ /** Contract address being called */
240
+ contractAddress?: SS58String;
241
+ /** Transaction hash (if from a transaction) */
242
+ txHash?: string;
243
+ /** Block number (if from a transaction) */
244
+ blockNumber?: number;
245
+ /** Block hash (if from a transaction) */
246
+ blockHash?: string;
247
+ }
248
+ /**
249
+ * Extract message labels as a union type from InkCallableDescriptor
250
+ * e.g. ExtractMessageLabels<Messages> = "PSP22::transfer" | "PSP22::balance_of" | ...
251
+ */
252
+ type ExtractMessageLabels<M$1 extends InkCallableDescriptor> = keyof M$1 & string;
253
+ /**
254
+ * Type-safe parsed contract call with discriminated union
255
+ * Enables type narrowing: `if (call.type === "PSP22::transfer") { call.args.to }`
256
+ */
257
+ type TypedContractCall<M$1 extends InkCallableDescriptor> = { [K in keyof M$1 & string]: {
258
+ /** Call type/method name (discriminant for type narrowing) */
259
+ type: K;
260
+ /** Decoded call arguments (type-safe based on method) */
261
+ args: M$1[K]["message"];
262
+ /** 4-byte selector */
263
+ selector: Uint8Array;
264
+ /** Original raw call data */
265
+ raw: RawContractCall;
266
+ } }[keyof M$1 & string];
267
+ /**
268
+ * Call filter options
269
+ */
270
+ interface CallFilterOptions {
271
+ /** Message labels to include (e.g., ["PSP22::transfer", "PSP22::approve"]) */
272
+ messageLabels?: string[];
273
+ }
274
+ /**
275
+ * Type-safe call filter options with literal message labels
276
+ * Provides compile-time validation of message label names
277
+ *
278
+ * @typeParam M - The InkCallableDescriptor type (message definitions)
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * const options: TypedCallFilterOptions<typeof contracts.usdt.__types.messages> = {
283
+ * messageLabels: ["PSP22::transfer", "PSP22::approve"], // Must be valid message names
284
+ * };
285
+ * ```
286
+ */
287
+ interface TypedCallFilterOptions<M$1 extends InkCallableDescriptor> {
288
+ /** Message labels to include (type-safe) */
289
+ messageLabels?: Array<ExtractMessageLabels<M$1>>;
290
+ }
291
+ /**
292
+ * Message info from metadata
293
+ */
294
+ interface MessageInfo {
295
+ /** Message label (e.g., "PSP22::transfer") */
296
+ label: string;
297
+ /** 4-byte selector */
298
+ selector: Uint8Array;
299
+ /** Whether the message is mutable (writes state) */
300
+ mutates: boolean;
301
+ /** Whether the message is payable */
302
+ payable: boolean;
303
+ /** Argument definitions */
304
+ args: Array<{
305
+ label: string;
306
+ type: {
307
+ type: number;
308
+ };
309
+ }>;
310
+ }
311
+ //#endregion
312
+ //#region src/message-builder.d.ts
313
+ /**
314
+ * Message attributes from metadata
315
+ */
316
+ interface MessageAttributes {
317
+ /** Whether the message mutates state */
318
+ mutates: boolean;
319
+ /** Whether the message is payable */
320
+ payable: boolean;
321
+ /** Whether this is the default message */
322
+ default: boolean;
323
+ }
324
+ /**
325
+ * Type-safe message interface with encode/decode methods
326
+ *
327
+ * @typeParam M - The InkCallableDescriptor type (message definitions)
328
+ * @typeParam L - The specific message label
329
+ */
330
+ interface TypedMessage<M$1 extends InkCallableDescriptor, L extends keyof M$1 & string> {
331
+ /**
332
+ * Encode message arguments to Binary
333
+ *
334
+ * @param args - The message arguments (fully typed)
335
+ * @returns Encoded call data as Binary
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * const transfer = builder.message("PSP22::transfer");
340
+ * const encoded = transfer.encode({
341
+ * to: recipientAddress,
342
+ * value: 1000n,
343
+ * data: new Uint8Array(),
344
+ * });
345
+ * ```
346
+ */
347
+ encode: {} extends M$1[L]["message"] ? (args?: M$1[L]["message"]) => Binary : (args: M$1[L]["message"]) => Binary;
348
+ /**
349
+ * Decode response to typed value
350
+ *
351
+ * @param response - The response data
352
+ * @returns Decoded response value
353
+ */
354
+ decode: (response: Binary | Uint8Array) => M$1[L]["response"];
355
+ /** Message attributes (mutates, payable, default) */
356
+ attributes: MessageAttributes;
357
+ /** 4-byte selector */
358
+ selector: Uint8Array;
359
+ /** Message label */
360
+ label: L;
361
+ }
362
+ /**
363
+ * Contract message builder interface
364
+ *
365
+ * @typeParam M - The InkCallableDescriptor type (message definitions)
366
+ */
367
+ interface ContractMessageBuilder<M$1 extends InkCallableDescriptor> {
368
+ /**
369
+ * Get a type-safe message interface for a specific message
370
+ *
371
+ * @param label - The message label (e.g., "PSP22::transfer")
372
+ * @returns Typed message interface with encode/decode methods
373
+ *
374
+ * @example
375
+ * ```ts
376
+ * const transfer = builder.message("PSP22::transfer");
377
+ * const encoded = transfer.encode({ to, value, data });
378
+ * const decoded = transfer.decode(response);
379
+ * ```
380
+ */
381
+ message<L extends ExtractMessageLabels<M$1>>(label: L): TypedMessage<M$1, L>;
382
+ /**
383
+ * Get all available message labels
384
+ *
385
+ * @returns Array of message labels
386
+ */
387
+ getMessageLabels(): Array<ExtractMessageLabels<M$1>>;
388
+ }
389
+ /**
390
+ * Create a type-safe message builder from a contract descriptor
391
+ *
392
+ * @typeParam S - Storage descriptor type
393
+ * @typeParam M - Messages descriptor type
394
+ * @typeParam C - Constructors descriptor type
395
+ * @typeParam E - Events Enum type
396
+ * @param descriptor - The ink! contract descriptor containing metadata
397
+ * @returns A ContractMessageBuilder instance
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * import { createMessageBuilder } from '@d9-network/ink';
402
+ * import { contracts } from '@polkadot-api/descriptors';
403
+ *
404
+ * const builder = createMessageBuilder(contracts.usdt);
405
+ *
406
+ * // Get a typed message interface
407
+ * const transfer = builder.message("PSP22::transfer");
408
+ *
409
+ * // Encode with full type checking on args
410
+ * const encoded = transfer.encode({
411
+ * to: recipientAddress, // Must be SS58String
412
+ * value: 1000000n, // Must be bigint
413
+ * data: new Uint8Array(), // Must be Uint8Array
414
+ * });
415
+ *
416
+ * // Decode response with full type inference
417
+ * const response = transfer.decode(resultBytes);
418
+ * ```
419
+ */
420
+ declare function createMessageBuilder<S extends InkStorageDescriptor, M$1 extends InkCallableDescriptor, C extends InkCallableDescriptor, E extends Enum<any>>(descriptor: InkDescriptors<S, M$1, C, E>): ContractMessageBuilder<M$1>;
421
+ //#endregion
180
422
  //#region src/types.d.ts
181
423
  /**
182
424
  * Decoder type for response decoding
@@ -222,16 +464,16 @@ interface SendOptions<Args = unknown> {
222
464
  /**
223
465
  * Sendable transaction that can be signed and submitted
224
466
  */
225
- interface SendableTransaction<T> {
467
+ interface SendableTransaction<T$1> {
226
468
  /** Sign and submit the transaction */
227
- signAndSubmit(signer: PolkadotSigner): Promise<TxResult<T>>;
469
+ signAndSubmit(signer: PolkadotSigner): Promise<TxResult<T$1>>;
228
470
  /** Get the encoded call data */
229
471
  getEncodedData(): Uint8Array;
230
472
  }
231
473
  /**
232
474
  * Transaction result
233
475
  */
234
- interface TxResult<T> {
476
+ interface TxResult<T$1> {
235
477
  /** Whether the transaction was successful */
236
478
  ok: boolean;
237
479
  /** Transaction hash */
@@ -242,7 +484,7 @@ interface TxResult<T> {
242
484
  number: number;
243
485
  };
244
486
  /** Decoded return value (if any) */
245
- result?: T;
487
+ result?: T$1;
246
488
  /** Events emitted by the transaction */
247
489
  events: unknown[];
248
490
  /** Dispatch error if failed */
@@ -251,9 +493,9 @@ interface TxResult<T> {
251
493
  /**
252
494
  * Successful query result value
253
495
  */
254
- interface QuerySuccessValue<T> {
496
+ interface QuerySuccessValue<T$1> {
255
497
  /** The decoded response from the contract */
256
- value: T;
498
+ value: T$1;
257
499
  /** Events that would be emitted */
258
500
  events: unknown[];
259
501
  /** Gas consumed during dry-run */
@@ -269,16 +511,16 @@ interface QuerySuccessValue<T> {
269
511
  /** Storage deposit required */
270
512
  storageDeposit: bigint;
271
513
  /** Create a sendable transaction from this query result */
272
- send(): SendableTransaction<T>;
514
+ send(): SendableTransaction<T$1>;
273
515
  }
274
516
  /**
275
517
  * Query result - discriminated union for success/failure
276
518
  * On success: QuerySuccessValue fields are spread to the same level as success
277
519
  * On failure: error field contains the ContractError
278
520
  */
279
- type QueryResult<T> = ({
521
+ type QueryResult<T$1> = ({
280
522
  success: true;
281
- } & QuerySuccessValue<T>) | {
523
+ } & QuerySuccessValue<T$1>) | {
282
524
  success: false;
283
525
  error: ContractError;
284
526
  };
@@ -306,7 +548,7 @@ interface ContractStorage {
306
548
  /**
307
549
  * Type helper to extract message args type
308
550
  */
309
- type MessageArgs<M$1 extends InkCallableDescriptor, K extends keyof M$1> = M$1[K]["message"];
551
+ type MessageArgs<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> = M$1[K$1]["message"];
310
552
  /**
311
553
  * ink! LangError type pattern
312
554
  * papi generates LangError variants with { type: string; value?: unknown }
@@ -319,9 +561,9 @@ type InkLangError = {
319
561
  * ink! MessageResult type pattern (Result<T, LangError>)
320
562
  * papi generates this as { success: true; value: T } | { success: false; value: LangError }
321
563
  */
322
- type InkMessageResult<T> = {
564
+ type InkMessageResult<T$1> = {
323
565
  success: true;
324
- value: T;
566
+ value: T$1;
325
567
  } | {
326
568
  success: false;
327
569
  value: unknown;
@@ -331,15 +573,18 @@ type InkMessageResult<T> = {
331
573
  * 1. Extract T from { success: true; value: T } | { success: false; value: ... }
332
574
  * 2. Exclude LangError variants from T
333
575
  */
334
- type UnwrapMessageResult<T> = T extends InkMessageResult<infer U> ? Exclude<U, InkLangError> : T;
576
+ type UnwrapMessageResult<T$1> = T$1 extends InkMessageResult<infer U> ? Exclude<U, InkLangError> : T$1;
335
577
  /**
336
578
  * Type helper to extract message response type (with MessageResult unwrapped)
337
579
  */
338
- type MessageResponse<M$1 extends InkCallableDescriptor, K extends keyof M$1> = UnwrapMessageResult<M$1[K]["response"]>;
580
+ type MessageResponse<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> = UnwrapMessageResult<M$1[K$1]["response"]>;
339
581
  /**
340
582
  * D9 Ink Contract interface
583
+ *
584
+ * @typeParam M - The callable descriptor type (message definitions)
585
+ * @typeParam E - The event type for type-safe event filtering
341
586
  */
342
- interface D9InkContract<M$1 extends InkCallableDescriptor> {
587
+ interface D9InkContract<M$1 extends InkCallableDescriptor, E extends Event = Event> {
343
588
  /** Contract address */
344
589
  readonly address: SS58String;
345
590
  /** Contract metadata */
@@ -349,26 +594,82 @@ interface D9InkContract<M$1 extends InkCallableDescriptor> {
349
594
  * @param method - The message label (e.g., "PSP22::balance_of")
350
595
  * @param options - Query options including origin and args
351
596
  */
352
- query<K extends keyof M$1 & string>(method: K, options: QueryOptions<MessageArgs<M$1, K>>): Promise<QueryResult<MessageResponse<M$1, K>>>;
597
+ query<K$1 extends keyof M$1 & string>(method: K$1, options: QueryOptions<MessageArgs<M$1, K$1>>): Promise<QueryResult<MessageResponse<M$1, K$1>>>;
353
598
  /**
354
599
  * Create a sendable transaction for a contract message
355
600
  * @param method - The message label (e.g., "PSP22::transfer")
356
601
  * @param options - Send options including origin and args
357
602
  */
358
- send<K extends keyof M$1 & string>(method: K, options: SendOptions<MessageArgs<M$1, K>>): SendableTransaction<MessageResponse<M$1, K>>;
603
+ send<K$1 extends keyof M$1 & string>(method: K$1, options: SendOptions<MessageArgs<M$1, K$1>>): SendableTransaction<MessageResponse<M$1, K$1>>;
359
604
  /**
360
605
  * Get storage query interface
361
606
  */
362
607
  getStorage(): ContractStorage;
363
608
  /**
364
609
  * Filter events from a transaction result to only include this contract's events
610
+ * Returns type-safe events that can be narrowed using `event.type`
611
+ *
612
+ * @example
613
+ * ```ts
614
+ * const events = contract.filterEvents(txResult.events);
615
+ * for (const event of events) {
616
+ * if (event.type === "Transfer") {
617
+ * console.log(event.value.from, event.value.to, event.value.value);
618
+ * }
619
+ * }
620
+ * ```
365
621
  */
366
- filterEvents(events: unknown[]): DecodedContractEvent[];
622
+ filterEvents(events: unknown[]): TypedContractEvent<E>[];
367
623
  /**
368
624
  * Subscribe to contract events as an RxJS Observable
369
625
  * @param options - Event subscription options (event labels to filter, etc.)
370
626
  */
371
- subscribeToEvents(options?: Omit<EventSubscriptionOptions, "contractAddress">): Observable<DecodedContractEvent>;
627
+ subscribeToEvents(options?: Omit<EventSubscriptionOptions, "contractAddress">): Observable<TypedContractEvent<E>>;
628
+ /**
629
+ * Get a type-safe message builder for a specific message
630
+ *
631
+ * Provides a polkadot-api compatible API for encoding and decoding
632
+ * contract messages with full TypeScript type inference.
633
+ *
634
+ * @param label - The message label (e.g., "PSP22::transfer")
635
+ * @returns Typed message interface with encode/decode methods
636
+ *
637
+ * @example
638
+ * ```ts
639
+ * const transfer = contract.message("PSP22::transfer");
640
+ *
641
+ * // Encode with full type checking on args
642
+ * const encoded = transfer.encode({
643
+ * to: recipientAddress,
644
+ * value: 1000000n,
645
+ * data: new Uint8Array(),
646
+ * });
647
+ *
648
+ * // Decode response with full type inference
649
+ * const decoded = transfer.decode(responseBytes);
650
+ * ```
651
+ */
652
+ message<L extends ExtractMessageLabels<M$1>>(label: L): TypedMessage<M$1, L>;
653
+ /**
654
+ * Filter events by specific type with proper type narrowing
655
+ *
656
+ * @param events - Array of chain events to filter
657
+ * @param label - The event label to filter by
658
+ * @returns Array of events narrowed to the specific type
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * const transfers = contract.filterEventsByType(txResult.events, "Transfer");
663
+ *
664
+ * for (const t of transfers) {
665
+ * // t.value is fully typed as Transfer event data
666
+ * console.log(t.value.from, "->", t.value.to, ":", t.value.value);
667
+ * }
668
+ * ```
669
+ */
670
+ filterEventsByType<L extends string>(events: unknown[], label: L): Array<TypedContractEvent<E> & {
671
+ type: L;
672
+ }>;
372
673
  }
373
674
  /**
374
675
  * D9 Ink SDK options
@@ -388,9 +689,12 @@ interface D9InkSdk {
388
689
  * @param descriptor - The contract descriptor from @polkadot-api/descriptors
389
690
  * @param address - The contract address (SS58 format)
390
691
  */
391
- getContract<S extends InkStorageDescriptor, M$1 extends InkCallableDescriptor, C extends InkCallableDescriptor, E extends Event>(descriptor: InkDescriptors<S, M$1, C, E>, address: SS58String): D9InkContract<M$1>;
692
+ getContract<S extends InkStorageDescriptor, M$1 extends InkCallableDescriptor, C extends InkCallableDescriptor, E extends Event>(descriptor: InkDescriptors<S, M$1, C, E>, address: SS58String): D9InkContract<M$1, E>;
392
693
  }
393
- type D9InkContractFromDescriptor<D> = D extends InkDescriptors<infer _S, infer M, infer _C, infer _E> ? D9InkContract<M> : never;
694
+ /**
695
+ * Type helper to extract D9InkContract type from an InkDescriptors
696
+ */
697
+ type D9InkContractFromDescriptor<D> = D extends InkDescriptors<infer _S, infer M, infer _C, infer E> ? D9InkContract<M, E extends Event ? E : Event> : never;
394
698
  /**
395
699
  * Internal options for contract creation
396
700
  */
@@ -403,7 +707,149 @@ interface CreateContractOptions {
403
707
  /**
404
708
  * Type helper to infer the Messages type from an InkDescriptors
405
709
  */
406
- type InferMessages<D> = D extends InkDescriptors<InkStorageDescriptor, infer M, InkCallableDescriptor, Event> ? M : never;
710
+ type InferMessages<D> = D extends InkDescriptors<InkStorageDescriptor, infer M, InkCallableDescriptor, any> ? M : never;
711
+ /**
712
+ * Type helper to infer the Events type from an InkDescriptors
713
+ */
714
+ type InferEvents<D> = D extends InkDescriptors<InkStorageDescriptor, InkCallableDescriptor, InkCallableDescriptor, infer E> ? E extends Event ? E : never : never;
715
+ //#endregion
716
+ //#region src/rpc-types.d.ts
717
+ /**
718
+ * Block header structure
719
+ */
720
+ interface BlockHeader {
721
+ parentHash: HexString;
722
+ number: HexString;
723
+ stateRoot: HexString;
724
+ extrinsicsRoot: HexString;
725
+ digest: {
726
+ logs: HexString[];
727
+ };
728
+ }
729
+ /**
730
+ * System health information
731
+ */
732
+ interface SystemHealth {
733
+ peers: number;
734
+ isSyncing: boolean;
735
+ shouldHavePeers: boolean;
736
+ }
737
+ /**
738
+ * Runtime version information
739
+ */
740
+ interface RuntimeVersion {
741
+ specName: string;
742
+ implName: string;
743
+ authoringVersion: number;
744
+ specVersion: number;
745
+ implVersion: number;
746
+ apis: [HexString, number][];
747
+ transactionVersion: number;
748
+ stateVersion: number;
749
+ }
750
+ /**
751
+ * Storage change set
752
+ */
753
+ interface StorageChangeSet {
754
+ block: HexString;
755
+ changes: [HexString, HexString | null][];
756
+ }
757
+ /**
758
+ * RPC method signatures: method name -> [params tuple, return type]
759
+ *
760
+ * This interface maps known Substrate RPC methods to their parameter and return types.
761
+ * Methods not in this list will fall back to unknown types.
762
+ */
763
+ interface SubstrateRpcMethods {
764
+ chain_getBlockHash: [[blockNumber?: number], HexString | null];
765
+ chain_getHeader: [[hash?: HexString], BlockHeader | null];
766
+ chain_getBlock: [[hash?: HexString], {
767
+ block: {
768
+ header: BlockHeader;
769
+ extrinsics: HexString[];
770
+ };
771
+ justifications: unknown;
772
+ } | null];
773
+ chain_getFinalizedHead: [[], HexString];
774
+ state_call: [[method: string, data: HexString, at?: HexString], HexString];
775
+ state_getStorage: [[key: HexString, at?: HexString], HexString | null];
776
+ state_getStorageAt: [[key: HexString, at: HexString], HexString | null];
777
+ state_getStorageHash: [[key: HexString, at?: HexString], HexString | null];
778
+ state_getStorageSize: [[key: HexString, at?: HexString], number | null];
779
+ state_getMetadata: [[at?: HexString], HexString];
780
+ state_getRuntimeVersion: [[at?: HexString], RuntimeVersion];
781
+ state_queryStorageAt: [[keys: HexString[], at?: HexString], StorageChangeSet[]];
782
+ system_chain: [[], string];
783
+ system_name: [[], string];
784
+ system_version: [[], string];
785
+ system_health: [[], SystemHealth];
786
+ system_properties: [[], Record<string, unknown>];
787
+ system_peers: [[], {
788
+ peerId: string;
789
+ roles: string;
790
+ bestHash: HexString;
791
+ bestNumber: number;
792
+ }[]];
793
+ system_chainType: [[], string];
794
+ author_submitExtrinsic: [[extrinsic: HexString], HexString];
795
+ author_pendingExtrinsics: [[], HexString[]];
796
+ author_removeExtrinsic: [[bytesOrHash: (HexString | {
797
+ Hash: HexString;
798
+ })[]], number];
799
+ payment_queryInfo: [[extrinsic: HexString, at?: HexString], {
800
+ weight: {
801
+ refTime: number;
802
+ proofSize: number;
803
+ };
804
+ class: string;
805
+ partialFee: string;
806
+ }];
807
+ payment_queryFeeDetails: [[extrinsic: HexString, at?: HexString], {
808
+ inclusionFee: {
809
+ baseFee: string;
810
+ lenFee: string;
811
+ adjustedWeightFee: string;
812
+ } | null;
813
+ }];
814
+ }
815
+ /**
816
+ * Known RPC method names (for autocomplete)
817
+ */
818
+ type KnownRpcMethod = keyof SubstrateRpcMethods;
819
+ /**
820
+ * Extract parameter types for a known RPC method
821
+ */
822
+ type RpcParams<M$1 extends KnownRpcMethod> = SubstrateRpcMethods[M$1][0];
823
+ /**
824
+ * Extract return type for a known RPC method
825
+ */
826
+ type RpcReturn<M$1 extends KnownRpcMethod> = SubstrateRpcMethods[M$1][1];
827
+ /**
828
+ * Type-safe RPC request interface
829
+ *
830
+ * Provides full type inference for known RPC methods while allowing
831
+ * arbitrary method calls with explicit type parameters.
832
+ *
833
+ * @example
834
+ * ```ts
835
+ * // Known method: types are inferred
836
+ * const hash = await rpc("chain_getBlockHash", [12345]);
837
+ * // hash: HexString | null
838
+ *
839
+ * // Unknown method: provide explicit types
840
+ * const result = await rpc<MyType>("custom_method", [arg1, arg2]);
841
+ * ```
842
+ */
843
+ interface TypedRpcRequest {
844
+ /**
845
+ * Call a known RPC method with full type inference
846
+ */
847
+ <M$1 extends KnownRpcMethod>(method: M$1, params: RpcParams<M$1>): Promise<RpcReturn<M$1>>;
848
+ /**
849
+ * Call an unknown RPC method with explicit type parameters
850
+ */
851
+ <Reply = unknown, Params extends unknown[] = unknown[]>(method: string, params: Params): Promise<Reply>;
852
+ }
407
853
  //#endregion
408
854
  //#region src/sdk.d.ts
409
855
  /**
@@ -416,6 +862,28 @@ interface CreateD9InkSdkOptions extends D9InkSdkOptions {
416
862
  */
417
863
  typedApi?: unknown;
418
864
  }
865
+ /**
866
+ * Extended D9 Ink SDK interface with typed RPC access
867
+ */
868
+ interface D9InkSdkWithRpc extends D9InkSdk {
869
+ /**
870
+ * Type-safe RPC request function
871
+ *
872
+ * Provides autocomplete for known Substrate RPC methods and type inference
873
+ * for parameters and return values.
874
+ *
875
+ * @example
876
+ * ```ts
877
+ * // Known method with full type inference
878
+ * const hash = await sdk.rpc("chain_getBlockHash", [12345]);
879
+ * // hash: HexString | null
880
+ *
881
+ * // Custom method with explicit types
882
+ * const custom = await sdk.rpc<MyType>("custom_method", [arg]);
883
+ * ```
884
+ */
885
+ rpc: TypedRpcRequest;
886
+ }
419
887
  /**
420
888
  * Create a D9 Ink SDK instance.
421
889
  *
@@ -457,15 +925,15 @@ interface CreateD9InkSdkOptions extends D9InkSdkOptions {
457
925
  *
458
926
  * @param client - The PolkadotClient instance
459
927
  * @param options - Optional SDK configuration
460
- * @returns D9 Ink SDK instance
928
+ * @returns D9 Ink SDK instance with typed RPC access
461
929
  */
462
- declare function createD9InkSdk(client: PolkadotClient, options?: CreateD9InkSdkOptions): D9InkSdk;
930
+ declare function createD9InkSdk(client: PolkadotClient, options?: CreateD9InkSdkOptions): D9InkSdkWithRpc;
463
931
  //#endregion
464
932
  //#region src/contract.d.ts
465
933
  /**
466
934
  * Create a D9 Ink Contract instance
467
935
  */
468
- declare function createD9InkContract<S extends InkStorageDescriptor, M$1 extends InkCallableDescriptor, C extends InkCallableDescriptor, E extends Event>(descriptor: InkDescriptors<S, M$1, C, E>, address: SS58String, options: CreateContractOptions): D9InkContract<M$1>;
936
+ declare function createD9InkContract<S extends InkStorageDescriptor, M$1 extends InkCallableDescriptor, C extends InkCallableDescriptor, E extends Event>(descriptor: InkDescriptors<S, M$1, C, E>, address: SS58String, options: CreateContractOptions): D9InkContract<M$1, E>;
469
937
  //#endregion
470
938
  //#region src/encode.d.ts
471
939
  /**
@@ -603,7 +1071,7 @@ declare function isLangError(data: Uint8Array): boolean;
603
1071
  * @param codec - The SCALE codec for the inner value type T
604
1072
  * @returns The decoded value
605
1073
  */
606
- declare function decodeInkValue<T>(data: Uint8Array, codec: Codec<T>): T;
1074
+ declare function decodeInkValue<T$1>(data: Uint8Array, codec: Codec<T$1>): T$1;
607
1075
  /**
608
1076
  * Pre-defined codecs for common types
609
1077
  */
@@ -666,24 +1134,65 @@ declare function getEventSignature(eventLabel: string): Uint8Array;
666
1134
  //#endregion
667
1135
  //#region src/events.d.ts
668
1136
  /**
669
- * Event parser for a specific contract
1137
+ * Type-safe event parser for a specific contract
1138
+ *
1139
+ * @typeParam S - The storage descriptor type
1140
+ * @typeParam M - The messages descriptor type
1141
+ * @typeParam C - The constructors descriptor type
1142
+ * @typeParam E - The event type representing all possible events for this contract
670
1143
  */
671
- declare class ContractEventParser {
1144
+ declare class ContractEventParser<S extends InkStorageDescriptor = InkStorageDescriptor, M$1 extends InkCallableDescriptor = InkCallableDescriptor, C extends InkCallableDescriptor = InkCallableDescriptor, E extends Event = Event> {
672
1145
  private eventDecoders;
673
1146
  private eventSignatures;
674
1147
  private contractAddressBytes;
675
1148
  private contractAddress;
676
1149
  private metadata;
677
- constructor(metadata: InkMetadata, contractAddress: SS58String);
1150
+ constructor(descriptor: InkDescriptors<S, M$1, C, E>, contractAddress: SS58String);
678
1151
  /**
679
- * Parse a raw chain event into a contract event (if it matches)
1152
+ * Parse a raw chain event into a type-safe contract event (if it matches)
680
1153
  * Returns null if the event is not from this contract or cannot be parsed
1154
+ *
1155
+ * @example
1156
+ * ```ts
1157
+ * const event = parser.parseEvent(chainEvent);
1158
+ * if (event?.type === "Transfer") {
1159
+ * // event.value is now typed as { from: SS58String; to: SS58String; value: bigint }
1160
+ * console.log(event.value.from);
1161
+ * }
1162
+ * ```
681
1163
  */
682
- parseEvent(chainEvent: unknown): DecodedContractEvent | null;
1164
+ parseEvent(chainEvent: unknown): TypedContractEvent<E> | null;
683
1165
  /**
684
- * Filter a batch of events
1166
+ * Filter a batch of events and return type-safe results
1167
+ *
1168
+ * @param chainEvents - Array of chain events to filter
1169
+ * @param options - Optional filter criteria
1170
+ * @returns Array of type-safe contract events
685
1171
  */
686
- filterEvents(chainEvents: unknown[], options?: EventFilterOptions): DecodedContractEvent[];
1172
+ filterEvents(chainEvents: unknown[], options?: EventFilterOptions): TypedContractEvent<E>[];
1173
+ /**
1174
+ * Filter events by specific type with proper type narrowing
1175
+ *
1176
+ * This method provides better type safety than filterEvents with eventLabels
1177
+ * because TypeScript can narrow the return type to only the specified event type.
1178
+ *
1179
+ * @param chainEvents - Array of chain events to filter
1180
+ * @param label - The event label to filter by
1181
+ * @returns Array of events narrowed to the specific type
1182
+ *
1183
+ * @example
1184
+ * ```ts
1185
+ * const transfers = parser.filterByType(events, "Transfer");
1186
+ *
1187
+ * for (const t of transfers) {
1188
+ * // t.value is fully typed as Transfer event data
1189
+ * console.log(t.value.from, "->", t.value.to, ":", t.value.value);
1190
+ * }
1191
+ * ```
1192
+ */
1193
+ filterByType<L extends string>(chainEvents: unknown[], label: L): Array<TypedContractEvent<E> & {
1194
+ type: L;
1195
+ }>;
687
1196
  /**
688
1197
  * Get the contract address as SS58 string
689
1198
  */
@@ -702,32 +1211,75 @@ declare class ContractEventParser {
702
1211
  */
703
1212
  private static buildEventSignatureMap;
704
1213
  }
1214
+ /**
1215
+ * Type guard for narrowing event types
1216
+ *
1217
+ * Use this function when you have a `TypedContractEvent` and need to
1218
+ * narrow it to a specific event type. This is useful when the type
1219
+ * information is lost (e.g., after serialization or in generic functions).
1220
+ *
1221
+ * @typeParam E - The Enum type representing all possible events
1222
+ * @typeParam L - The specific event label to check
1223
+ * @param event - The event to check
1224
+ * @param label - The event label to match
1225
+ * @returns True if the event type matches the label
1226
+ *
1227
+ * @example
1228
+ * ```ts
1229
+ * const event = parser.parseEvent(chainEvent);
1230
+ *
1231
+ * if (event && isEventType(event, "Transfer")) {
1232
+ * // TypeScript knows event.value is Transfer event data
1233
+ * console.log(event.value.from);
1234
+ * console.log(event.value.to);
1235
+ * console.log(event.value.value);
1236
+ * }
1237
+ * ```
1238
+ */
1239
+ declare function isEventType<E extends Event, L extends ExtractEventLabels<E>>(event: TypedContractEvent<E>, label: L): event is Extract<TypedContractEvent<E>, {
1240
+ type: L;
1241
+ }>;
705
1242
  //#endregion
706
1243
  //#region src/subscriptions.d.ts
707
1244
  /**
708
1245
  * Create an observable stream of contract events
709
1246
  *
710
1247
  * @param client - Polkadot API client
711
- * @param metadata - Contract metadata
1248
+ * @param descriptor - Contract descriptor
712
1249
  * @param options - Subscription options
713
- * @returns Observable stream of decoded contract events
1250
+ * @returns Observable stream of type-safe contract events
714
1251
  */
715
- declare function createContractEventStream(client: PolkadotClient, metadata: InkMetadata, options: EventSubscriptionOptions): Observable<DecodedContractEvent>;
1252
+ declare function createContractEventStream<S extends InkStorageDescriptor = InkStorageDescriptor, M$1 extends InkCallableDescriptor = InkCallableDescriptor, C extends InkCallableDescriptor = InkCallableDescriptor, E extends Event = Event>(client: PolkadotClient, descriptor: InkDescriptors<S, M$1, C, E>, options: EventSubscriptionOptions): Observable<TypedContractEvent<E>>;
1253
+ /**
1254
+ * PSP22 Transfer event type
1255
+ */
1256
+ interface PSP22TransferEvent {
1257
+ type: "Transfer";
1258
+ value: {
1259
+ from?: SS58String | null;
1260
+ to?: SS58String | null;
1261
+ value: bigint;
1262
+ };
1263
+ raw: {
1264
+ blockNumber: number;
1265
+ blockHash: string;
1266
+ eventIndex: number;
1267
+ contractAddress: SS58String;
1268
+ data: Uint8Array;
1269
+ topics: Uint8Array[];
1270
+ };
1271
+ }
716
1272
  /**
717
1273
  * Convenience helper to create a Transfer event stream for PSP22 tokens
718
1274
  *
719
1275
  * @param client - Polkadot API client
720
- * @param metadata - PSP22 contract metadata
1276
+ * @param descriptor - PSP22 contract descriptor
721
1277
  * @param contractAddress - PSP22 contract address
722
1278
  * @param getEvents - Function to fetch System.Events at a block hash
723
1279
  * @param watchAddress - Optional address to filter transfers (only events involving this address)
724
1280
  * @returns Observable stream of Transfer events
725
1281
  */
726
- declare function createPSP22TransferStream(client: PolkadotClient, metadata: InkMetadata, contractAddress: SS58String, getEvents: (blockHash: string) => Promise<unknown[]>, watchAddress?: SS58String): Observable<DecodedContractEvent<{
727
- from?: SS58String | null;
728
- to?: SS58String | null;
729
- value: bigint;
730
- }>>;
1282
+ declare function createPSP22TransferStream<S extends InkStorageDescriptor = InkStorageDescriptor, M$1 extends InkCallableDescriptor = InkCallableDescriptor, C extends InkCallableDescriptor = InkCallableDescriptor, E extends Event = Event>(client: PolkadotClient, descriptor: InkDescriptors<S, M$1, C, E>, contractAddress: SS58String, getEvents: (blockHash: string) => Promise<unknown[]>, watchAddress?: SS58String): Observable<PSP22TransferEvent>;
731
1283
  /**
732
1284
  * Create a native token (D9) transfer event stream
733
1285
  *
@@ -746,5 +1298,135 @@ declare function createNativeTransferStream(client: PolkadotClient, getEvents: (
746
1298
  blockHash: string;
747
1299
  }>;
748
1300
  //#endregion
749
- export { AbortedError, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, DecodeError, type DecodedContractEvent, EncodeError, type EventFilterOptions, type EventSubscriptionOptions, type GasInfo, type InferMessages, InkCodecs, LangError, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractEvent, type ResponseDecoder, type SendOptions, type SendableTransaction, SignerError, type StorageDepositInfo, TimeoutError, TransactionError, type TxResult, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createNativeTransferStream, createPSP22TransferStream, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, getEventSignature, isContractError, isErrorType, isLangError, unwrapInkResult };
1301
+ //#region src/calls.d.ts
1302
+ /**
1303
+ * Type-safe call parser for a specific contract
1304
+ *
1305
+ * @typeParam S - The storage descriptor type
1306
+ * @typeParam M - The InkCallableDescriptor type (message definitions)
1307
+ * @typeParam C - The constructors descriptor type
1308
+ * @typeParam E - The events Enum type
1309
+ */
1310
+ declare class ContractCallParser<S extends InkStorageDescriptor = InkStorageDescriptor, M$1 extends InkCallableDescriptor = InkCallableDescriptor, C extends InkCallableDescriptor = InkCallableDescriptor, E extends Event = Event> {
1311
+ private messageDecoders;
1312
+ private selectorToLabel;
1313
+ private metadata;
1314
+ constructor(descriptor: InkDescriptors<S, M$1, C, E>);
1315
+ /**
1316
+ * Parse raw call data into a type-safe contract call
1317
+ *
1318
+ * @param callData - The raw call data (selector + encoded args) or RawContractCall
1319
+ * @returns Parsed call or null if cannot parse
1320
+ *
1321
+ * @example
1322
+ * ```ts
1323
+ * const call = parser.parseCall(callData);
1324
+ * if (call?.type === "PSP22::transfer") {
1325
+ * // call.args is typed as { to: SS58String; value: bigint; data: Uint8Array }
1326
+ * console.log(call.args.to);
1327
+ * }
1328
+ * ```
1329
+ */
1330
+ parseCall(callData: Uint8Array | RawContractCall): TypedContractCall<M$1> | null;
1331
+ /**
1332
+ * Parse multiple calls and optionally filter by message labels
1333
+ *
1334
+ * @param calls - Array of raw call data
1335
+ * @param options - Filter options
1336
+ * @returns Array of parsed calls
1337
+ */
1338
+ parseCalls(calls: Array<Uint8Array | RawContractCall>, options?: CallFilterOptions): TypedContractCall<M$1>[];
1339
+ /**
1340
+ * Filter calls by specific type with proper type narrowing
1341
+ *
1342
+ * This method provides better type safety than parseCalls with messageLabels
1343
+ * because TypeScript can narrow the return type to only the specified call type.
1344
+ *
1345
+ * @param calls - Array of raw call data
1346
+ * @param label - The message label to filter by
1347
+ * @returns Array of calls narrowed to the specific type
1348
+ *
1349
+ * @example
1350
+ * ```ts
1351
+ * const transfers = parser.filterByType(callDataArray, "PSP22::transfer");
1352
+ *
1353
+ * for (const t of transfers) {
1354
+ * // t.args is fully typed as PSP22::transfer args
1355
+ * console.log(t.args.to, t.args.value);
1356
+ * }
1357
+ * ```
1358
+ */
1359
+ filterByType<L extends string>(calls: Array<Uint8Array | RawContractCall>, label: L): Array<TypedContractCall<M$1> & {
1360
+ type: L;
1361
+ }>;
1362
+ /**
1363
+ * Get information about a message by label
1364
+ */
1365
+ getMessageInfo(label: string): MessageInfo | null;
1366
+ /**
1367
+ * Get all available message labels
1368
+ */
1369
+ getMessageLabels(): string[];
1370
+ /**
1371
+ * Check if a selector matches a specific message
1372
+ */
1373
+ matchesMessage(selector: Uint8Array, label: string): boolean;
1374
+ }
1375
+ /**
1376
+ * Type guard for narrowing call types
1377
+ *
1378
+ * Use this function when you have a `TypedContractCall` and need to
1379
+ * narrow it to a specific call type. This is useful when the type
1380
+ * information is lost (e.g., after serialization or in generic functions).
1381
+ *
1382
+ * @typeParam M - The InkCallableDescriptor type (message definitions)
1383
+ * @typeParam L - The specific message label to check
1384
+ * @param call - The call to check
1385
+ * @param label - The message label to match
1386
+ * @returns True if the call type matches the label
1387
+ *
1388
+ * @example
1389
+ * ```ts
1390
+ * const call = parser.parseCall(callData);
1391
+ *
1392
+ * if (call && isCallType(call, "PSP22::transfer")) {
1393
+ * // TypeScript knows call.args is transfer args
1394
+ * console.log(call.args.to);
1395
+ * console.log(call.args.value);
1396
+ * }
1397
+ * ```
1398
+ */
1399
+ declare function isCallType<M$1 extends InkCallableDescriptor, L extends ExtractMessageLabels<M$1>>(call: TypedContractCall<M$1>, label: L): call is Extract<TypedContractCall<M$1>, {
1400
+ type: L;
1401
+ }>;
1402
+ //#endregion
1403
+ //#region src/rpc.d.ts
1404
+ /**
1405
+ * Create a type-safe RPC request function from a PolkadotClient
1406
+ *
1407
+ * This wraps the client's `_request` method with proper TypeScript types,
1408
+ * providing autocomplete for known RPC methods and type inference for
1409
+ * parameters and return values.
1410
+ *
1411
+ * @param client - The PolkadotClient instance
1412
+ * @returns A type-safe RPC request function
1413
+ *
1414
+ * @example
1415
+ * ```ts
1416
+ * const rpc = createTypedRpc(client);
1417
+ *
1418
+ * // Autocomplete for method names, typed params and return
1419
+ * const hash = await rpc("chain_getBlockHash", [12345]);
1420
+ * // hash: HexString | null
1421
+ *
1422
+ * const header = await rpc("chain_getHeader", [hash]);
1423
+ * // header: BlockHeader | null
1424
+ *
1425
+ * // Custom methods still work with explicit types
1426
+ * const custom = await rpc<MyType>("my_custom_method", [arg]);
1427
+ * ```
1428
+ */
1429
+ declare function createTypedRpc(client: PolkadotClient): TypedRpcRequest;
1430
+ //#endregion
1431
+ export { AbortedError, type BlockHeader, type CallFilterOptions, ContractCallParser, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractMessageBuilder, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, type D9InkSdkWithRpc, DecodeError, type DecodedContractEvent, EncodeError, type EventFilterOptions, type EventSubscriptionOptions, type ExtractEnumDef, type ExtractEventLabels, type ExtractMessageLabels, type GasInfo, type InferEvents, type InferMessages, InkCodecs, type KnownRpcMethod, LangError, type MessageAttributes, type MessageInfo, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractCall, type RawContractEvent, type ResponseDecoder, type RpcParams, type RpcReturn, type RuntimeVersion, type SendOptions, type SendableTransaction, SignerError, type StorageChangeSet, type StorageDepositInfo, type SubstrateRpcMethods, type SystemHealth, TimeoutError, TransactionError, type TxResult, type TypedCallFilterOptions, type TypedContractCall, type TypedContractEvent, type TypedEventFilterOptions, type TypedMessage, type TypedRpcRequest, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
750
1432
  //# sourceMappingURL=index.d.mts.map