@pezkuwi/rpc-provider 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 +10 -10
- package/bizinikiwi-connect/Health.js +259 -0
- package/{build/substrate-connect → bizinikiwi-connect}/index.d.ts +3 -3
- package/bizinikiwi-connect/index.js +319 -0
- package/{build/bundle.d.ts → bundle.d.ts} +1 -1
- package/{src/bundle.ts → bundle.js} +1 -4
- package/cjs/bizinikiwi-connect/Health.d.ts +7 -0
- package/cjs/bizinikiwi-connect/Health.js +264 -0
- package/cjs/bizinikiwi-connect/index.d.ts +22 -0
- package/cjs/bizinikiwi-connect/index.js +323 -0
- package/cjs/bizinikiwi-connect/types.d.ts +12 -0
- package/cjs/bizinikiwi-connect/types.js +2 -0
- package/cjs/bundle.d.ts +5 -0
- package/cjs/bundle.js +14 -0
- package/cjs/coder/error.js +53 -0
- package/cjs/coder/index.js +63 -0
- package/cjs/defaults.js +8 -0
- package/{build → cjs}/http/index.d.ts +1 -1
- package/cjs/http/index.js +196 -0
- package/cjs/http/types.js +2 -0
- package/cjs/index.js +5 -0
- package/cjs/lru.js +150 -0
- package/cjs/mock/index.js +196 -0
- package/cjs/mock/mockHttp.js +17 -0
- package/cjs/mock/mockWs.js +47 -0
- package/cjs/mock/types.js +2 -0
- package/cjs/package.json +3 -0
- package/cjs/packageDetect.d.ts +1 -0
- package/cjs/packageDetect.js +6 -0
- package/cjs/packageInfo.js +4 -0
- package/cjs/types.js +2 -0
- package/cjs/ws/errors.js +41 -0
- package/{build → cjs}/ws/index.d.ts +1 -1
- package/cjs/ws/index.js +529 -0
- package/coder/error.d.ts +29 -0
- package/coder/error.js +50 -0
- package/coder/index.d.ts +8 -0
- package/coder/index.js +58 -0
- package/defaults.d.ts +5 -0
- package/defaults.js +6 -0
- package/http/index.d.ts +81 -0
- package/http/index.js +191 -0
- package/http/types.d.ts +7 -0
- package/http/types.js +1 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/lru.d.ts +15 -0
- package/lru.js +146 -0
- package/mock/index.d.ts +35 -0
- package/mock/index.js +191 -0
- package/mock/mockHttp.d.ts +9 -0
- package/mock/mockHttp.js +12 -0
- package/mock/mockWs.d.ts +26 -0
- package/mock/mockWs.js +43 -0
- package/mock/types.d.ts +23 -0
- package/mock/types.js +1 -0
- package/package.json +316 -15
- package/packageDetect.d.ts +1 -0
- package/packageDetect.js +4 -0
- package/packageInfo.d.ts +6 -0
- package/packageInfo.js +1 -0
- package/types.d.ts +85 -0
- package/types.js +1 -0
- package/ws/errors.d.ts +1 -0
- package/ws/errors.js +38 -0
- package/ws/index.d.ts +121 -0
- package/ws/index.js +524 -0
- package/src/coder/decodeResponse.spec.ts +0 -70
- package/src/coder/encodeJson.spec.ts +0 -20
- package/src/coder/encodeObject.spec.ts +0 -25
- package/src/coder/error.spec.ts +0 -111
- package/src/coder/error.ts +0 -66
- package/src/coder/index.ts +0 -88
- package/src/defaults.ts +0 -10
- package/src/http/index.spec.ts +0 -72
- package/src/http/index.ts +0 -238
- package/src/http/send.spec.ts +0 -61
- package/src/http/types.ts +0 -11
- package/src/index.ts +0 -6
- package/src/lru.spec.ts +0 -74
- package/src/lru.ts +0 -197
- package/src/mock/index.ts +0 -259
- package/src/mock/mockHttp.ts +0 -35
- package/src/mock/mockWs.ts +0 -92
- package/src/mock/on.spec.ts +0 -43
- package/src/mock/send.spec.ts +0 -38
- package/src/mock/subscribe.spec.ts +0 -81
- package/src/mock/types.ts +0 -36
- package/src/mock/unsubscribe.spec.ts +0 -57
- package/src/mod.ts +0 -4
- package/src/packageDetect.ts +0 -12
- package/src/packageInfo.ts +0 -6
- package/src/substrate-connect/Health.ts +0 -325
- package/src/substrate-connect/index.spec.ts +0 -638
- package/src/substrate-connect/index.ts +0 -415
- package/src/substrate-connect/types.ts +0 -16
- package/src/types.ts +0 -101
- package/src/ws/connect.spec.ts +0 -167
- package/src/ws/errors.ts +0 -41
- package/src/ws/index.spec.ts +0 -97
- package/src/ws/index.ts +0 -652
- package/src/ws/send.spec.ts +0 -126
- package/src/ws/state.spec.ts +0 -20
- package/src/ws/subscribe.spec.ts +0 -68
- package/src/ws/unsubscribe.spec.ts +0 -100
- package/tsconfig.build.json +0 -17
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.spec.json +0 -18
- /package/{build/substrate-connect → bizinikiwi-connect}/Health.d.ts +0 -0
- /package/{build/substrate-connect → bizinikiwi-connect}/types.d.ts +0 -0
- /package/{build/packageDetect.d.ts → bizinikiwi-connect/types.js} +0 -0
- /package/{build → cjs}/coder/error.d.ts +0 -0
- /package/{build → cjs}/coder/index.d.ts +0 -0
- /package/{build → cjs}/defaults.d.ts +0 -0
- /package/{build → cjs}/http/types.d.ts +0 -0
- /package/{build → cjs}/index.d.ts +0 -0
- /package/{build → cjs}/lru.d.ts +0 -0
- /package/{build → cjs}/mock/index.d.ts +0 -0
- /package/{build → cjs}/mock/mockHttp.d.ts +0 -0
- /package/{build → cjs}/mock/mockWs.d.ts +0 -0
- /package/{build → cjs}/mock/types.d.ts +0 -0
- /package/{build → cjs}/packageInfo.d.ts +0 -0
- /package/{build → cjs}/types.d.ts +0 -0
- /package/{build → cjs}/ws/errors.d.ts +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScProvider = void 0;
|
|
4
|
+
const eventemitter3_1 = require("eventemitter3");
|
|
5
|
+
const util_1 = require("@pezkuwi/util");
|
|
6
|
+
const index_js_1 = require("../coder/index.js");
|
|
7
|
+
const Health_js_1 = require("./Health.js");
|
|
8
|
+
const l = (0, util_1.logger)('api-bizinikiwi-connect');
|
|
9
|
+
const subscriptionUnsubscriptionMethods = new Map([
|
|
10
|
+
['author_submitAndWatchExtrinsic', 'author_unwatchExtrinsic'],
|
|
11
|
+
['chain_subscribeAllHeads', 'chain_unsubscribeAllHeads'],
|
|
12
|
+
['chain_subscribeFinalizedHeads', 'chain_unsubscribeFinalizedHeads'],
|
|
13
|
+
['chain_subscribeFinalisedHeads', 'chain_subscribeFinalisedHeads'],
|
|
14
|
+
['chain_subscribeNewHeads', 'chain_unsubscribeNewHeads'],
|
|
15
|
+
['chain_subscribeNewHead', 'chain_unsubscribeNewHead'],
|
|
16
|
+
['chain_subscribeRuntimeVersion', 'chain_unsubscribeRuntimeVersion'],
|
|
17
|
+
['subscribe_newHead', 'unsubscribe_newHead'],
|
|
18
|
+
['state_subscribeRuntimeVersion', 'state_unsubscribeRuntimeVersion'],
|
|
19
|
+
['state_subscribeStorage', 'state_unsubscribeStorage']
|
|
20
|
+
]);
|
|
21
|
+
const scClients = new WeakMap();
|
|
22
|
+
class ScProvider {
|
|
23
|
+
#Sc;
|
|
24
|
+
#coder = new index_js_1.RpcCoder();
|
|
25
|
+
#spec;
|
|
26
|
+
#sharedSandbox;
|
|
27
|
+
#subscriptions = new Map();
|
|
28
|
+
#resubscribeMethods = new Map();
|
|
29
|
+
#requests = new Map();
|
|
30
|
+
#wellKnownChains;
|
|
31
|
+
#eventemitter = new eventemitter3_1.EventEmitter();
|
|
32
|
+
#chain = null;
|
|
33
|
+
#isChainReady = false;
|
|
34
|
+
constructor(Sc, spec, sharedSandbox) {
|
|
35
|
+
if (!(0, util_1.isObject)(Sc) || !(0, util_1.isObject)(Sc.WellKnownChain) || !(0, util_1.isFunction)(Sc.createScClient)) {
|
|
36
|
+
throw new Error('Expected an @bizinikiwi/connect interface as first parameter to ScProvider');
|
|
37
|
+
}
|
|
38
|
+
this.#Sc = Sc;
|
|
39
|
+
this.#spec = spec;
|
|
40
|
+
this.#sharedSandbox = sharedSandbox;
|
|
41
|
+
this.#wellKnownChains = new Set(Object.values(Sc.WellKnownChain));
|
|
42
|
+
}
|
|
43
|
+
get hasSubscriptions() {
|
|
44
|
+
// Indicates that subscriptions are supported
|
|
45
|
+
return !!true;
|
|
46
|
+
}
|
|
47
|
+
get isClonable() {
|
|
48
|
+
return !!false;
|
|
49
|
+
}
|
|
50
|
+
get isConnected() {
|
|
51
|
+
return !!this.#chain && this.#isChainReady;
|
|
52
|
+
}
|
|
53
|
+
clone() {
|
|
54
|
+
throw new Error('clone() is not supported.');
|
|
55
|
+
}
|
|
56
|
+
// Config details can be found in @bizinikiwi/connect repo following the link:
|
|
57
|
+
// https://github.com/pezkuwichain/bizinikiwi-connect/blob/main/packages/connect/src/connector/index.ts
|
|
58
|
+
async connect(config, checkerFactory = Health_js_1.healthChecker) {
|
|
59
|
+
if (this.isConnected) {
|
|
60
|
+
throw new Error('Already connected!');
|
|
61
|
+
}
|
|
62
|
+
// it could happen that after emitting `disconnected` due to the fact that
|
|
63
|
+
// smoldot is syncing, the consumer tries to reconnect after a certain amount
|
|
64
|
+
// of time... In which case we want to make sure that we don't create a new
|
|
65
|
+
// chain.
|
|
66
|
+
if (this.#chain) {
|
|
67
|
+
await this.#chain;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (this.#sharedSandbox && !this.#sharedSandbox.isConnected) {
|
|
71
|
+
await this.#sharedSandbox.connect();
|
|
72
|
+
}
|
|
73
|
+
const client = this.#sharedSandbox
|
|
74
|
+
? scClients.get(this.#sharedSandbox)
|
|
75
|
+
: this.#Sc.createScClient(config);
|
|
76
|
+
if (!client) {
|
|
77
|
+
throw new Error('Unknown ScProvider!');
|
|
78
|
+
}
|
|
79
|
+
scClients.set(this, client);
|
|
80
|
+
const hc = checkerFactory();
|
|
81
|
+
const onResponse = (res) => {
|
|
82
|
+
const hcRes = hc.responsePassThrough(res);
|
|
83
|
+
if (!hcRes) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const response = JSON.parse(hcRes);
|
|
87
|
+
let decodedResponse;
|
|
88
|
+
try {
|
|
89
|
+
decodedResponse = this.#coder.decodeResponse(response);
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
decodedResponse = e;
|
|
93
|
+
}
|
|
94
|
+
// It's not a subscription message, but rather a standar RPC response
|
|
95
|
+
if (response.params?.subscription === undefined || !response.method) {
|
|
96
|
+
return this.#requests.get(response.id)?.(decodedResponse);
|
|
97
|
+
}
|
|
98
|
+
// We are dealing with a subscription message
|
|
99
|
+
const subscriptionId = `${response.method}::${response.params.subscription}`;
|
|
100
|
+
const callback = this.#subscriptions.get(subscriptionId)?.[0];
|
|
101
|
+
callback?.(decodedResponse);
|
|
102
|
+
};
|
|
103
|
+
const addChain = this.#sharedSandbox
|
|
104
|
+
? (async (...args) => {
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
106
|
+
const source = this.#sharedSandbox;
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
108
|
+
return (await source.#chain).addChain(...args);
|
|
109
|
+
})
|
|
110
|
+
: this.#wellKnownChains.has(this.#spec)
|
|
111
|
+
? client.addWellKnownChain
|
|
112
|
+
: client.addChain;
|
|
113
|
+
this.#chain = addChain(this.#spec).then((chain) => {
|
|
114
|
+
hc.setSendJsonRpc(chain.sendJsonRpc);
|
|
115
|
+
// Start async response processing loop
|
|
116
|
+
// This replaces the callback-based API from older @substrate/connect versions
|
|
117
|
+
(async () => {
|
|
118
|
+
try {
|
|
119
|
+
for await (const res of chain.jsonRpcResponses) {
|
|
120
|
+
onResponse(res);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Chain was removed or connection closed - this is expected
|
|
125
|
+
}
|
|
126
|
+
})();
|
|
127
|
+
this.#isChainReady = false;
|
|
128
|
+
const cleanup = () => {
|
|
129
|
+
// If there are any callbacks left, we have to reject/error them.
|
|
130
|
+
// Otherwise, that would cause a memory leak.
|
|
131
|
+
const disconnectionError = new Error('Disconnected');
|
|
132
|
+
this.#requests.forEach((cb) => cb(disconnectionError));
|
|
133
|
+
this.#subscriptions.forEach(([cb]) => cb(disconnectionError));
|
|
134
|
+
this.#subscriptions.clear();
|
|
135
|
+
};
|
|
136
|
+
const staleSubscriptions = [];
|
|
137
|
+
const killStaleSubscriptions = () => {
|
|
138
|
+
if (staleSubscriptions.length === 0) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const stale = staleSubscriptions.pop();
|
|
142
|
+
if (!stale) {
|
|
143
|
+
throw new Error('Unable to get stale subscription');
|
|
144
|
+
}
|
|
145
|
+
const { id, unsubscribeMethod } = stale;
|
|
146
|
+
Promise
|
|
147
|
+
.race([
|
|
148
|
+
this.send(unsubscribeMethod, [id]).catch(util_1.noop),
|
|
149
|
+
new Promise((resolve) => setTimeout(resolve, 500))
|
|
150
|
+
])
|
|
151
|
+
.then(killStaleSubscriptions)
|
|
152
|
+
.catch(util_1.noop);
|
|
153
|
+
};
|
|
154
|
+
hc.start((health) => {
|
|
155
|
+
const isReady = !health.isSyncing && (health.peers > 0 || !health.shouldHavePeers);
|
|
156
|
+
// if it's the same as before, then nothing has changed and we are done
|
|
157
|
+
if (this.#isChainReady === isReady) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.#isChainReady = isReady;
|
|
161
|
+
if (!isReady) {
|
|
162
|
+
// If we've reached this point, that means that the chain used to be "ready"
|
|
163
|
+
// and now we are about to emit `disconnected`.
|
|
164
|
+
//
|
|
165
|
+
// This will cause the PezkuwiJs API think that the connection is
|
|
166
|
+
// actually dead. In reality the smoldot chain is not dead, of course.
|
|
167
|
+
// However, we have to cleanup all the existing callbacks because when
|
|
168
|
+
// the smoldot chain stops syncing, then we will emit `connected` and
|
|
169
|
+
// the PezkuwiJs API will try to re-create the previous
|
|
170
|
+
// subscriptions and requests. Although, now is not a good moment
|
|
171
|
+
// to be sending unsubscription messages to the smoldot chain, we
|
|
172
|
+
// should wait until is no longer syncing to send the unsubscription
|
|
173
|
+
// messages from the stale subscriptions of the previous connection.
|
|
174
|
+
//
|
|
175
|
+
// That's why -before we perform the cleanup of `this.#subscriptions`-
|
|
176
|
+
// we keep the necessary information that we will need later on to
|
|
177
|
+
// kill the stale subscriptions.
|
|
178
|
+
[...this.#subscriptions.values()].forEach((s) => {
|
|
179
|
+
staleSubscriptions.push(s[1]);
|
|
180
|
+
});
|
|
181
|
+
cleanup();
|
|
182
|
+
this.#eventemitter.emit('disconnected');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
killStaleSubscriptions();
|
|
186
|
+
this.#eventemitter.emit('connected');
|
|
187
|
+
if (this.#resubscribeMethods.size) {
|
|
188
|
+
this.#resubscribe();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return (0, util_1.objectSpread)({}, chain, {
|
|
193
|
+
remove: () => {
|
|
194
|
+
hc.stop();
|
|
195
|
+
chain.remove();
|
|
196
|
+
cleanup();
|
|
197
|
+
},
|
|
198
|
+
sendJsonRpc: hc.sendJsonRpc.bind(hc)
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
try {
|
|
202
|
+
await this.#chain;
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
this.#chain = null;
|
|
206
|
+
this.#eventemitter.emit('error', e);
|
|
207
|
+
throw e;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
#resubscribe = () => {
|
|
211
|
+
const promises = [];
|
|
212
|
+
this.#resubscribeMethods.forEach((subDetails) => {
|
|
213
|
+
// only re-create subscriptions which are not in author (only area where
|
|
214
|
+
// transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'
|
|
215
|
+
// are not included (and will not be re-broadcast)
|
|
216
|
+
if (subDetails.type.startsWith('author_')) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const promise = new Promise((resolve) => {
|
|
221
|
+
this.subscribe(subDetails.type, subDetails.method, subDetails.params, subDetails.callback).catch((error) => console.log(error));
|
|
222
|
+
resolve();
|
|
223
|
+
});
|
|
224
|
+
promises.push(promise);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
l.error(error);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
Promise.all(promises).catch((err) => l.log(err));
|
|
231
|
+
};
|
|
232
|
+
async disconnect() {
|
|
233
|
+
if (!this.#chain) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const chain = await this.#chain;
|
|
237
|
+
this.#chain = null;
|
|
238
|
+
this.#isChainReady = false;
|
|
239
|
+
try {
|
|
240
|
+
chain.remove();
|
|
241
|
+
}
|
|
242
|
+
catch (_) { }
|
|
243
|
+
this.#eventemitter.emit('disconnected');
|
|
244
|
+
}
|
|
245
|
+
on(type, sub) {
|
|
246
|
+
// It's possible. Although, quite unlikely, that by the time that pezkuwi
|
|
247
|
+
// subscribes to the `connected` event, the Provider is already connected.
|
|
248
|
+
// In that case, we must emit to let the consumer know that we are connected.
|
|
249
|
+
if (type === 'connected' && this.isConnected) {
|
|
250
|
+
sub();
|
|
251
|
+
}
|
|
252
|
+
this.#eventemitter.on(type, sub);
|
|
253
|
+
return () => {
|
|
254
|
+
this.#eventemitter.removeListener(type, sub);
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
async send(method, params) {
|
|
258
|
+
if (!this.isConnected || !this.#chain) {
|
|
259
|
+
throw new Error('Provider is not connected');
|
|
260
|
+
}
|
|
261
|
+
const chain = await this.#chain;
|
|
262
|
+
const [id, json] = this.#coder.encodeJson(method, params);
|
|
263
|
+
const result = new Promise((resolve, reject) => {
|
|
264
|
+
this.#requests.set(id, (response) => {
|
|
265
|
+
((0, util_1.isError)(response) ? reject : resolve)(response);
|
|
266
|
+
});
|
|
267
|
+
try {
|
|
268
|
+
chain.sendJsonRpc(json);
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
this.#chain = null;
|
|
272
|
+
try {
|
|
273
|
+
chain.remove();
|
|
274
|
+
}
|
|
275
|
+
catch (_) { }
|
|
276
|
+
this.#eventemitter.emit('error', e);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
try {
|
|
280
|
+
return await result;
|
|
281
|
+
}
|
|
282
|
+
finally {
|
|
283
|
+
// let's ensure that once the Promise is resolved/rejected, then we remove
|
|
284
|
+
// remove its entry from the internal #requests
|
|
285
|
+
this.#requests.delete(id);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async subscribe(type, method, params, callback) {
|
|
289
|
+
if (!subscriptionUnsubscriptionMethods.has(method)) {
|
|
290
|
+
throw new Error(`Unsupported subscribe method: ${method}`);
|
|
291
|
+
}
|
|
292
|
+
const id = await this.send(method, params);
|
|
293
|
+
const subscriptionId = `${type}::${id}`;
|
|
294
|
+
const cb = (response) => {
|
|
295
|
+
if (response instanceof Error) {
|
|
296
|
+
callback(response, undefined);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
callback(null, response);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
const unsubscribeMethod = subscriptionUnsubscriptionMethods.get(method);
|
|
303
|
+
if (!unsubscribeMethod) {
|
|
304
|
+
throw new Error('Invalid unsubscribe method found');
|
|
305
|
+
}
|
|
306
|
+
this.#resubscribeMethods.set(subscriptionId, { callback, method, params, type });
|
|
307
|
+
this.#subscriptions.set(subscriptionId, [cb, { id, unsubscribeMethod }]);
|
|
308
|
+
return id;
|
|
309
|
+
}
|
|
310
|
+
unsubscribe(type, method, id) {
|
|
311
|
+
if (!this.isConnected) {
|
|
312
|
+
throw new Error('Provider is not connected');
|
|
313
|
+
}
|
|
314
|
+
const subscriptionId = `${type}::${id}`;
|
|
315
|
+
if (!this.#subscriptions.has(subscriptionId)) {
|
|
316
|
+
return Promise.reject(new Error(`Unable to find active subscription=${subscriptionId}`));
|
|
317
|
+
}
|
|
318
|
+
this.#resubscribeMethods.delete(subscriptionId);
|
|
319
|
+
this.#subscriptions.delete(subscriptionId);
|
|
320
|
+
return this.send(method, [id]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
exports.ScProvider = ScProvider;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SmoldotHealth {
|
|
2
|
+
isSyncing: boolean;
|
|
3
|
+
peers: number;
|
|
4
|
+
shouldHavePeers: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface HealthChecker {
|
|
7
|
+
setSendJsonRpc(sendRequest: (request: string) => void): void;
|
|
8
|
+
start(healthCallback: (health: SmoldotHealth) => void): void;
|
|
9
|
+
stop(): void;
|
|
10
|
+
sendJsonRpc(request: string): void;
|
|
11
|
+
responsePassThrough(response: string): string | null;
|
|
12
|
+
}
|
package/cjs/bundle.d.ts
ADDED
package/cjs/bundle.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WsProvider = exports.ScProvider = exports.packageInfo = exports.LRUCache = exports.DEFAULT_CAPACITY = exports.HttpProvider = void 0;
|
|
4
|
+
var index_js_1 = require("./http/index.js");
|
|
5
|
+
Object.defineProperty(exports, "HttpProvider", { enumerable: true, get: function () { return index_js_1.HttpProvider; } });
|
|
6
|
+
var lru_js_1 = require("./lru.js");
|
|
7
|
+
Object.defineProperty(exports, "DEFAULT_CAPACITY", { enumerable: true, get: function () { return lru_js_1.DEFAULT_CAPACITY; } });
|
|
8
|
+
Object.defineProperty(exports, "LRUCache", { enumerable: true, get: function () { return lru_js_1.LRUCache; } });
|
|
9
|
+
var packageInfo_js_1 = require("./packageInfo.js");
|
|
10
|
+
Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } });
|
|
11
|
+
var index_js_2 = require("./bizinikiwi-connect/index.js");
|
|
12
|
+
Object.defineProperty(exports, "ScProvider", { enumerable: true, get: function () { return index_js_2.ScProvider; } });
|
|
13
|
+
var index_js_3 = require("./ws/index.js");
|
|
14
|
+
Object.defineProperty(exports, "WsProvider", { enumerable: true, get: function () { return index_js_3.WsProvider; } });
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const util_1 = require("@pezkuwi/util");
|
|
4
|
+
const UNKNOWN = -99999;
|
|
5
|
+
function extend(that, name, value) {
|
|
6
|
+
Object.defineProperty(that, name, {
|
|
7
|
+
configurable: true,
|
|
8
|
+
enumerable: false,
|
|
9
|
+
value
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @name RpcError
|
|
14
|
+
* @summary Extension to the basic JS Error.
|
|
15
|
+
* @description
|
|
16
|
+
* The built-in JavaScript Error class is extended by adding a code to allow for Error categorization. In addition to the normal `stack`, `message`, the numeric `code` and `data` (any types) parameters are available on the object.
|
|
17
|
+
* @example
|
|
18
|
+
* <BR>
|
|
19
|
+
*
|
|
20
|
+
* ```javascript
|
|
21
|
+
* const { RpcError } from '@pezkuwi/util');
|
|
22
|
+
*
|
|
23
|
+
* throw new RpcError('some message', RpcError.CODES.METHOD_NOT_FOUND); // => error.code = -32601
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
class RpcError extends Error {
|
|
27
|
+
code;
|
|
28
|
+
data;
|
|
29
|
+
message;
|
|
30
|
+
name;
|
|
31
|
+
stack;
|
|
32
|
+
constructor(message = '', code = UNKNOWN, data) {
|
|
33
|
+
super();
|
|
34
|
+
extend(this, 'message', String(message));
|
|
35
|
+
extend(this, 'name', this.constructor.name);
|
|
36
|
+
extend(this, 'data', data);
|
|
37
|
+
extend(this, 'code', code);
|
|
38
|
+
if ((0, util_1.isFunction)(Error.captureStackTrace)) {
|
|
39
|
+
Error.captureStackTrace(this, this.constructor);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const { stack } = new Error(message);
|
|
43
|
+
stack && extend(this, 'stack', stack);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
static CODES = {
|
|
47
|
+
ASSERT: -90009,
|
|
48
|
+
INVALID_JSONRPC: -99998,
|
|
49
|
+
METHOD_NOT_FOUND: -32601, // Rust client
|
|
50
|
+
UNKNOWN
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
exports.default = RpcError;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RpcCoder = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const util_1 = require("@pezkuwi/util");
|
|
6
|
+
const error_js_1 = tslib_1.__importDefault(require("./error.js"));
|
|
7
|
+
function formatErrorData(data) {
|
|
8
|
+
if ((0, util_1.isUndefined)(data)) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
const formatted = `: ${(0, util_1.isString)(data)
|
|
12
|
+
? data.replace(/Error\("/g, '').replace(/\("/g, '(').replace(/"\)/g, ')').replace(/\(/g, ', ').replace(/\)/g, '')
|
|
13
|
+
: (0, util_1.stringify)(data)}`;
|
|
14
|
+
// We need some sort of cut-off here since these can be very large and
|
|
15
|
+
// very nested, pick a number and trim the result display to it
|
|
16
|
+
return formatted.length <= 256
|
|
17
|
+
? formatted
|
|
18
|
+
: `${formatted.substring(0, 255)}…`;
|
|
19
|
+
}
|
|
20
|
+
function checkError(error) {
|
|
21
|
+
if (error) {
|
|
22
|
+
const { code, data, message } = error;
|
|
23
|
+
throw new error_js_1.default(`${code}: ${message}${formatErrorData(data)}`, code, data);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** @internal */
|
|
27
|
+
class RpcCoder {
|
|
28
|
+
#id = 0;
|
|
29
|
+
decodeResponse(response) {
|
|
30
|
+
if (!response || response.jsonrpc !== '2.0') {
|
|
31
|
+
throw new Error('Invalid jsonrpc field in decoded object');
|
|
32
|
+
}
|
|
33
|
+
const isSubscription = !(0, util_1.isUndefined)(response.params) && !(0, util_1.isUndefined)(response.method);
|
|
34
|
+
if (!(0, util_1.isNumber)(response.id) &&
|
|
35
|
+
(!isSubscription || (!(0, util_1.isNumber)(response.params.subscription) &&
|
|
36
|
+
!(0, util_1.isString)(response.params.subscription)))) {
|
|
37
|
+
throw new Error('Invalid id field in decoded object');
|
|
38
|
+
}
|
|
39
|
+
checkError(response.error);
|
|
40
|
+
if (response.result === undefined && !isSubscription) {
|
|
41
|
+
throw new Error('No result found in jsonrpc response');
|
|
42
|
+
}
|
|
43
|
+
if (isSubscription) {
|
|
44
|
+
checkError(response.params.error);
|
|
45
|
+
return response.params.result;
|
|
46
|
+
}
|
|
47
|
+
return response.result;
|
|
48
|
+
}
|
|
49
|
+
encodeJson(method, params) {
|
|
50
|
+
const [id, data] = this.encodeObject(method, params);
|
|
51
|
+
return [id, (0, util_1.stringify)(data)];
|
|
52
|
+
}
|
|
53
|
+
encodeObject(method, params) {
|
|
54
|
+
const id = ++this.#id;
|
|
55
|
+
return [id, {
|
|
56
|
+
id,
|
|
57
|
+
jsonrpc: '2.0',
|
|
58
|
+
method,
|
|
59
|
+
params
|
|
60
|
+
}];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.RpcCoder = RpcCoder;
|
package/cjs/defaults.js
ADDED