@dedot/api 0.0.1-alpha.32

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 (202) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1 -0
  3. package/chaintypes/index.d.ts +1 -0
  4. package/chaintypes/index.js +1 -0
  5. package/chaintypes/substrate/consts.d.ts +2132 -0
  6. package/chaintypes/substrate/consts.js +2 -0
  7. package/chaintypes/substrate/errors.d.ts +3490 -0
  8. package/chaintypes/substrate/errors.js +2 -0
  9. package/chaintypes/substrate/events.d.ts +5187 -0
  10. package/chaintypes/substrate/events.js +2 -0
  11. package/chaintypes/substrate/index.d.ts +22 -0
  12. package/chaintypes/substrate/index.js +2 -0
  13. package/chaintypes/substrate/json-rpc.d.ts +3 -0
  14. package/chaintypes/substrate/json-rpc.js +2 -0
  15. package/chaintypes/substrate/query.d.ts +3829 -0
  16. package/chaintypes/substrate/query.js +2 -0
  17. package/chaintypes/substrate/runtime.d.ts +850 -0
  18. package/chaintypes/substrate/runtime.js +2 -0
  19. package/chaintypes/substrate/tx.d.ts +14269 -0
  20. package/chaintypes/substrate/tx.js +2 -0
  21. package/chaintypes/substrate/types.d.ts +30457 -0
  22. package/chaintypes/substrate/types.js +2 -0
  23. package/cjs/chaintypes/index.js +17 -0
  24. package/cjs/chaintypes/substrate/consts.js +3 -0
  25. package/cjs/chaintypes/substrate/errors.js +3 -0
  26. package/cjs/chaintypes/substrate/events.js +3 -0
  27. package/cjs/chaintypes/substrate/index.js +18 -0
  28. package/cjs/chaintypes/substrate/json-rpc.js +3 -0
  29. package/cjs/chaintypes/substrate/query.js +3 -0
  30. package/cjs/chaintypes/substrate/runtime.js +3 -0
  31. package/cjs/chaintypes/substrate/tx.js +3 -0
  32. package/cjs/chaintypes/substrate/types.js +3 -0
  33. package/cjs/client/BaseSubstrateClient.js +257 -0
  34. package/cjs/client/Dedot.js +250 -0
  35. package/cjs/client/DedotClient.js +186 -0
  36. package/cjs/client/index.js +18 -0
  37. package/cjs/executor/ConstantExecutor.js +20 -0
  38. package/cjs/executor/ErrorExecutor.js +46 -0
  39. package/cjs/executor/EventExecutor.js +52 -0
  40. package/cjs/executor/Executor.js +42 -0
  41. package/cjs/executor/RuntimeApiExecutor.js +121 -0
  42. package/cjs/executor/StorageQueryExecutor.js +115 -0
  43. package/cjs/executor/TxExecutor.js +55 -0
  44. package/cjs/executor/index.js +26 -0
  45. package/cjs/executor/v2/RuntimeApiExecutorV2.js +21 -0
  46. package/cjs/executor/v2/StorageQueryExecutorV2.js +65 -0
  47. package/cjs/executor/v2/TxExecutorV2.js +20 -0
  48. package/cjs/extrinsic/extensions/ExtraSignedExtension.js +87 -0
  49. package/cjs/extrinsic/extensions/SignedExtension.js +41 -0
  50. package/cjs/extrinsic/extensions/index.js +19 -0
  51. package/cjs/extrinsic/extensions/known/ChargeAssetTxPayment.js +43 -0
  52. package/cjs/extrinsic/extensions/known/ChargeTransactionPayment.js +16 -0
  53. package/cjs/extrinsic/extensions/known/CheckGenesis.js +19 -0
  54. package/cjs/extrinsic/extensions/known/CheckMortality.js +90 -0
  55. package/cjs/extrinsic/extensions/known/CheckNonZeroSender.js +10 -0
  56. package/cjs/extrinsic/extensions/known/CheckNonce.js +33 -0
  57. package/cjs/extrinsic/extensions/known/CheckSpecVersion.js +19 -0
  58. package/cjs/extrinsic/extensions/known/CheckTxVersion.js +19 -0
  59. package/cjs/extrinsic/extensions/known/CheckWeight.js +10 -0
  60. package/cjs/extrinsic/extensions/known/PrevalidateAttests.js +11 -0
  61. package/cjs/extrinsic/extensions/known/index.js +25 -0
  62. package/cjs/extrinsic/index.js +18 -0
  63. package/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +70 -0
  64. package/cjs/extrinsic/submittable/SubmittableExtrinsic.js +47 -0
  65. package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +204 -0
  66. package/cjs/extrinsic/submittable/SubmittableResult.js +33 -0
  67. package/cjs/extrinsic/submittable/errors.js +16 -0
  68. package/cjs/extrinsic/submittable/fakeSigner.js +13 -0
  69. package/cjs/extrinsic/submittable/index.js +20 -0
  70. package/cjs/extrinsic/submittable/utils.js +20 -0
  71. package/cjs/index.js +21 -0
  72. package/cjs/json-rpc/JsonRpcClient.js +165 -0
  73. package/cjs/json-rpc/group/ChainHead/BlockUsage.js +24 -0
  74. package/cjs/json-rpc/group/ChainHead/ChainHead.js +603 -0
  75. package/cjs/json-rpc/group/ChainHead/error.js +59 -0
  76. package/cjs/json-rpc/group/ChainHead/index.js +18 -0
  77. package/cjs/json-rpc/group/ChainSpec.js +19 -0
  78. package/cjs/json-rpc/group/JsonRpcGroup.js +89 -0
  79. package/cjs/json-rpc/group/Transaction.js +25 -0
  80. package/cjs/json-rpc/group/TransactionWatch.js +17 -0
  81. package/cjs/json-rpc/group/index.js +21 -0
  82. package/cjs/json-rpc/index.js +20 -0
  83. package/cjs/json-rpc/scaledResponses.js +15 -0
  84. package/cjs/json-rpc/subscriptionsInfo.js +20 -0
  85. package/cjs/package.json +1 -0
  86. package/cjs/proxychain.js +27 -0
  87. package/cjs/storage/QueryableStorage.js +161 -0
  88. package/cjs/storage/index.js +17 -0
  89. package/cjs/types.js +2 -0
  90. package/client/BaseSubstrateClient.d.ts +65 -0
  91. package/client/BaseSubstrateClient.js +252 -0
  92. package/client/Dedot.d.ts +131 -0
  93. package/client/Dedot.js +246 -0
  94. package/client/DedotClient.d.ts +61 -0
  95. package/client/DedotClient.js +182 -0
  96. package/client/index.d.ts +2 -0
  97. package/client/index.js +2 -0
  98. package/executor/ConstantExecutor.d.ts +10 -0
  99. package/executor/ConstantExecutor.js +16 -0
  100. package/executor/ErrorExecutor.d.ts +10 -0
  101. package/executor/ErrorExecutor.js +42 -0
  102. package/executor/EventExecutor.d.ts +10 -0
  103. package/executor/EventExecutor.js +48 -0
  104. package/executor/Executor.d.ts +149 -0
  105. package/executor/Executor.js +38 -0
  106. package/executor/RuntimeApiExecutor.d.ts +27 -0
  107. package/executor/RuntimeApiExecutor.js +117 -0
  108. package/executor/StorageQueryExecutor.d.ts +14 -0
  109. package/executor/StorageQueryExecutor.js +111 -0
  110. package/executor/TxExecutor.d.ts +10 -0
  111. package/executor/TxExecutor.js +51 -0
  112. package/executor/index.d.ts +10 -0
  113. package/executor/index.js +10 -0
  114. package/executor/v2/RuntimeApiExecutorV2.d.ts +14 -0
  115. package/executor/v2/RuntimeApiExecutorV2.js +17 -0
  116. package/executor/v2/StorageQueryExecutorV2.d.ts +17 -0
  117. package/executor/v2/StorageQueryExecutorV2.js +61 -0
  118. package/executor/v2/TxExecutorV2.d.ts +11 -0
  119. package/executor/v2/TxExecutorV2.js +16 -0
  120. package/extrinsic/extensions/ExtraSignedExtension.d.ts +14 -0
  121. package/extrinsic/extensions/ExtraSignedExtension.js +60 -0
  122. package/extrinsic/extensions/SignedExtension.d.ts +40 -0
  123. package/extrinsic/extensions/SignedExtension.js +37 -0
  124. package/extrinsic/extensions/index.d.ts +3 -0
  125. package/extrinsic/extensions/index.js +3 -0
  126. package/extrinsic/extensions/known/ChargeAssetTxPayment.d.ts +14 -0
  127. package/extrinsic/extensions/known/ChargeAssetTxPayment.js +39 -0
  128. package/extrinsic/extensions/known/ChargeTransactionPayment.d.ts +6 -0
  129. package/extrinsic/extensions/known/ChargeTransactionPayment.js +12 -0
  130. package/extrinsic/extensions/known/CheckGenesis.d.ts +10 -0
  131. package/extrinsic/extensions/known/CheckGenesis.js +15 -0
  132. package/extrinsic/extensions/known/CheckMortality.d.ts +15 -0
  133. package/extrinsic/extensions/known/CheckMortality.js +86 -0
  134. package/extrinsic/extensions/known/CheckNonZeroSender.d.ts +6 -0
  135. package/extrinsic/extensions/known/CheckNonZeroSender.js +6 -0
  136. package/extrinsic/extensions/known/CheckNonce.d.ts +10 -0
  137. package/extrinsic/extensions/known/CheckNonce.js +29 -0
  138. package/extrinsic/extensions/known/CheckSpecVersion.d.ts +9 -0
  139. package/extrinsic/extensions/known/CheckSpecVersion.js +15 -0
  140. package/extrinsic/extensions/known/CheckTxVersion.d.ts +9 -0
  141. package/extrinsic/extensions/known/CheckTxVersion.js +15 -0
  142. package/extrinsic/extensions/known/CheckWeight.d.ts +6 -0
  143. package/extrinsic/extensions/known/CheckWeight.js +6 -0
  144. package/extrinsic/extensions/known/PrevalidateAttests.d.ts +7 -0
  145. package/extrinsic/extensions/known/PrevalidateAttests.js +7 -0
  146. package/extrinsic/extensions/known/index.d.ts +3 -0
  147. package/extrinsic/extensions/known/index.js +22 -0
  148. package/extrinsic/index.d.ts +2 -0
  149. package/extrinsic/index.js +2 -0
  150. package/extrinsic/submittable/BaseSubmittableExtrinsic.d.ts +17 -0
  151. package/extrinsic/submittable/BaseSubmittableExtrinsic.js +66 -0
  152. package/extrinsic/submittable/SubmittableExtrinsic.d.ts +12 -0
  153. package/extrinsic/submittable/SubmittableExtrinsic.js +43 -0
  154. package/extrinsic/submittable/SubmittableExtrinsicV2.d.ts +15 -0
  155. package/extrinsic/submittable/SubmittableExtrinsicV2.js +200 -0
  156. package/extrinsic/submittable/SubmittableResult.d.ts +19 -0
  157. package/extrinsic/submittable/SubmittableResult.js +29 -0
  158. package/extrinsic/submittable/errors.d.ts +11 -0
  159. package/extrinsic/submittable/errors.js +12 -0
  160. package/extrinsic/submittable/fakeSigner.d.ts +2 -0
  161. package/extrinsic/submittable/fakeSigner.js +10 -0
  162. package/extrinsic/submittable/index.d.ts +4 -0
  163. package/extrinsic/submittable/index.js +4 -0
  164. package/extrinsic/submittable/utils.d.ts +10 -0
  165. package/extrinsic/submittable/utils.js +15 -0
  166. package/index.d.ts +6 -0
  167. package/index.js +5 -0
  168. package/json-rpc/JsonRpcClient.d.ts +50 -0
  169. package/json-rpc/JsonRpcClient.js +160 -0
  170. package/json-rpc/group/ChainHead/BlockUsage.d.ts +11 -0
  171. package/json-rpc/group/ChainHead/BlockUsage.js +20 -0
  172. package/json-rpc/group/ChainHead/ChainHead.d.ts +70 -0
  173. package/json-rpc/group/ChainHead/ChainHead.js +599 -0
  174. package/json-rpc/group/ChainHead/error.d.ts +47 -0
  175. package/json-rpc/group/ChainHead/error.js +48 -0
  176. package/json-rpc/group/ChainHead/index.d.ts +2 -0
  177. package/json-rpc/group/ChainHead/index.js +2 -0
  178. package/json-rpc/group/ChainSpec.d.ts +10 -0
  179. package/json-rpc/group/ChainSpec.js +15 -0
  180. package/json-rpc/group/JsonRpcGroup.d.ts +74 -0
  181. package/json-rpc/group/JsonRpcGroup.js +85 -0
  182. package/json-rpc/group/Transaction.d.ts +11 -0
  183. package/json-rpc/group/Transaction.js +21 -0
  184. package/json-rpc/group/TransactionWatch.d.ts +10 -0
  185. package/json-rpc/group/TransactionWatch.js +13 -0
  186. package/json-rpc/group/index.d.ts +5 -0
  187. package/json-rpc/group/index.js +5 -0
  188. package/json-rpc/index.d.ts +4 -0
  189. package/json-rpc/index.js +4 -0
  190. package/json-rpc/scaledResponses.d.ts +2 -0
  191. package/json-rpc/scaledResponses.js +12 -0
  192. package/json-rpc/subscriptionsInfo.d.ts +2 -0
  193. package/json-rpc/subscriptionsInfo.js +17 -0
  194. package/package.json +54 -0
  195. package/proxychain.d.ts +14 -0
  196. package/proxychain.js +23 -0
  197. package/storage/QueryableStorage.d.ts +35 -0
  198. package/storage/QueryableStorage.js +157 -0
  199. package/storage/index.d.ts +1 -0
  200. package/storage/index.js +1 -0
  201. package/types.d.ts +120 -0
  202. package/types.js +1 -0
@@ -0,0 +1,182 @@
1
+ import { $H256, PortableRegistry } from '@dedot/codecs';
2
+ import { u32 } from '@dedot/shape';
3
+ import { assert, concatU8a, noop, twox64Concat, u8aToHex, xxhashAsU8a } from '@dedot/utils';
4
+ import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutorV2, StorageQueryExecutorV2, TxExecutorV2, } from '../executor/index.js';
5
+ import { ChainHead, ChainSpec, Transaction, TransactionWatch } from '../json-rpc/index.js';
6
+ import { newProxyChain } from '../proxychain.js';
7
+ import { BaseSubstrateClient, ensurePresence } from './BaseSubstrateClient.js';
8
+ /**
9
+ * @name DedotClient
10
+ * @description New promised-based API Client for Polkadot & Substrate based on JSON-RPC V2
11
+ *
12
+ * __Unstable, use with caution.__
13
+ */
14
+ export class DedotClient extends BaseSubstrateClient {
15
+ _chainHead;
16
+ _chainSpec;
17
+ _txBroadcaster;
18
+ #apiAtCache = {};
19
+ /**
20
+ * Use factory methods (`create`, `new`) to create `DedotClient` instances.
21
+ *
22
+ * @param options
23
+ */
24
+ constructor(options) {
25
+ super('v2', options);
26
+ }
27
+ /**
28
+ * Factory method to create a new DedotClient instance
29
+ *
30
+ * @param options
31
+ */
32
+ static async create(options) {
33
+ return new DedotClient(options).connect();
34
+ }
35
+ /**
36
+ * Alias for __DedotClient.create__
37
+ *
38
+ * @param options
39
+ */
40
+ static async new(options) {
41
+ return DedotClient.create(options);
42
+ }
43
+ get chainSpec() {
44
+ return ensurePresence(this._chainSpec);
45
+ }
46
+ get chainHead() {
47
+ return ensurePresence(this._chainHead);
48
+ }
49
+ get txBroadcaster() {
50
+ this.chainHead; // Ensure chain head is initialized
51
+ assert(this._txBroadcaster, 'JSON-RPC method to broadcast transactions is not supported by the server/node.');
52
+ return this._txBroadcaster;
53
+ }
54
+ async #initializeTxBroadcaster(rpcMethods) {
55
+ const tx = new Transaction(this, { rpcMethods });
56
+ if (await tx.supported())
57
+ return tx;
58
+ const txWatch = new TransactionWatch(this, { rpcMethods });
59
+ if (await txWatch.supported())
60
+ return txWatch;
61
+ }
62
+ /**
63
+ * Initialize APIs before usage
64
+ */
65
+ async doInitialize() {
66
+ const rpcMethods = (await this.rpc.rpc_methods()).methods;
67
+ this._chainHead = new ChainHead(this, { rpcMethods });
68
+ this._chainSpec = new ChainSpec(this, { rpcMethods });
69
+ this._txBroadcaster = await this.#initializeTxBroadcaster(rpcMethods);
70
+ // Fetching node information
71
+ let [_, genesisHash] = await Promise.all([
72
+ this.chainHead.follow(),
73
+ this.chainSpec.genesisHash().catch(() => undefined),
74
+ ]);
75
+ this._genesisHash = genesisHash || (await this.#getGenesisHashFallback());
76
+ this._runtimeVersion = await this.chainHead.bestRuntimeVersion();
77
+ let metadata;
78
+ if (await this.shouldPreloadMetadata()) {
79
+ metadata = await this.fetchMetadata();
80
+ }
81
+ await this.setupMetadata(metadata);
82
+ this.subscribeRuntimeUpgrades();
83
+ }
84
+ /**
85
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/bbd51ce867967f71657b901f1a956ad4f75d352e/substrate/frame/system/src/lib.rs#L909-L913
86
+ * @private
87
+ */
88
+ async #getGenesisHashFallback() {
89
+ const pallet = xxhashAsU8a('System', 128);
90
+ const item = xxhashAsU8a('BlockHash', 128);
91
+ const blockHeightAt0 = twox64Concat(u32.encode(0));
92
+ const key = u8aToHex(concatU8a(pallet, item, blockHeightAt0));
93
+ const storageValue = await this.chainHead.storage([{ type: 'value', key }]);
94
+ const rawGenesisHash = storageValue.at(0)?.value;
95
+ assert(rawGenesisHash, 'Genesis hash not found!');
96
+ // Here we assume that in most case the hash is stored as a H256
97
+ return $H256.tryDecode(rawGenesisHash);
98
+ }
99
+ subscribeRuntimeUpgrades() {
100
+ this.chainHead.on('bestBlock', this.onRuntimeUpgrade);
101
+ }
102
+ unsubscribeRuntimeUpgrades() {
103
+ this.chainHead.off('bestBlock', this.onRuntimeUpgrade);
104
+ }
105
+ onRuntimeUpgrade = async (block) => {
106
+ const runtimeUpgraded = block.runtime && block.runtime.specVersion !== this._runtimeVersion?.specVersion;
107
+ if (!runtimeUpgraded)
108
+ return;
109
+ this._runtimeVersion = block.runtime;
110
+ const newMetadata = await this.fetchMetadata(undefined, this._runtimeVersion);
111
+ await this.setupMetadata(newMetadata);
112
+ };
113
+ async beforeDisconnect() {
114
+ await this.chainHead.unfollow();
115
+ }
116
+ onDisconnected = async () => {
117
+ this.chainHead.unfollow().catch(noop);
118
+ };
119
+ cleanUp() {
120
+ super.cleanUp();
121
+ this._chainHead = undefined;
122
+ this._chainSpec = undefined;
123
+ this._txBroadcaster = undefined;
124
+ this.#apiAtCache = {};
125
+ }
126
+ get query() {
127
+ return newProxyChain({
128
+ executor: new StorageQueryExecutorV2(this, this.chainHead),
129
+ });
130
+ }
131
+ get call() {
132
+ return this.callAt();
133
+ }
134
+ callAt(blockHash) {
135
+ return newProxyChain({
136
+ executor: new RuntimeApiExecutorV2(this, this.chainHead, blockHash),
137
+ });
138
+ }
139
+ get tx() {
140
+ return newProxyChain({ executor: new TxExecutorV2(this) });
141
+ }
142
+ /**
143
+ * Get a new API instance at a specific block hash
144
+ * For now, this only supports pinned block hashes from the chain head
145
+ *
146
+ * @param hash
147
+ */
148
+ async at(hash) {
149
+ if (this.#apiAtCache[hash])
150
+ return this.#apiAtCache[hash];
151
+ const targetBlock = this.chainHead.findBlock(hash);
152
+ assert(targetBlock, 'Block is not pinned!');
153
+ let targetVersion = targetBlock.runtime;
154
+ if (!targetVersion) {
155
+ // fallback to fetching on-chain runtime if we can't find it in the block
156
+ targetVersion = this.toSubstrateRuntimeVersion(await this.callAt(hash).core.version());
157
+ }
158
+ let metadata = this.metadata;
159
+ let registry = this.registry;
160
+ if (targetVersion && targetVersion.specVersion !== this.runtimeVersion.specVersion) {
161
+ metadata = await this.fetchMetadata(hash, targetVersion);
162
+ registry = new PortableRegistry(metadata.latest, this.options.hasher);
163
+ }
164
+ const api = {
165
+ rpcVersion: 'v2',
166
+ atBlockHash: hash,
167
+ options: this.options,
168
+ genesisHash: this.genesisHash,
169
+ runtimeVersion: targetVersion,
170
+ metadata,
171
+ registry,
172
+ rpc: this.rpc,
173
+ };
174
+ api.consts = newProxyChain({ executor: new ConstantExecutor(api) });
175
+ api.events = newProxyChain({ executor: new EventExecutor(api) });
176
+ api.errors = newProxyChain({ executor: new ErrorExecutor(api) });
177
+ api.query = newProxyChain({ executor: new StorageQueryExecutorV2(api, this.chainHead) });
178
+ api.call = newProxyChain({ executor: new RuntimeApiExecutorV2(api, this.chainHead) });
179
+ this.#apiAtCache[hash] = api;
180
+ return api;
181
+ }
182
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Dedot.js';
2
+ export * from './DedotClient.js';
@@ -0,0 +1,2 @@
1
+ export * from './Dedot.js';
2
+ export * from './DedotClient.js';
@@ -0,0 +1,10 @@
1
+ import { GenericSubstrateApi } from '@dedot/types';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name ConstantExecutor
5
+ *
6
+ * Find & decode the constant value from metadata
7
+ */
8
+ export declare class ConstantExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
9
+ doExecute(pallet: string, constantName: string): unknown;
10
+ }
@@ -0,0 +1,16 @@
1
+ import { assert, stringCamelCase, UnknownApiError } from '@dedot/utils';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name ConstantExecutor
5
+ *
6
+ * Find & decode the constant value from metadata
7
+ */
8
+ export class ConstantExecutor extends Executor {
9
+ doExecute(pallet, constantName) {
10
+ const targetPallet = this.getPallet(pallet);
11
+ const constantDef = targetPallet.constants.find((one) => stringCamelCase(one.name) === constantName);
12
+ assert(constantDef, new UnknownApiError(`Constant ${constantName} not found in pallet ${pallet}`));
13
+ const $codec = this.registry.findCodec(constantDef.typeId);
14
+ return $codec.tryDecode(constantDef.value);
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ import type { GenericPalletError, GenericSubstrateApi } from '@dedot/types';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name ErrorExecutor
5
+ * @description Find pallet error information from metadata
6
+ */
7
+ export declare class ErrorExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
8
+ #private;
9
+ doExecute(pallet: string, errorName: string): GenericPalletError;
10
+ }
@@ -0,0 +1,42 @@
1
+ import { assert, hexToU8a, isHex, isNumber, isObject, stringPascalCase, UnknownApiError } from '@dedot/utils';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name ErrorExecutor
5
+ * @description Find pallet error information from metadata
6
+ */
7
+ export class ErrorExecutor extends Executor {
8
+ doExecute(pallet, errorName) {
9
+ const targetPallet = this.getPallet(pallet);
10
+ const errorTypeId = targetPallet.error;
11
+ assert(errorTypeId, new UnknownApiError(`Not found error with id ${errorTypeId} in pallet ${pallet}`));
12
+ const errorDef = this.#getErrorDef(errorTypeId, errorName);
13
+ return {
14
+ meta: {
15
+ ...errorDef,
16
+ pallet: targetPallet.name,
17
+ palletIndex: targetPallet.index,
18
+ },
19
+ is: (errorInfo) => {
20
+ if (isObject(errorInfo) && errorInfo.tag === 'Module') {
21
+ errorInfo = errorInfo.value;
22
+ }
23
+ if (isObject(errorInfo) && isNumber(errorInfo.index) && isHex(errorInfo.error)) {
24
+ return errorInfo.index === targetPallet.index && hexToU8a(errorInfo.error)[0] === errorDef.index;
25
+ }
26
+ return false;
27
+ },
28
+ };
29
+ }
30
+ #getErrorDef(errorTypeId, errorName) {
31
+ const def = this.metadata.types[errorTypeId];
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}`));
35
+ const errorDef = value.members.find(({ name }) => stringPascalCase(name) === errorName);
36
+ assert(errorDef, new UnknownApiError(`Error def not found for ${errorName}`));
37
+ return {
38
+ ...errorDef,
39
+ fieldCodecs: errorDef.fields.map(({ typeId }) => this.registry.findCodec(typeId)),
40
+ };
41
+ }
42
+ }
@@ -0,0 +1,10 @@
1
+ import type { GenericPalletEvent, GenericSubstrateApi } from '@dedot/types';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name EventExecutor
5
+ * @description Find pallet event information from metadata
6
+ */
7
+ export declare class EventExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
8
+ #private;
9
+ doExecute(pallet: string, errorName: string): GenericPalletEvent;
10
+ }
@@ -0,0 +1,48 @@
1
+ import { assert, stringCamelCase, stringPascalCase, UnknownApiError } from '@dedot/utils';
2
+ import { Executor } from './Executor.js';
3
+ /**
4
+ * @name EventExecutor
5
+ * @description Find pallet event information from metadata
6
+ */
7
+ export class EventExecutor extends Executor {
8
+ doExecute(pallet, errorName) {
9
+ const targetPallet = this.getPallet(pallet);
10
+ const eventTypeId = targetPallet.event;
11
+ assert(eventTypeId, new UnknownApiError(`Not found event with id ${eventTypeId} in pallet ${pallet}`));
12
+ const eventDef = this.#getEventDef(eventTypeId, errorName);
13
+ const is = (event) => {
14
+ const palletCheck = stringCamelCase(event.pallet) === pallet;
15
+ if (typeof event.palletEvent === 'string') {
16
+ return palletCheck && stringPascalCase(event.palletEvent) === errorName;
17
+ }
18
+ else if (typeof event.palletEvent === 'object') {
19
+ return palletCheck && stringPascalCase(event.palletEvent.name) === errorName;
20
+ }
21
+ return false;
22
+ };
23
+ const as = (event) => {
24
+ return is(event) ? event : undefined;
25
+ };
26
+ return {
27
+ is,
28
+ as,
29
+ meta: {
30
+ ...eventDef,
31
+ pallet: targetPallet.name,
32
+ palletIndex: targetPallet.index,
33
+ },
34
+ };
35
+ }
36
+ #getEventDef(eventTypeId, errorName) {
37
+ const def = this.metadata.types[eventTypeId];
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}`));
41
+ const eventDef = value.members.find(({ name }) => stringPascalCase(name) === errorName);
42
+ assert(eventDef, new UnknownApiError(`Event def not found for ${errorName}`));
43
+ return {
44
+ ...eventDef,
45
+ fieldCodecs: eventDef.fields.map(({ typeId }) => this.registry.findCodec(typeId)),
46
+ };
47
+ }
48
+ }
@@ -0,0 +1,149 @@
1
+ import type { BlockHash, PalletDefLatest } from '@dedot/codecs';
2
+ import type { GenericSubstrateApi } from '@dedot/types';
3
+ import { ISubstrateClientAt } from '../types.js';
4
+ /**
5
+ * @name Executor
6
+ * @description Execution abstraction for a specific action
7
+ */
8
+ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> {
9
+ #private;
10
+ api: ISubstrateClientAt<ChainApi>;
11
+ constructor(api: ISubstrateClientAt<ChainApi>, atBlockHash?: BlockHash);
12
+ get atBlockHash(): `0x${string}` | undefined;
13
+ get registry(): import("@dedot/codecs").PortableRegistry;
14
+ get metadata(): {
15
+ types: {
16
+ id: number;
17
+ path: string[];
18
+ params: {
19
+ name: string;
20
+ typeId: number | undefined;
21
+ }[];
22
+ type: {
23
+ tag: "Struct";
24
+ value: {
25
+ fields: import("@dedot/codecs").Field[];
26
+ };
27
+ } | {
28
+ tag: "Enum";
29
+ value: {
30
+ members: {
31
+ name: string;
32
+ fields: import("@dedot/codecs").Field[];
33
+ index: number;
34
+ docs: string[];
35
+ }[];
36
+ };
37
+ } | {
38
+ tag: "Sequence";
39
+ value: {
40
+ typeParam: number;
41
+ };
42
+ } | {
43
+ tag: "SizedVec";
44
+ value: {
45
+ len: number;
46
+ typeParam: number;
47
+ };
48
+ } | {
49
+ tag: "Tuple";
50
+ value: {
51
+ fields: number[];
52
+ };
53
+ } | {
54
+ tag: "Primitive";
55
+ value: {
56
+ kind: "bool" | "char" | "str" | "u8" | "u16" | "u32" | "u64" | "u128" | "u256" | "i8" | "i16" | "i32" | "i64" | "i128" | "i256";
57
+ };
58
+ } | {
59
+ tag: "Compact";
60
+ value: {
61
+ typeParam: number;
62
+ };
63
+ } | {
64
+ tag: "BitSequence";
65
+ value: {
66
+ bitOrderType: number;
67
+ bitStoreType: number;
68
+ };
69
+ };
70
+ docs: string[];
71
+ }[];
72
+ pallets: {
73
+ name: string;
74
+ storage: {
75
+ prefix: string;
76
+ entries: {
77
+ name: string;
78
+ modifier: string;
79
+ type: {
80
+ tag: "Plain";
81
+ value: {
82
+ valueTypeId: number;
83
+ };
84
+ } | {
85
+ tag: "Map";
86
+ value: {
87
+ hashers: ("identity" | "blake2_128" | "blake2_256" | "blake2_128Concat" | "twox128" | "twox256" | "twox64Concat")[];
88
+ keyTypeId: number;
89
+ valueTypeId: number;
90
+ };
91
+ };
92
+ default: `0x${string}`;
93
+ docs: string[];
94
+ }[];
95
+ } | undefined;
96
+ calls: number | undefined;
97
+ event: number | undefined;
98
+ constants: {
99
+ name: string;
100
+ typeId: number;
101
+ value: `0x${string}`;
102
+ docs: string[];
103
+ }[];
104
+ error: number | undefined;
105
+ index: number;
106
+ docs: string[];
107
+ }[];
108
+ extrinsic: {
109
+ version: number;
110
+ addressTypeId: number;
111
+ callTypeId: number;
112
+ signatureTypeId: number;
113
+ extraTypeId: number;
114
+ signedExtensions: {
115
+ ident: string;
116
+ typeId: number;
117
+ additionalSigned: number;
118
+ }[];
119
+ };
120
+ runtimeType: number;
121
+ apis: {
122
+ name: string;
123
+ methods: {
124
+ name: string;
125
+ inputs: {
126
+ name: string;
127
+ typeId: number;
128
+ }[];
129
+ output: number;
130
+ docs: string[];
131
+ }[];
132
+ docs: string[];
133
+ }[];
134
+ outerEnums: {
135
+ callEnumTypeId: number;
136
+ eventEnumTypeId: number;
137
+ errorEnumTypeId: number;
138
+ };
139
+ custom: {
140
+ map: ReadonlyMap<string, {
141
+ typeId: number;
142
+ value: `0x${string}`;
143
+ }>;
144
+ };
145
+ };
146
+ getPallet(name: string): PalletDefLatest;
147
+ execute(...paths: string[]): unknown;
148
+ abstract doExecute(...paths: string[]): unknown;
149
+ }
@@ -0,0 +1,38 @@
1
+ import { assert, stringCamelCase, UnknownApiError } from '@dedot/utils';
2
+ /**
3
+ * @name Executor
4
+ * @description Execution abstraction for a specific action
5
+ */
6
+ export class Executor {
7
+ api;
8
+ #atBlockHash;
9
+ constructor(api, atBlockHash) {
10
+ this.api = api;
11
+ this.#atBlockHash = atBlockHash;
12
+ }
13
+ get atBlockHash() {
14
+ return this.#atBlockHash || this.api.atBlockHash;
15
+ }
16
+ get registry() {
17
+ return this.api.registry;
18
+ }
19
+ get metadata() {
20
+ return this.registry.metadata;
21
+ }
22
+ getPallet(name) {
23
+ const targetPallet = this.metadata.pallets.find((p) => stringCamelCase(p.name) === name);
24
+ assert(targetPallet, new UnknownApiError(`Pallet not found: ${name}`));
25
+ return targetPallet;
26
+ }
27
+ execute(...paths) {
28
+ try {
29
+ return this.doExecute(...paths);
30
+ }
31
+ catch (e) {
32
+ if (!this.api.options?.throwOnUnknownApi && e instanceof UnknownApiError) {
33
+ return undefined;
34
+ }
35
+ throw e;
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,27 @@
1
+ import { BlockHash } from '@dedot/codecs';
2
+ import type { GenericRuntimeApiMethod, GenericSubstrateApi, RuntimeApiMethodParamSpec, RuntimeApiMethodSpec, RuntimeApiSpec } from '@dedot/types';
3
+ import { HexString } from '@dedot/utils';
4
+ import { Executor } from './Executor.js';
5
+ export declare const FallbackRuntimeApis: Record<string, number>;
6
+ export declare const FallbackRuntimeApiSpecs: {
7
+ Metadata: RuntimeApiSpec[];
8
+ };
9
+ export interface StateCallParams {
10
+ func: string;
11
+ params: HexString;
12
+ at?: BlockHash;
13
+ }
14
+ /**
15
+ * @name RuntimeApiExecutor
16
+ * @description Execute a runtime api call,
17
+ * runtime api definitions/specs are either from Metadata V15
18
+ * or defined externally when initializing `Dedot` instance
19
+ * via `ApiOptions.runtimeApis` option.
20
+ */
21
+ export declare class RuntimeApiExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
22
+ #private;
23
+ doExecute(runtimeApi: string, method: string): GenericRuntimeApiMethod;
24
+ protected stateCall(callParams: StateCallParams): Promise<HexString>;
25
+ tryDecode(callSpec: RuntimeApiMethodSpec, raw: any): unknown;
26
+ tryEncode(paramSpec: RuntimeApiMethodParamSpec, value: any): Uint8Array;
27
+ }
@@ -0,0 +1,117 @@
1
+ import { Metadata, toRuntimeApiMethods, toRuntimeApiSpecs } from '@dedot/runtime-specs';
2
+ import { assert, calcRuntimeApiHash, concatU8a, isNumber, stringPascalCase, stringSnakeCase, u8aToHex, UnknownApiError, } from '@dedot/utils';
3
+ import { Executor } from './Executor.js';
4
+ export const FallbackRuntimeApis = { '0x37e397fc7c91f5e4': 2 };
5
+ export const FallbackRuntimeApiSpecs = { Metadata };
6
+ /**
7
+ * @name RuntimeApiExecutor
8
+ * @description Execute a runtime api call,
9
+ * runtime api definitions/specs are either from Metadata V15
10
+ * or defined externally when initializing `Dedot` instance
11
+ * via `ApiOptions.runtimeApis` option.
12
+ */
13
+ export class RuntimeApiExecutor extends Executor {
14
+ doExecute(runtimeApi, method) {
15
+ const runtimeApiName = stringPascalCase(runtimeApi);
16
+ const methodName = stringSnakeCase(method);
17
+ const callName = this.#callName({ runtimeApiName, methodName });
18
+ const callSpec = this.#findRuntimeApiMethodSpec(runtimeApiName, methodName);
19
+ assert(callSpec, new UnknownApiError(`Runtime api spec not found for ${callName}`));
20
+ const callFn = async (...args) => {
21
+ const { params } = callSpec;
22
+ const formattedInputs = params.map((param, index) => this.tryEncode(param, args[index]));
23
+ const bytes = u8aToHex(concatU8a(...formattedInputs));
24
+ const callParams = {
25
+ func: callName,
26
+ params: bytes,
27
+ at: this.atBlockHash,
28
+ };
29
+ const result = await this.stateCall(callParams);
30
+ return this.tryDecode(callSpec, result);
31
+ };
32
+ callFn.meta = callSpec;
33
+ return callFn;
34
+ }
35
+ stateCall(callParams) {
36
+ const { func, params, at } = callParams;
37
+ const args = [func, params];
38
+ if (at)
39
+ args.push(at);
40
+ return this.api.rpc.state_call(...args);
41
+ }
42
+ tryDecode(callSpec, raw) {
43
+ const $codec = this.#findCodec(callSpec, `Codec not found to decode respond data for ${this.#callName(callSpec)}`);
44
+ return $codec.tryDecode(raw);
45
+ }
46
+ tryEncode(paramSpec, value) {
47
+ const $codec = this.#findCodec(paramSpec, `Codec not found to encode input for param ${paramSpec.name}`);
48
+ return $codec.tryEncode(value);
49
+ }
50
+ #findCodec(spec, error) {
51
+ const { codec, typeId, type } = spec;
52
+ if (codec)
53
+ return codec;
54
+ if (isNumber(typeId)) {
55
+ return this.registry.findCodec(typeId);
56
+ }
57
+ throw new Error(error || 'Codec not found');
58
+ }
59
+ #callName({ runtimeApiName, methodName }) {
60
+ return `${runtimeApiName}_${methodName}`;
61
+ }
62
+ #findRuntimeApiMethodSpec(runtimeApi, method) {
63
+ const targetVersion = this.#findTargetRuntimeApiVersion(runtimeApi);
64
+ if (!isNumber(targetVersion))
65
+ return undefined;
66
+ const userDefinedSpec = this.#findDefinedSpec(this.api.options.runtimeApis, runtimeApi, method, targetVersion);
67
+ if (userDefinedSpec)
68
+ return userDefinedSpec;
69
+ const methodDef = this.#findRuntimeApiMethodDef(runtimeApi, method);
70
+ if (methodDef) {
71
+ return this.#toMethodSpec(runtimeApi, methodDef);
72
+ }
73
+ return this.#findDefinedSpec(FallbackRuntimeApiSpecs, runtimeApi, method, targetVersion);
74
+ }
75
+ #findRuntimeApiMethodDef(runtimeApi, method) {
76
+ try {
77
+ for (const api of this.metadata.apis) {
78
+ if (api.name !== runtimeApi)
79
+ continue;
80
+ for (const apiMethod of api.methods) {
81
+ if (apiMethod.name === method)
82
+ return apiMethod;
83
+ }
84
+ }
85
+ }
86
+ catch { }
87
+ }
88
+ #toMethodSpec(runtimeApi, methodDef) {
89
+ const { name, inputs, output, docs } = methodDef;
90
+ return {
91
+ docs,
92
+ runtimeApiName: runtimeApi,
93
+ methodName: name,
94
+ typeId: output,
95
+ params: inputs.map(({ name, typeId }) => ({
96
+ name,
97
+ typeId,
98
+ })),
99
+ };
100
+ }
101
+ #findTargetRuntimeApiVersion(runtimeApi) {
102
+ const runtimeApiHash = calcRuntimeApiHash(runtimeApi);
103
+ try {
104
+ return this.api.runtimeVersion.apis[runtimeApiHash] || FallbackRuntimeApis[runtimeApiHash];
105
+ }
106
+ catch {
107
+ return FallbackRuntimeApis[runtimeApiHash];
108
+ }
109
+ }
110
+ #findDefinedSpec(specs, runtimeApi, method, runtimeApiVersion) {
111
+ if (!specs)
112
+ return undefined;
113
+ const methodSpecs = toRuntimeApiSpecs(specs).map(toRuntimeApiMethods).flat();
114
+ return methodSpecs.find(({ runtimeApiName, methodName, version }) => `${stringPascalCase(runtimeApiName)}_${stringSnakeCase(methodName)}` === `${runtimeApi}_${method}` &&
115
+ runtimeApiVersion === version);
116
+ }
117
+ }
@@ -0,0 +1,14 @@
1
+ import { BlockHash, Option, StorageData, StorageKey } from '@dedot/codecs';
2
+ import type { AsyncMethod, Callback, GenericStorageQuery, GenericSubstrateApi, Unsub } from '@dedot/types';
3
+ import { QueryableStorage } from '../storage/QueryableStorage.js';
4
+ import { Executor } from './Executor.js';
5
+ /**
6
+ * @name StorageQueryExecutor
7
+ * @description Execute a query to on-chain storage
8
+ */
9
+ export declare class StorageQueryExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
10
+ doExecute(pallet: string, storage: string): GenericStorageQuery;
11
+ protected exposeStorageMapMethods(entry: QueryableStorage): Record<string, AsyncMethod>;
12
+ protected queryStorage(keys: StorageKey[], hash?: BlockHash): Promise<Record<StorageKey, Option<StorageData>>>;
13
+ protected subscribeStorage(keys: StorageKey[], callback: Callback<Array<StorageData | undefined>>): Promise<Unsub>;
14
+ }