dedot 0.0.1-alpha.28 → 0.0.1-alpha.29

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 (90) hide show
  1. package/README.md +156 -13
  2. package/cjs/client/Dedot.js +87 -24
  3. package/cjs/client/index.js +1 -1
  4. package/cjs/executor/ConstantExecutor.js +6 -8
  5. package/cjs/executor/ErrorExecutor.js +11 -12
  6. package/cjs/executor/EventExecutor.js +11 -12
  7. package/cjs/executor/Executor.js +15 -6
  8. package/cjs/executor/RpcExecutor.js +8 -12
  9. package/cjs/executor/RuntimeApiExecutor.js +17 -11
  10. package/cjs/executor/StorageQueryExecutor.js +34 -8
  11. package/cjs/executor/TxExecutor.js +24 -26
  12. package/cjs/executor/index.js +8 -8
  13. package/cjs/extrinsic/extensions/ExtraSignedExtension.js +6 -7
  14. package/cjs/extrinsic/extensions/index.js +3 -3
  15. package/cjs/extrinsic/extensions/known/ChargeAssetTxPayment.js +3 -4
  16. package/cjs/extrinsic/extensions/known/ChargeTransactionPayment.js +2 -2
  17. package/cjs/extrinsic/extensions/known/CheckGenesis.js +2 -2
  18. package/cjs/extrinsic/extensions/known/CheckMortality.js +5 -6
  19. package/cjs/extrinsic/extensions/known/CheckNonZeroSender.js +2 -2
  20. package/cjs/extrinsic/extensions/known/CheckNonce.js +3 -4
  21. package/cjs/extrinsic/extensions/known/CheckSpecVersion.js +4 -4
  22. package/cjs/extrinsic/extensions/known/CheckTxVersion.js +4 -4
  23. package/cjs/extrinsic/extensions/known/CheckWeight.js +2 -2
  24. package/cjs/extrinsic/extensions/known/PrevalidateAttests.js +2 -2
  25. package/cjs/extrinsic/extensions/known/index.js +20 -20
  26. package/cjs/extrinsic/index.js +2 -2
  27. package/cjs/index.js +4 -4
  28. package/cjs/proxychain.js +7 -0
  29. package/cjs/storage/QueryableStorage.js +8 -9
  30. package/client/Dedot.d.ts +33 -7
  31. package/client/Dedot.js +78 -15
  32. package/client/index.d.ts +1 -1
  33. package/client/index.js +1 -1
  34. package/executor/ConstantExecutor.d.ts +2 -2
  35. package/executor/ConstantExecutor.js +4 -6
  36. package/executor/ErrorExecutor.d.ts +2 -2
  37. package/executor/ErrorExecutor.js +7 -8
  38. package/executor/EventExecutor.d.ts +2 -2
  39. package/executor/EventExecutor.js +7 -8
  40. package/executor/Executor.d.ts +5 -4
  41. package/executor/Executor.js +14 -5
  42. package/executor/RpcExecutor.d.ts +3 -3
  43. package/executor/RpcExecutor.js +6 -10
  44. package/executor/RuntimeApiExecutor.d.ts +9 -2
  45. package/executor/RuntimeApiExecutor.js +13 -7
  46. package/executor/StorageQueryExecutor.d.ts +3 -3
  47. package/executor/StorageQueryExecutor.js +32 -6
  48. package/executor/TxExecutor.d.ts +4 -4
  49. package/executor/TxExecutor.js +8 -10
  50. package/executor/index.d.ts +8 -8
  51. package/executor/index.js +8 -8
  52. package/extrinsic/extensions/ExtraSignedExtension.d.ts +1 -1
  53. package/extrinsic/extensions/ExtraSignedExtension.js +4 -5
  54. package/extrinsic/extensions/SignedExtension.d.ts +1 -1
  55. package/extrinsic/extensions/index.d.ts +3 -3
  56. package/extrinsic/extensions/index.js +3 -3
  57. package/extrinsic/extensions/known/ChargeAssetTxPayment.d.ts +1 -1
  58. package/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -3
  59. package/extrinsic/extensions/known/ChargeTransactionPayment.d.ts +1 -1
  60. package/extrinsic/extensions/known/ChargeTransactionPayment.js +1 -1
  61. package/extrinsic/extensions/known/CheckGenesis.d.ts +1 -1
  62. package/extrinsic/extensions/known/CheckGenesis.js +1 -1
  63. package/extrinsic/extensions/known/CheckMortality.d.ts +1 -1
  64. package/extrinsic/extensions/known/CheckMortality.js +3 -4
  65. package/extrinsic/extensions/known/CheckNonZeroSender.d.ts +1 -1
  66. package/extrinsic/extensions/known/CheckNonZeroSender.js +1 -1
  67. package/extrinsic/extensions/known/CheckNonce.d.ts +1 -1
  68. package/extrinsic/extensions/known/CheckNonce.js +2 -3
  69. package/extrinsic/extensions/known/CheckSpecVersion.d.ts +1 -1
  70. package/extrinsic/extensions/known/CheckSpecVersion.js +2 -2
  71. package/extrinsic/extensions/known/CheckTxVersion.d.ts +1 -1
  72. package/extrinsic/extensions/known/CheckTxVersion.js +2 -2
  73. package/extrinsic/extensions/known/CheckWeight.d.ts +1 -1
  74. package/extrinsic/extensions/known/CheckWeight.js +1 -1
  75. package/extrinsic/extensions/known/PrevalidateAttests.d.ts +1 -1
  76. package/extrinsic/extensions/known/PrevalidateAttests.js +1 -1
  77. package/extrinsic/extensions/known/index.d.ts +1 -1
  78. package/extrinsic/extensions/known/index.js +10 -10
  79. package/extrinsic/index.d.ts +2 -2
  80. package/extrinsic/index.js +2 -2
  81. package/index.d.ts +4 -5
  82. package/index.js +3 -4
  83. package/package.json +9 -10
  84. package/proxychain.d.ts +8 -1
  85. package/proxychain.js +7 -0
  86. package/storage/QueryableStorage.js +6 -7
  87. package/types.d.ts +9 -1
  88. package/cjs/packageInfo.js +0 -5
  89. package/packageInfo.d.ts +0 -4
  90. package/packageInfo.js +0 -3
package/README.md CHANGED
@@ -87,23 +87,25 @@ const api = await Dedot.new('wss://rpc.polkadot.io');
87
87
  - [Submit Transactions](#transaction-apis)
88
88
  - [Events](#events)
89
89
  - [Errors](#errors)
90
+ - [`@polkadot/api` -> `dedot`](#migration-from-polkadotapi-to-dedot)
90
91
  - [Credit](#credit)
91
92
 
92
93
  ### Status
93
94
 
94
- | Feature | Status |
95
- |-------------------------------------------------------| ----------- |
96
- | Execute RPC (`api.rpc`) | ✅ |
97
- | Query On-chain Storage (`api.query`) | ✅ |
98
- | Get runtime constants (`api.consts`) | ✅ |
99
- | Runtime APIs (`api.call`) | ✅ |
100
- | Transaction APIs (`api.tx`) | ✅ |
101
- | Events (`api.events`) | ✅ |
102
- | Errors (`api.errors`) | ✅ |
103
- | Contract APIs | ⏳ |
104
- | Metadata v14 | ✅ |
105
- | Metadata v15 | ✅ |
106
- | [RPC v2](https://github.com/dedotdev/dedot/issues/20) | ⏳ |
95
+ | Feature | Status |
96
+ |-------------------------------------------------------------|--------|
97
+ | Execute RPC (`api.rpc`) | ✅ |
98
+ | Query On-chain Storage (`api.query`) | ✅ |
99
+ | Get runtime constants (`api.consts`) | ✅ |
100
+ | Runtime APIs (`api.call`) | ✅ |
101
+ | Transaction APIs (`api.tx`) | ✅ |
102
+ | Events (`api.events`) | ✅ |
103
+ | Errors (`api.errors`) | ✅ |
104
+ | Contract APIs | ⏳ |
105
+ | Metadata v14 | ✅ |
106
+ | Metadata v15 | ✅ |
107
+ | [RPC v2](https://github.com/dedotdev/dedot/issues/20) | ⏳ |
108
+ | [Extrinsic V5](https://github.com/dedotdev/dedot/issues/55) | ⏳ |
107
109
 
108
110
  ### Chain Types & APIs
109
111
 
@@ -299,6 +301,67 @@ const unsub = api.tx.utility.batch([transferTx.call, remarkCall])
299
301
  });
300
302
  ```
301
303
 
304
+ <details>
305
+ <summary>Example 4: Teleport WND from Westend Asset Hub to Westend via XCM</summary>
306
+
307
+ ```typescript
308
+ import { WestendAssetHubApi, XcmVersionedLocation, XcmVersionedAssets, XcmV3WeightLimit } from '@dedot/chaintypes/westendAssetHub';
309
+ import { AccountId32 } from '@dedot/codecs';
310
+
311
+ const TWO_TOKENS = 2_000_000_000_000n;
312
+ const destAddress = <bobAddress>;
313
+
314
+ const api = await Dedot.new<WestendAssetHubApi>('...westend-assethub-rpc...');
315
+
316
+ const dest: XcmVersionedLocation = {
317
+ tag: 'V3',
318
+ value: { parents: 1, interior: { tag: 'Here' } },
319
+ };
320
+
321
+ const beneficiary: XcmVersionedLocation = {
322
+ tag: 'V3',
323
+ value: {
324
+ parents: 0,
325
+ interior: {
326
+ tag: 'X1',
327
+ value: {
328
+ tag: 'AccountId32',
329
+ value: { id: new AccountId32(destAddress).raw },
330
+ },
331
+ },
332
+ },
333
+ };
334
+
335
+ const assets: XcmVersionedAssets = {
336
+ tag: 'V3',
337
+ value: [
338
+ {
339
+ id: {
340
+ tag: 'Concrete',
341
+ value: {
342
+ parents: 1,
343
+ interior: { tag: 'Here' },
344
+ },
345
+ },
346
+ fun: {
347
+ tag: 'Fungible',
348
+ value: TWO_TOKENS,
349
+ },
350
+ },
351
+ ],
352
+ };
353
+
354
+ const weight: XcmV3WeightLimit = { tag: 'Unlimited' };
355
+
356
+ api.tx.polkadotXcm
357
+ .limitedTeleportAssets(dest, beneficiary, assets, 0, weight)
358
+ .signAndSend(alice, { signer, tip: 1_000_000n }, (result) => {
359
+ console.dir(result, { depth: null });
360
+ });
361
+ ```
362
+ </details>
363
+
364
+
302
365
  ### Events
303
366
 
304
367
  Events for each pallet emit during runtime operations and are defined in the medata. Available events are also exposed in `ChainApi` interface so we can get information of an event through syntax `api.events.<pallet>.<eventName>`. E.g: Events for Polkadot network can be found [here](https://github.com/dedotdev/dedot/blob/main/packages/chaintypes/src/polkadot/events.d.ts), similarly for other network as well.
@@ -347,6 +410,86 @@ await api.query.system.events(async (eventRecords) => {
347
410
  // ...
348
411
  ```
349
412
 
413
+ ### Migration from `@polkadot/api` to `dedot`
414
+ `dedot` is inspired by `@polkadot/api`, so both are sharing some common patterns and api styling (eg: api syntax `api.<type>.<module>.<section>`). Although we have experimented some other different api stylings but to our findings and development experience, we find that the api style of `@polkadot/api` is very intuiative and easy to use. We decide the use a similar api styling with `@polkadot/api`, this also helps the migration from `@polkadot/api` to `dedot` easier & faster.
415
+
416
+ While the api style are similar, but there're also some differences you might need to be aware of when switching to use `dedot`.
417
+
418
+ **Initialize api client**
419
+ - `@polkadot/api`
420
+ ```typescript
421
+ import { ApiPromise, WsProvider } from '@polkadot/api';
422
+
423
+ const api = await ApiPromise.create({ provider: new WsProvider('wss://rpc.polkadot.io') });
424
+ ```
425
+ - `dedot`
426
+ ```typescript
427
+ import { Dedot } from 'dedot';
428
+ import type { PolkadotApi } from '@dedot/chaintypes';
429
+
430
+ const api = await Dedot.new<PolkadotApi>('wss://rpc.polkadot.io'); // or Dedot.create(...) if you prefer
431
+
432
+ // OR you want to have a custom provider
433
+ import { WsProvider } from 'dedot'
434
+ const api = await Dedot.new<PolkadotApi>({ provider: new WsProvider('wss://rpc.polkadot.io') });
435
+ ```
436
+
437
+ - Notes:
438
+ - Under the hood, a `WsProvider` will be created if you initialize `Dedot` directly with an rpc endpoint.
439
+ - `dedot` only supports provider can make subscription request (e.g: via Websocket).
440
+ - We recommend specifying the `ChainApi` interface (e.g: [`PolkadotApi`](https://github.com/dedotdev/dedot/blob/02d7bca4c3c3d12c9591ea43b3410daf8e5aacbb/packages/chaintypes/src/polkadot/index.d.ts) in the example above) of the chain that you want to interact with. This enable apis & types suggestion/autocompletion for that particular chain (via IntelliSense). If you don't specify a `ChainApi` interface, the default [`SubstrateApi`](https://github.com/dedotdev/dedot/blob/a762faf8f6af40d3e4ef163bd538b270a5ca31e8/packages/chaintypes/src/substrate/index.d.ts) interface will be used.
441
+
442
+ **Type system**
443
+
444
+ Unlike `@polkadot/api` where data are wrapped inside a [codec types](https://polkadot.js.org/docs/api/start/types.basics), so we always need to unwrap the data before using it (e.g: via `.unwrap()`, `.toNumber()`, `.toString()`, `.toJSON()` ...). `dedot` leverages the native TypeScript type system to represent scale-codec types, so you can use the data directly without extra handling/unwrapping. The table below is a mapping between scale-codec types and TypeScript types that we're using for `dedot`:
445
+
446
+
447
+ | Scale Codec | TypeScript (`dedot`) |
448
+ |---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
449
+ | `u8`, `u16`, `u32`, `i8`, `i16`, `i32` | `number` |
450
+ | `u64`, `u128`, `u256`, `i64`, `i128`, `i256` | `bigint` (native [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt), not bn.js) |
451
+ | `bool` | `boolean` (true, false) |
452
+ | `Option<T>` | `T \| undefined` |
453
+ | `Result<Ok, Err>` | `{ isOk: true; isErr?: false; value: Ok } \| { isOk?: false; isErr: true; err: Err }` |
454
+ | `Vec<T>` | `Array<T>` |
455
+ | `str` | `string` |
456
+ | Tuple: `(A, B)`, `()` | `[A, B]`, `[]` |
457
+ | Struct: `struct { field_1: u8, field_2: str }` | `{ field_1: number, field_2: string}` |
458
+ | Enum: `enum { Variant1(u8), Variant2(bool), Variant3 }` | `{ tag: 'Variant1', value: number } \| { tag: 'Variant2', value: boolean } \| { tag: 'Variant2' }` |
459
+ | FlatEnum: `enum { Variant1, Variant2 }` | `'Variant1' \| 'Variant2'` |
460
+
461
+ E.g 1:
462
+ ```typescript
463
+ const runtimeVersion = api.consts.system.version;
464
+
465
+ // @polkadot/api
466
+ const specName: string = runtimeVersion.toJSON().specName; // OR runtimeVersion.specName.toString()
467
+
468
+ // dedot
469
+ const specName: string = runtimeVersion.specName;
470
+ ```
471
+
472
+ E.g 2:
473
+ ```typescript
474
+ const balance = await api.query.system.account(<address>);
475
+
476
+ // @polkadot/api
477
+ const freeBalance: bigint = balance.data.free.toBigInt();
478
+
479
+ // dedot
480
+ const freeBalance: bigint = balance.data.free;
481
+ ```
482
+
483
+ E.g 3:
484
+ ```typescript
485
+ // @polkadot/api
486
+ const proposalBondMaximum: bigint | undefined = api.consts.treasury.proposalBondMaximum.unwrapOr(undefined)?.toBigInt();
487
+
488
+ // dedot
489
+ const proposalBondMaximum: bigint | undefined = api.consts.treasury.proposalBondMaximum;
490
+ ```
491
+
492
+
350
493
  ### Credit
351
494
 
352
495
  `dedot` take a lot of inspirations from project [@polkadot/api](https://github.com/polkadot-js/api). A big thank to all the maintainers/contributors of this awesome library.
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Dedot = exports.SUPPORTED_METADATA_VERSIONS = exports.CATCH_ALL_METADATA_KEY = exports.KEEP_ALIVE_INTERVAL = void 0;
4
4
  const rpc_provider_1 = require("@polkadot/rpc-provider");
5
5
  const codecs_1 = require("@dedot/codecs");
6
- const executor_1 = require("../executor");
7
- const proxychain_1 = require("../proxychain");
8
- const util_1 = require("@polkadot/util");
6
+ const index_js_1 = require("../executor/index.js");
7
+ const proxychain_js_1 = require("../proxychain.js");
9
8
  const storage_1 = require("@dedot/storage");
10
9
  const utils_1 = require("@dedot/utils");
11
10
  exports.KEEP_ALIVE_INTERVAL = 10_000; // in ms
@@ -18,7 +17,7 @@ exports.SUPPORTED_METADATA_VERSIONS = [15, 14];
18
17
  * ### Initialize API instance and interact with substrate-based network
19
18
  * ```typescript
20
19
  * import { Dedot } from 'dedot';
21
- * import { PolkadotApi } from '@dedot/chaintypes/polkadot';
20
+ * import type { PolkadotApi } from '@dedot/chaintypes/polkadot';
22
21
  *
23
22
  * const run = async () => {
24
23
  * const api = await Dedot.new<PolkadotApi>('wss://rpc.polkadot.io');
@@ -49,9 +48,10 @@ exports.SUPPORTED_METADATA_VERSIONS = [15, 14];
49
48
  * run().catch(console.error);
50
49
  * ```
51
50
  */
52
- class Dedot {
51
+ class Dedot extends utils_1.EventEmitter {
53
52
  #provider;
54
53
  #options;
54
+ #ready;
55
55
  #registry;
56
56
  #metadata;
57
57
  #metadataLatest;
@@ -69,8 +69,10 @@ class Dedot {
69
69
  * @protected
70
70
  */
71
71
  constructor(options) {
72
+ super();
72
73
  this.#options = this.#normalizeOptions(options);
73
74
  this.#provider = this.#getProvider();
75
+ this.#ready = this.#handleProviderEvents();
74
76
  }
75
77
  /**
76
78
  * Factory method to create a new Dedot instance
@@ -79,23 +81,50 @@ class Dedot {
79
81
  */
80
82
  static async create(options) {
81
83
  const api = new Dedot(options);
82
- if (api.provider instanceof rpc_provider_1.WsProvider) {
83
- await api.provider.isReady;
84
- }
85
- await api.init();
86
- return api;
84
+ return api.untilReady().then(() => api);
87
85
  }
88
86
  /**
89
87
  * Alias for __Dedot.create__
88
+ *
90
89
  * @param options
91
90
  */
92
91
  static async new(options) {
93
92
  return Dedot.create(options);
94
93
  }
94
+ async untilReady() {
95
+ await this.#ready;
96
+ }
97
+ #handleProviderEvents() {
98
+ return new Promise((resolve, reject) => {
99
+ const onConnect = () => {
100
+ this.#onConnected()
101
+ .then(resolve)
102
+ .catch((e) => this.#onError(e).finally(reject));
103
+ };
104
+ this.provider.on('connected', onConnect);
105
+ this.provider.on('disconnected', this.#onDisconnected.bind(this));
106
+ this.provider.on('error', this.#onError.bind(this));
107
+ if (this.provider.isConnected) {
108
+ onConnect();
109
+ }
110
+ });
111
+ }
112
+ async #onConnected() {
113
+ this.emit('connected');
114
+ await this.#initialize();
115
+ this.emit('ready');
116
+ }
117
+ async #onDisconnected() {
118
+ await this.#unsubscribeUpdates();
119
+ this.emit('disconnected');
120
+ }
121
+ async #onError(e) {
122
+ this.emit('error', e);
123
+ }
95
124
  /**
96
125
  * Initialize APIs before usage
97
126
  */
98
- async init() {
127
+ async #initialize() {
99
128
  await this.#initializeLocalCache();
100
129
  // Fetching node information
101
130
  let [genesisHash, runtimeVersion, chainName, chainProps, metadata] = await Promise.all([
@@ -161,7 +190,7 @@ class Dedot {
161
190
  }
162
191
  }
163
192
  if (shouldUpdateCache && this.#localCache) {
164
- await this.#localCache.set(metadataKey, (0, util_1.u8aToHex)(codecs_1.$Metadata.tryEncode(metadata)));
193
+ await this.#localCache.set(metadataKey, (0, utils_1.u8aToHex)(codecs_1.$Metadata.tryEncode(metadata)));
165
194
  }
166
195
  if (!metadata) {
167
196
  throw new Error('Cannot load metadata');
@@ -246,18 +275,23 @@ class Dedot {
246
275
  }
247
276
  #normalizeOptions(options) {
248
277
  if (typeof options === 'string') {
249
- return { endpoint: options };
278
+ return { ...this.#getDefaultOptions(), endpoint: options };
250
279
  }
251
280
  else {
252
281
  let { metadata } = options || {};
253
282
  if (metadata && typeof metadata === 'string') {
254
283
  metadata = {
255
- [exports.CATCH_ALL_METADATA_KEY]: (0, util_1.hexAddPrefix)(metadata),
284
+ [exports.CATCH_ALL_METADATA_KEY]: metadata,
256
285
  };
257
286
  }
258
- return { ...options, metadata };
287
+ return { ...this.#getDefaultOptions(), ...options, metadata };
259
288
  }
260
289
  }
290
+ #getDefaultOptions() {
291
+ return {
292
+ throwOnUnknownApi: true,
293
+ };
294
+ }
261
295
  #getProvider() {
262
296
  const { provider, endpoint } = this.#options;
263
297
  if (provider) {
@@ -290,7 +324,7 @@ class Dedot {
290
324
  */
291
325
  get rpc() {
292
326
  // TODO add executable carrier to support calling arbitrary rpc methods via api.rpc(<method>)
293
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.RpcExecutor(this) });
327
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.RpcExecutor(this) });
294
328
  }
295
329
  /**
296
330
  * @description Entry-point for inspecting constants (parameter types) for all pallets (modules).
@@ -301,7 +335,7 @@ class Dedot {
301
335
  * ```
302
336
  */
303
337
  get consts() {
304
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.ConstantExecutor(this) });
338
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.ConstantExecutor(this) });
305
339
  }
306
340
  /**
307
341
  * @description Entry-point for executing query to on-chain storage.
@@ -312,31 +346,54 @@ class Dedot {
312
346
  * ```
313
347
  */
314
348
  get query() {
315
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.StorageQueryExecutor(this) });
349
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.StorageQueryExecutor(this) });
316
350
  }
317
351
  queryAt(blockHash) {
318
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.StorageQueryExecutor(this, blockHash) });
352
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.StorageQueryExecutor(this, blockHash) });
319
353
  }
320
354
  /**
321
355
  * @description Entry-point for inspecting errors from metadata
322
356
  */
323
357
  get errors() {
324
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.ErrorExecutor(this) });
358
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.ErrorExecutor(this) });
325
359
  }
326
360
  /**
327
361
  * @description Entry-point for inspecting events from metadata
328
362
  */
329
363
  get events() {
330
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.EventExecutor(this) });
364
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.EventExecutor(this) });
331
365
  }
366
+ /**
367
+ * @description Entry-point for executing runtime api
368
+ *
369
+ * ```typescript
370
+ * // Get account nonce
371
+ * const nonce = await api.call.accountNonceApi.accountNonce(<address>);
372
+ *
373
+ * // Query transaction payment info
374
+ * const tx = api.tx.balances.transferKeepAlive(<address>, 2_000_000_000_000n);
375
+ * const queryInfo = await api.call.transactionPaymentApi.queryInfo(tx.toU8a(), tx.length);
376
+ * ```
377
+ */
332
378
  get call() {
333
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.RuntimeApiExecutor(this) });
379
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.RuntimeApiExecutor(this) });
334
380
  }
335
381
  callAt(blockHash) {
336
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.RuntimeApiExecutor(this, blockHash) });
382
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.RuntimeApiExecutor(this, blockHash) });
337
383
  }
384
+ /**
385
+ * @description Entry-point for executing on-chain transactions
386
+ *
387
+ * ```typescript
388
+ * // Make a transfer balance transaction
389
+ * api.tx.balances.transferKeepAlive(<address>, <amount>)
390
+ * .signAndSend(<keyPair|address>, { signer }, ({ status }) => {
391
+ * console.log('Transaction status', status.tag);
392
+ * });
393
+ * ```
394
+ */
338
395
  get tx() {
339
- return (0, proxychain_1.newProxyChain)({ executor: new executor_1.TxExecutor(this) });
396
+ return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.TxExecutor(this) });
340
397
  }
341
398
  /**
342
399
  * @description Current provider for api connection
@@ -371,6 +428,12 @@ class Dedot {
371
428
  this.#metadataLatest = metadata.latest;
372
429
  this.#registry = new codecs_1.PortableRegistry(this.#metadataLatest);
373
430
  }
431
+ /**
432
+ * @description Connect to blockchain node
433
+ */
434
+ async connect() {
435
+ await this.#provider.connect();
436
+ }
374
437
  /**
375
438
  * @description Disconnect to blockchain node
376
439
  */
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./Dedot"), exports);
17
+ __exportStar(require("./Dedot.js"), exports);
@@ -1,20 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConstantExecutor = void 0;
4
- const util_1 = require("@polkadot/util");
5
- const Executor_1 = require("./Executor");
4
+ const Executor_js_1 = require("./Executor.js");
5
+ const utils_1 = require("@dedot/utils");
6
6
  /**
7
7
  * @name ConstantExecutor
8
8
  *
9
9
  * Find & decode the constant value from metadata
10
10
  */
11
- class ConstantExecutor extends Executor_1.Executor {
12
- execute(pallet, constantName) {
11
+ class ConstantExecutor extends Executor_js_1.Executor {
12
+ doExecute(pallet, constantName) {
13
13
  const targetPallet = this.getPallet(pallet);
14
- const constantDef = targetPallet.constants.find((one) => (0, util_1.stringCamelCase)(one.name) === constantName);
15
- if (!constantDef) {
16
- throw new Error(`Constant ${constantName} not found in pallet ${pallet}`);
17
- }
14
+ const constantDef = targetPallet.constants.find((one) => (0, utils_1.stringCamelCase)(one.name) === constantName);
15
+ (0, utils_1.assert)(constantDef, new utils_1.UnknownApiError(`Constant ${constantName} not found in pallet ${pallet}`));
18
16
  const $codec = this.registry.findCodec(constantDef.typeId);
19
17
  return $codec.tryDecode(constantDef.value);
20
18
  }
@@ -1,18 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ErrorExecutor = void 0;
4
- const Executor_1 = require("./Executor");
4
+ const Executor_js_1 = require("./Executor.js");
5
5
  const utils_1 = require("@dedot/utils");
6
- const util_1 = require("@polkadot/util");
7
6
  /**
8
7
  * @name ErrorExecutor
9
8
  * @description Find pallet error information from metadata
10
9
  */
11
- class ErrorExecutor extends Executor_1.Executor {
12
- execute(pallet, errorName) {
10
+ class ErrorExecutor extends Executor_js_1.Executor {
11
+ doExecute(pallet, errorName) {
13
12
  const targetPallet = this.getPallet(pallet);
14
13
  const errorTypeId = targetPallet.error;
15
- (0, utils_1.assert)(errorTypeId, `Not found error with id ${errorTypeId} in pallet ${pallet}`);
14
+ (0, utils_1.assert)(errorTypeId, new utils_1.UnknownApiError(`Not found error with id ${errorTypeId} in pallet ${pallet}`));
16
15
  const errorDef = this.#getErrorDef(errorTypeId, errorName);
17
16
  return {
18
17
  meta: {
@@ -21,11 +20,11 @@ class ErrorExecutor extends Executor_1.Executor {
21
20
  palletIndex: targetPallet.index,
22
21
  },
23
22
  is: (errorInfo) => {
24
- if ((0, util_1.isObject)(errorInfo) && errorInfo.tag === 'Module') {
23
+ if ((0, utils_1.isObject)(errorInfo) && errorInfo.tag === 'Module') {
25
24
  errorInfo = errorInfo.value;
26
25
  }
27
- if ((0, util_1.isObject)(errorInfo) && (0, util_1.isNumber)(errorInfo.index) && (0, util_1.isHex)(errorInfo.error)) {
28
- return errorInfo.index === targetPallet.index && (0, util_1.hexToU8a)(errorInfo.error)[0] === errorDef.index;
26
+ if ((0, utils_1.isObject)(errorInfo) && (0, utils_1.isNumber)(errorInfo.index) && (0, utils_1.isHex)(errorInfo.error)) {
27
+ return errorInfo.index === targetPallet.index && (0, utils_1.hexToU8a)(errorInfo.error)[0] === errorDef.index;
29
28
  }
30
29
  return false;
31
30
  },
@@ -33,11 +32,11 @@ class ErrorExecutor extends Executor_1.Executor {
33
32
  }
34
33
  #getErrorDef(errorTypeId, errorName) {
35
34
  const def = this.metadata.types[errorTypeId];
36
- (0, utils_1.assert)(def, `Error def not found for id ${errorTypeId}`);
35
+ (0, utils_1.assert)(def, new utils_1.UnknownApiError(`Error def not found for id ${errorTypeId}`));
37
36
  const { tag, value } = def.type;
38
- (0, utils_1.assert)(tag === 'Enum', `Error type should be an enum, found: ${tag}`);
39
- const errorDef = value.members.find(({ name }) => (0, util_1.stringPascalCase)(name) === errorName);
40
- (0, utils_1.assert)(errorDef, `Error def not found for ${errorName}`);
37
+ (0, utils_1.assert)(tag === 'Enum', new utils_1.UnknownApiError(`Error type should be an enum, found: ${tag}`));
38
+ const errorDef = value.members.find(({ name }) => (0, utils_1.stringPascalCase)(name) === errorName);
39
+ (0, utils_1.assert)(errorDef, new utils_1.UnknownApiError(`Error def not found for ${errorName}`));
41
40
  return {
42
41
  ...errorDef,
43
42
  fieldCodecs: errorDef.fields.map(({ typeId }) => this.registry.findCodec(typeId)),
@@ -1,26 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventExecutor = void 0;
4
- const Executor_1 = require("./Executor");
5
- const util_1 = require("@polkadot/util");
4
+ const Executor_js_1 = require("./Executor.js");
6
5
  const utils_1 = require("@dedot/utils");
7
6
  /**
8
7
  * @name EventExecutor
9
8
  * @description Find pallet event information from metadata
10
9
  */
11
- class EventExecutor extends Executor_1.Executor {
12
- execute(pallet, errorName) {
10
+ class EventExecutor extends Executor_js_1.Executor {
11
+ doExecute(pallet, errorName) {
13
12
  const targetPallet = this.getPallet(pallet);
14
13
  const eventTypeId = targetPallet.event;
15
- (0, utils_1.assert)(eventTypeId, `Not found event with id ${eventTypeId} in pallet ${pallet}`);
14
+ (0, utils_1.assert)(eventTypeId, new utils_1.UnknownApiError(`Not found event with id ${eventTypeId} in pallet ${pallet}`));
16
15
  const eventDef = this.#getEventDef(eventTypeId, errorName);
17
16
  const is = (event) => {
18
- const palletCheck = (0, util_1.stringCamelCase)(event.pallet) === pallet;
17
+ const palletCheck = (0, utils_1.stringCamelCase)(event.pallet) === pallet;
19
18
  if (typeof event.palletEvent === 'string') {
20
- return palletCheck && (0, util_1.stringPascalCase)(event.palletEvent) === errorName;
19
+ return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent) === errorName;
21
20
  }
22
21
  else if (typeof event.palletEvent === 'object') {
23
- return palletCheck && (0, util_1.stringPascalCase)(event.palletEvent.name) === errorName;
22
+ return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent.name) === errorName;
24
23
  }
25
24
  return false;
26
25
  };
@@ -39,11 +38,11 @@ class EventExecutor extends Executor_1.Executor {
39
38
  }
40
39
  #getEventDef(eventTypeId, errorName) {
41
40
  const def = this.metadata.types[eventTypeId];
42
- (0, utils_1.assert)(def, `Event def not found for id ${eventTypeId}`);
41
+ (0, utils_1.assert)(def, new utils_1.UnknownApiError(`Event def not found for id ${eventTypeId}`));
43
42
  const { tag, value } = def.type;
44
- (0, utils_1.assert)(tag === 'Enum', `Event type should be an enum, found: ${tag}`);
45
- const eventDef = value.members.find(({ name }) => (0, util_1.stringPascalCase)(name) === errorName);
46
- (0, utils_1.assert)(eventDef, `Event def not found for ${errorName}`);
43
+ (0, utils_1.assert)(tag === 'Enum', new utils_1.UnknownApiError(`Event type should be an enum, found: ${tag}`));
44
+ const eventDef = value.members.find(({ name }) => (0, utils_1.stringPascalCase)(name) === errorName);
45
+ (0, utils_1.assert)(eventDef, new utils_1.UnknownApiError(`Event def not found for ${errorName}`));
47
46
  return {
48
47
  ...eventDef,
49
48
  fieldCodecs: eventDef.fields.map(({ typeId }) => this.registry.findCodec(typeId)),
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Executor = void 0;
4
- const util_1 = require("@polkadot/util");
4
+ const utils_1 = require("@dedot/utils");
5
5
  /**
6
6
  * @name Executor
7
7
  * @description Execution abstraction for a specific action
@@ -28,12 +28,21 @@ class Executor {
28
28
  get metadata() {
29
29
  return this.api.metadataLatest;
30
30
  }
31
- getPallet(name, throwErr = true) {
32
- const targetPallet = this.metadata.pallets.find((p) => (0, util_1.stringCamelCase)(p.name) === name);
33
- if (!targetPallet && throwErr) {
34
- throw new Error(`Pallet not found: ${name}`);
35
- }
31
+ getPallet(name) {
32
+ const targetPallet = this.metadata.pallets.find((p) => (0, utils_1.stringCamelCase)(p.name) === name);
33
+ (0, utils_1.assert)(targetPallet, new utils_1.UnknownApiError(`Pallet not found: ${name}`));
36
34
  return targetPallet;
37
35
  }
36
+ execute(...paths) {
37
+ try {
38
+ return this.doExecute(...paths);
39
+ }
40
+ catch (e) {
41
+ if (!this.api.options.throwOnUnknownApi && e instanceof utils_1.UnknownApiError) {
42
+ return undefined;
43
+ }
44
+ throw e;
45
+ }
46
+ }
38
47
  }
39
48
  exports.Executor = Executor;
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RpcExecutor = void 0;
4
- const util_1 = require("@polkadot/util");
5
4
  const specs_1 = require("@dedot/specs");
6
5
  const utils_1 = require("@dedot/utils");
7
- const Executor_1 = require("./Executor");
6
+ const Executor_js_1 = require("./Executor.js");
8
7
  const isOptionalParam = (param) => {
9
8
  return param.isOptional || param.name.startsWith('Option<');
10
9
  };
@@ -13,14 +12,14 @@ const isOptionalParam = (param) => {
13
12
  * @description Execute a rpc based from an RPC spec,
14
13
  * if a spec is not found we execute an arbitrary rpc method
15
14
  */
16
- class RpcExecutor extends Executor_1.Executor {
17
- execute(section, method) {
15
+ class RpcExecutor extends Executor_js_1.Executor {
16
+ doExecute(section, method) {
18
17
  const maybeRpcName = `${section}_${method}`;
19
18
  const callSpec = (0, specs_1.findRpcSpec)(maybeRpcName) || (0, specs_1.findAliasRpcSpec)(maybeRpcName);
20
19
  const rpcName = callSpec?.name || `${section}_${method}`;
21
20
  const isSubscription = !!callSpec?.pubsub;
22
21
  const fnRpc = async (...args) => {
23
- (0, utils_1.assert)(callSpec, 'Rpc spec not found');
22
+ (0, utils_1.assert)(callSpec, new utils_1.UnknownApiError('Rpc spec not found'));
24
23
  this.checkRpcInputs(callSpec, args);
25
24
  const { params } = callSpec;
26
25
  const formattedInputs = args.map((input, index) => this.tryEncode(params[index], input));
@@ -28,10 +27,10 @@ class RpcExecutor extends Executor_1.Executor {
28
27
  return this.tryDecode(callSpec, result);
29
28
  };
30
29
  const fnSubRpc = async (...args) => {
31
- (0, utils_1.assert)(callSpec, 'Rpc spec not found');
30
+ (0, utils_1.assert)(callSpec, new utils_1.UnknownApiError('Rpc spec not found'));
32
31
  const inArgs = args.slice();
33
32
  const callback = inArgs.pop();
34
- (0, utils_1.assert)((0, util_1.isFunction)(callback), 'A callback is required for subscription');
33
+ (0, utils_1.assert)((0, utils_1.isFunction)(callback), 'A callback is required for subscription');
35
34
  this.checkRpcInputs(callSpec, inArgs);
36
35
  const onNewMessage = (error, result) => {
37
36
  if (error) {
@@ -68,14 +67,11 @@ class RpcExecutor extends Executor_1.Executor {
68
67
  // We use `undefined` to represent Option::None in the client
69
68
  return undefined;
70
69
  }
71
- const { type, isScale, codec } = callSpec;
70
+ const { isScale, codec } = callSpec;
72
71
  if (isScale) {
73
72
  (0, utils_1.assert)(codec, 'Codec not found to decode response');
74
73
  return codec.tryDecode(raw);
75
74
  }
76
- if ((0, utils_1.isNativeType)(type)) {
77
- return raw;
78
- }
79
75
  return raw;
80
76
  }
81
77
  tryEncode(paramSpec, value) {
@@ -85,7 +81,7 @@ class RpcExecutor extends Executor_1.Executor {
85
81
  return null;
86
82
  }
87
83
  (0, utils_1.assert)(codec, 'Codec not found to encode params');
88
- return (0, util_1.u8aToHex)(codec.tryEncode(value));
84
+ return (0, utils_1.u8aToHex)(codec.tryEncode(value));
89
85
  }
90
86
  // TODO generalize this!
91
87
  if (value && value['toJSON']) {