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.
- package/README.md +156 -13
- package/cjs/client/Dedot.js +87 -24
- package/cjs/client/index.js +1 -1
- package/cjs/executor/ConstantExecutor.js +6 -8
- package/cjs/executor/ErrorExecutor.js +11 -12
- package/cjs/executor/EventExecutor.js +11 -12
- package/cjs/executor/Executor.js +15 -6
- package/cjs/executor/RpcExecutor.js +8 -12
- package/cjs/executor/RuntimeApiExecutor.js +17 -11
- package/cjs/executor/StorageQueryExecutor.js +34 -8
- package/cjs/executor/TxExecutor.js +24 -26
- package/cjs/executor/index.js +8 -8
- package/cjs/extrinsic/extensions/ExtraSignedExtension.js +6 -7
- package/cjs/extrinsic/extensions/index.js +3 -3
- package/cjs/extrinsic/extensions/known/ChargeAssetTxPayment.js +3 -4
- package/cjs/extrinsic/extensions/known/ChargeTransactionPayment.js +2 -2
- package/cjs/extrinsic/extensions/known/CheckGenesis.js +2 -2
- package/cjs/extrinsic/extensions/known/CheckMortality.js +5 -6
- package/cjs/extrinsic/extensions/known/CheckNonZeroSender.js +2 -2
- package/cjs/extrinsic/extensions/known/CheckNonce.js +3 -4
- package/cjs/extrinsic/extensions/known/CheckSpecVersion.js +4 -4
- package/cjs/extrinsic/extensions/known/CheckTxVersion.js +4 -4
- package/cjs/extrinsic/extensions/known/CheckWeight.js +2 -2
- package/cjs/extrinsic/extensions/known/PrevalidateAttests.js +2 -2
- package/cjs/extrinsic/extensions/known/index.js +20 -20
- package/cjs/extrinsic/index.js +2 -2
- package/cjs/index.js +4 -4
- package/cjs/proxychain.js +7 -0
- package/cjs/storage/QueryableStorage.js +8 -9
- package/client/Dedot.d.ts +33 -7
- package/client/Dedot.js +78 -15
- package/client/index.d.ts +1 -1
- package/client/index.js +1 -1
- package/executor/ConstantExecutor.d.ts +2 -2
- package/executor/ConstantExecutor.js +4 -6
- package/executor/ErrorExecutor.d.ts +2 -2
- package/executor/ErrorExecutor.js +7 -8
- package/executor/EventExecutor.d.ts +2 -2
- package/executor/EventExecutor.js +7 -8
- package/executor/Executor.d.ts +5 -4
- package/executor/Executor.js +14 -5
- package/executor/RpcExecutor.d.ts +3 -3
- package/executor/RpcExecutor.js +6 -10
- package/executor/RuntimeApiExecutor.d.ts +9 -2
- package/executor/RuntimeApiExecutor.js +13 -7
- package/executor/StorageQueryExecutor.d.ts +3 -3
- package/executor/StorageQueryExecutor.js +32 -6
- package/executor/TxExecutor.d.ts +4 -4
- package/executor/TxExecutor.js +8 -10
- package/executor/index.d.ts +8 -8
- package/executor/index.js +8 -8
- package/extrinsic/extensions/ExtraSignedExtension.d.ts +1 -1
- package/extrinsic/extensions/ExtraSignedExtension.js +4 -5
- package/extrinsic/extensions/SignedExtension.d.ts +1 -1
- package/extrinsic/extensions/index.d.ts +3 -3
- package/extrinsic/extensions/index.js +3 -3
- package/extrinsic/extensions/known/ChargeAssetTxPayment.d.ts +1 -1
- package/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -3
- package/extrinsic/extensions/known/ChargeTransactionPayment.d.ts +1 -1
- package/extrinsic/extensions/known/ChargeTransactionPayment.js +1 -1
- package/extrinsic/extensions/known/CheckGenesis.d.ts +1 -1
- package/extrinsic/extensions/known/CheckGenesis.js +1 -1
- package/extrinsic/extensions/known/CheckMortality.d.ts +1 -1
- package/extrinsic/extensions/known/CheckMortality.js +3 -4
- package/extrinsic/extensions/known/CheckNonZeroSender.d.ts +1 -1
- package/extrinsic/extensions/known/CheckNonZeroSender.js +1 -1
- package/extrinsic/extensions/known/CheckNonce.d.ts +1 -1
- package/extrinsic/extensions/known/CheckNonce.js +2 -3
- package/extrinsic/extensions/known/CheckSpecVersion.d.ts +1 -1
- package/extrinsic/extensions/known/CheckSpecVersion.js +2 -2
- package/extrinsic/extensions/known/CheckTxVersion.d.ts +1 -1
- package/extrinsic/extensions/known/CheckTxVersion.js +2 -2
- package/extrinsic/extensions/known/CheckWeight.d.ts +1 -1
- package/extrinsic/extensions/known/CheckWeight.js +1 -1
- package/extrinsic/extensions/known/PrevalidateAttests.d.ts +1 -1
- package/extrinsic/extensions/known/PrevalidateAttests.js +1 -1
- package/extrinsic/extensions/known/index.d.ts +1 -1
- package/extrinsic/extensions/known/index.js +10 -10
- package/extrinsic/index.d.ts +2 -2
- package/extrinsic/index.js +2 -2
- package/index.d.ts +4 -5
- package/index.js +3 -4
- package/package.json +9 -10
- package/proxychain.d.ts +8 -1
- package/proxychain.js +7 -0
- package/storage/QueryableStorage.js +6 -7
- package/types.d.ts +9 -1
- package/cjs/packageInfo.js +0 -5
- package/packageInfo.d.ts +0 -4
- 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
|
|
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.
|
package/cjs/client/Dedot.js
CHANGED
|
@@ -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
|
|
7
|
-
const
|
|
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
|
-
|
|
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
|
|
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,
|
|
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]:
|
|
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,
|
|
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,
|
|
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,
|
|
349
|
+
return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.StorageQueryExecutor(this) });
|
|
316
350
|
}
|
|
317
351
|
queryAt(blockHash) {
|
|
318
|
-
return (0,
|
|
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,
|
|
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,
|
|
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,
|
|
379
|
+
return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.RuntimeApiExecutor(this) });
|
|
334
380
|
}
|
|
335
381
|
callAt(blockHash) {
|
|
336
|
-
return (0,
|
|
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,
|
|
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
|
*/
|
package/cjs/client/index.js
CHANGED
|
@@ -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
|
|
5
|
-
const
|
|
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
|
|
12
|
-
|
|
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,
|
|
15
|
-
|
|
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
|
|
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
|
|
12
|
-
|
|
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,
|
|
23
|
+
if ((0, utils_1.isObject)(errorInfo) && errorInfo.tag === 'Module') {
|
|
25
24
|
errorInfo = errorInfo.value;
|
|
26
25
|
}
|
|
27
|
-
if ((0,
|
|
28
|
-
return errorInfo.index === targetPallet.index && (0,
|
|
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,
|
|
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
|
|
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
|
|
12
|
-
|
|
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,
|
|
17
|
+
const palletCheck = (0, utils_1.stringCamelCase)(event.pallet) === pallet;
|
|
19
18
|
if (typeof event.palletEvent === 'string') {
|
|
20
|
-
return palletCheck && (0,
|
|
19
|
+
return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent) === errorName;
|
|
21
20
|
}
|
|
22
21
|
else if (typeof event.palletEvent === 'object') {
|
|
23
|
-
return palletCheck && (0,
|
|
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,
|
|
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)),
|
package/cjs/executor/Executor.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Executor = void 0;
|
|
4
|
-
const
|
|
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
|
|
32
|
-
const targetPallet = this.metadata.pallets.find((p) => (0,
|
|
33
|
-
|
|
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
|
|
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
|
|
17
|
-
|
|
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,
|
|
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 {
|
|
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,
|
|
84
|
+
return (0, utils_1.u8aToHex)(codec.tryEncode(value));
|
|
89
85
|
}
|
|
90
86
|
// TODO generalize this!
|
|
91
87
|
if (value && value['toJSON']) {
|