@dedot/api 0.0.1-next.d9aff57d.57 → 0.1.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 (70) hide show
  1. package/chaintypes/substrate/consts.js +1 -1
  2. package/chaintypes/substrate/errors.js +1 -1
  3. package/chaintypes/substrate/events.js +1 -1
  4. package/chaintypes/substrate/index.js +1 -1
  5. package/chaintypes/substrate/json-rpc.d.ts +1 -1
  6. package/chaintypes/substrate/json-rpc.js +1 -1
  7. package/chaintypes/substrate/query.js +1 -1
  8. package/chaintypes/substrate/runtime.js +1 -1
  9. package/chaintypes/substrate/tx.d.ts +2 -2
  10. package/chaintypes/substrate/tx.js +1 -1
  11. package/chaintypes/substrate/types.d.ts +377 -377
  12. package/chaintypes/substrate/types.js +1 -1
  13. package/cjs/chaintypes/substrate/consts.js +1 -1
  14. package/cjs/chaintypes/substrate/errors.js +1 -1
  15. package/cjs/chaintypes/substrate/events.js +1 -1
  16. package/cjs/chaintypes/substrate/index.js +1 -1
  17. package/cjs/chaintypes/substrate/json-rpc.js +1 -1
  18. package/cjs/chaintypes/substrate/query.js +1 -1
  19. package/cjs/chaintypes/substrate/runtime.js +1 -1
  20. package/cjs/chaintypes/substrate/tx.js +1 -1
  21. package/cjs/chaintypes/substrate/types.js +1 -1
  22. package/cjs/client/BaseSubstrateClient.js +21 -0
  23. package/cjs/client/DedotClient.js +5 -4
  24. package/cjs/client/{Dedot.js → LegacyClient.js} +13 -9
  25. package/cjs/client/index.js +1 -1
  26. package/cjs/executor/ErrorExecutor.js +3 -3
  27. package/cjs/executor/EventExecutor.js +2 -2
  28. package/cjs/executor/StorageQueryExecutor.js +1 -1
  29. package/cjs/executor/TxExecutor.js +3 -3
  30. package/cjs/executor/v2/StorageQueryExecutorV2.js +7 -7
  31. package/cjs/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -2
  32. package/cjs/extrinsic/extensions/known/CheckMetadataHash.js +31 -0
  33. package/cjs/extrinsic/extensions/known/StorageWeightReclaim.js +10 -0
  34. package/cjs/extrinsic/extensions/known/index.js +4 -0
  35. package/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +31 -1
  36. package/cjs/extrinsic/submittable/SubmittableExtrinsic.js +7 -4
  37. package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +11 -11
  38. package/cjs/extrinsic/submittable/utils.js +66 -1
  39. package/cjs/storage/QueryableStorage.js +17 -17
  40. package/client/BaseSubstrateClient.d.ts +15 -9
  41. package/client/BaseSubstrateClient.js +22 -1
  42. package/client/DedotClient.d.ts +2 -2
  43. package/client/DedotClient.js +5 -4
  44. package/client/{Dedot.d.ts → LegacyClient.d.ts} +8 -7
  45. package/client/{Dedot.js → LegacyClient.js} +11 -7
  46. package/client/index.d.ts +1 -1
  47. package/client/index.js +1 -1
  48. package/executor/ErrorExecutor.js +3 -3
  49. package/executor/EventExecutor.js +2 -2
  50. package/executor/Executor.d.ts +12 -12
  51. package/executor/StorageQueryExecutor.js +1 -1
  52. package/executor/TxExecutor.js +3 -3
  53. package/executor/v2/StorageQueryExecutorV2.js +7 -7
  54. package/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -2
  55. package/extrinsic/extensions/known/CheckMetadataHash.d.ts +13 -0
  56. package/extrinsic/extensions/known/CheckMetadataHash.js +27 -0
  57. package/extrinsic/extensions/known/StorageWeightReclaim.d.ts +6 -0
  58. package/extrinsic/extensions/known/StorageWeightReclaim.js +6 -0
  59. package/extrinsic/extensions/known/index.js +4 -0
  60. package/extrinsic/submittable/BaseSubmittableExtrinsic.d.ts +2 -0
  61. package/extrinsic/submittable/BaseSubmittableExtrinsic.js +32 -2
  62. package/extrinsic/submittable/SubmittableExtrinsic.js +7 -4
  63. package/extrinsic/submittable/SubmittableExtrinsicV2.js +11 -11
  64. package/extrinsic/submittable/SubmittableResult.d.ts +4 -4
  65. package/extrinsic/submittable/utils.d.ts +10 -1
  66. package/extrinsic/submittable/utils.js +65 -1
  67. package/json-rpc/JsonRpcClient.d.ts +6 -5
  68. package/package.json +11 -11
  69. package/storage/QueryableStorage.js +17 -17
  70. package/types.d.ts +9 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.signRaw = exports.isKeyringPair = void 0;
3
+ exports.toTxStatus = exports.signRaw = exports.isKeyringPair = void 0;
4
4
  const utils_1 = require("@dedot/utils");
5
5
  function isKeyringPair(account) {
6
6
  return (0, utils_1.isFunction)(account.sign);
@@ -18,3 +18,68 @@ function signRaw(signerPair, raw) {
18
18
  return signerPair.sign(toSignRaw, { withType: true });
19
19
  }
20
20
  exports.signRaw = signRaw;
21
+ /**
22
+ * Convert transaction status to transaction event
23
+ *
24
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/98a364fe6e7abf10819f5fddd3de0588f7c38700/substrate/client/rpc-spec-v2/src/transaction/transaction.rs#L132-L159
25
+ * @param txStatus
26
+ * @param txIndex
27
+ */
28
+ function toTxStatus(txStatus, txIndex) {
29
+ switch (txStatus.type) {
30
+ case 'Ready':
31
+ case 'Future':
32
+ return { type: 'Validated' };
33
+ case 'Broadcast':
34
+ return { type: 'Broadcasting' };
35
+ case 'Retracted':
36
+ return { type: 'NoLongerInBestChain' };
37
+ case 'InBlock':
38
+ (0, utils_1.assert)(txIndex, 'TxIndex is required');
39
+ return {
40
+ type: 'BestChainBlockIncluded',
41
+ value: {
42
+ blockHash: txStatus.value,
43
+ txIndex,
44
+ },
45
+ };
46
+ case 'Finalized':
47
+ (0, utils_1.assert)(txIndex, 'TxIndex is required');
48
+ return {
49
+ type: 'Finalized',
50
+ value: {
51
+ blockHash: txStatus.value,
52
+ txIndex,
53
+ },
54
+ };
55
+ case 'FinalityTimeout':
56
+ return {
57
+ type: 'Drop',
58
+ value: {
59
+ error: 'Maximum number of finality watchers has been reached',
60
+ },
61
+ };
62
+ case 'Dropped':
63
+ return {
64
+ type: 'Drop',
65
+ value: {
66
+ error: 'Extrinsic dropped from the pool due to exceeding limits',
67
+ },
68
+ };
69
+ case 'Usurped':
70
+ return {
71
+ type: 'Invalid',
72
+ value: {
73
+ error: 'Extrinsic was rendered invalid by another extrinsic',
74
+ },
75
+ };
76
+ case 'Invalid':
77
+ return {
78
+ type: 'Invalid',
79
+ value: {
80
+ error: 'Extrinsic marked as invalid',
81
+ },
82
+ };
83
+ }
84
+ }
85
+ exports.toTxStatus = toTxStatus;
@@ -39,14 +39,14 @@ class QueryableStorage {
39
39
  const storageItemHash = (0, utils_2.xxhashAsU8a)(this.storageEntry.name, 128);
40
40
  return (0, utils_2.concatU8a)(palletNameHash, storageItemHash);
41
41
  }
42
- #getStorageMapInfo(type) {
43
- (0, utils_1.assert)(type.tag === 'Map');
44
- const { hashers, keyTypeId } = type.value;
42
+ #getStorageMapInfo(storageType) {
43
+ (0, utils_1.assert)(storageType.type === 'Map');
44
+ const { hashers, keyTypeId } = storageType.value;
45
45
  let keyTypeIds = [keyTypeId];
46
46
  if (hashers.length > 1) {
47
- const { type } = this.registry.findType(keyTypeId);
48
- (0, utils_1.assert)(type.tag === 'Tuple', 'Key type should be a tuple!');
49
- keyTypeIds = type.value.fields;
47
+ const { typeDef } = this.registry.findType(keyTypeId);
48
+ (0, utils_1.assert)(typeDef.type === 'Tuple', 'Key type should be a tuple!');
49
+ keyTypeIds = typeDef.value.fields;
50
50
  }
51
51
  return { hashers, keyTypeIds };
52
52
  }
@@ -56,12 +56,12 @@ class QueryableStorage {
56
56
  * @param keyInput
57
57
  */
58
58
  encodeKey(keyInput) {
59
- const { type } = this.storageEntry;
60
- if (type.tag === 'Plain') {
59
+ const { storageType } = this.storageEntry;
60
+ if (storageType.type === 'Plain') {
61
61
  return this.prefixKey;
62
62
  }
63
- else if (type.tag === 'Map') {
64
- const { hashers, keyTypeIds } = this.#getStorageMapInfo(type);
63
+ else if (storageType.type === 'Map') {
64
+ const { hashers, keyTypeIds } = this.#getStorageMapInfo(storageType);
65
65
  const extractedInputs = this.#extractRequiredKeyInputs(keyInput, hashers.length);
66
66
  const keyParts = keyTypeIds.map((keyId, index) => {
67
67
  const input = extractedInputs[index];
@@ -71,7 +71,7 @@ class QueryableStorage {
71
71
  });
72
72
  return (0, utils_2.u8aToHex)((0, utils_2.concatU8a)(this.prefixKeyAsU8a, ...keyParts));
73
73
  }
74
- throw Error(`Invalid storage entry type: ${type}`);
74
+ throw Error(`Invalid storage entry type: ${JSON.stringify(storageType)}`);
75
75
  }
76
76
  /**
77
77
  * Decode storage key to plain key input
@@ -80,16 +80,16 @@ class QueryableStorage {
80
80
  * @param key
81
81
  */
82
82
  decodeKey(key) {
83
- const { type } = this.storageEntry;
84
- if (type.tag === 'Plain') {
83
+ const { storageType } = this.storageEntry;
84
+ if (storageType.type === 'Plain') {
85
85
  return;
86
86
  }
87
- else if (type.tag === 'Map') {
87
+ else if (storageType.type === 'Map') {
88
88
  const prefix = this.prefixKey;
89
89
  if (!key.startsWith(prefix)) {
90
90
  throw new Error(`Storage key does not match this storage entry (${this.palletName}.${this.storageItem})`);
91
91
  }
92
- const { hashers, keyTypeIds } = this.#getStorageMapInfo(type);
92
+ const { hashers, keyTypeIds } = this.#getStorageMapInfo(storageType);
93
93
  let keyData = (0, utils_2.hexToU8a)((0, utils_1.hexAddPrefix)(key.slice(prefix.length)));
94
94
  const results = keyTypeIds.map((keyId, index) => {
95
95
  const [hashLen, canDecode] = HASHER_INFO[hashers[index]];
@@ -104,7 +104,7 @@ class QueryableStorage {
104
104
  });
105
105
  return hashers.length > 1 ? results : results[0];
106
106
  }
107
- throw Error(`Invalid storage entry type: ${type}`);
107
+ throw Error(`Invalid storage entry type: ${JSON.stringify(storageType)}`);
108
108
  }
109
109
  /**
110
110
  * Decode raw/bytes storage data to plain value
@@ -112,7 +112,7 @@ class QueryableStorage {
112
112
  * @param raw
113
113
  */
114
114
  decodeValue(raw) {
115
- const { modifier, type: { value: { valueTypeId }, }, default: defaultValue, } = this.storageEntry;
115
+ const { modifier, storageType: { value: { valueTypeId }, }, default: defaultValue, } = this.storageEntry;
116
116
  if (raw === null || raw === undefined) {
117
117
  if (modifier === 'Optional') {
118
118
  return undefined;
@@ -2,6 +2,7 @@ import { BlockHash, Hash, Metadata, PortableRegistry, RuntimeVersion } from '@de
2
2
  import type { JsonRpcProvider } from '@dedot/providers';
3
3
  import { type IStorage } from '@dedot/storage';
4
4
  import { GenericSubstrateApi, RpcVersion, VersionedGenericSubstrateApi } from '@dedot/types';
5
+ import { Deferred } from '@dedot/utils';
5
6
  import type { SubstrateApi } from '../chaintypes/index.js';
6
7
  import { JsonRpcClient } from '../json-rpc/index.js';
7
8
  import type { ApiEvent, ApiOptions, ISubstrateClient, ISubstrateClientAt, JsonRpcClientOptions, MetadataKey, SubstrateRuntimeVersion } from '../types.js';
@@ -10,7 +11,7 @@ export declare function ensurePresence<T>(value: T): NonNullable<T>;
10
11
  * @name BaseSubstrateClient
11
12
  * @description Base & shared abstraction for Substrate API Clients
12
13
  */
13
- export declare abstract class BaseSubstrateClient<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends JsonRpcClient<ChainApi[RpcVersion], ApiEvent> implements ISubstrateClient<ChainApi[RpcVersion]> {
14
+ export declare abstract class BaseSubstrateClient<Rv extends RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends JsonRpcClient<ChainApi, ApiEvent> implements ISubstrateClient<ChainApi[Rv]> {
14
15
  rpcVersion: RpcVersion;
15
16
  protected _options: ApiOptions;
16
17
  protected _registry?: PortableRegistry;
@@ -18,6 +19,7 @@ export declare abstract class BaseSubstrateClient<ChainApi extends VersionedGene
18
19
  protected _genesisHash?: Hash;
19
20
  protected _runtimeVersion?: SubstrateRuntimeVersion;
20
21
  protected _localCache?: IStorage;
22
+ protected _runtimeUpgrading?: Deferred<void>;
21
23
  protected constructor(rpcVersion: RpcVersion, options: JsonRpcClientOptions | JsonRpcProvider);
22
24
  protected normalizeOptions(options: ApiOptions | JsonRpcProvider): ApiOptions;
23
25
  protected initializeLocalCache(): Promise<void>;
@@ -41,6 +43,9 @@ export declare abstract class BaseSubstrateClient<ChainApi extends VersionedGene
41
43
  protected beforeDisconnect(): Promise<void>;
42
44
  protected afterDisconnect(): Promise<void>;
43
45
  protected toSubstrateRuntimeVersion(runtimeVersion: RuntimeVersion): SubstrateRuntimeVersion;
46
+ protected startRuntimeUpgrade(): void;
47
+ protected doneRuntimeUpgrade(): void;
48
+ protected ensureRuntimeUpgraded(): Promise<void>;
44
49
  /**
45
50
  * @description Connect to blockchain node
46
51
  */
@@ -54,12 +59,13 @@ export declare abstract class BaseSubstrateClient<ChainApi extends VersionedGene
54
59
  get registry(): PortableRegistry;
55
60
  get genesisHash(): Hash;
56
61
  get runtimeVersion(): SubstrateRuntimeVersion;
57
- get consts(): ChainApi[RpcVersion]['consts'];
58
- get errors(): ChainApi[RpcVersion]['errors'];
59
- get events(): ChainApi[RpcVersion]['events'];
60
- get query(): ChainApi[RpcVersion]['query'];
61
- get call(): ChainApi[RpcVersion]['call'];
62
- protected callAt(hash?: BlockHash): ChainApi[RpcVersion]['call'];
63
- get tx(): ChainApi[RpcVersion]['tx'];
64
- at<ChainApiAt extends GenericSubstrateApi = ChainApi[RpcVersion]>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;
62
+ getRuntimeVersion(): Promise<SubstrateRuntimeVersion>;
63
+ get consts(): ChainApi[Rv]['consts'];
64
+ get errors(): ChainApi[Rv]['errors'];
65
+ get events(): ChainApi[Rv]['events'];
66
+ get query(): ChainApi[Rv]['query'];
67
+ get call(): ChainApi[Rv]['call'];
68
+ protected callAt(hash?: BlockHash): ChainApi[Rv]['call'];
69
+ get tx(): ChainApi[Rv]['tx'];
70
+ at<ChainApiAt extends GenericSubstrateApi = ChainApi[Rv]>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;
65
71
  }
@@ -1,6 +1,6 @@
1
1
  import { $Metadata, PortableRegistry } from '@dedot/codecs';
2
2
  import { LocalStorage } from '@dedot/storage';
3
- import { calcRuntimeApiHash, ensurePresence as _ensurePresence, u8aToHex } from '@dedot/utils';
3
+ import { calcRuntimeApiHash, deferred, ensurePresence as _ensurePresence, u8aToHex } from '@dedot/utils';
4
4
  import { ConstantExecutor, ErrorExecutor, EventExecutor } from '../executor/index.js';
5
5
  import { isJsonRpcProvider, JsonRpcClient } from '../json-rpc/index.js';
6
6
  import { newProxyChain } from '../proxychain.js';
@@ -22,6 +22,7 @@ export class BaseSubstrateClient extends JsonRpcClient {
22
22
  _genesisHash;
23
23
  _runtimeVersion;
24
24
  _localCache;
25
+ _runtimeUpgrading;
25
26
  constructor(rpcVersion, options) {
26
27
  super(options);
27
28
  this.rpcVersion = rpcVersion;
@@ -193,6 +194,22 @@ export class BaseSubstrateClient extends JsonRpcClient {
193
194
  }, {}),
194
195
  };
195
196
  }
197
+ startRuntimeUpgrade() {
198
+ this._runtimeUpgrading = deferred();
199
+ }
200
+ doneRuntimeUpgrade() {
201
+ if (!this._runtimeUpgrading)
202
+ return;
203
+ this._runtimeUpgrading.resolve();
204
+ setTimeout(() => {
205
+ this._runtimeUpgrading = undefined;
206
+ });
207
+ }
208
+ async ensureRuntimeUpgraded() {
209
+ if (!this._runtimeUpgrading)
210
+ return;
211
+ await this._runtimeUpgrading.promise;
212
+ }
196
213
  /// --- Public APIs ---
197
214
  /**
198
215
  * @description Connect to blockchain node
@@ -224,6 +241,10 @@ export class BaseSubstrateClient extends JsonRpcClient {
224
241
  get runtimeVersion() {
225
242
  return ensurePresence(this._runtimeVersion);
226
243
  }
244
+ async getRuntimeVersion() {
245
+ await this.ensureRuntimeUpgraded();
246
+ return this.runtimeVersion;
247
+ }
227
248
  get consts() {
228
249
  return newProxyChain({ executor: new ConstantExecutor(this) });
229
250
  }
@@ -11,7 +11,8 @@ import { BaseSubstrateClient } from './BaseSubstrateClient.js';
11
11
  *
12
12
  * __Unstable, use with caution.__
13
13
  */
14
- export declare class DedotClient<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends BaseSubstrateClient<ChainApi> {
14
+ export declare class DedotClient<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>// prettier-end-here
15
+ extends BaseSubstrateClient<RpcV2, ChainApi> {
15
16
  #private;
16
17
  protected _chainHead?: ChainHead;
17
18
  protected _chainSpec?: ChainSpec;
@@ -42,7 +43,6 @@ export declare class DedotClient<ChainApi extends VersionedGenericSubstrateApi =
42
43
  */
43
44
  protected doInitialize(): Promise<void>;
44
45
  protected subscribeRuntimeUpgrades(): void;
45
- protected unsubscribeRuntimeUpgrades(): void;
46
46
  protected onRuntimeUpgrade: (block: PinnedBlock) => Promise<void>;
47
47
  protected beforeDisconnect(): Promise<void>;
48
48
  protected onDisconnected: () => Promise<void>;
@@ -11,7 +11,8 @@ import { BaseSubstrateClient, ensurePresence } from './BaseSubstrateClient.js';
11
11
  *
12
12
  * __Unstable, use with caution.__
13
13
  */
14
- export class DedotClient extends BaseSubstrateClient {
14
+ export class DedotClient// prettier-end-here
15
+ extends BaseSubstrateClient {
15
16
  _chainHead;
16
17
  _chainSpec;
17
18
  _txBroadcaster;
@@ -99,16 +100,16 @@ export class DedotClient extends BaseSubstrateClient {
99
100
  subscribeRuntimeUpgrades() {
100
101
  this.chainHead.on('bestBlock', this.onRuntimeUpgrade);
101
102
  }
102
- unsubscribeRuntimeUpgrades() {
103
- this.chainHead.off('bestBlock', this.onRuntimeUpgrade);
104
- }
105
103
  onRuntimeUpgrade = async (block) => {
106
104
  const runtimeUpgraded = block.runtime && block.runtime.specVersion !== this._runtimeVersion?.specVersion;
107
105
  if (!runtimeUpgraded)
108
106
  return;
107
+ this.startRuntimeUpgrade();
109
108
  this._runtimeVersion = block.runtime;
110
109
  const newMetadata = await this.fetchMetadata(undefined, this._runtimeVersion);
111
110
  await this.setupMetadata(newMetadata);
111
+ this.emit('runtimeUpgraded', this._runtimeVersion);
112
+ this.doneRuntimeUpgrade();
112
113
  };
113
114
  async beforeDisconnect() {
114
115
  await this.chainHead.unfollow();
@@ -5,7 +5,7 @@ import type { SubstrateApi } from '../chaintypes/index.js';
5
5
  import type { ApiOptions, ISubstrateClientAt } from '../types.js';
6
6
  import { BaseSubstrateClient } from './BaseSubstrateClient.js';
7
7
  /**
8
- * @name Dedot
8
+ * @name LegacyClient
9
9
  * @description Promised-based API Client for Polkadot & Substrate
10
10
  *
11
11
  * Initialize API instance and interact with substrate-based network
@@ -14,7 +14,7 @@ import { BaseSubstrateClient } from './BaseSubstrateClient.js';
14
14
  * import type { PolkadotApi } from '@dedot/chaintypes/polkadot';
15
15
  *
16
16
  * const run = async () => {
17
- * const api = await Dedot.new<PolkadotApi>('wss://rpc.polkadot.io');
17
+ * const api = await LegacyClient.new<PolkadotApi>('wss://rpc.polkadot.io');
18
18
  *
19
19
  * // Call rpc `state_getMetadata` to fetch raw scale-encoded metadata and decode it.
20
20
  * const metadata = await api.rpc.state.getMetadata();
@@ -42,7 +42,8 @@ import { BaseSubstrateClient } from './BaseSubstrateClient.js';
42
42
  * run().catch(console.error);
43
43
  * ```
44
44
  */
45
- export declare class Dedot<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends BaseSubstrateClient<ChainApi> {
45
+ export declare class LegacyClient<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>// prettier-end-here
46
+ extends BaseSubstrateClient<RpcLegacy, ChainApi> {
46
47
  #private;
47
48
  /**
48
49
  * Use factory methods (`create`, `new`) to create `Dedot` instances.
@@ -55,13 +56,13 @@ export declare class Dedot<ChainApi extends VersionedGenericSubstrateApi = Subst
55
56
  *
56
57
  * @param options
57
58
  */
58
- static create<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>(options: ApiOptions | JsonRpcProvider): Promise<Dedot<ChainApi>>;
59
+ static create<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>(options: ApiOptions | JsonRpcProvider): Promise<LegacyClient<ChainApi>>;
59
60
  /**
60
- * Alias for __Dedot.create__
61
+ * Alias for __LegacyClient.create__
61
62
  *
62
63
  * @param options
63
64
  */
64
- static new<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>(options: ApiOptions | JsonRpcProvider): Promise<Dedot<ChainApi>>;
65
+ static new<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>(options: ApiOptions | JsonRpcProvider): Promise<LegacyClient<ChainApi>>;
65
66
  protected onDisconnected: () => Promise<void>;
66
67
  protected beforeDisconnect(): Promise<void>;
67
68
  /**
@@ -116,7 +117,7 @@ export declare class Dedot<ChainApi extends VersionedGenericSubstrateApi = Subst
116
117
  * // Make a transfer balance transaction
117
118
  * api.tx.balances.transferKeepAlive(<address>, <amount>)
118
119
  * .signAndSend(<keyPair|address>, { signer }, ({ status }) => {
119
- * console.log('Transaction status', status.tag);
120
+ * console.log('Transaction status', status.type);
120
121
  * });
121
122
  * ```
122
123
  */
@@ -4,7 +4,7 @@ import { newProxyChain } from '../proxychain.js';
4
4
  import { BaseSubstrateClient } from './BaseSubstrateClient.js';
5
5
  const KEEP_ALIVE_INTERVAL = 10_000; // in ms
6
6
  /**
7
- * @name Dedot
7
+ * @name LegacyClient
8
8
  * @description Promised-based API Client for Polkadot & Substrate
9
9
  *
10
10
  * Initialize API instance and interact with substrate-based network
@@ -13,7 +13,7 @@ const KEEP_ALIVE_INTERVAL = 10_000; // in ms
13
13
  * import type { PolkadotApi } from '@dedot/chaintypes/polkadot';
14
14
  *
15
15
  * const run = async () => {
16
- * const api = await Dedot.new<PolkadotApi>('wss://rpc.polkadot.io');
16
+ * const api = await LegacyClient.new<PolkadotApi>('wss://rpc.polkadot.io');
17
17
  *
18
18
  * // Call rpc `state_getMetadata` to fetch raw scale-encoded metadata and decode it.
19
19
  * const metadata = await api.rpc.state.getMetadata();
@@ -41,7 +41,8 @@ const KEEP_ALIVE_INTERVAL = 10_000; // in ms
41
41
  * run().catch(console.error);
42
42
  * ```
43
43
  */
44
- export class Dedot extends BaseSubstrateClient {
44
+ export class LegacyClient// prettier-end-here
45
+ extends BaseSubstrateClient {
45
46
  #runtimeSubscriptionUnsub;
46
47
  #healthTimer;
47
48
  #apiAtCache = {};
@@ -59,15 +60,15 @@ export class Dedot extends BaseSubstrateClient {
59
60
  * @param options
60
61
  */
61
62
  static async create(options) {
62
- return new Dedot(options).connect();
63
+ return new LegacyClient(options).connect();
63
64
  }
64
65
  /**
65
- * Alias for __Dedot.create__
66
+ * Alias for __LegacyClient.create__
66
67
  *
67
68
  * @param options
68
69
  */
69
70
  static async new(options) {
70
- return Dedot.create(options);
71
+ return LegacyClient.create(options);
71
72
  }
72
73
  onDisconnected = async () => {
73
74
  await this.#unsubscribeUpdates();
@@ -101,9 +102,12 @@ export class Dedot extends BaseSubstrateClient {
101
102
  this.rpc
102
103
  .state_subscribeRuntimeVersion(async (runtimeVersion) => {
103
104
  if (runtimeVersion.specVersion !== this.runtimeVersion?.specVersion) {
105
+ this.startRuntimeUpgrade();
104
106
  this._runtimeVersion = this.toSubstrateRuntimeVersion(runtimeVersion);
105
107
  const newMetadata = await this.fetchMetadata(undefined, this._runtimeVersion);
106
108
  await this.setupMetadata(newMetadata);
109
+ this.emit('runtimeUpgraded', this._runtimeVersion);
110
+ this.doneRuntimeUpgrade();
107
111
  }
108
112
  })
109
113
  .then((unsub) => {
@@ -202,7 +206,7 @@ export class Dedot extends BaseSubstrateClient {
202
206
  * // Make a transfer balance transaction
203
207
  * api.tx.balances.transferKeepAlive(<address>, <amount>)
204
208
  * .signAndSend(<keyPair|address>, { signer }, ({ status }) => {
205
- * console.log('Transaction status', status.tag);
209
+ * console.log('Transaction status', status.type);
206
210
  * });
207
211
  * ```
208
212
  */
package/client/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './Dedot.js';
1
+ export * from './LegacyClient.js';
2
2
  export * from './DedotClient.js';
package/client/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export * from './Dedot.js';
1
+ export * from './LegacyClient.js';
2
2
  export * from './DedotClient.js';
@@ -17,7 +17,7 @@ export class ErrorExecutor extends Executor {
17
17
  palletIndex: targetPallet.index,
18
18
  },
19
19
  is: (errorInfo) => {
20
- if (isObject(errorInfo) && errorInfo.tag === 'Module') {
20
+ if (isObject(errorInfo) && errorInfo.type === 'Module') {
21
21
  errorInfo = errorInfo.value;
22
22
  }
23
23
  if (isObject(errorInfo) && isNumber(errorInfo.index) && isHex(errorInfo.error)) {
@@ -30,8 +30,8 @@ export class ErrorExecutor extends Executor {
30
30
  #getErrorDef(errorTypeId, errorName) {
31
31
  const def = this.metadata.types[errorTypeId];
32
32
  assert(def, new UnknownApiError(`Error def not found for id ${errorTypeId}`));
33
- const { tag, value } = def.type;
34
- assert(tag === 'Enum', new UnknownApiError(`Error type should be an enum, found: ${tag}`));
33
+ const { type, value } = def.typeDef;
34
+ assert(type === 'Enum', new UnknownApiError(`Error type should be an enum, found: ${type}`));
35
35
  const errorDef = value.members.find(({ name }) => stringPascalCase(name) === errorName);
36
36
  assert(errorDef, new UnknownApiError(`Error def not found for ${errorName}`));
37
37
  return {
@@ -36,8 +36,8 @@ export class EventExecutor extends Executor {
36
36
  #getEventDef(eventTypeId, errorName) {
37
37
  const def = this.metadata.types[eventTypeId];
38
38
  assert(def, new UnknownApiError(`Event def not found for id ${eventTypeId}`));
39
- const { tag, value } = def.type;
40
- assert(tag === 'Enum', new UnknownApiError(`Event type should be an enum, found: ${tag}`));
39
+ const { type, value } = def.typeDef;
40
+ assert(type === 'Enum', new UnknownApiError(`Event type should be an enum, found: ${type}`));
41
41
  const eventDef = value.members.find(({ name }) => stringPascalCase(name) === errorName);
42
42
  assert(eventDef, new UnknownApiError(`Event def not found for ${errorName}`));
43
43
  return {
@@ -19,13 +19,13 @@ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = Ge
19
19
  name: string;
20
20
  typeId: number | undefined;
21
21
  }[];
22
- type: {
23
- tag: "Struct";
22
+ typeDef: {
23
+ type: "Struct";
24
24
  value: {
25
25
  fields: import("@dedot/codecs").Field[];
26
26
  };
27
27
  } | {
28
- tag: "Enum";
28
+ type: "Enum";
29
29
  value: {
30
30
  members: {
31
31
  name: string;
@@ -35,33 +35,33 @@ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = Ge
35
35
  }[];
36
36
  };
37
37
  } | {
38
- tag: "Sequence";
38
+ type: "Sequence";
39
39
  value: {
40
40
  typeParam: number;
41
41
  };
42
42
  } | {
43
- tag: "SizedVec";
43
+ type: "SizedVec";
44
44
  value: {
45
45
  len: number;
46
46
  typeParam: number;
47
47
  };
48
48
  } | {
49
- tag: "Tuple";
49
+ type: "Tuple";
50
50
  value: {
51
51
  fields: number[];
52
52
  };
53
53
  } | {
54
- tag: "Primitive";
54
+ type: "Primitive";
55
55
  value: {
56
56
  kind: "bool" | "char" | "str" | "u8" | "u16" | "u32" | "u64" | "u128" | "u256" | "i8" | "i16" | "i32" | "i64" | "i128" | "i256";
57
57
  };
58
58
  } | {
59
- tag: "Compact";
59
+ type: "Compact";
60
60
  value: {
61
61
  typeParam: number;
62
62
  };
63
63
  } | {
64
- tag: "BitSequence";
64
+ type: "BitSequence";
65
65
  value: {
66
66
  bitOrderType: number;
67
67
  bitStoreType: number;
@@ -76,13 +76,13 @@ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = Ge
76
76
  entries: {
77
77
  name: string;
78
78
  modifier: string;
79
- type: {
80
- tag: "Plain";
79
+ storageType: {
80
+ type: "Plain";
81
81
  value: {
82
82
  valueTypeId: number;
83
83
  };
84
84
  } | {
85
- tag: "Map";
85
+ type: "Map";
86
86
  value: {
87
87
  hashers: ("identity" | "blake2_128" | "blake2_256" | "blake2_128Concat" | "twox128" | "twox256" | "twox64Concat")[];
88
88
  keyTypeId: number;
@@ -49,7 +49,7 @@ export class StorageQueryExecutor extends Executor {
49
49
  palletIndex: entry.pallet.index,
50
50
  ...entry.storageEntry,
51
51
  };
52
- const isMap = entry.storageEntry.type.tag === 'Map';
52
+ const isMap = entry.storageEntry.storageType.type === 'Map';
53
53
  if (isMap) {
54
54
  const queryMultiFn = async (...args) => {
55
55
  const [inArgs, callback] = extractArgs(args);
@@ -10,9 +10,9 @@ export class TxExecutor extends Executor {
10
10
  const targetPallet = this.getPallet(pallet);
11
11
  assert(targetPallet.calls, new UnknownApiError(`Tx calls are not available for pallet ${targetPallet.name}`));
12
12
  const txType = this.metadata.types[targetPallet.calls];
13
- assert(txType.type.tag === 'Enum', new UnknownApiError('Tx type defs should be enum'));
14
- const isFlatEnum = txType.type.value.members.every((m) => m.fields.length === 0);
15
- const txCallDef = txType.type.value.members.find((m) => stringCamelCase(m.name) === functionName);
13
+ assert(txType.typeDef.type === 'Enum', new UnknownApiError('Tx type defs should be enum'));
14
+ const isFlatEnum = txType.typeDef.value.members.every((m) => m.fields.length === 0);
15
+ const txCallDef = txType.typeDef.value.members.find((m) => stringCamelCase(m.name) === functionName);
16
16
  assert(txCallDef, new UnknownApiError(`Tx call spec not found for ${pallet}.${functionName}`));
17
17
  const txCallFn = (...args) => {
18
18
  let call;
@@ -32,27 +32,27 @@ export class StorageQueryExecutorV2 extends StorageQueryExecutor {
32
32
  }, {});
33
33
  }
34
34
  async subscribeStorage(keys, callback) {
35
- let initialHash = await this.chainHead.bestHash();
35
+ let best = await this.chainHead.bestBlock();
36
36
  let eventToListen = 'bestBlock';
37
37
  // TODO subscribe to finalized data source
38
38
  // initialHash = this.chainHead.finalizedHash;
39
39
  // eventToListen = 'finalizedBlock';
40
- const latestChanges = {};
41
- const pull = async (hash) => {
40
+ const latestChanges = new Map();
41
+ const pull = async ({ hash }) => {
42
42
  const results = await this.queryStorage(keys, hash);
43
43
  let changed = false;
44
44
  keys.forEach((key) => {
45
45
  const newValue = results[key];
46
- if (latestChanges[key] === newValue)
46
+ if (latestChanges.size > 0 && latestChanges.get(key) === newValue)
47
47
  return;
48
48
  changed = true;
49
- latestChanges[key] = newValue;
49
+ latestChanges.set(key, newValue);
50
50
  });
51
51
  if (!changed)
52
52
  return;
53
- callback(keys.map((key) => latestChanges[key]));
53
+ callback(keys.map((key) => latestChanges.get(key)));
54
54
  };
55
- await pull(initialHash);
55
+ await pull(best);
56
56
  const unsub = this.chainHead.on(eventToListen, pull);
57
57
  return async () => {
58
58
  unsub();
@@ -27,8 +27,8 @@ export class ChargeAssetTxPayment extends SignedExtension {
27
27
  }
28
28
  $AssetId() {
29
29
  const extensionTypeDef = this.registry.findType(this.signedExtensionDef.typeId);
30
- assert(extensionTypeDef.type.tag === 'Struct');
31
- const assetIdTypeDef = extensionTypeDef.type.value.fields.find((f) => f.name === 'asset_id');
30
+ assert(extensionTypeDef.typeDef.type === 'Struct');
31
+ const assetIdTypeDef = extensionTypeDef.typeDef.value.fields.find((f) => f.name === 'asset_id');
32
32
  const $codec = this.registry.findCodec(assetIdTypeDef.typeId);
33
33
  const codecMetadata = $codec.metadata[0];
34
34
  if (codecMetadata.name === '$.option') {
@@ -0,0 +1,13 @@
1
+ import { SignerPayloadJSON } from '@polkadot/types/types';
2
+ import { Hash } from '@dedot/codecs';
3
+ import { SignedExtension } from '../SignedExtension.js';
4
+ export type CheckMetadataHashMode = 'Disabled' | 'Enabled';
5
+ /**
6
+ * @description Genesis hash check to provide replay protection between different networks.
7
+ */
8
+ export declare class CheckMetadataHash extends SignedExtension<{
9
+ mode: CheckMetadataHashMode;
10
+ }, Hash | undefined> {
11
+ init(): Promise<void>;
12
+ toPayload(): Partial<SignerPayloadJSON>;
13
+ }