@dedot/api 0.15.2 → 0.16.0

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.
Files changed (49) hide show
  1. package/chaintypes/substrate/index.d.ts +21 -1
  2. package/cjs/client/BaseSubstrateClient.js +12 -3
  3. package/cjs/client/DedotClient.js +51 -11
  4. package/cjs/client/LegacyClient.js +4 -5
  5. package/cjs/executor/Executor.js +1 -0
  6. package/cjs/executor/v2/StorageQueryExecutorV2.js +1 -3
  7. package/cjs/executor/v2/TxExecutorV2.js +5 -3
  8. package/cjs/json-rpc/group/Archive.js +232 -0
  9. package/cjs/json-rpc/group/ChainHead/ChainHead.js +149 -52
  10. package/cjs/json-rpc/group/ChainHead/error.js +5 -0
  11. package/cjs/json-rpc/group/index.js +1 -0
  12. package/cjs/json-rpc/subscriptionsInfo.js +4 -0
  13. package/cjs/storage/LegacyStorageQuery.js +5 -0
  14. package/cjs/storage/NewStorageQuery.js +5 -0
  15. package/client/BaseSubstrateClient.d.ts +8 -6
  16. package/client/BaseSubstrateClient.js +13 -4
  17. package/client/DedotClient.d.ts +11 -4
  18. package/client/DedotClient.js +54 -14
  19. package/client/LegacyClient.d.ts +2 -2
  20. package/client/LegacyClient.js +4 -5
  21. package/executor/Executor.d.ts +5 -5
  22. package/executor/Executor.js +1 -0
  23. package/executor/StorageQueryExecutor.d.ts +2 -2
  24. package/executor/v2/RuntimeApiExecutorV2.d.ts +2 -2
  25. package/executor/v2/StorageQueryExecutorV2.d.ts +4 -4
  26. package/executor/v2/StorageQueryExecutorV2.js +1 -3
  27. package/executor/v2/TxExecutorV2.d.ts +2 -1
  28. package/executor/v2/TxExecutorV2.js +5 -3
  29. package/executor/v2/ViewFunctionExecutorV2.d.ts +2 -2
  30. package/extrinsic/extensions/SignedExtension.d.ts +3 -3
  31. package/extrinsic/submittable/BaseSubmittableExtrinsic.d.ts +2 -2
  32. package/extrinsic/submittable/SubmittableExtrinsicV2.d.ts +2 -2
  33. package/json-rpc/group/Archive.d.ts +134 -0
  34. package/json-rpc/group/Archive.js +228 -0
  35. package/json-rpc/group/ChainHead/ChainHead.d.ts +21 -0
  36. package/json-rpc/group/ChainHead/ChainHead.js +150 -53
  37. package/json-rpc/group/ChainHead/error.d.ts +3 -0
  38. package/json-rpc/group/ChainHead/error.js +5 -0
  39. package/json-rpc/group/index.d.ts +1 -0
  40. package/json-rpc/group/index.js +1 -0
  41. package/json-rpc/subscriptionsInfo.js +4 -0
  42. package/package.json +9 -9
  43. package/storage/BaseStorageQuery.d.ts +5 -6
  44. package/storage/LegacyStorageQuery.d.ts +4 -3
  45. package/storage/LegacyStorageQuery.js +5 -0
  46. package/storage/NewStorageQuery.d.ts +4 -3
  47. package/storage/NewStorageQuery.js +5 -0
  48. package/storage/QueryableStorage.d.ts +2 -2
  49. package/types.d.ts +11 -6
@@ -1,9 +1,11 @@
1
1
  import { $Header } from '@dedot/codecs';
2
- import { assert, AsyncQueue, deferred, ensurePresence, noop, ThrottleQueue, waitFor, } from '@dedot/utils';
2
+ import { assert, AsyncQueue, deferred, ensurePresence, noop, ThrottleQueue, waitFor, LRUCache, } from '@dedot/utils';
3
3
  import { JsonRpcGroup } from '../JsonRpcGroup.js';
4
4
  import { BlockUsage } from './BlockUsage.js';
5
5
  import { ChainHeadBlockNotPinnedError, ChainHeadBlockPrunedError, ChainHeadError, ChainHeadLimitReachedError, ChainHeadOperationError, ChainHeadOperationInaccessibleError, ChainHeadStopError, RetryStrategy, } from './error.js';
6
6
  export const MIN_FINALIZED_QUEUE_SIZE = 10; // finalized queue size
7
+ const CHAINHEAD_CACHE_CAPACITY = 256;
8
+ const CHAINHEAD_CACHE_TTL = 30_000; // 30 seconds
7
9
  export class ChainHead extends JsonRpcGroup {
8
10
  #unsub;
9
11
  #subscriptionId;
@@ -20,6 +22,17 @@ export class ChainHead extends JsonRpcGroup {
20
22
  #blockUsage;
21
23
  #cache;
22
24
  #operationQueue;
25
+ /**
26
+ * Archive instance used as fallback when ChainHead blocks are not pinned.
27
+ *
28
+ * When ChainHead operations fail with ChainHeadBlockNotPinnedError, the system
29
+ * automatically attempts the same operation using the Archive API. This provides
30
+ * seamless access to historical blockchain data even when blocks are no longer
31
+ * maintained in the ChainHead's pinned block set.
32
+ *
33
+ * @private
34
+ */
35
+ #archive;
23
36
  constructor(client, options) {
24
37
  super(client, { prefix: 'chainHead', supportedVersions: ['unstable', 'v1'], ...options });
25
38
  this.#handlers = {};
@@ -29,10 +42,22 @@ export class ChainHead extends JsonRpcGroup {
29
42
  this.#followResponseQueue = new AsyncQueue();
30
43
  this.#retryQueue = new AsyncQueue();
31
44
  this.#blockUsage = new BlockUsage();
32
- this.#cache = new Map();
45
+ this.#cache = new LRUCache(CHAINHEAD_CACHE_CAPACITY, CHAINHEAD_CACHE_TTL);
33
46
  // This helps us to not accidentally putting too much stress on the JSON-RPC server, especially smoldot/light-client
34
47
  this.#operationQueue = new ThrottleQueue(this.#__unsafe__isSmoldot() ? 25 : 250);
35
48
  }
49
+ /**
50
+ * Attach an Archive instance as fallback for operations that fail due to unpinned blocks.
51
+ * When a ChainHeadBlockNotPinnedError occurs, the operation will automatically fallback
52
+ * to the Archive API to attempt to retrieve the data from historical blocks.
53
+ *
54
+ * @param archive - Archive instance to use as fallback
55
+ * @returns this ChainHead instance for method chaining
56
+ */
57
+ withArchive(archive) {
58
+ this.#archive = archive;
59
+ return this;
60
+ }
36
61
  async runtimeVersion() {
37
62
  await this.#ensureFollowed();
38
63
  return this.#finalizedRuntime;
@@ -219,8 +244,9 @@ export class ChainHead extends JsonRpcGroup {
219
244
  if (!this.isPinned(hash))
220
245
  return;
221
246
  delete this.#pinnedBlocks[hash];
222
- // clear cache
223
- Array.from(this.#cache.keys())
247
+ // Clear cache entries related to the pruned block
248
+ // Filter and remove only cache entries for this specific block
249
+ this.#cache.keys()
224
250
  .filter((key) => key.startsWith(`${hash}::`))
225
251
  .forEach((key) => this.#cache.delete(key));
226
252
  });
@@ -341,11 +367,38 @@ export class ChainHead extends JsonRpcGroup {
341
367
  return hash;
342
368
  }
343
369
  else {
344
- throw new ChainHeadBlockNotPinnedError(`Block hash ${hash} is not pinned`);
370
+ throw new ChainHeadBlockNotPinnedError(`Block hash ${hash} is not pinned`, hash);
345
371
  }
346
372
  }
347
373
  return ensurePresence(this.#bestHash || this.#finalizedHash);
348
374
  }
375
+ /**
376
+ * Executes a ChainHead operation with automatic Archive fallback.
377
+ *
378
+ * This method first attempts the primary ChainHead operation. If it fails with
379
+ * ChainHeadBlockNotPinnedError (indicating the block is no longer pinned), and
380
+ * an Archive instance is available, it automatically retries the operation using
381
+ * the Archive API.
382
+ *
383
+ * @param operation - Primary ChainHead operation to attempt
384
+ * @param fallback - Archive operation to fallback to
385
+ * @param hash - Block hash being accessed (for logging)
386
+ * @returns Result from either ChainHead or Archive operation
387
+ * @throws Original error if not a pinning error or no Archive available
388
+ * @private
389
+ */
390
+ async #tryWithArchive(operation, fallback) {
391
+ try {
392
+ return await operation();
393
+ }
394
+ catch (error) {
395
+ if (error instanceof ChainHeadBlockNotPinnedError && this.#archive) {
396
+ const errorHash = error.hash;
397
+ return await fallback(this.#archive, errorHash);
398
+ }
399
+ throw error;
400
+ }
401
+ }
349
402
  #getOperationHandler(result) {
350
403
  const handler = this.#handlers[result.operationId];
351
404
  if (handler)
@@ -400,7 +453,7 @@ export class ChainHead extends JsonRpcGroup {
400
453
  this.#followResponseQueue.clear();
401
454
  this.#retryQueue.clear();
402
455
  this.#blockUsage.clear();
403
- this.#cache.clear();
456
+ this.clearCache();
404
457
  this.#operationQueue.cancel();
405
458
  }
406
459
  async #ensureFollowed() {
@@ -475,21 +528,32 @@ export class ChainHead extends JsonRpcGroup {
475
528
  async body(at) {
476
529
  await this.#ensureFollowed();
477
530
  const shouldRetryOnPrunedBlock = !at;
478
- try {
531
+ const operation = async () => {
479
532
  const atHash = this.#ensurePinnedHash(at);
480
533
  const cacheKey = `${atHash}::body`;
481
- if (this.#cache.has(cacheKey)) {
482
- return this.#cache.get(cacheKey);
534
+ const cached = this.#cache.get(cacheKey);
535
+ if (cached) {
536
+ return cached;
483
537
  }
484
- const operation = async () => {
538
+ const bodyOperation = async () => {
485
539
  await this.#ensureFollowed();
486
540
  const hash = this.#ensurePinnedHash(atHash);
487
541
  const resp = await this.send('body', this.#subscriptionId, hash);
488
542
  return this.#awaitOperation(resp, hash);
489
543
  };
490
- const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(operation, atHash));
544
+ const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(bodyOperation, atHash));
491
545
  this.#cache.set(cacheKey, resp);
492
546
  return resp;
547
+ };
548
+ const fallback = async (archive, hash) => {
549
+ const result = await archive.body(hash);
550
+ if (result === undefined) {
551
+ throw new ChainHeadOperationError(`Block ${hash} not found in Archive`);
552
+ }
553
+ return result;
554
+ };
555
+ try {
556
+ return await this.#tryWithArchive(operation, fallback);
493
557
  }
494
558
  catch (e) {
495
559
  if (e instanceof ChainHeadBlockPrunedError && shouldRetryOnPrunedBlock) {
@@ -504,21 +568,26 @@ export class ChainHead extends JsonRpcGroup {
504
568
  async call(func, params = '0x', at) {
505
569
  await this.#ensureFollowed();
506
570
  const shouldRetryOnPrunedBlock = !at;
507
- try {
571
+ const operation = async () => {
508
572
  const atHash = this.#ensurePinnedHash(at);
509
573
  const cacheKey = `${atHash}::call::${func}::${params}`;
510
- if (this.#cache.has(cacheKey)) {
511
- return this.#cache.get(cacheKey);
574
+ const cached = this.#cache.get(cacheKey);
575
+ if (cached) {
576
+ return cached;
512
577
  }
513
- const operation = async () => {
578
+ const callOperation = async () => {
514
579
  await this.#ensureFollowed();
515
580
  const hash = this.#ensurePinnedHash(atHash);
516
581
  const resp = await this.send('call', this.#subscriptionId, hash, func, params);
517
582
  return this.#awaitOperation(resp, hash);
518
583
  };
519
- const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(operation, atHash));
584
+ const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(callOperation, atHash));
520
585
  this.#cache.set(cacheKey, resp);
521
586
  return resp;
587
+ };
588
+ const fallback = (archive, hash) => archive.call(func, params, hash);
589
+ try {
590
+ return await this.#tryWithArchive(operation, fallback);
522
591
  }
523
592
  catch (e) {
524
593
  if (e instanceof ChainHeadBlockPrunedError && shouldRetryOnPrunedBlock) {
@@ -532,14 +601,19 @@ export class ChainHead extends JsonRpcGroup {
532
601
  */
533
602
  async header(at) {
534
603
  await this.#ensureFollowed();
535
- const hash = this.#ensurePinnedHash(at);
536
- const cacheKey = `${hash}::header`;
537
- if (this.#cache.has(cacheKey)) {
538
- return this.#cache.get(cacheKey);
539
- }
540
- const resp = await this.#getHeader(hash);
541
- this.#cache.set(cacheKey, resp);
542
- return resp;
604
+ const operation = async () => {
605
+ const hash = this.#ensurePinnedHash(at);
606
+ const cacheKey = `${hash}::header`;
607
+ const cached = this.#cache.get(cacheKey);
608
+ if (cached) {
609
+ return cached;
610
+ }
611
+ const resp = await this.#getHeader(hash);
612
+ this.#cache.set(cacheKey, resp);
613
+ return resp;
614
+ };
615
+ const fallback = (archive, errorHash) => archive.header(errorHash);
616
+ return await this.#tryWithArchive(operation, fallback);
543
617
  }
544
618
  async #getHeader(at) {
545
619
  return await this.send('header', this.#subscriptionId, at);
@@ -550,35 +624,47 @@ export class ChainHead extends JsonRpcGroup {
550
624
  async storage(items, childTrie, at) {
551
625
  await this.#ensureFollowed();
552
626
  const shouldRetryOnPrunedBlock = !at;
553
- const hash = this.#ensurePinnedHash(at);
554
- try {
555
- // JSON.stringify(items) might get big, we probably should do a twox hashing in such case
556
- const cacheKey = `${hash}::storage::${JSON.stringify(items)}::${childTrie ?? null}`;
557
- if (this.#cache.has(cacheKey)) {
558
- return this.#cache.get(cacheKey);
559
- }
560
- this.#blockUsage.use(hash);
561
- let results = [];
562
- if (this.#__unsafe__isSmoldot()) {
563
- const fetchItem = async (item) => {
564
- const [batch, newDiscardedItems] = await this.#getStorage([item], childTrie ?? null, hash);
565
- if (newDiscardedItems.length > 0) {
566
- return fetchItem(item);
627
+ const operation = async () => {
628
+ const hash = this.#ensurePinnedHash(at);
629
+ try {
630
+ // JSON.stringify(items) might get big, we probably should do a twox hashing in such case
631
+ const cacheKey = `${hash}::storage::${JSON.stringify(items)}::${childTrie ?? null}`;
632
+ const cached = this.#cache.get(cacheKey);
633
+ if (cached) {
634
+ return cached;
635
+ }
636
+ this.#blockUsage.use(hash);
637
+ let results = [];
638
+ if (this.#__unsafe__isSmoldot()) {
639
+ const fetchItem = async (item) => {
640
+ const [batch, newDiscardedItems] = await this.#getStorage([item], childTrie ?? null, hash);
641
+ if (newDiscardedItems.length > 0) {
642
+ return fetchItem(item);
643
+ }
644
+ return batch;
645
+ };
646
+ results = (await Promise.all(items.map((one) => fetchItem(one)))).flat();
647
+ }
648
+ else {
649
+ let queryItems = items;
650
+ while (queryItems.length > 0) {
651
+ const [newBatch, newDiscardedItems] = await this.#getStorage(queryItems, childTrie ?? null, hash);
652
+ results.push(...newBatch);
653
+ queryItems = newDiscardedItems;
567
654
  }
568
- return batch;
569
- };
570
- results = (await Promise.all(items.map((one) => fetchItem(one)))).flat();
571
- }
572
- else {
573
- let queryItems = items;
574
- while (queryItems.length > 0) {
575
- const [newBatch, newDiscardedItems] = await this.#getStorage(queryItems, childTrie ?? null, hash);
576
- results.push(...newBatch);
577
- queryItems = newDiscardedItems;
578
655
  }
656
+ this.#cache.set(cacheKey, results);
657
+ return results;
658
+ }
659
+ finally {
660
+ this.#blockUsage.release(hash);
579
661
  }
580
- this.#cache.set(cacheKey, results);
581
- return results;
662
+ };
663
+ const fallback = (archive, hash) => {
664
+ return archive.storage(items, childTrie, hash);
665
+ };
666
+ try {
667
+ return await this.#tryWithArchive(operation, fallback);
582
668
  }
583
669
  catch (e) {
584
670
  if (e instanceof ChainHeadBlockPrunedError && shouldRetryOnPrunedBlock) {
@@ -586,9 +672,6 @@ export class ChainHead extends JsonRpcGroup {
586
672
  }
587
673
  throw e;
588
674
  }
589
- finally {
590
- this.#blockUsage.release(hash);
591
- }
592
675
  }
593
676
  async #getStorage(items, childTrie, at) {
594
677
  const operation = () => this.#getStorageOperation(items, childTrie, this.#ensurePinnedHash(at));
@@ -633,4 +716,18 @@ export class ChainHead extends JsonRpcGroup {
633
716
  // @ts-ignore a trick internally to check whether a provider is using smoldot connection
634
717
  return typeof this.client.provider['chain'] === 'function';
635
718
  }
719
+ /**
720
+ * Clears the internal cache used for storing query results (both chainHead & archive instances)
721
+ * This can be useful for memory management or when you want to force fresh data retrieval.
722
+ *
723
+ * @example
724
+ * ```typescript
725
+ * // Clear all cached results
726
+ * chainHead.clearCache();
727
+ * ```
728
+ */
729
+ clearCache() {
730
+ this.#cache.clear();
731
+ this.#archive?.clearCache();
732
+ }
636
733
  }
@@ -1,3 +1,4 @@
1
+ import { BlockHash } from '@dedot/codecs';
1
2
  import { DedotError } from '@dedot/utils';
2
3
  export declare enum RetryStrategy {
3
4
  NOW = "NOW",// Retry immediately
@@ -49,6 +50,8 @@ export declare class ChainHeadInvalidRuntimeError extends ChainHeadError {
49
50
  }
50
51
  export declare class ChainHeadBlockNotPinnedError extends ChainHeadError {
51
52
  name: string;
53
+ hash: BlockHash;
54
+ constructor(message: string, hash: BlockHash | string);
52
55
  }
53
56
  export declare class ChainHeadBlockPrunedError extends ChainHeadError {
54
57
  name: string;
@@ -50,6 +50,11 @@ export class ChainHeadInvalidRuntimeError extends ChainHeadError {
50
50
  }
51
51
  export class ChainHeadBlockNotPinnedError extends ChainHeadError {
52
52
  name = 'ChainHeadBlockNotPinnedError';
53
+ hash;
54
+ constructor(message, hash) {
55
+ super(message);
56
+ this.hash = hash;
57
+ }
53
58
  }
54
59
  export class ChainHeadBlockPrunedError extends ChainHeadError {
55
60
  name = 'ChainHeadBlockPrunedError';
@@ -1,4 +1,5 @@
1
1
  export * from './JsonRpcGroup.js';
2
+ export * from './Archive.js';
2
3
  export * from './ChainSpec.js';
3
4
  export * from './Transaction.js';
4
5
  export * from './TransactionWatch.js';
@@ -1,4 +1,5 @@
1
1
  export * from './JsonRpcGroup.js';
2
+ export * from './Archive.js';
2
3
  export * from './ChainSpec.js';
3
4
  export * from './Transaction.js';
4
5
  export * from './TransactionWatch.js';
@@ -14,4 +14,8 @@ export const subscriptionsInfo = {
14
14
  'transactionWatch_unstable_unwatch',
15
15
  ],
16
16
  transactionWatch_v1_submitAndWatch: ['transactionWatch_v1_watchEvent', 'transactionWatch_v1_unwatch'],
17
+ archive_v1_storage: ['archive_v1_storageEvent', 'archive_v1_stopStorage'],
18
+ archive_v1_storageDiff: ['archive_v1_storageDiffEvent', 'archive_v1_stopStorageDiff'],
19
+ archive_unstable_storage: ['archive_unstable_storageEvent', 'archive_unstable_stopStorage'],
20
+ archive_unstable_storageDiff: ['archive_unstable_storageDiffEvent', 'archive_unstable_stopStorageDiff'],
17
21
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/api",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
5
5
  "author": "Thang X. Vu <thang@dedot.dev>",
6
6
  "homepage": "https://dedot.dev",
@@ -13,13 +13,13 @@
13
13
  "type": "module",
14
14
  "sideEffects": false,
15
15
  "dependencies": {
16
- "@dedot/codecs": "0.15.2",
17
- "@dedot/providers": "0.15.2",
18
- "@dedot/runtime-specs": "0.15.2",
19
- "@dedot/shape": "0.15.2",
20
- "@dedot/storage": "0.15.2",
21
- "@dedot/types": "0.15.2",
22
- "@dedot/utils": "0.15.2"
16
+ "@dedot/codecs": "0.16.0",
17
+ "@dedot/providers": "0.16.0",
18
+ "@dedot/runtime-specs": "0.16.0",
19
+ "@dedot/shape": "0.16.0",
20
+ "@dedot/storage": "0.16.0",
21
+ "@dedot/types": "0.16.0",
22
+ "@dedot/utils": "0.16.0"
23
23
  },
24
24
  "scripts": {
25
25
  "build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
@@ -48,7 +48,7 @@
48
48
  "node": ">=18"
49
49
  },
50
50
  "license": "Apache-2.0",
51
- "gitHead": "75231d6888303dcf598cfd31592df13230707cb4",
51
+ "gitHead": "3e78a8eebb8977de0c5fb956154e5b09c4448f31",
52
52
  "module": "./index.js",
53
53
  "types": "./index.d.ts"
54
54
  }
@@ -1,7 +1,6 @@
1
1
  import { BlockHash, StorageData, StorageKey } from '@dedot/codecs';
2
- import type { Callback, RpcVersion, Unsub, VersionedGenericSubstrateApi } from '@dedot/types';
3
- import type { SubstrateApi } from '../chaintypes/index.js';
4
- import { BaseSubstrateClient } from '../client/BaseSubstrateClient.js';
2
+ import type { Callback, Unsub } from '@dedot/types';
3
+ import { ISubstrateClient, ISubstrateClientAt } from '../types.js';
5
4
  /**
6
5
  * @name BaseStorageQuery
7
6
  * @description
@@ -16,12 +15,12 @@ import { BaseSubstrateClient } from '../client/BaseSubstrateClient.js';
16
15
  * This abstraction eliminates code duplication between different client implementations
17
16
  * and provides a consistent interface for storage operations.
18
17
  */
19
- export declare abstract class BaseStorageQuery<Rv extends RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi, T extends BaseSubstrateClient<Rv, ChainApi> = BaseSubstrateClient<Rv, ChainApi>> {
20
- protected client: T;
18
+ export declare abstract class BaseStorageQuery {
19
+ protected client: ISubstrateClientAt<any> | ISubstrateClient<any, any>;
21
20
  /**
22
21
  * @param client - The substrate client instance
23
22
  */
24
- constructor(client: T);
23
+ protected constructor(client: ISubstrateClientAt<any> | ISubstrateClient<any, any>);
25
24
  /**
26
25
  * Query multiple storage items in a single call
27
26
  *
@@ -1,6 +1,5 @@
1
1
  import { BlockHash, StorageData, StorageKey } from '@dedot/codecs';
2
- import type { Callback, RpcLegacy, Unsub, VersionedGenericSubstrateApi } from '@dedot/types';
3
- import type { SubstrateApi } from '../chaintypes/index.js';
2
+ import type { Callback, Unsub } from '@dedot/types';
4
3
  import { LegacyClient } from '../client/LegacyClient.js';
5
4
  import { BaseStorageQuery } from './BaseStorageQuery.js';
6
5
  /**
@@ -15,7 +14,9 @@ import { BaseStorageQuery } from './BaseStorageQuery.js';
15
14
  * - Subscriptions using state_subscribeStorage
16
15
  * - Efficient change tracking for subscriptions
17
16
  */
18
- export declare class LegacyStorageQuery<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends BaseStorageQuery<RpcLegacy, ChainApi, LegacyClient<ChainApi>> {
17
+ export declare class LegacyStorageQuery extends BaseStorageQuery {
18
+ protected client: LegacyClient<any>;
19
+ constructor(client: LegacyClient<any>);
19
20
  /**
20
21
  * Query multiple storage items in a single call using state_queryStorageAt
21
22
  *
@@ -12,6 +12,11 @@ import { BaseStorageQuery } from './BaseStorageQuery.js';
12
12
  * - Efficient change tracking for subscriptions
13
13
  */
14
14
  export class LegacyStorageQuery extends BaseStorageQuery {
15
+ client;
16
+ constructor(client) {
17
+ super(client);
18
+ this.client = client;
19
+ }
15
20
  /**
16
21
  * Query multiple storage items in a single call using state_queryStorageAt
17
22
  *
@@ -1,6 +1,5 @@
1
1
  import { BlockHash, StorageData, StorageKey } from '@dedot/codecs';
2
- import type { Callback, RpcV2, Unsub, VersionedGenericSubstrateApi } from '@dedot/types';
3
- import type { SubstrateApi } from '../chaintypes/index.js';
2
+ import type { Callback, Unsub } from '@dedot/types';
4
3
  import { DedotClient } from '../client/DedotClient.js';
5
4
  import { BaseStorageQuery } from './BaseStorageQuery.js';
6
5
  /**
@@ -15,7 +14,9 @@ import { BaseStorageQuery } from './BaseStorageQuery.js';
15
14
  * - Subscriptions using chainHead 'bestBlock' events
16
15
  * - Efficient change detection for subscriptions
17
16
  */
18
- export declare class NewStorageQuery<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends BaseStorageQuery<RpcV2, ChainApi, DedotClient<ChainApi>> {
17
+ export declare class NewStorageQuery extends BaseStorageQuery {
18
+ protected client: DedotClient<any>;
19
+ constructor(client: DedotClient<any>);
19
20
  /**
20
21
  * Query multiple storage items in a single call using chainHead_storage
21
22
  *
@@ -13,6 +13,11 @@ import { BaseStorageQuery } from './BaseStorageQuery.js';
13
13
  * - Efficient change detection for subscriptions
14
14
  */
15
15
  export class NewStorageQuery extends BaseStorageQuery {
16
+ client;
17
+ constructor(client) {
18
+ super(client);
19
+ this.client = client;
20
+ }
16
21
  /**
17
22
  * Query multiple storage items in a single call using chainHead_storage
18
23
  *
@@ -5,12 +5,12 @@ import { PortableRegistry, PalletDefLatest, StorageDataLike, StorageEntryLatest,
5
5
  */
6
6
  export declare class QueryableStorage {
7
7
  #private;
8
- readonly registry: PortableRegistry;
8
+ readonly registry: PortableRegistry<any>;
9
9
  readonly palletName: string;
10
10
  readonly storageItem: string;
11
11
  readonly pallet: PalletDefLatest;
12
12
  readonly storageEntry: StorageEntryLatest;
13
- constructor(registry: PortableRegistry, palletName: string, storageItem: string);
13
+ constructor(registry: PortableRegistry<any>, palletName: string, storageItem: string);
14
14
  get prefixKey(): PrefixedStorageKey;
15
15
  get prefixKeyAsU8a(): Uint8Array;
16
16
  /**
package/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { ChainHeadEvent } from '@dedot/api/json-rpc';
2
1
  import { BlockHash, Hash, Metadata, PortableRegistry } from '@dedot/codecs';
3
2
  import type { ConnectionStatus, JsonRpcProvider, ProviderEvent } from '@dedot/providers';
4
3
  import type { AnyShape } from '@dedot/shape';
@@ -6,6 +5,7 @@ import type { IStorage } from '@dedot/storage';
6
5
  import type { Callback, GenericStorageQuery, GenericSubstrateApi, InjectedSigner, Query, QueryFnResult, RpcVersion, RuntimeApiName, RuntimeApiSpec, Unsub } from '@dedot/types';
7
6
  import type { HashFn, HexString, IEventEmitter } from '@dedot/utils';
8
7
  import type { AnySignedExtension } from './extrinsic/index.js';
8
+ import type { ChainHeadEvent } from './json-rpc/index.js';
9
9
  export type MetadataKey = `RAW_META/${string}`;
10
10
  export type SubscribeMethod = string;
11
11
  export type UnsubscribeMethod = string;
@@ -83,16 +83,15 @@ export interface IJsonRpcClient<ChainApi extends GenericSubstrateApi = GenericSu
83
83
  rpc: ChainApi['rpc'];
84
84
  }
85
85
  /**
86
- * A generic interface for Substrate clients at a specific block
86
+ * @internal
87
87
  */
88
- export interface ISubstrateClientAt<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> {
89
- atBlockHash?: BlockHash;
88
+ export interface IGenericSubstrateClient<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> {
90
89
  rpcVersion: RpcVersion;
91
90
  options: ApiOptions;
92
91
  genesisHash: Hash;
93
92
  runtimeVersion: SubstrateRuntimeVersion;
94
93
  metadata: Metadata;
95
- registry: PortableRegistry;
94
+ registry: PortableRegistry<ChainApi>;
96
95
  rpc: ChainApi['rpc'];
97
96
  consts: ChainApi['consts'];
98
97
  query: ChainApi['query'];
@@ -101,10 +100,16 @@ export interface ISubstrateClientAt<ChainApi extends GenericSubstrateApi = Gener
101
100
  errors: ChainApi['errors'];
102
101
  view: ChainApi['view'];
103
102
  }
103
+ /**
104
+ * A generic interface for Substrate clients at a specific block
105
+ */
106
+ export interface ISubstrateClientAt<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends IGenericSubstrateClient<ChainApi> {
107
+ atBlockHash: BlockHash;
108
+ }
104
109
  /**
105
110
  * A generic interface for Substrate clients
106
111
  */
107
- export interface ISubstrateClient<ChainApi extends GenericSubstrateApi = GenericSubstrateApi, Events extends string = ApiEvent> extends IJsonRpcClient<ChainApi, Events>, ISubstrateClientAt<ChainApi> {
112
+ export interface ISubstrateClient<ChainApi extends GenericSubstrateApi = GenericSubstrateApi, Events extends string = ApiEvent> extends IJsonRpcClient<ChainApi, Events>, IGenericSubstrateClient<ChainApi> {
108
113
  options: ApiOptions;
109
114
  tx: ChainApi['tx'];
110
115
  at<ChainApiAt extends GenericSubstrateApi = ChainApi>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;