@pezkuwi/api 16.5.5 → 16.5.6
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/LICENSE +201 -0
- package/README.md +12 -12
- package/augment.js +1 -0
- package/base/Decorate.js +752 -0
- package/base/Events.js +78 -0
- package/base/Getters.js +207 -0
- package/base/Init.js +400 -0
- package/base/find.js +7 -0
- package/{build/base → base}/index.d.ts +1 -1
- package/base/index.js +57 -0
- package/bundle-pezkuwi-api.js +26238 -0
- package/{src/bundle.ts → bundle.js} +0 -9
- package/cjs/augment.d.ts +1 -0
- package/cjs/augment.js +3 -0
- package/cjs/base/Decorate.d.ts +143 -0
- package/cjs/base/Decorate.js +756 -0
- package/cjs/base/Events.d.ts +67 -0
- package/cjs/base/Events.js +82 -0
- package/cjs/base/Getters.d.ts +163 -0
- package/cjs/base/Getters.js +211 -0
- package/cjs/base/Init.d.ts +44 -0
- package/cjs/base/Init.js +404 -0
- package/cjs/base/find.d.ts +3 -0
- package/cjs/base/find.js +11 -0
- package/cjs/base/index.d.ts +47 -0
- package/cjs/base/index.js +61 -0
- package/{src/base/types.ts → cjs/base/types.d.ts} +8 -12
- package/cjs/base/types.js +2 -0
- package/cjs/bundle.d.ts +7 -0
- package/cjs/bundle.js +17 -0
- package/cjs/index.js +5 -0
- package/cjs/package.json +3 -0
- package/cjs/packageDetect.d.ts +1 -0
- package/cjs/packageDetect.js +10 -0
- package/cjs/packageInfo.js +4 -0
- package/{build → cjs}/promise/Api.d.ts +2 -2
- package/cjs/promise/Api.js +195 -0
- package/cjs/promise/Combinator.js +72 -0
- package/cjs/promise/decorateMethod.js +75 -0
- package/cjs/promise/index.js +7 -0
- package/cjs/promise/types.js +2 -0
- package/{build → cjs}/rx/Api.d.ts +2 -2
- package/cjs/rx/Api.js +173 -0
- package/cjs/rx/decorateMethod.js +6 -0
- package/cjs/rx/index.js +7 -0
- package/cjs/submittable/Result.js +84 -0
- package/cjs/submittable/createClass.js +277 -0
- package/cjs/submittable/createSubmittable.js +8 -0
- package/cjs/submittable/index.js +7 -0
- package/cjs/submittable/types.js +2 -0
- package/cjs/types/calls.js +4 -0
- package/cjs/types/consts.js +4 -0
- package/cjs/types/errors.js +4 -0
- package/cjs/types/events.js +4 -0
- package/cjs/types/index.js +13 -0
- package/cjs/types/storage.js +4 -0
- package/cjs/types/submittable.js +4 -0
- package/cjs/util/augmentObject.js +84 -0
- package/cjs/util/decorate.js +17 -0
- package/cjs/util/filterEvents.js +25 -0
- package/cjs/util/index.js +11 -0
- package/cjs/util/isKeyringPair.js +7 -0
- package/cjs/util/logging.js +5 -0
- package/cjs/util/validate.js +26 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +588 -22
- package/packageDetect.d.ts +1 -0
- package/{src/packageDetect.ts → packageDetect.js} +0 -8
- package/packageInfo.d.ts +6 -0
- package/packageInfo.js +1 -0
- package/promise/Api.d.ts +158 -0
- package/promise/Api.js +191 -0
- package/promise/Combinator.d.ts +12 -0
- package/promise/Combinator.js +68 -0
- package/promise/decorateMethod.d.ts +14 -0
- package/promise/decorateMethod.js +71 -0
- package/promise/index.d.ts +2 -0
- package/promise/index.js +2 -0
- package/{src/promise/types.ts → promise/types.d.ts} +0 -4
- package/promise/types.js +1 -0
- package/rx/Api.d.ts +155 -0
- package/{src/rx/Api.ts → rx/Api.js} +67 -84
- package/rx/decorateMethod.d.ts +3 -0
- package/rx/decorateMethod.js +3 -0
- package/rx/index.d.ts +2 -0
- package/rx/index.js +2 -0
- package/submittable/Result.d.ts +31 -0
- package/submittable/Result.js +80 -0
- package/submittable/createClass.d.ts +12 -0
- package/submittable/createClass.js +274 -0
- package/submittable/createSubmittable.d.ts +8 -0
- package/submittable/createSubmittable.js +5 -0
- package/{src/submittable/index.ts → submittable/index.d.ts} +0 -3
- package/submittable/index.js +2 -0
- package/{src/submittable/types.ts → submittable/types.d.ts} +0 -3
- package/submittable/types.js +1 -0
- package/types/calls.d.ts +1 -0
- package/types/calls.js +1 -0
- package/types/consts.d.ts +1 -0
- package/types/consts.js +1 -0
- package/types/errors.d.ts +1 -0
- package/types/errors.js +1 -0
- package/types/events.d.ts +1 -0
- package/types/events.js +1 -0
- package/types/index.d.ts +114 -0
- package/types/index.js +8 -0
- package/types/storage.d.ts +1 -0
- package/types/storage.js +1 -0
- package/types/submittable.d.ts +1 -0
- package/types/submittable.js +1 -0
- package/util/augmentObject.d.ts +9 -0
- package/util/augmentObject.js +81 -0
- package/util/decorate.d.ts +16 -0
- package/util/decorate.js +14 -0
- package/util/filterEvents.d.ts +6 -0
- package/util/filterEvents.js +22 -0
- package/{src/util/index.ts → util/index.d.ts} +0 -6
- package/util/index.js +4 -0
- package/util/isKeyringPair.d.ts +3 -0
- package/util/isKeyringPair.js +4 -0
- package/util/logging.d.ts +1 -0
- package/util/logging.js +2 -0
- package/util/validate.d.ts +3 -0
- package/util/validate.js +23 -0
- package/src/augment.ts +0 -4
- package/src/base/Decorate.ts +0 -1103
- package/src/base/Events.ts +0 -91
- package/src/base/Getters.ts +0 -245
- package/src/base/Init.ts +0 -525
- package/src/base/find.ts +0 -14
- package/src/base/index.ts +0 -85
- package/src/checkTypes.manual.ts +0 -323
- package/src/index.ts +0 -6
- package/src/mod.ts +0 -4
- package/src/packageInfo.ts +0 -6
- package/src/promise/Api.ts +0 -214
- package/src/promise/Combinator.ts +0 -91
- package/src/promise/Combinators.spec.ts +0 -109
- package/src/promise/decorateMethod.ts +0 -118
- package/src/promise/index.spec.ts +0 -167
- package/src/promise/index.ts +0 -5
- package/src/rx/decorateMethod.ts +0 -9
- package/src/rx/index.ts +0 -5
- package/src/submittable/Result.ts +0 -111
- package/src/submittable/createClass.ts +0 -438
- package/src/submittable/createSubmittable.ts +0 -19
- package/src/test/SingleAccountSigner.ts +0 -53
- package/src/test/index.ts +0 -5
- package/src/test/logEvents.ts +0 -24
- package/src/types/calls.ts +0 -4
- package/src/types/consts.ts +0 -4
- package/src/types/errors.ts +0 -4
- package/src/types/events.ts +0 -4
- package/src/types/index.ts +0 -137
- package/src/types/storage.ts +0 -4
- package/src/types/submittable.ts +0 -4
- package/src/util/augmentObject.spec.ts +0 -54
- package/src/util/augmentObject.ts +0 -112
- package/src/util/decorate.ts +0 -43
- package/src/util/filterEvents.ts +0 -34
- package/src/util/isKeyringPair.ts +0 -11
- package/src/util/logging.ts +0 -6
- package/src/util/validate.spec.ts +0 -72
- package/src/util/validate.ts +0 -36
- package/tsconfig.build.json +0 -25
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.spec.json +0 -26
- /package/{build/augment.d.ts → augment.d.ts} +0 -0
- /package/{build/base → base}/Decorate.d.ts +0 -0
- /package/{build/base → base}/Events.d.ts +0 -0
- /package/{build/base → base}/Getters.d.ts +0 -0
- /package/{build/base → base}/Init.d.ts +0 -0
- /package/{build/base → base}/find.d.ts +0 -0
- /package/{build/base → base}/types.d.ts +0 -0
- /package/{build/packageDetect.d.ts → base/types.js} +0 -0
- /package/{build/bundle.d.ts → bundle.d.ts} +0 -0
- /package/{build → cjs}/index.d.ts +0 -0
- /package/{build → cjs}/packageInfo.d.ts +0 -0
- /package/{build → cjs}/promise/Combinator.d.ts +0 -0
- /package/{build → cjs}/promise/decorateMethod.d.ts +0 -0
- /package/{build → cjs}/promise/index.d.ts +0 -0
- /package/{build → cjs}/promise/types.d.ts +0 -0
- /package/{build → cjs}/rx/decorateMethod.d.ts +0 -0
- /package/{build → cjs}/rx/index.d.ts +0 -0
- /package/{build → cjs}/submittable/Result.d.ts +0 -0
- /package/{build → cjs}/submittable/createClass.d.ts +0 -0
- /package/{build → cjs}/submittable/createSubmittable.d.ts +0 -0
- /package/{build → cjs}/submittable/index.d.ts +0 -0
- /package/{build → cjs}/submittable/types.d.ts +0 -0
- /package/{build → cjs}/types/calls.d.ts +0 -0
- /package/{build → cjs}/types/consts.d.ts +0 -0
- /package/{build → cjs}/types/errors.d.ts +0 -0
- /package/{build → cjs}/types/events.d.ts +0 -0
- /package/{build → cjs}/types/index.d.ts +0 -0
- /package/{build → cjs}/types/storage.d.ts +0 -0
- /package/{build → cjs}/types/submittable.d.ts +0 -0
- /package/{build → cjs}/util/augmentObject.d.ts +0 -0
- /package/{build → cjs}/util/decorate.d.ts +0 -0
- /package/{build → cjs}/util/filterEvents.d.ts +0 -0
- /package/{build → cjs}/util/index.d.ts +0 -0
- /package/{build → cjs}/util/isKeyringPair.d.ts +0 -0
- /package/{build → cjs}/util/logging.d.ts +0 -0
- /package/{build → cjs}/util/validate.d.ts +0 -0
package/base/Events.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { EventEmitter } from 'eventemitter3';
|
|
2
|
+
export class Events {
|
|
3
|
+
#eventemitter = new EventEmitter();
|
|
4
|
+
emit(type, ...args) {
|
|
5
|
+
return this.#eventemitter.emit(type, ...args);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* @description Attach an eventemitter handler to listen to a specific event
|
|
9
|
+
*
|
|
10
|
+
* @param type The type of event to listen to. Available events are `connected`, `disconnected`, `ready` and `error`
|
|
11
|
+
* @param handler The callback to be called when the event fires. Depending on the event type, it could fire with additional arguments.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <BR>
|
|
15
|
+
*
|
|
16
|
+
* ```javascript
|
|
17
|
+
* api.on('connected', (): void => {
|
|
18
|
+
* console.log('API has been connected to the endpoint');
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* api.on('disconnected', (): void => {
|
|
22
|
+
* console.log('API has been disconnected from the endpoint');
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
on(type, handler) {
|
|
27
|
+
this.#eventemitter.on(type, handler);
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @description Remove the given eventemitter handler
|
|
32
|
+
*
|
|
33
|
+
* @param type The type of event the callback was attached to. Available events are `connected`, `disconnected`, `ready` and `error`
|
|
34
|
+
* @param handler The callback to unregister.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* <BR>
|
|
38
|
+
*
|
|
39
|
+
* ```javascript
|
|
40
|
+
* const handler = (): void => {
|
|
41
|
+
* console.log('Connected !);
|
|
42
|
+
* };
|
|
43
|
+
*
|
|
44
|
+
* // Start listening
|
|
45
|
+
* api.on('connected', handler);
|
|
46
|
+
*
|
|
47
|
+
* // Stop listening
|
|
48
|
+
* api.off('connected', handler);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
off(type, handler) {
|
|
52
|
+
this.#eventemitter.removeListener(type, handler);
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @description Attach an one-time eventemitter handler to listen to a specific event
|
|
57
|
+
*
|
|
58
|
+
* @param type The type of event to listen to. Available events are `connected`, `disconnected`, `ready` and `error`
|
|
59
|
+
* @param handler The callback to be called when the event fires. Depending on the event type, it could fire with additional arguments.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <BR>
|
|
63
|
+
*
|
|
64
|
+
* ```javascript
|
|
65
|
+
* api.once('connected', (): void => {
|
|
66
|
+
* console.log('API has been connected to the endpoint');
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* api.once('disconnected', (): void => {
|
|
70
|
+
* console.log('API has been disconnected from the endpoint');
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
once(type, handler) {
|
|
75
|
+
this.#eventemitter.once(type, handler);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
}
|
package/base/Getters.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { packageInfo } from '../packageInfo.js';
|
|
2
|
+
import { findCall, findError } from './find.js';
|
|
3
|
+
import { Init } from './Init.js';
|
|
4
|
+
function assertResult(value) {
|
|
5
|
+
if (value === undefined) {
|
|
6
|
+
throw new Error("Api interfaces needs to be initialized before using, wait for 'isReady'");
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
export class Getters extends Init {
|
|
11
|
+
/**
|
|
12
|
+
* @description Runtime call interfaces (currently untyped, only decorated via API options)
|
|
13
|
+
*/
|
|
14
|
+
get call() {
|
|
15
|
+
return assertResult(this._call);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @description Contains the parameter types (constants) of all modules.
|
|
19
|
+
*
|
|
20
|
+
* The values are instances of the appropriate type and are accessible using `section`.`constantName`,
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* <BR>
|
|
24
|
+
*
|
|
25
|
+
* ```javascript
|
|
26
|
+
* console.log(api.consts.democracy.enactmentPeriod.toString())
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
get consts() {
|
|
30
|
+
return assertResult(this._consts);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @description Derived results that are injected into the API, allowing for combinations of various query results.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* <BR>
|
|
37
|
+
*
|
|
38
|
+
* ```javascript
|
|
39
|
+
* api.derive.chain.bestNumber((number) => {
|
|
40
|
+
* console.log('best number', number);
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
get derive() {
|
|
45
|
+
return assertResult(this._derive);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @description Errors from metadata
|
|
49
|
+
*/
|
|
50
|
+
get errors() {
|
|
51
|
+
return assertResult(this._errors);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @description Events from metadata
|
|
55
|
+
*/
|
|
56
|
+
get events() {
|
|
57
|
+
return assertResult(this._events);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @description Returns the version of extrinsics in-use on this chain
|
|
61
|
+
*/
|
|
62
|
+
get extrinsicVersion() {
|
|
63
|
+
return this._extrinsicType;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @description Contains the genesis Hash of the attached chain. Apart from being useful to determine the actual chain, it can also be used to sign immortal transactions.
|
|
67
|
+
*/
|
|
68
|
+
get genesisHash() {
|
|
69
|
+
return assertResult(this._genesisHash);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @description true is the underlying provider is connected
|
|
73
|
+
*/
|
|
74
|
+
get isConnected() {
|
|
75
|
+
return this._isConnected.getValue();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @description The library information name & version (from package.json)
|
|
79
|
+
*/
|
|
80
|
+
get libraryInfo() {
|
|
81
|
+
return `${packageInfo.name} v${packageInfo.version}`;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @description Contains all the chain state modules and their subsequent methods in the API. These are attached dynamically from the runtime metadata.
|
|
85
|
+
*
|
|
86
|
+
* All calls inside the namespace, is denoted by `section`.`method` and may take an optional query parameter. As an example, `api.query.timestamp.now()` (current block timestamp) does not take parameters, while `api.query.system.account(<accountId>)` (retrieving the associated nonce & balances for an account), takes the `AccountId` as a parameter.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* <BR>
|
|
90
|
+
*
|
|
91
|
+
* ```javascript
|
|
92
|
+
* api.query.system.account(<accountId>, ([nonce, balance]) => {
|
|
93
|
+
* console.log('new free balance', balance.free, 'new nonce', nonce);
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
get query() {
|
|
98
|
+
return assertResult(this._query);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @description Allows for the querying of multiple storage entries and the combination thereof into a single result. This is a very optimal way to make multiple queries since it only makes a single connection to the node and retrieves the data over one subscription.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* <BR>
|
|
105
|
+
*
|
|
106
|
+
* ```javascript
|
|
107
|
+
* const unsub = await api.queryMulti(
|
|
108
|
+
* [
|
|
109
|
+
* // you can include the storage without any parameters
|
|
110
|
+
* api.query.balances.totalIssuance,
|
|
111
|
+
* // or you can pass parameters to the storage query
|
|
112
|
+
* [api.query.system.account, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY']
|
|
113
|
+
* ],
|
|
114
|
+
* ([existential, [, { free }]]) => {
|
|
115
|
+
* console.log(`You have ${free.sub(existential)} more than the existential deposit`);
|
|
116
|
+
*
|
|
117
|
+
* unsub();
|
|
118
|
+
* }
|
|
119
|
+
* );
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
get queryMulti() {
|
|
123
|
+
return assertResult(this._queryMulti);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @description Contains all the raw rpc sections and their subsequent methods in the API as defined by the jsonrpc interface definitions. Unlike the dynamic `api.query` and `api.tx` sections, these methods are fixed (although extensible with node upgrades) and not determined by the runtime.
|
|
127
|
+
*
|
|
128
|
+
* RPC endpoints available here allow for the query of chain, node and system information, in addition to providing interfaces for the raw queries of state (using known keys) and the submission of transactions.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* <BR>
|
|
132
|
+
*
|
|
133
|
+
* ```javascript
|
|
134
|
+
* api.rpc.chain.subscribeNewHeads((header) => {
|
|
135
|
+
* console.log('new header', header);
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
get rpc() {
|
|
140
|
+
return assertResult(this._rpc);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* @description Contains the chain information for the current node.
|
|
144
|
+
*/
|
|
145
|
+
get runtimeChain() {
|
|
146
|
+
return assertResult(this._runtimeChain);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @description Yields the current attached runtime metadata. Generally this is only used to construct extrinsics & storage, but is useful for current runtime inspection.
|
|
150
|
+
*/
|
|
151
|
+
get runtimeMetadata() {
|
|
152
|
+
return assertResult(this._runtimeMetadata);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* @description Contains the version information for the current runtime.
|
|
156
|
+
*/
|
|
157
|
+
get runtimeVersion() {
|
|
158
|
+
return assertResult(this._runtimeVersion);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* @description The underlying Rx API interface
|
|
162
|
+
*/
|
|
163
|
+
get rx() {
|
|
164
|
+
return assertResult(this._rx);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* @description Returns the underlying provider stats
|
|
168
|
+
*/
|
|
169
|
+
get stats() {
|
|
170
|
+
return this._rpcCore.stats;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* @description The type of this API instance, either 'rxjs' or 'promise'
|
|
174
|
+
*/
|
|
175
|
+
get type() {
|
|
176
|
+
return this._type;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* @description Contains all the extrinsic modules and their subsequent methods in the API. It allows for the construction of transactions and the submission thereof. These are attached dynamically from the runtime metadata.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* <BR>
|
|
183
|
+
*
|
|
184
|
+
* ```javascript
|
|
185
|
+
* api.tx.balances
|
|
186
|
+
* .transferAllowDeath(<recipientId>, <balance>)
|
|
187
|
+
* .signAndSend(<keyPair>, ({status}) => {
|
|
188
|
+
* console.log('tx status', status.asFinalized.toHex());
|
|
189
|
+
* });
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
get tx() {
|
|
193
|
+
return assertResult(this._extrinsics);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* @description Finds the definition for a specific [[CallFunction]] based on the index supplied
|
|
197
|
+
*/
|
|
198
|
+
findCall(callIndex) {
|
|
199
|
+
return findCall(this.registry, callIndex);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* @description Finds the definition for a specific [[RegistryError]] based on the index supplied
|
|
203
|
+
*/
|
|
204
|
+
findError(errorIndex) {
|
|
205
|
+
return findError(this.registry, errorIndex);
|
|
206
|
+
}
|
|
207
|
+
}
|
package/base/Init.js
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { firstValueFrom, map, of, switchMap } from 'rxjs';
|
|
2
|
+
import { Metadata, TypeRegistry } from '@pezkuwi/types';
|
|
3
|
+
import { LATEST_EXTRINSIC_VERSION } from '@pezkuwi/types/extrinsic/constants';
|
|
4
|
+
import { getSpecAlias, getSpecExtensions, getSpecHasher, getSpecRpc, getSpecTypes, getUpgradeVersion } from '@pezkuwi/types-known';
|
|
5
|
+
import { assertReturn, BN_ZERO, isUndefined, logger, noop, objectSpread, u8aEq, u8aToHex, u8aToU8a } from '@pezkuwi/util';
|
|
6
|
+
import { blake2AsHex, cryptoWaitReady } from '@pezkuwi/util-crypto';
|
|
7
|
+
import { Decorate } from './Decorate.js';
|
|
8
|
+
const KEEPALIVE_INTERVAL = 10000;
|
|
9
|
+
const WITH_VERSION_SHORTCUT = false;
|
|
10
|
+
const SUPPORTED_METADATA_VERSIONS = [16, 15, 14];
|
|
11
|
+
const l = logger('api/init');
|
|
12
|
+
function textToString(t) {
|
|
13
|
+
return t.toString();
|
|
14
|
+
}
|
|
15
|
+
export class Init extends Decorate {
|
|
16
|
+
#atLast = null;
|
|
17
|
+
#healthTimer = null;
|
|
18
|
+
#registries = [];
|
|
19
|
+
#updateSub = null;
|
|
20
|
+
#waitingRegistries = {};
|
|
21
|
+
constructor(options, type, decorateMethod) {
|
|
22
|
+
super(options, type, decorateMethod);
|
|
23
|
+
// all injected types added to the registry for overrides
|
|
24
|
+
this.registry.setKnownTypes(options);
|
|
25
|
+
// We only register the types (global) if this is not a cloned instance.
|
|
26
|
+
// Do right up-front, so we get in the user types before we are actually
|
|
27
|
+
// doing anything on-chain, this ensures we have the overrides in-place
|
|
28
|
+
if (!options.source) {
|
|
29
|
+
this.registerTypes(options.types);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.#registries = options.source.#registries;
|
|
33
|
+
}
|
|
34
|
+
this._rpc = this._decorateRpc(this._rpcCore, this._decorateMethod);
|
|
35
|
+
this._rx.rpc = this._decorateRpc(this._rpcCore, this._rxDecorateMethod);
|
|
36
|
+
if (this.supportMulti) {
|
|
37
|
+
this._queryMulti = this._decorateMulti(this._decorateMethod);
|
|
38
|
+
this._rx.queryMulti = this._decorateMulti(this._rxDecorateMethod);
|
|
39
|
+
}
|
|
40
|
+
this._rx.signer = options.signer;
|
|
41
|
+
this._rpcCore.setRegistrySwap((blockHash) => this.getBlockRegistry(blockHash));
|
|
42
|
+
this._rpcCore.setResolveBlockHash((blockNumber) => firstValueFrom(this._rpcCore.chain.getBlockHash(blockNumber)));
|
|
43
|
+
if (this.hasSubscriptions) {
|
|
44
|
+
this._rpcCore.provider.on('disconnected', () => this.#onProviderDisconnect());
|
|
45
|
+
this._rpcCore.provider.on('error', (e) => this.#onProviderError(e));
|
|
46
|
+
this._rpcCore.provider.on('connected', () => this.#onProviderConnect());
|
|
47
|
+
}
|
|
48
|
+
else if (!this._options.noInitWarn) {
|
|
49
|
+
l.warn('Api will be available in a limited mode since the provider does not support subscriptions');
|
|
50
|
+
}
|
|
51
|
+
// If the provider was instantiated earlier, and has already emitted a
|
|
52
|
+
// 'connected' event, then the `on('connected')` won't fire anymore. To
|
|
53
|
+
// cater for this case, we call manually `this._onProviderConnect`.
|
|
54
|
+
if (this._rpcCore.provider.isConnected) {
|
|
55
|
+
this.#onProviderConnect().catch(noop);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @description Decorates a registry based on the runtime version
|
|
60
|
+
*/
|
|
61
|
+
_initRegistry(registry, chain, version, metadata, chainProps) {
|
|
62
|
+
registry.clearCache();
|
|
63
|
+
registry.setChainProperties(chainProps || this.registry.getChainProperties());
|
|
64
|
+
registry.setKnownTypes(this._options);
|
|
65
|
+
registry.register(getSpecTypes(registry, chain, version.specName, version.specVersion));
|
|
66
|
+
registry.setHasher(getSpecHasher(registry, chain, version.specName));
|
|
67
|
+
// for bundled types, pull through the aliases defined
|
|
68
|
+
if (registry.knownTypes.typesBundle) {
|
|
69
|
+
registry.knownTypes.typesAlias = getSpecAlias(registry, chain, version.specName);
|
|
70
|
+
}
|
|
71
|
+
registry.setMetadata(metadata, undefined, objectSpread({}, getSpecExtensions(registry, chain, version.specName), this._options.signedExtensions), this._options.noInitWarn);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @description Returns the default versioned registry
|
|
75
|
+
*/
|
|
76
|
+
_getDefaultRegistry() {
|
|
77
|
+
return assertReturn(this.#registries.find(({ isDefault }) => isDefault), 'Initialization error, cannot find the default registry');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @description Returns a decorated API instance at a specific point in time
|
|
81
|
+
*/
|
|
82
|
+
async at(blockHash, knownVersion) {
|
|
83
|
+
const u8aHash = u8aToU8a(blockHash);
|
|
84
|
+
const u8aHex = u8aToHex(u8aHash);
|
|
85
|
+
const registry = await this.getBlockRegistry(u8aHash, knownVersion);
|
|
86
|
+
if (!this.#atLast || this.#atLast[0] !== u8aHex) {
|
|
87
|
+
// always create a new decoration - since we are pointing to a specific hash, this
|
|
88
|
+
// means that all queries needs to use that hash (not a previous one already existing)
|
|
89
|
+
this.#atLast = [u8aHex, this._createDecorated(registry, true, null, u8aHash).decoratedApi];
|
|
90
|
+
}
|
|
91
|
+
return this.#atLast[1];
|
|
92
|
+
}
|
|
93
|
+
async _createBlockRegistry(blockHash, header, version) {
|
|
94
|
+
const registry = new TypeRegistry(blockHash);
|
|
95
|
+
const metadata = await this._retrieveMetadata(version.apis, header.parentHash, registry);
|
|
96
|
+
const runtimeChain = this._runtimeChain;
|
|
97
|
+
if (!runtimeChain) {
|
|
98
|
+
throw new Error('Invalid initializion order, runtimeChain is not available');
|
|
99
|
+
}
|
|
100
|
+
this._initRegistry(registry, runtimeChain, version, metadata);
|
|
101
|
+
// add our new registry
|
|
102
|
+
const result = { counter: 0, lastBlockHash: blockHash, metadata, registry, runtimeVersion: version };
|
|
103
|
+
this.#registries.push(result);
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
_cacheBlockRegistryProgress(key, creator) {
|
|
107
|
+
// look for waiting resolves
|
|
108
|
+
let waiting = this.#waitingRegistries[key];
|
|
109
|
+
if (isUndefined(waiting)) {
|
|
110
|
+
// nothing waiting, construct new
|
|
111
|
+
waiting = this.#waitingRegistries[key] = new Promise((resolve, reject) => {
|
|
112
|
+
creator()
|
|
113
|
+
.then((registry) => {
|
|
114
|
+
delete this.#waitingRegistries[key];
|
|
115
|
+
resolve(registry);
|
|
116
|
+
})
|
|
117
|
+
.catch((error) => {
|
|
118
|
+
delete this.#waitingRegistries[key];
|
|
119
|
+
reject(error);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return waiting;
|
|
124
|
+
}
|
|
125
|
+
_getBlockRegistryViaVersion(blockHash, version) {
|
|
126
|
+
if (version) {
|
|
127
|
+
// check for pre-existing registries. We also check specName, e.g. it
|
|
128
|
+
// could be changed like in Westmint with upgrade from shell -> westmint
|
|
129
|
+
const existingViaVersion = this.#registries.find(({ runtimeVersion: { specName, specVersion } }) => specName.eq(version.specName) &&
|
|
130
|
+
specVersion.eq(version.specVersion));
|
|
131
|
+
if (existingViaVersion) {
|
|
132
|
+
existingViaVersion.counter++;
|
|
133
|
+
existingViaVersion.lastBlockHash = blockHash;
|
|
134
|
+
return existingViaVersion;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
async _getBlockRegistryViaHash(blockHash) {
|
|
140
|
+
// ensure we have everything required
|
|
141
|
+
if (!this._genesisHash || !this._runtimeVersion) {
|
|
142
|
+
throw new Error('Cannot retrieve data on an uninitialized chain');
|
|
143
|
+
}
|
|
144
|
+
// We have to assume that on the RPC layer the calls used here does not call back into
|
|
145
|
+
// the registry swap, so getHeader & getRuntimeVersion should not be historic
|
|
146
|
+
const header = this.registry.createType('HeaderPartial', this._genesisHash.eq(blockHash)
|
|
147
|
+
? { number: BN_ZERO, parentHash: this._genesisHash }
|
|
148
|
+
: await firstValueFrom(this._rpcCore.chain.getHeader.raw(blockHash)));
|
|
149
|
+
if (header.parentHash.isEmpty) {
|
|
150
|
+
l.warn(`Unable to retrieve header ${blockHash.toString()} and parent ${header.parentHash.toString()} from supplied hash`);
|
|
151
|
+
throw new Error('Unable to retrieve header and parent from supplied hash');
|
|
152
|
+
}
|
|
153
|
+
// get the runtime version, either on-chain or via an known upgrade history
|
|
154
|
+
const [firstVersion, lastVersion] = getUpgradeVersion(this._genesisHash, header.number);
|
|
155
|
+
const version = this.registry.createType('RuntimeVersionPartial', WITH_VERSION_SHORTCUT && (firstVersion && (lastVersion ||
|
|
156
|
+
firstVersion.specVersion.eq(this._runtimeVersion.specVersion)))
|
|
157
|
+
? { apis: firstVersion.apis, specName: this._runtimeVersion.specName, specVersion: firstVersion.specVersion }
|
|
158
|
+
: await firstValueFrom(this._rpcCore.state.getRuntimeVersion.raw(header.parentHash)));
|
|
159
|
+
return (
|
|
160
|
+
// try to find via version
|
|
161
|
+
this._getBlockRegistryViaVersion(blockHash, version) ||
|
|
162
|
+
// return new or in-flight result
|
|
163
|
+
await this._cacheBlockRegistryProgress(version.toHex(), () => this._createBlockRegistry(blockHash, header, version)));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* @description Sets up a registry based on the block hash defined
|
|
167
|
+
*/
|
|
168
|
+
async getBlockRegistry(blockHash, knownVersion) {
|
|
169
|
+
return (
|
|
170
|
+
// try to find via blockHash
|
|
171
|
+
this.#registries.find(({ lastBlockHash }) => lastBlockHash && u8aEq(lastBlockHash, blockHash)) ||
|
|
172
|
+
// try to find via version
|
|
173
|
+
this._getBlockRegistryViaVersion(blockHash, knownVersion) ||
|
|
174
|
+
// return new or in-flight result
|
|
175
|
+
await this._cacheBlockRegistryProgress(u8aToHex(blockHash), () => this._getBlockRegistryViaHash(blockHash)));
|
|
176
|
+
}
|
|
177
|
+
async _loadMeta() {
|
|
178
|
+
// on re-connection to the same chain, we don't want to re-do everything from chain again
|
|
179
|
+
if (this._isReady) {
|
|
180
|
+
// on re-connection only re-subscribe to chain updates if we are not a clone
|
|
181
|
+
if (!this._options.source) {
|
|
182
|
+
this._subscribeUpdates();
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
this._unsubscribeUpdates();
|
|
187
|
+
// only load from on-chain if we are not a clone (default path), alternatively
|
|
188
|
+
// just use the values from the source instance provided
|
|
189
|
+
[this._genesisHash, this._runtimeMetadata] = this._options.source?._isReady
|
|
190
|
+
? await this._metaFromSource(this._options.source)
|
|
191
|
+
: await this._metaFromChain(this._options.metadata);
|
|
192
|
+
return this._initFromMeta(this._runtimeMetadata);
|
|
193
|
+
}
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
195
|
+
async _metaFromSource(source) {
|
|
196
|
+
this._extrinsicType = source.extrinsicVersion;
|
|
197
|
+
this._runtimeChain = source.runtimeChain;
|
|
198
|
+
this._runtimeVersion = source.runtimeVersion;
|
|
199
|
+
// manually build a list of all available methods in this RPC, we are
|
|
200
|
+
// going to filter on it to align the cloned RPC without making a call
|
|
201
|
+
const sections = Object.keys(source.rpc);
|
|
202
|
+
const rpcs = [];
|
|
203
|
+
for (let s = 0, scount = sections.length; s < scount; s++) {
|
|
204
|
+
const section = sections[s];
|
|
205
|
+
const methods = Object.keys(source.rpc[section]);
|
|
206
|
+
for (let m = 0, mcount = methods.length; m < mcount; m++) {
|
|
207
|
+
rpcs.push(`${section}_${methods[m]}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
this._filterRpc(rpcs, getSpecRpc(this.registry, source.runtimeChain, source.runtimeVersion.specName));
|
|
211
|
+
return [source.genesisHash, source.runtimeMetadata];
|
|
212
|
+
}
|
|
213
|
+
// subscribe to metadata updates, inject the types on changes
|
|
214
|
+
_subscribeUpdates() {
|
|
215
|
+
if (this.#updateSub || !this.hasSubscriptions) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
this.#updateSub = this._rpcCore.state.subscribeRuntimeVersion().pipe(switchMap((version) =>
|
|
219
|
+
// only retrieve the metadata when the on-chain version has been changed
|
|
220
|
+
this._runtimeVersion?.specVersion.eq(version.specVersion)
|
|
221
|
+
? of(false)
|
|
222
|
+
: this._rpcCore.state.getMetadata().pipe(map((metadata) => {
|
|
223
|
+
l.log(`Runtime version updated to spec=${version.specVersion.toString()}, tx=${version.transactionVersion.toString()}`);
|
|
224
|
+
this._runtimeMetadata = metadata;
|
|
225
|
+
this._runtimeVersion = version;
|
|
226
|
+
this._rx.runtimeVersion = version;
|
|
227
|
+
// update the default registry version
|
|
228
|
+
const thisRegistry = this._getDefaultRegistry();
|
|
229
|
+
const runtimeChain = this._runtimeChain;
|
|
230
|
+
if (!runtimeChain) {
|
|
231
|
+
throw new Error('Invalid initializion order, runtimeChain is not available');
|
|
232
|
+
}
|
|
233
|
+
// setup the data as per the current versions
|
|
234
|
+
thisRegistry.metadata = metadata;
|
|
235
|
+
thisRegistry.runtimeVersion = version;
|
|
236
|
+
this._initRegistry(this.registry, runtimeChain, version, metadata);
|
|
237
|
+
this._injectMetadata(thisRegistry, true);
|
|
238
|
+
return true;
|
|
239
|
+
})))).subscribe();
|
|
240
|
+
}
|
|
241
|
+
async _metaFromChain(optMetadata) {
|
|
242
|
+
const [genesisHash, runtimeVersion, chain, chainProps, rpcMethods] = await Promise.all([
|
|
243
|
+
firstValueFrom(this._rpcCore.chain.getBlockHash(0)),
|
|
244
|
+
firstValueFrom(this._rpcCore.state.getRuntimeVersion()),
|
|
245
|
+
firstValueFrom(this._rpcCore.system.chain()),
|
|
246
|
+
firstValueFrom(this._rpcCore.system.properties()),
|
|
247
|
+
firstValueFrom(this._rpcCore.rpc.methods())
|
|
248
|
+
]);
|
|
249
|
+
// set our chain version & genesisHash as returned
|
|
250
|
+
this._runtimeChain = chain;
|
|
251
|
+
this._runtimeVersion = runtimeVersion;
|
|
252
|
+
this._rx.runtimeVersion = runtimeVersion;
|
|
253
|
+
// retrieve metadata, either from chain or as pass-in via options
|
|
254
|
+
const metadataKey = `${genesisHash.toHex() || '0x'}-${runtimeVersion.specVersion.toString()}`;
|
|
255
|
+
const metadata = optMetadata?.[metadataKey]
|
|
256
|
+
? new Metadata(this.registry, optMetadata[metadataKey])
|
|
257
|
+
: await this._retrieveMetadata(runtimeVersion.apis);
|
|
258
|
+
// initializes the registry & RPC
|
|
259
|
+
this._initRegistry(this.registry, chain, runtimeVersion, metadata, chainProps);
|
|
260
|
+
this._filterRpc(rpcMethods.methods.map(textToString), getSpecRpc(this.registry, chain, runtimeVersion.specName));
|
|
261
|
+
this._subscribeUpdates();
|
|
262
|
+
// setup the initial registry, when we have none
|
|
263
|
+
if (!this.#registries.length) {
|
|
264
|
+
this.#registries.push({ counter: 0, isDefault: true, metadata, registry: this.registry, runtimeVersion });
|
|
265
|
+
}
|
|
266
|
+
// get unique types & validate
|
|
267
|
+
metadata.getUniqTypes(this._options.throwOnUnknown || false);
|
|
268
|
+
return [genesisHash, metadata];
|
|
269
|
+
}
|
|
270
|
+
_initFromMeta(metadata) {
|
|
271
|
+
const runtimeVersion = this._runtimeVersion;
|
|
272
|
+
if (!runtimeVersion) {
|
|
273
|
+
throw new Error('Invalid initializion order, runtimeVersion is not available');
|
|
274
|
+
}
|
|
275
|
+
// ExtrinsicV5 is not fully supported yet, for that reason we default to version 4
|
|
276
|
+
this._extrinsicType = metadata.asLatest.extrinsic.versions.at(0) || LATEST_EXTRINSIC_VERSION;
|
|
277
|
+
this._rx.extrinsicType = this._extrinsicType;
|
|
278
|
+
this._rx.genesisHash = this._genesisHash;
|
|
279
|
+
this._rx.runtimeVersion = runtimeVersion;
|
|
280
|
+
// inject metadata and adjust the types as detected
|
|
281
|
+
this._injectMetadata(this._getDefaultRegistry(), true);
|
|
282
|
+
// derive is last, since it uses the decorated rx
|
|
283
|
+
this._rx.derive = this._decorateDeriveRx(this._rxDecorateMethod);
|
|
284
|
+
this._derive = this._decorateDerive(this._decorateMethod);
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* @internal
|
|
289
|
+
*
|
|
290
|
+
* Tries to use runtime api calls to retrieve metadata. This ensures the api initializes with the latest metadata.
|
|
291
|
+
* If the runtime call is not there it will use the rpc method.
|
|
292
|
+
*/
|
|
293
|
+
async _retrieveMetadata(apis, at, registry) {
|
|
294
|
+
let metadataVersion = null;
|
|
295
|
+
const metadataApi = apis.find(([a]) => a.eq(blake2AsHex('Metadata', 64)));
|
|
296
|
+
const typeRegistry = registry || this.registry;
|
|
297
|
+
// This chain does not have support for the metadataApi, or does not have the required version.
|
|
298
|
+
if (!metadataApi || metadataApi[1].toNumber() < 2) {
|
|
299
|
+
l.warn('MetadataApi not available, rpc::state::get_metadata will be used.');
|
|
300
|
+
return at
|
|
301
|
+
? new Metadata(typeRegistry, await firstValueFrom(this._rpcCore.state.getMetadata.raw(at)))
|
|
302
|
+
: await firstValueFrom(this._rpcCore.state.getMetadata());
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
const metadataVersionsAsBytes = at
|
|
306
|
+
? await firstValueFrom(this._rpcCore.state.call.raw('Metadata_metadata_versions', '0x', at))
|
|
307
|
+
: await firstValueFrom(this._rpcCore.state.call('Metadata_metadata_versions', '0x'));
|
|
308
|
+
const versions = typeRegistry.createType('Vec<u32>', metadataVersionsAsBytes);
|
|
309
|
+
// For unstable versions of the metadata the last value is set to u32 MAX in the runtime. This ensures only supported stable versions are used.
|
|
310
|
+
metadataVersion = versions.filter((ver) => SUPPORTED_METADATA_VERSIONS.includes(ver.toNumber())).reduce((largest, current) => current.gt(largest) ? current : largest);
|
|
311
|
+
}
|
|
312
|
+
catch (e) {
|
|
313
|
+
l.debug(e.message);
|
|
314
|
+
l.warn('error with state_call::Metadata_metadata_versions, rpc::state::get_metadata will be used');
|
|
315
|
+
}
|
|
316
|
+
// When the metadata version does not align with the latest supported versions we ensure not to call the metadata runtime call.
|
|
317
|
+
// I noticed on some previous runtimes that have support for `Metadata_metadata_at_version` that very irregular versions were being returned.
|
|
318
|
+
// This was evident with runtime 1000000 - it return a very large number. This ensures we always stick within what is supported.
|
|
319
|
+
if (metadataVersion && !SUPPORTED_METADATA_VERSIONS.includes(metadataVersion.toNumber())) {
|
|
320
|
+
metadataVersion = null;
|
|
321
|
+
}
|
|
322
|
+
if (metadataVersion) {
|
|
323
|
+
try {
|
|
324
|
+
const metadataBytes = at
|
|
325
|
+
? await firstValueFrom(this._rpcCore.state.call.raw('Metadata_metadata_at_version', u8aToHex(metadataVersion.toU8a()), at))
|
|
326
|
+
: await firstValueFrom(this._rpcCore.state.call('Metadata_metadata_at_version', u8aToHex(metadataVersion.toU8a())));
|
|
327
|
+
// When the metadata is called with `at` it is required to use `.raw`. Therefore since the length prefix is not present the
|
|
328
|
+
// need to create a `Raw` type is necessary before creating the `OpaqueMetadata` type or else there will be a magic number
|
|
329
|
+
// mismatch
|
|
330
|
+
const rawMeta = at
|
|
331
|
+
? typeRegistry.createType('Raw', metadataBytes).toU8a()
|
|
332
|
+
: metadataBytes;
|
|
333
|
+
const opaqueMetadata = typeRegistry.createType('Option<OpaqueMetadata>', rawMeta).unwrapOr(null);
|
|
334
|
+
if (opaqueMetadata) {
|
|
335
|
+
return new Metadata(typeRegistry, opaqueMetadata.toHex());
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch (e) {
|
|
339
|
+
l.debug(e.message);
|
|
340
|
+
l.warn('error with state_call::Metadata_metadata_at_version, rpc::state::get_metadata will be used');
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return at
|
|
344
|
+
? new Metadata(typeRegistry, await firstValueFrom(this._rpcCore.state.getMetadata.raw(at)))
|
|
345
|
+
: await firstValueFrom(this._rpcCore.state.getMetadata());
|
|
346
|
+
}
|
|
347
|
+
_subscribeHealth() {
|
|
348
|
+
this._unsubscribeHealth();
|
|
349
|
+
// Only enable the health keepalive on WS, not needed on HTTP
|
|
350
|
+
this.#healthTimer = this.hasSubscriptions
|
|
351
|
+
? setInterval(() => {
|
|
352
|
+
firstValueFrom(this._rpcCore.system.health.raw()).catch(noop);
|
|
353
|
+
}, KEEPALIVE_INTERVAL)
|
|
354
|
+
: null;
|
|
355
|
+
}
|
|
356
|
+
_unsubscribeHealth() {
|
|
357
|
+
if (this.#healthTimer) {
|
|
358
|
+
clearInterval(this.#healthTimer);
|
|
359
|
+
this.#healthTimer = null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
_unsubscribeUpdates() {
|
|
363
|
+
if (this.#updateSub) {
|
|
364
|
+
this.#updateSub.unsubscribe();
|
|
365
|
+
this.#updateSub = null;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
_unsubscribe() {
|
|
369
|
+
this._unsubscribeHealth();
|
|
370
|
+
this._unsubscribeUpdates();
|
|
371
|
+
}
|
|
372
|
+
async #onProviderConnect() {
|
|
373
|
+
this._isConnected.next(true);
|
|
374
|
+
this.emit('connected');
|
|
375
|
+
try {
|
|
376
|
+
const cryptoReady = this._options.initWasm === false
|
|
377
|
+
? true
|
|
378
|
+
: await cryptoWaitReady();
|
|
379
|
+
const hasMeta = await this._loadMeta();
|
|
380
|
+
this._subscribeHealth();
|
|
381
|
+
if (hasMeta && !this._isReady && cryptoReady) {
|
|
382
|
+
this._isReady = true;
|
|
383
|
+
this.emit('ready', this);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
catch (_error) {
|
|
387
|
+
const error = new Error(`FATAL: Unable to initialize the API: ${_error.message}`);
|
|
388
|
+
l.error(error);
|
|
389
|
+
this.emit('error', error);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
#onProviderDisconnect() {
|
|
393
|
+
this._isConnected.next(false);
|
|
394
|
+
this._unsubscribe();
|
|
395
|
+
this.emit('disconnected');
|
|
396
|
+
}
|
|
397
|
+
#onProviderError(error) {
|
|
398
|
+
this.emit('error', error);
|
|
399
|
+
}
|
|
400
|
+
}
|