dedot 0.0.1-alpha.29 → 0.0.1-alpha.30
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 +10 -0
- package/cjs/client/Dedot.js +34 -46
- package/cjs/executor/RpcExecutor.js +4 -9
- package/cjs/index.js +2 -2
- package/cjs/test.js +69 -0
- package/client/Dedot.d.ts +6 -12
- package/client/Dedot.js +34 -46
- package/executor/Executor.d.ts +1 -1
- package/executor/RpcExecutor.js +4 -9
- package/executor/TxExecutor.d.ts +2 -2
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +9 -9
- package/test.d.ts +1 -0
- package/test.js +67 -0
- package/types.d.ts +6 -6
package/README.md
CHANGED
|
@@ -11,6 +11,16 @@ A delightful JavaScript/TypeScript client for [Polkadot](https://polkadot.networ
|
|
|
11
11
|
_Note: The project is still in active development phase, the information on this page might be outdated. Feel free to raise an [issue](https://github.com/dedotdev/dedot/issues/new) if you run into any problems or want to share any ideas._
|
|
12
12
|
|
|
13
13
|
---
|
|
14
|
+
### Features
|
|
15
|
+
- ⏳ Small bundle size, tree-shakable (no more bn.js (⏳) or wasm-blob (✅) tight dependencies)
|
|
16
|
+
- ✅ Built-in metadata caching mechanism
|
|
17
|
+
- ✅ Types & APIs suggestions for each individual Substrate-based blockchain network ([@dedot/chaintypes](https://github.com/dedotdev/chaintypes))
|
|
18
|
+
- ✅ Familiar api style with `@polkadot/api`, easy & fast migration!
|
|
19
|
+
- ✅ Native TypeScript type system for scale-codec
|
|
20
|
+
- ✅ Compatible with `@polkadot/extension`-based wallets
|
|
21
|
+
- ⏳ Use the new JSON-RPC APIs ([v2](https://paritytech.github.io/json-rpc-interface-spec/introduction.html))
|
|
22
|
+
- ✅ Support Metadata V14, V15 (latest)
|
|
23
|
+
|
|
14
24
|
### Have a quick taste
|
|
15
25
|
|
|
16
26
|
Try `dedot` now on [CodeSandbox Playground](https://codesandbox.io/p/devbox/trydedot-th96cm?file=%2Fmain.ts%3A24%2C26) or follow the below steps to run it on your local environment.
|
package/cjs/client/Dedot.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
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
|
-
const rpc_provider_1 = require("@polkadot/rpc-provider");
|
|
5
4
|
const codecs_1 = require("@dedot/codecs");
|
|
6
5
|
const index_js_1 = require("../executor/index.js");
|
|
7
6
|
const proxychain_js_1 = require("../proxychain.js");
|
|
8
7
|
const storage_1 = require("@dedot/storage");
|
|
9
8
|
const utils_1 = require("@dedot/utils");
|
|
9
|
+
const providers_1 = require("@dedot/providers");
|
|
10
10
|
exports.KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
11
11
|
exports.CATCH_ALL_METADATA_KEY = `RAW_META/ALL`;
|
|
12
12
|
exports.SUPPORTED_METADATA_VERSIONS = [15, 14];
|
|
@@ -51,7 +51,6 @@ exports.SUPPORTED_METADATA_VERSIONS = [15, 14];
|
|
|
51
51
|
class Dedot extends utils_1.EventEmitter {
|
|
52
52
|
#provider;
|
|
53
53
|
#options;
|
|
54
|
-
#ready;
|
|
55
54
|
#registry;
|
|
56
55
|
#metadata;
|
|
57
56
|
#metadataLatest;
|
|
@@ -66,13 +65,11 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
66
65
|
* Use factory methods (`create`, `new`) to create `Dedot` instances.
|
|
67
66
|
*
|
|
68
67
|
* @param options
|
|
69
|
-
* @protected
|
|
70
68
|
*/
|
|
71
69
|
constructor(options) {
|
|
72
70
|
super();
|
|
73
71
|
this.#options = this.#normalizeOptions(options);
|
|
74
72
|
this.#provider = this.#getProvider();
|
|
75
|
-
this.#ready = this.#handleProviderEvents();
|
|
76
73
|
}
|
|
77
74
|
/**
|
|
78
75
|
* Factory method to create a new Dedot instance
|
|
@@ -80,8 +77,7 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
80
77
|
* @param options
|
|
81
78
|
*/
|
|
82
79
|
static async create(options) {
|
|
83
|
-
|
|
84
|
-
return api.untilReady().then(() => api);
|
|
80
|
+
return new Dedot(options).connect();
|
|
85
81
|
}
|
|
86
82
|
/**
|
|
87
83
|
* Alias for __Dedot.create__
|
|
@@ -91,36 +87,37 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
91
87
|
static async new(options) {
|
|
92
88
|
return Dedot.create(options);
|
|
93
89
|
}
|
|
94
|
-
async
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
async #doConnect() {
|
|
91
|
+
this.provider.on('connected', this.#onConnected);
|
|
92
|
+
this.provider.on('disconnected', this.#onDisconnected);
|
|
93
|
+
this.provider.on('reconnecting', this.#onReconnecting);
|
|
94
|
+
this.provider.on('error', this.#onError);
|
|
98
95
|
return new Promise((resolve, reject) => {
|
|
99
|
-
|
|
100
|
-
this.#onConnected()
|
|
101
|
-
|
|
102
|
-
|
|
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();
|
|
96
|
+
if (this.status === 'connected') {
|
|
97
|
+
this.#onConnected().catch(reject);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
this.provider.connect().catch(reject);
|
|
109
101
|
}
|
|
102
|
+
this.once('ready', () => {
|
|
103
|
+
resolve(this);
|
|
104
|
+
});
|
|
110
105
|
});
|
|
111
106
|
}
|
|
112
|
-
async
|
|
107
|
+
#onConnected = async () => {
|
|
113
108
|
this.emit('connected');
|
|
114
109
|
await this.#initialize();
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
async #onDisconnected() {
|
|
110
|
+
};
|
|
111
|
+
#onDisconnected = async () => {
|
|
118
112
|
await this.#unsubscribeUpdates();
|
|
119
113
|
this.emit('disconnected');
|
|
120
|
-
}
|
|
121
|
-
async
|
|
114
|
+
};
|
|
115
|
+
#onReconnecting = async () => {
|
|
116
|
+
this.emit('reconnecting');
|
|
117
|
+
};
|
|
118
|
+
#onError = async (e) => {
|
|
122
119
|
this.emit('error', e);
|
|
123
|
-
}
|
|
120
|
+
};
|
|
124
121
|
/**
|
|
125
122
|
* Initialize APIs before usage
|
|
126
123
|
*/
|
|
@@ -140,6 +137,7 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
140
137
|
this.#runtimeChain = chainName;
|
|
141
138
|
await this.#setupMetadata(metadata);
|
|
142
139
|
this.#subscribeUpdates();
|
|
140
|
+
this.emit('ready');
|
|
143
141
|
}
|
|
144
142
|
async #initializeLocalCache() {
|
|
145
143
|
if (!this.#options.cacheMetadata)
|
|
@@ -219,7 +217,7 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
219
217
|
}
|
|
220
218
|
#subscribeRuntimeUpgrades() {
|
|
221
219
|
// Disable runtime upgrades subscriptions if using a catch all metadata
|
|
222
|
-
if (this.#runtimeSubscriptionUnsub ||
|
|
220
|
+
if (this.#runtimeSubscriptionUnsub || this.hasCatchAllMetadata) {
|
|
223
221
|
return;
|
|
224
222
|
}
|
|
225
223
|
this.rpc.state
|
|
@@ -295,19 +293,14 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
295
293
|
#getProvider() {
|
|
296
294
|
const { provider, endpoint } = this.#options;
|
|
297
295
|
if (provider) {
|
|
298
|
-
|
|
296
|
+
// assert(provider.hasSubscriptions, 'Only supports RPC Provider can make subscription requests');
|
|
299
297
|
return provider;
|
|
300
298
|
}
|
|
301
299
|
if (endpoint) {
|
|
302
|
-
|
|
303
|
-
return new rpc_provider_1.WsProvider(endpoint);
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
throw new Error('Invalid RPC network endpoint, a valid endpoint should start with `wss://`, `ws://`');
|
|
307
|
-
}
|
|
300
|
+
return new providers_1.WsProvider(endpoint);
|
|
308
301
|
}
|
|
309
302
|
// TODO support light-client
|
|
310
|
-
return new
|
|
303
|
+
return new providers_1.WsProvider('ws://127.0.0.1:9944');
|
|
311
304
|
}
|
|
312
305
|
/**
|
|
313
306
|
* @description Entry-point for executing RPCs to blockchain node.
|
|
@@ -432,7 +425,8 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
432
425
|
* @description Connect to blockchain node
|
|
433
426
|
*/
|
|
434
427
|
async connect() {
|
|
435
|
-
|
|
428
|
+
(0, utils_1.assert)(this.status !== 'connected', 'Already connected!');
|
|
429
|
+
return this.#doConnect();
|
|
436
430
|
}
|
|
437
431
|
/**
|
|
438
432
|
* @description Disconnect to blockchain node
|
|
@@ -448,16 +442,10 @@ class Dedot extends utils_1.EventEmitter {
|
|
|
448
442
|
await this.#localCache?.clear();
|
|
449
443
|
}
|
|
450
444
|
/**
|
|
451
|
-
* @description Check
|
|
452
|
-
*/
|
|
453
|
-
get hasSubscriptions() {
|
|
454
|
-
return this.provider.hasSubscriptions;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* @description Check if it's connected to the blockchain node
|
|
445
|
+
* @description Check connection status of the api instance
|
|
458
446
|
*/
|
|
459
|
-
get
|
|
460
|
-
return this.provider.
|
|
447
|
+
get status() {
|
|
448
|
+
return this.provider.status;
|
|
461
449
|
}
|
|
462
450
|
/**
|
|
463
451
|
* @description Check if the api instance is using a catch-all metadata
|
|
@@ -40,16 +40,11 @@ class RpcExecutor extends Executor_js_1.Executor {
|
|
|
40
40
|
callback(this.tryDecode(callSpec, result));
|
|
41
41
|
};
|
|
42
42
|
const { params, pubsub } = callSpec;
|
|
43
|
-
const
|
|
44
|
-
const [subname, subscribe,
|
|
45
|
-
const subscription = this.provider.subscribe(subname, subscribe,
|
|
43
|
+
const formattedParams = inArgs.map((input, index) => this.tryEncode(params[index], input));
|
|
44
|
+
const [subname, subscribe, unsubscribe] = pubsub;
|
|
45
|
+
const subscription = await this.provider.subscribe({ subname, subscribe, params: formattedParams, unsubscribe }, onNewMessage);
|
|
46
46
|
return async () => {
|
|
47
|
-
|
|
48
|
-
.then((subscriptionId) => this.provider.unsubscribe(subname, unsubcribe, subscriptionId))
|
|
49
|
-
.catch((err) => {
|
|
50
|
-
console.error(err);
|
|
51
|
-
return false;
|
|
52
|
-
});
|
|
47
|
+
await subscription.unsubscribe();
|
|
53
48
|
};
|
|
54
49
|
};
|
|
55
50
|
if (!callSpec) {
|
package/cjs/index.js
CHANGED
|
@@ -19,5 +19,5 @@ __exportStar(require("./executor/index.js"), exports);
|
|
|
19
19
|
__exportStar(require("./extrinsic/index.js"), exports);
|
|
20
20
|
var index_js_1 = require("./client/index.js");
|
|
21
21
|
Object.defineProperty(exports, "Dedot", { enumerable: true, get: function () { return index_js_1.Dedot; } });
|
|
22
|
-
var
|
|
23
|
-
Object.defineProperty(exports, "WsProvider", { enumerable: true, get: function () { return
|
|
22
|
+
var providers_1 = require("@dedot/providers");
|
|
23
|
+
Object.defineProperty(exports, "WsProvider", { enumerable: true, get: function () { return providers_1.WsProvider; } });
|
package/cjs/test.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const providers_1 = require("@dedot/providers");
|
|
4
|
+
const run = async () => {
|
|
5
|
+
// const api = new Dedot('');
|
|
6
|
+
// await api.connect();
|
|
7
|
+
// console.log(await api.rpc.chain.getHeader());
|
|
8
|
+
// await api.disconnect();
|
|
9
|
+
// await api.connect();
|
|
10
|
+
// console.log(await api.rpc.chain.getHeader());
|
|
11
|
+
// await api.disconnect();
|
|
12
|
+
// const provider = new WsProvider({ endpoint: 'wss://rpc.polkadot.io', retryDelayMs: -1 });
|
|
13
|
+
// const provider = new WsProvider({ endpoint: 'ws://hello' });
|
|
14
|
+
// provider.on('reconnecting', () => {
|
|
15
|
+
// console.log('reconnecting');
|
|
16
|
+
// });
|
|
17
|
+
// //
|
|
18
|
+
// await provider.connect();
|
|
19
|
+
const provider = new providers_1.WsProvider('wss://rpc.polkadot.io');
|
|
20
|
+
await provider.connect();
|
|
21
|
+
const genesisHash = await provider.send('chain_getBlockHash', [0]);
|
|
22
|
+
console.log(genesisHash);
|
|
23
|
+
await provider.subscribe({
|
|
24
|
+
subname: 'chain_newHead',
|
|
25
|
+
subscribe: 'chain_subscribeNewHeads',
|
|
26
|
+
params: [],
|
|
27
|
+
unsubscribe: 'chain_unsubscribeNewHeads',
|
|
28
|
+
}, (error, newHead, subscription) => {
|
|
29
|
+
console.log('newHead', newHead);
|
|
30
|
+
});
|
|
31
|
+
// await provider.disconnect();
|
|
32
|
+
//
|
|
33
|
+
// await provider.subscribe(
|
|
34
|
+
// {
|
|
35
|
+
// subname: 'chain_newHead',
|
|
36
|
+
// subscribe: 'chain_subscribeNewHead',
|
|
37
|
+
// unsubscribe: 'chain_unsubscribeNewHead',
|
|
38
|
+
// params: [],
|
|
39
|
+
// },
|
|
40
|
+
// async (error, head, subscription) => {
|
|
41
|
+
// if (error) {
|
|
42
|
+
// console.log('01 - New head error:', error);
|
|
43
|
+
// } else {
|
|
44
|
+
// console.log('01 - New head:', head.number, subscription);
|
|
45
|
+
// }
|
|
46
|
+
// },
|
|
47
|
+
// );
|
|
48
|
+
//
|
|
49
|
+
// setTimeout(async () => {
|
|
50
|
+
// await provider.disconnect();
|
|
51
|
+
// }, 3000);
|
|
52
|
+
//
|
|
53
|
+
// setTimeout(async () => {
|
|
54
|
+
// await provider.connect();
|
|
55
|
+
//
|
|
56
|
+
// await provider.subscribe(
|
|
57
|
+
// {
|
|
58
|
+
// subname: 'chain_newHead',
|
|
59
|
+
// subscribe: 'chain_subscribeNewHead',
|
|
60
|
+
// unsubscribe: 'chain_unsubscribeNewHead',
|
|
61
|
+
// params: [],
|
|
62
|
+
// },
|
|
63
|
+
// async (error, head, subscription) => {
|
|
64
|
+
// console.log('02 - New head:', head.number, subscription);
|
|
65
|
+
// },
|
|
66
|
+
// );
|
|
67
|
+
// }, 10000);
|
|
68
|
+
};
|
|
69
|
+
run().catch(console.error);
|
package/client/Dedot.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
|
2
1
|
import type { SubstrateApi } from '@dedot/chaintypes';
|
|
3
2
|
import { BlockHash, Metadata, MetadataLatest, PortableRegistry } from '@dedot/codecs';
|
|
4
3
|
import { ChainProperties, GenericSubstrateApi } from '@dedot/types';
|
|
5
4
|
import { ApiEventNames, ApiOptions, MetadataKey, NetworkEndpoint, NormalizedApiOptions } from '../types.js';
|
|
6
5
|
import { EventEmitter } from '@dedot/utils';
|
|
6
|
+
import { ConnectionStatus, type JsonRpcProvider } from '@dedot/providers';
|
|
7
7
|
export declare const KEEP_ALIVE_INTERVAL = 10000;
|
|
8
8
|
export declare const CATCH_ALL_METADATA_KEY: MetadataKey;
|
|
9
9
|
export declare const SUPPORTED_METADATA_VERSIONS: number[];
|
|
@@ -51,9 +51,8 @@ export declare class Dedot<ChainApi extends GenericSubstrateApi = SubstrateApi>
|
|
|
51
51
|
* Use factory methods (`create`, `new`) to create `Dedot` instances.
|
|
52
52
|
*
|
|
53
53
|
* @param options
|
|
54
|
-
* @protected
|
|
55
54
|
*/
|
|
56
|
-
|
|
55
|
+
constructor(options: ApiOptions | NetworkEndpoint);
|
|
57
56
|
/**
|
|
58
57
|
* Factory method to create a new Dedot instance
|
|
59
58
|
*
|
|
@@ -66,7 +65,6 @@ export declare class Dedot<ChainApi extends GenericSubstrateApi = SubstrateApi>
|
|
|
66
65
|
* @param options
|
|
67
66
|
*/
|
|
68
67
|
static new<ChainApi extends GenericSubstrateApi = SubstrateApi>(options: ApiOptions | NetworkEndpoint): Promise<Dedot<ChainApi>>;
|
|
69
|
-
untilReady(): Promise<void>;
|
|
70
68
|
/**
|
|
71
69
|
* @description Entry-point for executing RPCs to blockchain node.
|
|
72
70
|
*
|
|
@@ -137,7 +135,7 @@ export declare class Dedot<ChainApi extends GenericSubstrateApi = SubstrateApi>
|
|
|
137
135
|
/**
|
|
138
136
|
* @description Current provider for api connection
|
|
139
137
|
*/
|
|
140
|
-
get provider():
|
|
138
|
+
get provider(): JsonRpcProvider;
|
|
141
139
|
/**
|
|
142
140
|
* @description Codec registry
|
|
143
141
|
*/
|
|
@@ -156,7 +154,7 @@ export declare class Dedot<ChainApi extends GenericSubstrateApi = SubstrateApi>
|
|
|
156
154
|
/**
|
|
157
155
|
* @description Connect to blockchain node
|
|
158
156
|
*/
|
|
159
|
-
connect(): Promise<
|
|
157
|
+
connect(): Promise<this>;
|
|
160
158
|
/**
|
|
161
159
|
* @description Disconnect to blockchain node
|
|
162
160
|
*/
|
|
@@ -166,13 +164,9 @@ export declare class Dedot<ChainApi extends GenericSubstrateApi = SubstrateApi>
|
|
|
166
164
|
*/
|
|
167
165
|
clearCache(): Promise<void>;
|
|
168
166
|
/**
|
|
169
|
-
* @description Check
|
|
167
|
+
* @description Check connection status of the api instance
|
|
170
168
|
*/
|
|
171
|
-
get
|
|
172
|
-
/**
|
|
173
|
-
* @description Check if it's connected to the blockchain node
|
|
174
|
-
*/
|
|
175
|
-
get isConnected(): boolean;
|
|
169
|
+
get status(): ConnectionStatus;
|
|
176
170
|
/**
|
|
177
171
|
* @description Check if the api instance is using a catch-all metadata
|
|
178
172
|
*/
|
package/client/Dedot.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { WsProvider } from '@polkadot/rpc-provider';
|
|
2
1
|
import { $Metadata, PortableRegistry } from '@dedot/codecs';
|
|
3
2
|
import { ConstantExecutor, ErrorExecutor, EventExecutor, RpcExecutor, RuntimeApiExecutor, StorageQueryExecutor, TxExecutor, } from '../executor/index.js';
|
|
4
3
|
import { newProxyChain } from '../proxychain.js';
|
|
5
4
|
import { LocalStorage } from '@dedot/storage';
|
|
6
5
|
import { assert, EventEmitter, u8aToHex } from '@dedot/utils';
|
|
6
|
+
import { WsProvider } from '@dedot/providers';
|
|
7
7
|
export const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
8
8
|
export const CATCH_ALL_METADATA_KEY = `RAW_META/ALL`;
|
|
9
9
|
export const SUPPORTED_METADATA_VERSIONS = [15, 14];
|
|
@@ -48,7 +48,6 @@ export const SUPPORTED_METADATA_VERSIONS = [15, 14];
|
|
|
48
48
|
export class Dedot extends EventEmitter {
|
|
49
49
|
#provider;
|
|
50
50
|
#options;
|
|
51
|
-
#ready;
|
|
52
51
|
#registry;
|
|
53
52
|
#metadata;
|
|
54
53
|
#metadataLatest;
|
|
@@ -63,13 +62,11 @@ export class Dedot extends EventEmitter {
|
|
|
63
62
|
* Use factory methods (`create`, `new`) to create `Dedot` instances.
|
|
64
63
|
*
|
|
65
64
|
* @param options
|
|
66
|
-
* @protected
|
|
67
65
|
*/
|
|
68
66
|
constructor(options) {
|
|
69
67
|
super();
|
|
70
68
|
this.#options = this.#normalizeOptions(options);
|
|
71
69
|
this.#provider = this.#getProvider();
|
|
72
|
-
this.#ready = this.#handleProviderEvents();
|
|
73
70
|
}
|
|
74
71
|
/**
|
|
75
72
|
* Factory method to create a new Dedot instance
|
|
@@ -77,8 +74,7 @@ export class Dedot extends EventEmitter {
|
|
|
77
74
|
* @param options
|
|
78
75
|
*/
|
|
79
76
|
static async create(options) {
|
|
80
|
-
|
|
81
|
-
return api.untilReady().then(() => api);
|
|
77
|
+
return new Dedot(options).connect();
|
|
82
78
|
}
|
|
83
79
|
/**
|
|
84
80
|
* Alias for __Dedot.create__
|
|
@@ -88,36 +84,37 @@ export class Dedot extends EventEmitter {
|
|
|
88
84
|
static async new(options) {
|
|
89
85
|
return Dedot.create(options);
|
|
90
86
|
}
|
|
91
|
-
async
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
async #doConnect() {
|
|
88
|
+
this.provider.on('connected', this.#onConnected);
|
|
89
|
+
this.provider.on('disconnected', this.#onDisconnected);
|
|
90
|
+
this.provider.on('reconnecting', this.#onReconnecting);
|
|
91
|
+
this.provider.on('error', this.#onError);
|
|
95
92
|
return new Promise((resolve, reject) => {
|
|
96
|
-
|
|
97
|
-
this.#onConnected()
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this.provider.on('connected', onConnect);
|
|
102
|
-
this.provider.on('disconnected', this.#onDisconnected.bind(this));
|
|
103
|
-
this.provider.on('error', this.#onError.bind(this));
|
|
104
|
-
if (this.provider.isConnected) {
|
|
105
|
-
onConnect();
|
|
93
|
+
if (this.status === 'connected') {
|
|
94
|
+
this.#onConnected().catch(reject);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.provider.connect().catch(reject);
|
|
106
98
|
}
|
|
99
|
+
this.once('ready', () => {
|
|
100
|
+
resolve(this);
|
|
101
|
+
});
|
|
107
102
|
});
|
|
108
103
|
}
|
|
109
|
-
async
|
|
104
|
+
#onConnected = async () => {
|
|
110
105
|
this.emit('connected');
|
|
111
106
|
await this.#initialize();
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
async #onDisconnected() {
|
|
107
|
+
};
|
|
108
|
+
#onDisconnected = async () => {
|
|
115
109
|
await this.#unsubscribeUpdates();
|
|
116
110
|
this.emit('disconnected');
|
|
117
|
-
}
|
|
118
|
-
async
|
|
111
|
+
};
|
|
112
|
+
#onReconnecting = async () => {
|
|
113
|
+
this.emit('reconnecting');
|
|
114
|
+
};
|
|
115
|
+
#onError = async (e) => {
|
|
119
116
|
this.emit('error', e);
|
|
120
|
-
}
|
|
117
|
+
};
|
|
121
118
|
/**
|
|
122
119
|
* Initialize APIs before usage
|
|
123
120
|
*/
|
|
@@ -137,6 +134,7 @@ export class Dedot extends EventEmitter {
|
|
|
137
134
|
this.#runtimeChain = chainName;
|
|
138
135
|
await this.#setupMetadata(metadata);
|
|
139
136
|
this.#subscribeUpdates();
|
|
137
|
+
this.emit('ready');
|
|
140
138
|
}
|
|
141
139
|
async #initializeLocalCache() {
|
|
142
140
|
if (!this.#options.cacheMetadata)
|
|
@@ -216,7 +214,7 @@ export class Dedot extends EventEmitter {
|
|
|
216
214
|
}
|
|
217
215
|
#subscribeRuntimeUpgrades() {
|
|
218
216
|
// Disable runtime upgrades subscriptions if using a catch all metadata
|
|
219
|
-
if (this.#runtimeSubscriptionUnsub ||
|
|
217
|
+
if (this.#runtimeSubscriptionUnsub || this.hasCatchAllMetadata) {
|
|
220
218
|
return;
|
|
221
219
|
}
|
|
222
220
|
this.rpc.state
|
|
@@ -292,19 +290,14 @@ export class Dedot extends EventEmitter {
|
|
|
292
290
|
#getProvider() {
|
|
293
291
|
const { provider, endpoint } = this.#options;
|
|
294
292
|
if (provider) {
|
|
295
|
-
assert(provider.hasSubscriptions, 'Only supports RPC Provider can make subscription requests');
|
|
293
|
+
// assert(provider.hasSubscriptions, 'Only supports RPC Provider can make subscription requests');
|
|
296
294
|
return provider;
|
|
297
295
|
}
|
|
298
296
|
if (endpoint) {
|
|
299
|
-
|
|
300
|
-
return new WsProvider(endpoint);
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
throw new Error('Invalid RPC network endpoint, a valid endpoint should start with `wss://`, `ws://`');
|
|
304
|
-
}
|
|
297
|
+
return new WsProvider(endpoint);
|
|
305
298
|
}
|
|
306
299
|
// TODO support light-client
|
|
307
|
-
return new WsProvider();
|
|
300
|
+
return new WsProvider('ws://127.0.0.1:9944');
|
|
308
301
|
}
|
|
309
302
|
/**
|
|
310
303
|
* @description Entry-point for executing RPCs to blockchain node.
|
|
@@ -429,7 +422,8 @@ export class Dedot extends EventEmitter {
|
|
|
429
422
|
* @description Connect to blockchain node
|
|
430
423
|
*/
|
|
431
424
|
async connect() {
|
|
432
|
-
|
|
425
|
+
assert(this.status !== 'connected', 'Already connected!');
|
|
426
|
+
return this.#doConnect();
|
|
433
427
|
}
|
|
434
428
|
/**
|
|
435
429
|
* @description Disconnect to blockchain node
|
|
@@ -445,16 +439,10 @@ export class Dedot extends EventEmitter {
|
|
|
445
439
|
await this.#localCache?.clear();
|
|
446
440
|
}
|
|
447
441
|
/**
|
|
448
|
-
* @description Check
|
|
449
|
-
*/
|
|
450
|
-
get hasSubscriptions() {
|
|
451
|
-
return this.provider.hasSubscriptions;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* @description Check if it's connected to the blockchain node
|
|
442
|
+
* @description Check connection status of the api instance
|
|
455
443
|
*/
|
|
456
|
-
get
|
|
457
|
-
return this.provider.
|
|
444
|
+
get status() {
|
|
445
|
+
return this.provider.status;
|
|
458
446
|
}
|
|
459
447
|
/**
|
|
460
448
|
* @description Check if the api instance is using a catch-all metadata
|
package/executor/Executor.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = Su
|
|
|
11
11
|
constructor(api: Dedot<ChainApi>, atBlockHash?: BlockHash);
|
|
12
12
|
get api(): Dedot<ChainApi>;
|
|
13
13
|
get atBlockHash(): `0x${string}` | undefined;
|
|
14
|
-
get provider(): import("@
|
|
14
|
+
get provider(): import("@dedot/providers").JsonRpcProvider;
|
|
15
15
|
get registry(): import("@dedot/codecs").PortableRegistry;
|
|
16
16
|
get metadata(): {
|
|
17
17
|
types: {
|
package/executor/RpcExecutor.js
CHANGED
|
@@ -37,16 +37,11 @@ export class RpcExecutor extends Executor {
|
|
|
37
37
|
callback(this.tryDecode(callSpec, result));
|
|
38
38
|
};
|
|
39
39
|
const { params, pubsub } = callSpec;
|
|
40
|
-
const
|
|
41
|
-
const [subname, subscribe,
|
|
42
|
-
const subscription = this.provider.subscribe(subname, subscribe,
|
|
40
|
+
const formattedParams = inArgs.map((input, index) => this.tryEncode(params[index], input));
|
|
41
|
+
const [subname, subscribe, unsubscribe] = pubsub;
|
|
42
|
+
const subscription = await this.provider.subscribe({ subname, subscribe, params: formattedParams, unsubscribe }, onNewMessage);
|
|
43
43
|
return async () => {
|
|
44
|
-
|
|
45
|
-
.then((subscriptionId) => this.provider.unsubscribe(subname, unsubcribe, subscriptionId))
|
|
46
|
-
.catch((err) => {
|
|
47
|
-
console.error(err);
|
|
48
|
-
return false;
|
|
49
|
-
});
|
|
44
|
+
await subscription.unsubscribe();
|
|
50
45
|
};
|
|
51
46
|
};
|
|
52
47
|
if (!callSpec) {
|
package/executor/TxExecutor.d.ts
CHANGED
|
@@ -24,11 +24,11 @@ export declare class TxExecutor<ChainApi extends GenericSubstrateApi = Substrate
|
|
|
24
24
|
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): Promise<Hash>;
|
|
25
25
|
signAndSend(account: AddressOrPair, callback: Callback<ISubmittableResult>): Promise<Unsub>;
|
|
26
26
|
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, callback?: Callback<ISubmittableResult>): Promise<Unsub>;
|
|
27
|
-
"__#
|
|
27
|
+
"__#40@#normalizeOptions"(partialOptions?: Partial<SignerOptions> | Callback<ISubmittableResult>, callback?: Callback<ISubmittableResult>): [Partial<SignerOptions>, Callback<ISubmittableResult> | undefined];
|
|
28
28
|
dryRun(account: AddressOrPair, optionsOrHash?: Partial<SignerOptions> | BlockHash): Promise<DryRunResult>;
|
|
29
29
|
send(): Promise<Hash>;
|
|
30
30
|
send(callback: Callback<ISubmittableResult>): Promise<Unsub>;
|
|
31
|
-
"__#
|
|
31
|
+
"__#6@#private": any;
|
|
32
32
|
registry: import("@dedot/codecs").PortableRegistry;
|
|
33
33
|
readonly signed: boolean;
|
|
34
34
|
readonly version: number;
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dedot",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.30",
|
|
4
4
|
"description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
|
|
5
5
|
"author": "Thang X. Vu <thang@coongcrafts.io>",
|
|
6
6
|
"homepage": "https://github.com/dedotdev/dedot",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dedot/chaintypes": "
|
|
17
|
-
"@dedot/codecs": "0.0.1-alpha.
|
|
18
|
-
"@dedot/
|
|
19
|
-
"@dedot/
|
|
20
|
-
"@dedot/
|
|
21
|
-
"@dedot/
|
|
22
|
-
"@
|
|
16
|
+
"@dedot/chaintypes": "0.0.1-alpha.35",
|
|
17
|
+
"@dedot/codecs": "0.0.1-alpha.30",
|
|
18
|
+
"@dedot/providers": "^0.0.1-alpha.30",
|
|
19
|
+
"@dedot/shape": "0.0.1-alpha.30",
|
|
20
|
+
"@dedot/specs": "0.0.1-alpha.30",
|
|
21
|
+
"@dedot/storage": "0.0.1-alpha.30",
|
|
22
|
+
"@dedot/utils": "0.0.1-alpha.30"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@polkadot/keyring": "^12.6.2",
|
|
36
36
|
"@polkadot/types": "^10.11.2"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ebc78daa1c0786f16dbf3a1f2c7a385142860ebc",
|
|
39
39
|
"module": "./index.js",
|
|
40
40
|
"types": "./index.d.ts",
|
|
41
41
|
"exports": {
|
package/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/test.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { WsProvider } from '@dedot/providers';
|
|
2
|
+
const run = async () => {
|
|
3
|
+
// const api = new Dedot('');
|
|
4
|
+
// await api.connect();
|
|
5
|
+
// console.log(await api.rpc.chain.getHeader());
|
|
6
|
+
// await api.disconnect();
|
|
7
|
+
// await api.connect();
|
|
8
|
+
// console.log(await api.rpc.chain.getHeader());
|
|
9
|
+
// await api.disconnect();
|
|
10
|
+
// const provider = new WsProvider({ endpoint: 'wss://rpc.polkadot.io', retryDelayMs: -1 });
|
|
11
|
+
// const provider = new WsProvider({ endpoint: 'ws://hello' });
|
|
12
|
+
// provider.on('reconnecting', () => {
|
|
13
|
+
// console.log('reconnecting');
|
|
14
|
+
// });
|
|
15
|
+
// //
|
|
16
|
+
// await provider.connect();
|
|
17
|
+
const provider = new WsProvider('wss://rpc.polkadot.io');
|
|
18
|
+
await provider.connect();
|
|
19
|
+
const genesisHash = await provider.send('chain_getBlockHash', [0]);
|
|
20
|
+
console.log(genesisHash);
|
|
21
|
+
await provider.subscribe({
|
|
22
|
+
subname: 'chain_newHead',
|
|
23
|
+
subscribe: 'chain_subscribeNewHeads',
|
|
24
|
+
params: [],
|
|
25
|
+
unsubscribe: 'chain_unsubscribeNewHeads',
|
|
26
|
+
}, (error, newHead, subscription) => {
|
|
27
|
+
console.log('newHead', newHead);
|
|
28
|
+
});
|
|
29
|
+
// await provider.disconnect();
|
|
30
|
+
//
|
|
31
|
+
// await provider.subscribe(
|
|
32
|
+
// {
|
|
33
|
+
// subname: 'chain_newHead',
|
|
34
|
+
// subscribe: 'chain_subscribeNewHead',
|
|
35
|
+
// unsubscribe: 'chain_unsubscribeNewHead',
|
|
36
|
+
// params: [],
|
|
37
|
+
// },
|
|
38
|
+
// async (error, head, subscription) => {
|
|
39
|
+
// if (error) {
|
|
40
|
+
// console.log('01 - New head error:', error);
|
|
41
|
+
// } else {
|
|
42
|
+
// console.log('01 - New head:', head.number, subscription);
|
|
43
|
+
// }
|
|
44
|
+
// },
|
|
45
|
+
// );
|
|
46
|
+
//
|
|
47
|
+
// setTimeout(async () => {
|
|
48
|
+
// await provider.disconnect();
|
|
49
|
+
// }, 3000);
|
|
50
|
+
//
|
|
51
|
+
// setTimeout(async () => {
|
|
52
|
+
// await provider.connect();
|
|
53
|
+
//
|
|
54
|
+
// await provider.subscribe(
|
|
55
|
+
// {
|
|
56
|
+
// subname: 'chain_newHead',
|
|
57
|
+
// subscribe: 'chain_subscribeNewHead',
|
|
58
|
+
// unsubscribe: 'chain_unsubscribeNewHead',
|
|
59
|
+
// params: [],
|
|
60
|
+
// },
|
|
61
|
+
// async (error, head, subscription) => {
|
|
62
|
+
// console.log('02 - New head:', head.number, subscription);
|
|
63
|
+
// },
|
|
64
|
+
// );
|
|
65
|
+
// }, 10000);
|
|
66
|
+
};
|
|
67
|
+
run().catch(console.error);
|
package/types.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { RuntimeApiName, RuntimeApiSpec } from '@dedot/types';
|
|
1
|
+
import type { HexString } from '@dedot/utils';
|
|
2
|
+
import type { AnySignedExtension } from './extrinsic/index.js';
|
|
3
|
+
import type { RuntimeApiName, RuntimeApiSpec } from '@dedot/types';
|
|
5
4
|
import type { IStorage } from '@dedot/storage';
|
|
5
|
+
import type { JsonRpcProvider, ProviderEvent } from '@dedot/providers';
|
|
6
6
|
export type NetworkEndpoint = string;
|
|
7
7
|
export type MetadataKey = `RAW_META/${string}`;
|
|
8
8
|
export interface ApiOptions {
|
|
9
|
-
provider?:
|
|
9
|
+
provider?: JsonRpcProvider;
|
|
10
10
|
/**
|
|
11
11
|
* @description A `ProviderInterface` will be created based on the supplied endpoint.
|
|
12
12
|
* If both `provider` and `endpoint` is provided, the `provider` will be used for connection.
|
|
@@ -59,4 +59,4 @@ export interface ApiOptions {
|
|
|
59
59
|
export interface NormalizedApiOptions extends ApiOptions {
|
|
60
60
|
metadata?: Record<string, HexString>;
|
|
61
61
|
}
|
|
62
|
-
export type ApiEventNames =
|
|
62
|
+
export type ApiEventNames = ProviderEvent | 'ready';
|