smoldot 0.3.6 → 0.7.11
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 +18 -21
- package/dist/cjs/base64.d.ts +22 -0
- package/dist/cjs/base64.js +104 -0
- package/dist/cjs/client.d.ts +287 -0
- package/dist/cjs/client.js +175 -0
- package/dist/cjs/index-browser.d.ts +11 -0
- package/dist/cjs/index-browser.js +465 -0
- package/dist/cjs/index-deno.d.ts +10 -0
- package/dist/cjs/index-deno.js +263 -0
- package/dist/cjs/index-nodejs.d.ts +10 -0
- package/dist/cjs/index-nodejs.js +174 -0
- package/dist/cjs/instance/autogen/wasm.d.ts +2 -0
- package/dist/cjs/instance/autogen/wasm.js +6 -0
- package/dist/cjs/instance/autogen/wasm0.d.ts +1 -0
- package/dist/cjs/instance/autogen/wasm0.js +4 -0
- package/dist/cjs/instance/autogen/wasm1.d.ts +1 -0
- package/dist/cjs/instance/autogen/wasm1.js +4 -0
- package/dist/cjs/instance/autogen/wasm2.d.ts +1 -0
- package/dist/cjs/instance/autogen/wasm2.js +4 -0
- package/dist/cjs/instance/bindings-smoldot-light.d.ts +154 -0
- package/dist/cjs/instance/bindings-smoldot-light.js +266 -0
- package/dist/cjs/instance/bindings-wasi.d.ts +23 -0
- package/dist/cjs/instance/bindings-wasi.js +142 -0
- package/dist/cjs/instance/bindings.d.ts +31 -0
- package/dist/cjs/instance/bindings.js +5 -0
- package/dist/cjs/instance/buffer.d.ts +10 -0
- package/dist/cjs/instance/buffer.js +53 -0
- package/dist/cjs/instance/instance.d.ts +45 -0
- package/dist/cjs/instance/instance.js +301 -0
- package/dist/cjs/instance/raw-instance.d.ts +65 -0
- package/dist/cjs/instance/raw-instance.js +72 -0
- package/dist/cjs/package.json +3 -0
- package/dist/mjs/base64.d.ts +22 -0
- package/dist/mjs/base64.js +97 -0
- package/dist/mjs/client.d.ts +287 -0
- package/dist/mjs/client.js +165 -0
- package/dist/mjs/index-browser.d.ts +11 -0
- package/dist/mjs/index-browser.js +455 -0
- package/dist/mjs/index-deno.d.ts +10 -0
- package/dist/mjs/index-deno.js +253 -0
- package/dist/mjs/index-nodejs.d.ts +10 -0
- package/dist/mjs/index-nodejs.js +164 -0
- package/dist/mjs/instance/autogen/wasm.d.ts +2 -0
- package/dist/mjs/instance/autogen/wasm.js +4 -0
- package/dist/mjs/instance/autogen/wasm0.d.ts +1 -0
- package/dist/mjs/instance/autogen/wasm0.js +1 -0
- package/dist/mjs/instance/autogen/wasm1.d.ts +1 -0
- package/dist/mjs/instance/autogen/wasm1.js +1 -0
- package/dist/mjs/instance/autogen/wasm2.d.ts +1 -0
- package/dist/mjs/instance/autogen/wasm2.js +1 -0
- package/dist/mjs/instance/bindings-smoldot-light.d.ts +154 -0
- package/dist/mjs/instance/bindings-smoldot-light.js +261 -0
- package/dist/mjs/instance/bindings-wasi.d.ts +23 -0
- package/{src → dist/mjs/instance}/bindings-wasi.js +47 -58
- package/dist/mjs/instance/bindings.d.ts +31 -0
- package/dist/mjs/instance/bindings.js +4 -0
- package/dist/mjs/instance/buffer.d.ts +10 -0
- package/dist/mjs/instance/buffer.js +46 -0
- package/dist/mjs/instance/instance.d.ts +45 -0
- package/dist/mjs/instance/instance.js +293 -0
- package/dist/mjs/instance/raw-instance.d.ts +65 -0
- package/dist/mjs/instance/raw-instance.js +67 -0
- package/dist/mjs/package.json +3 -0
- package/package.json +35 -19
- package/src/autogen/wasm.js +0 -1
- package/src/bindings-smoldot-js.js +0 -223
- package/src/compat-browser.js +0 -25
- package/src/compat-nodejs.js +0 -30
- package/src/health.js +0 -206
- package/src/index.d.ts +0 -68
- package/src/index.js +0 -192
- package/src/index.test-d.ts +0 -36
- package/src/tsconfig.json +0 -13
- package/src/worker.js +0 -151
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
// Smoldot
|
|
2
|
-
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
3
|
-
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
-
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU General Public License for more details.
|
|
14
|
-
|
|
15
|
-
// You should have received a copy of the GNU General Public License
|
|
16
|
-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
//! Exports a function that provides bindings for the bindings found in the Rust part of the code.
|
|
19
|
-
//!
|
|
20
|
-
//! In order to use this code, call the function passing an object, then fill the `instance` field
|
|
21
|
-
//! of that object with the Wasm instance.
|
|
22
|
-
|
|
23
|
-
import { Buffer } from 'buffer';
|
|
24
|
-
import Websocket from 'websocket';
|
|
25
|
-
import now from 'performance-now';
|
|
26
|
-
import { net } from './compat-nodejs.js';
|
|
27
|
-
|
|
28
|
-
export default (config) => {
|
|
29
|
-
// Used below to store the list of all connections.
|
|
30
|
-
// The indices within this array are chosen by the Rust code.
|
|
31
|
-
let connections = {};
|
|
32
|
-
|
|
33
|
-
const bindings = {
|
|
34
|
-
// Must throw an error. A human-readable message can be found in the WebAssembly memory in
|
|
35
|
-
// the given buffer.
|
|
36
|
-
throw: (ptr, len) => {
|
|
37
|
-
const message = Buffer.from(config.instance.exports.memory.buffer).toString('utf8', ptr, ptr + len);
|
|
38
|
-
throw new Error(message);
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
// Used by the Rust side to emit a JSON-RPC response or subscription notification.
|
|
42
|
-
json_rpc_respond: (ptr, len, chainId) => {
|
|
43
|
-
let message = Buffer.from(config.instance.exports.memory.buffer).toString('utf8', ptr, ptr + len);
|
|
44
|
-
if (config.jsonRpcCallback) {
|
|
45
|
-
config.jsonRpcCallback(message, chainId);
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
// Used by the Rust side to emit a log entry.
|
|
50
|
-
// See also the `max_log_level` parameter in the configuration.
|
|
51
|
-
log: (level, target_ptr, target_len, message_ptr, message_len) => {
|
|
52
|
-
if (config.logCallback) {
|
|
53
|
-
let target = Buffer.from(config.instance.exports.memory.buffer)
|
|
54
|
-
.toString('utf8', target_ptr, target_ptr + target_len);
|
|
55
|
-
let message = Buffer.from(config.instance.exports.memory.buffer)
|
|
56
|
-
.toString('utf8', message_ptr, message_ptr + message_len);
|
|
57
|
-
config.logCallback(level, target, message);
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// Must return the UNIX time in milliseconds.
|
|
62
|
-
unix_time_ms: () => Date.now(),
|
|
63
|
-
|
|
64
|
-
// Must return the value of a monotonic clock in milliseconds.
|
|
65
|
-
monotonic_clock_ms: () => now(),
|
|
66
|
-
|
|
67
|
-
// Must call `timer_finished` after the given number of milliseconds has elapsed.
|
|
68
|
-
start_timer: (id, ms) => {
|
|
69
|
-
// In browsers, `setTimeout` works as expected when `ms` equals 0. However, NodeJS
|
|
70
|
-
// requires a minimum of 1 millisecond (if `0` is passed, it is automatically replaced
|
|
71
|
-
// with `1`) and wants you to use `setImmediate` instead.
|
|
72
|
-
if (ms == 0 && typeof setImmediate === "function") {
|
|
73
|
-
setImmediate(() => {
|
|
74
|
-
config.instance.exports.timer_finished(id);
|
|
75
|
-
})
|
|
76
|
-
} else {
|
|
77
|
-
setTimeout(() => {
|
|
78
|
-
config.instance.exports.timer_finished(id);
|
|
79
|
-
}, ms)
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
// Must create a new connection object. This implementation stores the created object in
|
|
84
|
-
// `connections`.
|
|
85
|
-
connection_new: (id, addr_ptr, addr_len, error_ptr_ptr) => {
|
|
86
|
-
try {
|
|
87
|
-
if (!!connections[id]) {
|
|
88
|
-
throw new Error("internal error: connection already allocated");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const addr = Buffer.from(config.instance.exports.memory.buffer)
|
|
92
|
-
.toString('utf8', addr_ptr, addr_ptr + addr_len);
|
|
93
|
-
|
|
94
|
-
let connection;
|
|
95
|
-
|
|
96
|
-
// Attempt to parse the multiaddress.
|
|
97
|
-
// Note: peers can decide of the content of `addr`, meaning that it shouldn't be
|
|
98
|
-
// trusted.
|
|
99
|
-
const wsParsed = addr.match(/^\/(ip4|ip6|dns4|dns6|dns)\/(.*?)\/tcp\/(.*?)\/(ws|wss)$/);
|
|
100
|
-
const tcpParsed = addr.match(/^\/(ip4|ip6|dns4|dns6|dns)\/(.*?)\/tcp\/(.*?)$/);
|
|
101
|
-
|
|
102
|
-
if (wsParsed != null) {
|
|
103
|
-
let proto = 'wss';
|
|
104
|
-
if (wsParsed[4] == 'ws') {
|
|
105
|
-
proto = 'ws';
|
|
106
|
-
}
|
|
107
|
-
if ((proto == 'ws' && config.forbidWs) || (proto == 'wss' && config.forbidWss)) {
|
|
108
|
-
throw new Error('Connection type not allowed');
|
|
109
|
-
}
|
|
110
|
-
if (wsParsed[1] == 'ip6') {
|
|
111
|
-
connection = new Websocket.w3cwebsocket(proto + "://[" + wsParsed[2] + "]:" + wsParsed[3]);
|
|
112
|
-
} else {
|
|
113
|
-
connection = new Websocket.w3cwebsocket(proto + "://" + wsParsed[2] + ":" + wsParsed[3]);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
connection.binaryType = 'arraybuffer';
|
|
117
|
-
|
|
118
|
-
connection.onopen = () => {
|
|
119
|
-
config.instance.exports.connection_open(id);
|
|
120
|
-
};
|
|
121
|
-
connection.onclose = (event) => {
|
|
122
|
-
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
123
|
-
const len = Buffer.byteLength(message, 'utf8');
|
|
124
|
-
const ptr = config.instance.exports.alloc(len);
|
|
125
|
-
Buffer.from(config.instance.exports.memory.buffer).write(message, ptr);
|
|
126
|
-
config.instance.exports.connection_closed(id, ptr, len);
|
|
127
|
-
};
|
|
128
|
-
connection.onmessage = (msg) => {
|
|
129
|
-
const message = Buffer.from(msg.data);
|
|
130
|
-
const ptr = config.instance.exports.alloc(message.length);
|
|
131
|
-
message.copy(Buffer.from(config.instance.exports.memory.buffer), ptr);
|
|
132
|
-
config.instance.exports.connection_message(id, ptr, message.length);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
} else if (tcpParsed != null) {
|
|
136
|
-
// `net` module will be missing when we're not in NodeJS.
|
|
137
|
-
if (!net || config.forbidTcp) {
|
|
138
|
-
throw new Error('TCP connections not available');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
connection = net.createConnection({
|
|
142
|
-
host: tcpParsed[2],
|
|
143
|
-
port: parseInt(tcpParsed[3], 10),
|
|
144
|
-
});
|
|
145
|
-
connection.setNoDelay();
|
|
146
|
-
|
|
147
|
-
connection.on('connect', () => {
|
|
148
|
-
if (connection.destroyed) return;
|
|
149
|
-
config.instance.exports.connection_open(id);
|
|
150
|
-
});
|
|
151
|
-
connection.on('close', (hasError) => {
|
|
152
|
-
if (connection.destroyed) return;
|
|
153
|
-
// NodeJS doesn't provide a reason why the closing happened, but only
|
|
154
|
-
// whether it was caused by an error.
|
|
155
|
-
const message = hasError ? "Error" : "Closed gracefully";
|
|
156
|
-
const len = Buffer.byteLength(message, 'utf8');
|
|
157
|
-
const ptr = config.instance.exports.alloc(len);
|
|
158
|
-
Buffer.from(config.instance.exports.memory.buffer).write(message, ptr);
|
|
159
|
-
config.instance.exports.connection_closed(id, ptr, len);
|
|
160
|
-
});
|
|
161
|
-
connection.on('error', () => { });
|
|
162
|
-
connection.on('data', (message) => {
|
|
163
|
-
if (connection.destroyed) return;
|
|
164
|
-
const ptr = config.instance.exports.alloc(message.length);
|
|
165
|
-
message.copy(Buffer.from(config.instance.exports.memory.buffer), ptr);
|
|
166
|
-
config.instance.exports.connection_message(id, ptr, message.length);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
} else {
|
|
170
|
-
throw new Error('Unrecognized multiaddr format');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
connections[id] = connection;
|
|
174
|
-
return 0;
|
|
175
|
-
|
|
176
|
-
} catch (error) {
|
|
177
|
-
const errorStr = error.toString();
|
|
178
|
-
const mem = Buffer.from(config.instance.exports.memory.buffer);
|
|
179
|
-
const len = Buffer.byteLength(errorStr, 'utf8');
|
|
180
|
-
const ptr = config.instance.exports.alloc(len);
|
|
181
|
-
mem.write(errorStr, ptr);
|
|
182
|
-
mem.writeUInt32LE(ptr, error_ptr_ptr);
|
|
183
|
-
mem.writeUInt32LE(len, error_ptr_ptr + 4);
|
|
184
|
-
return 1;
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
// Must close and destroy the connection object.
|
|
189
|
-
connection_close: (id) => {
|
|
190
|
-
let connection = connections[id];
|
|
191
|
-
if (connection.close) {
|
|
192
|
-
// WebSocket
|
|
193
|
-
connection.onopen = null;
|
|
194
|
-
connection.onclose = null;
|
|
195
|
-
connection.onmessage = null;
|
|
196
|
-
connection.onerror = null;
|
|
197
|
-
connection.close();
|
|
198
|
-
} else {
|
|
199
|
-
// TCP
|
|
200
|
-
connection.destroy();
|
|
201
|
-
}
|
|
202
|
-
connections[id] = undefined;
|
|
203
|
-
},
|
|
204
|
-
|
|
205
|
-
// Must queue the data found in the WebAssembly memory at the given pointer. It is assumed
|
|
206
|
-
// that this function is called only when the connection is in an open state.
|
|
207
|
-
connection_send: (id, ptr, len) => {
|
|
208
|
-
let data = Buffer.from(config.instance.exports.memory.buffer).slice(ptr, ptr + len);
|
|
209
|
-
let connection = connections[id];
|
|
210
|
-
if (connection.send) {
|
|
211
|
-
// WebSocket
|
|
212
|
-
connection.send(data);
|
|
213
|
-
} else {
|
|
214
|
-
// TCP
|
|
215
|
-
connection.write(data);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
return {
|
|
221
|
-
bindings,
|
|
222
|
-
}
|
|
223
|
-
}
|
package/src/compat-browser.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// Smoldot
|
|
2
|
-
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
3
|
-
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
-
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU General Public License for more details.
|
|
14
|
-
|
|
15
|
-
// You should have received a copy of the GNU General Public License
|
|
16
|
-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
// Overrides `compat-nodejs.js` when in a browser.
|
|
19
|
-
|
|
20
|
-
export const net = null;
|
|
21
|
-
export const Worker = typeof window != 'undefined' ? window.Worker : null;
|
|
22
|
-
export const workerOnMessage = (worker, callback) => { worker.onmessage = (event) => callback(event.data) };
|
|
23
|
-
export const workerOnError = (worker, callback) => { worker.onerror = callback; }; // TODO: unclear if the parameter of the callback is same as with NodeJS
|
|
24
|
-
export const postMessage = (msg) => self.postMessage(msg);
|
|
25
|
-
export const setOnMessage = (callback) => { self.onmessage = (event) => callback(event.data) };
|
package/src/compat-nodejs.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Smoldot
|
|
2
|
-
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
3
|
-
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
-
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU General Public License for more details.
|
|
14
|
-
|
|
15
|
-
// You should have received a copy of the GNU General Public License
|
|
16
|
-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
// This small dummy module re-exports some types from NodeJS.
|
|
19
|
-
//
|
|
20
|
-
// A rule in the `package.json` overrides it with `compat-browser.js` when in a browser.
|
|
21
|
-
|
|
22
|
-
import { parentPort } from 'worker_threads';
|
|
23
|
-
|
|
24
|
-
export { default as net } from 'net';
|
|
25
|
-
export { Worker } from 'worker_threads';
|
|
26
|
-
|
|
27
|
-
export const workerOnMessage = (worker, callback) => worker.on('message', callback);
|
|
28
|
-
export const workerOnError = (worker, callback) => worker.on('error', callback);
|
|
29
|
-
export const postMessage = (msg) => parentPort.postMessage(msg);
|
|
30
|
-
export const setOnMessage = (callback) => parentPort.on('message', callback);
|
package/src/health.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
// Smoldot
|
|
2
|
-
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
3
|
-
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
-
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU General Public License for more details.
|
|
14
|
-
|
|
15
|
-
// You should have received a copy of the GNU General Public License
|
|
16
|
-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import randombytes from 'randombytes';
|
|
19
|
-
|
|
20
|
-
// Creates a new health checker.
|
|
21
|
-
//
|
|
22
|
-
// The role of the health checker is to report to the user the health of a smoldot chain.
|
|
23
|
-
//
|
|
24
|
-
// In order to use it, start by creating a health checker. The health checker is disabled by
|
|
25
|
-
// default. Use `start()` in order to start the health checks. The `start()` function must be
|
|
26
|
-
// passed a function that the health checker can use to send JSON-RPC requests to the chain, and
|
|
27
|
-
// a callback called when an update to the health of the node is available.
|
|
28
|
-
//
|
|
29
|
-
// When the chain send a JSON-RPC response, it must be passed to `responsePassThrough()`. This
|
|
30
|
-
// function intercepts the responses destined to the requests that have been emitted by the health
|
|
31
|
-
// checker and returns `null`. If the response doesn't concern the health checker, the response is
|
|
32
|
-
// simply returned by the function.
|
|
33
|
-
//
|
|
34
|
-
// # How it works
|
|
35
|
-
//
|
|
36
|
-
// The health checker periodically calls the `system_health` JSON-RPC call in order to determine
|
|
37
|
-
// the health of the chain.
|
|
38
|
-
//
|
|
39
|
-
// In addition to this, as long as the health check reports that `isSyncing` is `true`, the
|
|
40
|
-
// health checker also maintains a subscription to new best blocks using `chain_subscribeNewHeads`.
|
|
41
|
-
// Whenever a new block is notified, a health check is performed immediately in order to determine
|
|
42
|
-
// whether `isSyncing` has changed to `false`.
|
|
43
|
-
//
|
|
44
|
-
// Thanks to this subscription, the latency of the report of the switch from `isSyncing: true` to
|
|
45
|
-
// `isSyncing: false` is very low.
|
|
46
|
-
//
|
|
47
|
-
export function healthChecker() {
|
|
48
|
-
// `null` if health checker is not started.
|
|
49
|
-
let checker = null;
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
start: (sendJsonRpc, healthCallback) => {
|
|
53
|
-
if (checker !== null)
|
|
54
|
-
throw new Error("Can't start the health checker multiple times in parallel");
|
|
55
|
-
|
|
56
|
-
checker = {
|
|
57
|
-
healthCallback,
|
|
58
|
-
currentHealthCheckId: null,
|
|
59
|
-
currentHealthTimeout: null,
|
|
60
|
-
currentSubunsubRequestId: null,
|
|
61
|
-
currentSubscriptionId: null,
|
|
62
|
-
isSyncing: false,
|
|
63
|
-
|
|
64
|
-
responsePassThrough: function (jsonRpcResponse) {
|
|
65
|
-
let parsedResponse;
|
|
66
|
-
try {
|
|
67
|
-
parsedResponse = JSON.parse(jsonRpcResponse);
|
|
68
|
-
} catch (err) {
|
|
69
|
-
return jsonRpcResponse;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// Check whether response is a response to `system_health`.
|
|
73
|
-
if (parsedResponse.id && this.currentHealthCheckId == parsedResponse.id) {
|
|
74
|
-
this.currentHealthCheckId = null;
|
|
75
|
-
|
|
76
|
-
// Check whether query was successful. It is possible for queries to fail for
|
|
77
|
-
// various reasons, such as the client being overloaded.
|
|
78
|
-
if (!parsedResponse.result) {
|
|
79
|
-
this.update();
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.healthCallback(parsedResponse.result);
|
|
84
|
-
this.isSyncing = parsedResponse.result.isSyncing;
|
|
85
|
-
this.update();
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Check whether response is a response to the subscription or unsubscription.
|
|
90
|
-
if (parsedResponse.id && this.currentSubunsubRequestId == parsedResponse.id) {
|
|
91
|
-
this.currentSubunsubRequestId = null;
|
|
92
|
-
|
|
93
|
-
// Check whether query was successful. It is possible for queries to fail for
|
|
94
|
-
// various reasons, such as the client being overloaded.
|
|
95
|
-
if (!parsedResponse.result) {
|
|
96
|
-
this.update();
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (this.currentSubscriptionId)
|
|
101
|
-
this.currentSubscriptionId = null;
|
|
102
|
-
else
|
|
103
|
-
this.currentSubscriptionId = parsedResponse.result;
|
|
104
|
-
|
|
105
|
-
this.update();
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Check whether response is a notification to a subscription.
|
|
110
|
-
if (parsedResponse.params && this.currentSubscriptionId &&
|
|
111
|
-
parsedResponse.params.subscription == this.currentSubscriptionId) {
|
|
112
|
-
// Note that after a successful subscription, a notification containing
|
|
113
|
-
// the current best block is always returned. Considering that a
|
|
114
|
-
// subscription is performed in response to a health check, calling
|
|
115
|
-
// `startHealthCheck()` here will lead to a second health check.
|
|
116
|
-
// It might seem redundant to perform two health checks in a quick
|
|
117
|
-
// succession, but doing so doesn't lead to any problem, and it is
|
|
118
|
-
// actually possible for the health to have changed in between as the
|
|
119
|
-
// current best block might have been updated during the subscription
|
|
120
|
-
// request.
|
|
121
|
-
this.startHealthCheck();
|
|
122
|
-
this.update();
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Response doesn't concern us.
|
|
127
|
-
return jsonRpcResponse;
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
update: function () {
|
|
131
|
-
if (!this.currentHealthTimeout) {
|
|
132
|
-
this.currentHealthTimeout = setTimeout(() => {
|
|
133
|
-
this.currentHealthTimeout = null;
|
|
134
|
-
this.startHealthCheck();
|
|
135
|
-
}, 10000);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (this.isSyncing && !this.currentSubscriptionId && !this.currentSubunsubRequestId)
|
|
139
|
-
this.startSubscription();
|
|
140
|
-
if (!this.isSyncing && this.currentSubscriptionId && !this.currentSubunsubRequestId)
|
|
141
|
-
this.endSubscription();
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
startHealthCheck: function () {
|
|
145
|
-
if (this.currentHealthCheckId)
|
|
146
|
-
throw new Error('Internal error in health checker');
|
|
147
|
-
if (this.currentHealthTimeout) {
|
|
148
|
-
clearTimeout(this.currentHealthTimeout);
|
|
149
|
-
this.currentHealthTimeout = null;
|
|
150
|
-
}
|
|
151
|
-
this.currentHealthCheckId = randombytes(32).toString('base64');
|
|
152
|
-
sendJsonRpc(JSON.stringify({
|
|
153
|
-
jsonrpc: "2.0",
|
|
154
|
-
id: this.currentHealthCheckId,
|
|
155
|
-
method: 'system_health',
|
|
156
|
-
params: [],
|
|
157
|
-
}));
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
startSubscription: function () {
|
|
161
|
-
if (this.currentSubunsubRequestId || this.currentSubscriptionId)
|
|
162
|
-
throw new Error('Internal error in health checker');
|
|
163
|
-
this.currentSubunsubRequestId = randombytes(32).toString('base64');
|
|
164
|
-
sendJsonRpc(JSON.stringify({
|
|
165
|
-
jsonrpc: "2.0",
|
|
166
|
-
id: this.currentSubunsubRequestId,
|
|
167
|
-
method: 'chain_subscribeNewHeads',
|
|
168
|
-
params: [],
|
|
169
|
-
}));
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
endSubscription: function () {
|
|
173
|
-
if (this.currentSubunsubRequestId || !this.currentSubscriptionId)
|
|
174
|
-
throw new Error('Internal error in health checker');
|
|
175
|
-
this.currentSubunsubRequestId = randombytes(32).toString('base64');
|
|
176
|
-
sendJsonRpc(JSON.stringify({
|
|
177
|
-
jsonrpc: "2.0",
|
|
178
|
-
id: this.currentSubunsubRequestId,
|
|
179
|
-
method: 'chain_unsubscribeNewHeads',
|
|
180
|
-
params: [this.currentSubscriptionId],
|
|
181
|
-
}));
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
destroy: function () {
|
|
185
|
-
if (this.currentHealthTimeout) {
|
|
186
|
-
clearTimeout(this.currentHealthTimeout);
|
|
187
|
-
this.currentHealthTimeout = null;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
checker.startHealthCheck();
|
|
193
|
-
},
|
|
194
|
-
stop: () => {
|
|
195
|
-
if (checker === null)
|
|
196
|
-
return; // Already stopped.
|
|
197
|
-
checker.destroy();
|
|
198
|
-
checker = null;
|
|
199
|
-
},
|
|
200
|
-
responsePassThrough: (jsonRpcResponse) => {
|
|
201
|
-
if (checker === null)
|
|
202
|
-
return jsonRpcResponse;
|
|
203
|
-
return checker.responsePassThrough(jsonRpcResponse);
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
}
|
package/src/index.d.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// Smoldot
|
|
2
|
-
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
3
|
-
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
-
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU General Public License for more details.
|
|
14
|
-
|
|
15
|
-
// You should have received a copy of the GNU General Public License
|
|
16
|
-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
declare class SmoldotError extends Error {
|
|
19
|
-
constructor(message: string);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface SmoldotClient {
|
|
23
|
-
addChain(options: SmoldotAddChainOptions): Promise<SmoldotChain>;
|
|
24
|
-
terminate(): void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface SmoldotChain {
|
|
28
|
-
sendJsonRpc(rpc: string): void;
|
|
29
|
-
remove(): void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type SmoldotJsonRpcCallback = (response: string) => void;
|
|
33
|
-
export type SmoldotLogCallback = (level: number, target: string, message: string) => void;
|
|
34
|
-
|
|
35
|
-
export interface SmoldotOptions {
|
|
36
|
-
maxLogLevel?: number;
|
|
37
|
-
logCallback?: SmoldotLogCallback;
|
|
38
|
-
forbidTcp?: boolean;
|
|
39
|
-
forbidWs?: boolean;
|
|
40
|
-
forbidWss?: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface SmoldotAddChainOptions {
|
|
44
|
-
chainSpec: string;
|
|
45
|
-
potentialRelayChains?: SmoldotChain[];
|
|
46
|
-
jsonRpcCallback?: SmoldotJsonRpcCallback;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface SmoldotHealth {
|
|
50
|
-
isSyncing: boolean;
|
|
51
|
-
peers: number;
|
|
52
|
-
shouldHavePeers: boolean;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface HealthChecker {
|
|
56
|
-
start(sendRequest: (request: string) => void, healthCallback: (health: SmoldotHealth) => void): void;
|
|
57
|
-
stop(): void;
|
|
58
|
-
responsePassThrough(response: string): string | null;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface Smoldot {
|
|
62
|
-
start(options?: SmoldotOptions): Promise<SmoldotClient>;
|
|
63
|
-
healthChecker(): HealthChecker;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const smoldot: Smoldot;
|
|
67
|
-
|
|
68
|
-
export default smoldot;
|