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
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { PlatformBindings } from './instance/instance.js';
|
|
2
|
+
export { MalformedJsonRpcError, QueueFullError, CrashError } from './instance/instance.js';
|
|
3
|
+
/**
|
|
4
|
+
* Thrown in case of a problem when initializing the chain.
|
|
5
|
+
*/
|
|
6
|
+
export declare class AddChainError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Thrown in case the API user tries to use a chain or client that has already been destroyed.
|
|
11
|
+
*/
|
|
12
|
+
export declare class AlreadyDestroyedError extends Error {
|
|
13
|
+
constructor();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Thrown when trying to send a JSON-RPC message to a chain whose JSON-RPC system hasn't been
|
|
17
|
+
* enabled.
|
|
18
|
+
*/
|
|
19
|
+
export declare class JsonRpcDisabledError extends Error {
|
|
20
|
+
constructor();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Client with zero or more active connections to blockchains.
|
|
24
|
+
*/
|
|
25
|
+
export interface Client {
|
|
26
|
+
/**
|
|
27
|
+
* Connects to a chain.
|
|
28
|
+
*
|
|
29
|
+
* Throws an exception if the chain specification isn't valid, or if the chain specification
|
|
30
|
+
* concerns a parachain but no corresponding relay chain can be found.
|
|
31
|
+
*
|
|
32
|
+
* Smoldot will automatically de-duplicate chains if multiple identical chains are added, in
|
|
33
|
+
* order to save resources. In other words, it is not a problem to call `addChain` multiple
|
|
34
|
+
* times with the same chain specifications and obtain multiple `Chain`.
|
|
35
|
+
* When the same client is used for multiple different purposes, you are in fact strongly
|
|
36
|
+
* encouraged to trust smoldot and not attempt to de-duplicate chains yourself, as determining
|
|
37
|
+
* whether two chains are identical is complicated and might have security implications.
|
|
38
|
+
*
|
|
39
|
+
* Smoldot tries to distribute CPU resources equally between all active `Chain` objects.
|
|
40
|
+
*
|
|
41
|
+
* @param options Configuration of the chain to add.
|
|
42
|
+
*
|
|
43
|
+
* @throws {@link AddChainError} If the chain can't be added.
|
|
44
|
+
* @throws {@link AlreadyDestroyedError} If the client has been terminated earlier.
|
|
45
|
+
* @throws {@link CrashError} If the background client has crashed.
|
|
46
|
+
*/
|
|
47
|
+
addChain(options: AddChainOptions): Promise<Chain>;
|
|
48
|
+
/**
|
|
49
|
+
* Terminates the client.
|
|
50
|
+
*
|
|
51
|
+
* Afterwards, trying to use the client or any of its chains again will lead to an exception
|
|
52
|
+
* being thrown.
|
|
53
|
+
*
|
|
54
|
+
* @throws {@link AlreadyDestroyedError} If the client has already been terminated earlier.
|
|
55
|
+
* @throws {@link CrashError} If the background client has crashed.
|
|
56
|
+
*/
|
|
57
|
+
terminate(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Active connection to a blockchain.
|
|
61
|
+
*/
|
|
62
|
+
export interface Chain {
|
|
63
|
+
/**
|
|
64
|
+
* Enqueues a JSON-RPC request that the client will process as soon as possible.
|
|
65
|
+
*
|
|
66
|
+
* The response will be sent back using the callback passed when adding the chain.
|
|
67
|
+
*
|
|
68
|
+
* See <https://www.jsonrpc.org/specification> for a specification of the JSON-RPC format. Only
|
|
69
|
+
* version 2 is supported.
|
|
70
|
+
* Be aware that some requests will cause notifications to be sent back using the same callback
|
|
71
|
+
* as the responses.
|
|
72
|
+
*
|
|
73
|
+
* A {@link MalformedJsonRpcError} is thrown if the request isn't a valid JSON-RPC request or
|
|
74
|
+
* if the request is unreasonably large (64 MiB at the time of writing of this comment).
|
|
75
|
+
* If, however, the request is a valid JSON-RPC request but that concerns an unknown method, a
|
|
76
|
+
* error response is properly generated.
|
|
77
|
+
*
|
|
78
|
+
* Two JSON-RPC APIs are supported by smoldot:
|
|
79
|
+
*
|
|
80
|
+
* - The "legacy" one, documented here: <https://polkadot.js.org/docs/substrate/rpc>
|
|
81
|
+
* - The more recent one: <https://github.com/paritytech/json-rpc-interface-spec>
|
|
82
|
+
*
|
|
83
|
+
* @param rpc JSON-encoded RPC request.
|
|
84
|
+
*
|
|
85
|
+
* @throws {@link MalformedJsonRpcError} If the payload isn't valid JSON-RPC.
|
|
86
|
+
* @throws {@link QueueFullError} If the queue of JSON-RPC requests of the chain is full.
|
|
87
|
+
* @throws {@link AlreadyDestroyedError} If the chain has been removed or the client has been terminated.
|
|
88
|
+
* @throws {@link JsonRpcDisabledError} If the JSON-RPC system was disabled in the options of the chain.
|
|
89
|
+
* @throws {@link CrashError} If the background client has crashed.
|
|
90
|
+
*/
|
|
91
|
+
sendJsonRpc(rpc: string): void;
|
|
92
|
+
/**
|
|
93
|
+
* Waits for a JSON-RPC response or notification to be generated.
|
|
94
|
+
*
|
|
95
|
+
* If this function is called multiple times "simultaneously" (generating multiple different
|
|
96
|
+
* `Promise`s), each `Promise` will return a different JSON-RPC response or notification.
|
|
97
|
+
*
|
|
98
|
+
* Each chain contains a buffer of the responses waiting to be sent out. Calling this function
|
|
99
|
+
* pulls one element from the buffer. If this function is called at a slower rate than responses
|
|
100
|
+
* are generated, then buffer will eventually become full, at which point calling
|
|
101
|
+
* {@link Chain.sendJsonRpc} will throw an exception.
|
|
102
|
+
*
|
|
103
|
+
* @throws {@link AlreadyDestroyedError} If the chain has been removed or the client has been terminated.
|
|
104
|
+
* @throws {@link JsonRpcDisabledError} If the JSON-RPC system was disabled in the options of the chain.
|
|
105
|
+
* @throws {@link CrashError} If the background client has crashed.
|
|
106
|
+
*/
|
|
107
|
+
nextJsonRpcResponse(): Promise<string>;
|
|
108
|
+
/**
|
|
109
|
+
* Disconnects from the blockchain.
|
|
110
|
+
*
|
|
111
|
+
* The JSON-RPC callback will no longer be called.
|
|
112
|
+
*
|
|
113
|
+
* Trying to use the chain again will lead to an exception being thrown.
|
|
114
|
+
*
|
|
115
|
+
* If this chain is a relay chain, then all parachains that use it will continue to work. Smoldot
|
|
116
|
+
* automatically keeps alive all relay chains that have an active parachains. There is no need
|
|
117
|
+
* to track parachains and relaychains, or to destroy them in the correct order, as this is
|
|
118
|
+
* handled automatically.
|
|
119
|
+
*
|
|
120
|
+
* @throws {@link AlreadyDestroyedError} If the chain has already been removed or the client has been terminated.
|
|
121
|
+
* @throws {@link CrashError} If the background client has crashed.
|
|
122
|
+
*/
|
|
123
|
+
remove(): void;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @param level How important this message is. 1 = Error, 2 = Warn, 3 = Info, 4 = Debug, 5 = Trace
|
|
127
|
+
* @param target Name of the sub-system that the message concerns.
|
|
128
|
+
* @param message Human-readable message that developers can use to figure out what is happening.
|
|
129
|
+
*/
|
|
130
|
+
export type LogCallback = (level: number, target: string, message: string) => void;
|
|
131
|
+
/**
|
|
132
|
+
* Configuration of a client.
|
|
133
|
+
*/
|
|
134
|
+
export interface ClientOptions {
|
|
135
|
+
/**
|
|
136
|
+
* Callback that the client will invoke in order to report a log event.
|
|
137
|
+
*
|
|
138
|
+
* By default, prints the log on the `console`. If you want to disable logging altogether,
|
|
139
|
+
* please pass an empty callback function.
|
|
140
|
+
*/
|
|
141
|
+
logCallback?: LogCallback;
|
|
142
|
+
/**
|
|
143
|
+
* The client will never call the callback with a value of `level` superior to this value.
|
|
144
|
+
* Defaults to 3.
|
|
145
|
+
*
|
|
146
|
+
* While this filtering could be done directly by the `logCallback`, passing a maximum log level
|
|
147
|
+
* leads to better performances as the client doesn't even need to generate a `message` when it
|
|
148
|
+
* knows that this message isn't interesting.
|
|
149
|
+
*/
|
|
150
|
+
maxLogLevel?: number;
|
|
151
|
+
/**
|
|
152
|
+
* Maximum amount of CPU that the client should consume on average.
|
|
153
|
+
*
|
|
154
|
+
* This must be a number between `0.0` and `1.0`. For example, passing `0.25` bounds the client
|
|
155
|
+
* to 25% of CPU power.
|
|
156
|
+
* Defaults to `1.0` if no value is provided.
|
|
157
|
+
*
|
|
158
|
+
* Note that this is implemented by sleeping for certain amounts of time in order for the average
|
|
159
|
+
* CPU consumption to not go beyond the given limit. It is therefore still possible for the
|
|
160
|
+
* client to use high amounts of CPU for short amounts of time.
|
|
161
|
+
*/
|
|
162
|
+
cpuRateLimit?: number;
|
|
163
|
+
/**
|
|
164
|
+
* If `true`, then the client will never open any TCP connection.
|
|
165
|
+
* Defaults to `false`.
|
|
166
|
+
*
|
|
167
|
+
* This option can be used in order to mimic an environment where the TCP protocol isn't
|
|
168
|
+
* supported (e.g. browsers) from an environment where TCP is supported (e.g. NodeJS).
|
|
169
|
+
*
|
|
170
|
+
* This option has no effect in environments where the TCP protocol isn't supported anyway.
|
|
171
|
+
*/
|
|
172
|
+
forbidTcp?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* If `true`, then the client will never open any non-secure WebSocket connection.
|
|
175
|
+
* Defaults to `false`.
|
|
176
|
+
*
|
|
177
|
+
* This option can be used in order to mimic an environment where non-secure WebSocket
|
|
178
|
+
* connections aren't supported (e.g. web pages) from an environment where they are supported
|
|
179
|
+
* (e.g. NodeJS).
|
|
180
|
+
*
|
|
181
|
+
* This option has no effect in environments where non-secure WebSocket connections aren't
|
|
182
|
+
* supported anyway.
|
|
183
|
+
*/
|
|
184
|
+
forbidWs?: boolean;
|
|
185
|
+
/**
|
|
186
|
+
* If `true`, then the client will never open any non-secure WebSocket connection to addresses
|
|
187
|
+
* other than `localhost` or `127.0.0.1`.
|
|
188
|
+
* Defaults to `false`.
|
|
189
|
+
*
|
|
190
|
+
* This option is similar to `forbidWs`, except that connections to `localhost` and `127.0.0.1`
|
|
191
|
+
* do not take the value of this option into account.
|
|
192
|
+
*
|
|
193
|
+
* This option can be used in order to mimic an environment where non-secure WebSocket
|
|
194
|
+
* connections aren't supported (e.g. web pages) from an environment where they are supported
|
|
195
|
+
* (e.g. NodeJS).
|
|
196
|
+
*
|
|
197
|
+
* This option has no effect in environments where non-secure WebSocket connections aren't
|
|
198
|
+
* supported anyway.
|
|
199
|
+
*/
|
|
200
|
+
forbidNonLocalWs?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* If `true`, then the client will never open any secure WebSocket connection.
|
|
203
|
+
* Defaults to `false`.
|
|
204
|
+
*
|
|
205
|
+
* This option exists of the sake of completeness. All environments support secure WebSocket
|
|
206
|
+
* connections.
|
|
207
|
+
*/
|
|
208
|
+
forbidWss?: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* If `true`, then the client will never open any WebRTC connection.
|
|
211
|
+
* Defaults to `false`.
|
|
212
|
+
*
|
|
213
|
+
* This option has no effect in environments where non-secure WebSocket connections aren't
|
|
214
|
+
* supported anyway.
|
|
215
|
+
*/
|
|
216
|
+
forbidWebRtc?: boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Configuration of a blockchain.
|
|
220
|
+
*/
|
|
221
|
+
export interface AddChainOptions {
|
|
222
|
+
/**
|
|
223
|
+
* JSON-encoded specification of the chain.
|
|
224
|
+
*
|
|
225
|
+
* The specification of the chain can be generated from a Substrate node by calling
|
|
226
|
+
* `<client> build-spec --raw > spec.json`. Only "raw" chain specifications are supported by
|
|
227
|
+
* smoldot at the moment.
|
|
228
|
+
*
|
|
229
|
+
* If the chain specification contains a `relay_chain` field, then smoldot will try to match
|
|
230
|
+
* the value in `relay_chain` with the value in `id` of the chains in `potentialRelayChains`.
|
|
231
|
+
*/
|
|
232
|
+
chainSpec: string;
|
|
233
|
+
/**
|
|
234
|
+
* Content of the database of this chain. Can be obtained by using the
|
|
235
|
+
* `chainHead_unstable_finalizedDatabase` JSON-RPC function.
|
|
236
|
+
*
|
|
237
|
+
* Smoldot reserves the right to change its database format, making previous databases
|
|
238
|
+
* incompatible. For this reason, no error is generated if the content of the database is invalid
|
|
239
|
+
* and/or can't be decoded.
|
|
240
|
+
*
|
|
241
|
+
* Important: please note that using a malicious database content can lead to a security
|
|
242
|
+
* vulnerability. This database content is considered by smoldot as trusted input. It is the
|
|
243
|
+
* responsibility of the API user to make sure that the value passed in this field comes from
|
|
244
|
+
* the same source of trust as the chain specification that was used when retrieving this
|
|
245
|
+
* database content.
|
|
246
|
+
*/
|
|
247
|
+
databaseContent?: string;
|
|
248
|
+
/**
|
|
249
|
+
* If `chainSpec` concerns a parachain, contains the list of chains whose `id` smoldot will try
|
|
250
|
+
* to match with the parachain's `relay_chain`.
|
|
251
|
+
* Defaults to `[]`.
|
|
252
|
+
*
|
|
253
|
+
* Must contain exactly the objects that were returned by previous calls to `addChain`. The
|
|
254
|
+
* library uses a `WeakMap` in its implementation in order to identify chains.
|
|
255
|
+
*
|
|
256
|
+
* The primary way smoldot determines which relay chain is associated to a parachain is by
|
|
257
|
+
* inspecting the chain specification of that parachain (i.e. the `chainSpec` field).
|
|
258
|
+
*
|
|
259
|
+
* This poses a problem in situations where the same client is shared between multiple different
|
|
260
|
+
* applications: multiple applications could add mutiple different chains with the same `id`,
|
|
261
|
+
* creating an ambiguity, or an application could register malicious chains with small variations
|
|
262
|
+
* of a popular chain's `id` and try to benefit from a typo in a legitimate application's
|
|
263
|
+
* `relay_chain`.
|
|
264
|
+
*
|
|
265
|
+
* These problems can be solved by using this parameter to segregate multiple different uses of
|
|
266
|
+
* the same client. To use it, pass the list of all chains that the same application has
|
|
267
|
+
* previously added to the client. By doing so, you are guaranteed that the chains of multiple
|
|
268
|
+
* different applications can't interact in any way (good or bad), while still benefiting from
|
|
269
|
+
* the de-duplication of resources that smoldot performs in `addChain`.
|
|
270
|
+
*
|
|
271
|
+
* When multiple different parachains use the same relay chain, it is important to be sure that
|
|
272
|
+
* they are indeed using the same relay chain, and not accidentally using different ones. For
|
|
273
|
+
* this reason, this parameter is a list of potential relay chains in which only one chain
|
|
274
|
+
* should match, rather than a single `Chain` corresponding to the relay chain.
|
|
275
|
+
*/
|
|
276
|
+
potentialRelayChains?: Chain[];
|
|
277
|
+
/**
|
|
278
|
+
* Disables the JSON-RPC system of the chain.
|
|
279
|
+
*
|
|
280
|
+
* This option can be used in order to save up some resources.
|
|
281
|
+
*
|
|
282
|
+
* It will be illegal to call {@link Chain.sendJsonRpc} and {@link Chain.nextJsonRpcResponse} on
|
|
283
|
+
* this chain.
|
|
284
|
+
*/
|
|
285
|
+
disableJsonRpc?: boolean;
|
|
286
|
+
}
|
|
287
|
+
export declare function start(options: ClientOptions, platformBindings: PlatformBindings): Client;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Smoldot
|
|
2
|
+
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
4
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
7
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
// This program is free software: you can redistribute it and/or modify
|
|
14
|
+
// it under the terms of the GNU General Public License as published by
|
|
15
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
// (at your option) any later version.
|
|
17
|
+
// This program is distributed in the hope that it will be useful,
|
|
18
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
// GNU General Public License for more details.
|
|
21
|
+
// You should have received a copy of the GNU General Public License
|
|
22
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
23
|
+
import { MalformedJsonRpcError, start as startInstance } from './instance/instance.js';
|
|
24
|
+
export { MalformedJsonRpcError, QueueFullError, CrashError } from './instance/instance.js';
|
|
25
|
+
/**
|
|
26
|
+
* Thrown in case of a problem when initializing the chain.
|
|
27
|
+
*/
|
|
28
|
+
export class AddChainError extends Error {
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "AddChainError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Thrown in case the API user tries to use a chain or client that has already been destroyed.
|
|
36
|
+
*/
|
|
37
|
+
export class AlreadyDestroyedError extends Error {
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
this.name = "AlreadyDestroyedError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Thrown when trying to send a JSON-RPC message to a chain whose JSON-RPC system hasn't been
|
|
45
|
+
* enabled.
|
|
46
|
+
*/
|
|
47
|
+
export class JsonRpcDisabledError extends Error {
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.name = "JsonRpcDisabledError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// This function is similar to the `start` function found in `index.ts`, except with an extra
|
|
54
|
+
// parameter containing the platform-specific bindings.
|
|
55
|
+
// Contrary to the one within `index.js`, this function is not supposed to be directly used.
|
|
56
|
+
export function start(options, platformBindings) {
|
|
57
|
+
const logCallback = options.logCallback || ((level, target, message) => {
|
|
58
|
+
// The first parameter of the methods of `console` has some printf-like substitution
|
|
59
|
+
// capabilities. We don't really need to use this, but not using it means that the logs might
|
|
60
|
+
// not get printed correctly if they contain `%`.
|
|
61
|
+
if (level <= 1) {
|
|
62
|
+
console.error("[%s] %s", target, message);
|
|
63
|
+
}
|
|
64
|
+
else if (level == 2) {
|
|
65
|
+
console.warn("[%s] %s", target, message);
|
|
66
|
+
}
|
|
67
|
+
else if (level == 3) {
|
|
68
|
+
console.info("[%s] %s", target, message);
|
|
69
|
+
}
|
|
70
|
+
else if (level == 4) {
|
|
71
|
+
console.debug("[%s] %s", target, message);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.trace("[%s] %s", target, message);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// For each chain object returned by `addChain`, the associated internal chain id.
|
|
78
|
+
//
|
|
79
|
+
// Immediately cleared when `remove()` is called on a chain.
|
|
80
|
+
let chainIds = new WeakMap();
|
|
81
|
+
// If `Client.terminate()̀ is called, this error is set to a value.
|
|
82
|
+
// All the functions of the public API check if this contains a value.
|
|
83
|
+
let alreadyDestroyedError = null;
|
|
84
|
+
const instance = startInstance({
|
|
85
|
+
// Maximum level of log entries sent by the client.
|
|
86
|
+
// 0 = Logging disabled, 1 = Error, 2 = Warn, 3 = Info, 4 = Debug, 5 = Trace
|
|
87
|
+
maxLogLevel: options.maxLogLevel || 3,
|
|
88
|
+
logCallback,
|
|
89
|
+
// `enableCurrentTask` adds a small performance hit, but adds some additional information to
|
|
90
|
+
// crash reports. Whether this should be enabled is very opiniated and not that important. At
|
|
91
|
+
// the moment, we enable it all the time, except if the user has logging disabled altogether.
|
|
92
|
+
enableCurrentTask: options.maxLogLevel ? options.maxLogLevel >= 1 : true,
|
|
93
|
+
cpuRateLimit: options.cpuRateLimit || 1.0,
|
|
94
|
+
}, platformBindings);
|
|
95
|
+
return {
|
|
96
|
+
addChain: (options) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
if (alreadyDestroyedError)
|
|
98
|
+
throw alreadyDestroyedError;
|
|
99
|
+
// Passing a JSON object for the chain spec is an easy mistake, so we provide a more
|
|
100
|
+
// readable error.
|
|
101
|
+
if (!(typeof options.chainSpec === 'string'))
|
|
102
|
+
throw new Error("Chain specification must be a string");
|
|
103
|
+
let potentialRelayChainsIds = [];
|
|
104
|
+
if (!!options.potentialRelayChains) {
|
|
105
|
+
for (const chain of options.potentialRelayChains) {
|
|
106
|
+
// The content of `options.potentialRelayChains` are supposed to be chains earlier
|
|
107
|
+
// returned by `addChain`.
|
|
108
|
+
const id = chainIds.get(chain);
|
|
109
|
+
if (id === undefined) // It is possible for `id` to be missing if it has earlier been removed.
|
|
110
|
+
continue;
|
|
111
|
+
potentialRelayChainsIds.push(id);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const outcome = yield instance.addChain(options.chainSpec, typeof options.databaseContent === 'string' ? options.databaseContent : "", potentialRelayChainsIds, !!options.disableJsonRpc);
|
|
115
|
+
if (!outcome.success)
|
|
116
|
+
throw new AddChainError(outcome.error);
|
|
117
|
+
const chainId = outcome.chainId;
|
|
118
|
+
const wasDestroyed = { destroyed: false };
|
|
119
|
+
// `expected` was pushed by the `addChain` method.
|
|
120
|
+
// Resolve the promise that `addChain` returned to the user.
|
|
121
|
+
const newChain = {
|
|
122
|
+
sendJsonRpc: (request) => {
|
|
123
|
+
if (alreadyDestroyedError)
|
|
124
|
+
throw alreadyDestroyedError;
|
|
125
|
+
if (wasDestroyed.destroyed)
|
|
126
|
+
throw new AlreadyDestroyedError();
|
|
127
|
+
if (options.disableJsonRpc)
|
|
128
|
+
throw new JsonRpcDisabledError();
|
|
129
|
+
if (request.length >= 64 * 1024 * 1024) {
|
|
130
|
+
throw new MalformedJsonRpcError();
|
|
131
|
+
}
|
|
132
|
+
;
|
|
133
|
+
instance.request(request, chainId);
|
|
134
|
+
},
|
|
135
|
+
nextJsonRpcResponse: () => {
|
|
136
|
+
if (alreadyDestroyedError)
|
|
137
|
+
return Promise.reject(alreadyDestroyedError);
|
|
138
|
+
if (wasDestroyed.destroyed)
|
|
139
|
+
return Promise.reject(new AlreadyDestroyedError());
|
|
140
|
+
if (options.disableJsonRpc)
|
|
141
|
+
return Promise.reject(new JsonRpcDisabledError());
|
|
142
|
+
return instance.nextJsonRpcResponse(chainId);
|
|
143
|
+
},
|
|
144
|
+
remove: () => {
|
|
145
|
+
if (alreadyDestroyedError)
|
|
146
|
+
throw alreadyDestroyedError;
|
|
147
|
+
if (wasDestroyed.destroyed)
|
|
148
|
+
throw new AlreadyDestroyedError();
|
|
149
|
+
wasDestroyed.destroyed = true;
|
|
150
|
+
console.assert(chainIds.has(newChain));
|
|
151
|
+
chainIds.delete(newChain);
|
|
152
|
+
instance.removeChain(chainId);
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
chainIds.set(newChain, chainId);
|
|
156
|
+
return newChain;
|
|
157
|
+
}),
|
|
158
|
+
terminate: () => __awaiter(this, void 0, void 0, function* () {
|
|
159
|
+
if (alreadyDestroyedError)
|
|
160
|
+
throw alreadyDestroyedError;
|
|
161
|
+
alreadyDestroyedError = new AlreadyDestroyedError();
|
|
162
|
+
instance.startShutdown();
|
|
163
|
+
})
|
|
164
|
+
};
|
|
165
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
import { Client, ClientOptions } from './client.js';
|
|
3
|
+
export { AddChainError, AddChainOptions, AlreadyDestroyedError, Chain, Client, ClientOptions, CrashError, JsonRpcDisabledError, MalformedJsonRpcError, QueueFullError, LogCallback } from './client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Initializes a new client. This is a pre-requisite to connecting to a blockchain.
|
|
6
|
+
*
|
|
7
|
+
* Can never fail.
|
|
8
|
+
*
|
|
9
|
+
* @param options Configuration of the client. Defaults to `{}`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function start(options?: ClientOptions): Client;
|