@leofcoin/peernet 1.1.72 → 1.1.74
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/exports/browser/browser-rHvRu5xW.js +187 -0
- package/exports/browser/browser-store.js +2 -27
- package/exports/browser/client-peGn0FvK.js +605 -0
- package/exports/browser/identity.d.ts +19 -0
- package/exports/browser/{index-687f692b.js → index-Wv-fIkmw.js} +2 -2
- package/exports/browser/index-jZbVSPhQ.js +7889 -0
- package/exports/browser/{messages-1c117282.js → messages-y2oPb2AE.js} +2 -2
- package/exports/browser/{peernet-fa94440c.js → peernet-w0f2V8kl.js} +610 -836
- package/exports/browser/peernet.js +2 -2
- package/exports/peernet.js +1 -1
- package/exports/types/identity.d.ts +19 -0
- package/package.json +12 -22
- package/rollup.config.js +1 -8
- package/src/identity.ts +1 -0
- package/.eslintrc.json +0 -24
- /package/exports/browser/{browser-2c73e2ef.js → browser-AyxSBUXj.js} +0 -0
- /package/exports/browser/{qr-scanner-worker.min-c002e984.js → qr-scanner-worker.min-RaSiJc_R.js} +0 -0
- /package/exports/browser/{value-4e80eeeb.js → value-wzPYMxsX.js} +0 -0
- /package/exports/{messages-42b2109e.js → messages-T3M-Ff1E.js} +0 -0
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { L as LittlePubSub } from './peernet-w0f2V8kl.js';
|
|
2
|
+
import './value-wzPYMxsX.js';
|
|
3
|
+
|
|
4
|
+
class Api {
|
|
5
|
+
_pubsub;
|
|
6
|
+
constructor(_pubsub) {
|
|
7
|
+
this._pubsub = _pubsub;
|
|
8
|
+
}
|
|
9
|
+
subscribe(topic, cb) {
|
|
10
|
+
this._pubsub.subscribe(topic, cb);
|
|
11
|
+
}
|
|
12
|
+
unsubscribe(topic, cb) {
|
|
13
|
+
this._pubsub.unsubscribe(topic, cb);
|
|
14
|
+
}
|
|
15
|
+
publish(topic, value) {
|
|
16
|
+
this._pubsub.publish(topic, value);
|
|
17
|
+
}
|
|
18
|
+
subscribers() {
|
|
19
|
+
this._pubsub.subscribers;
|
|
20
|
+
}
|
|
21
|
+
connectionState(state) {
|
|
22
|
+
switch (state) {
|
|
23
|
+
case 0:
|
|
24
|
+
return 'connecting';
|
|
25
|
+
case 1:
|
|
26
|
+
return 'open';
|
|
27
|
+
case 2:
|
|
28
|
+
return 'closing';
|
|
29
|
+
case 3:
|
|
30
|
+
return 'closed';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @param {string} type
|
|
35
|
+
* @param {string} name
|
|
36
|
+
* @param {object} params
|
|
37
|
+
*/
|
|
38
|
+
request(client, request) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const state = this.connectionState(client.readyState);
|
|
41
|
+
if (state !== 'open')
|
|
42
|
+
return reject(`coudn't send request to ${client.id}, no open connection found.`);
|
|
43
|
+
request.id = Math.random().toString(36).slice(-12);
|
|
44
|
+
const handler = result => {
|
|
45
|
+
if (result && result.error)
|
|
46
|
+
return reject(result.error);
|
|
47
|
+
resolve({ result, id: request.id, handler });
|
|
48
|
+
this.unsubscribe(request.id, handler);
|
|
49
|
+
};
|
|
50
|
+
this.subscribe(request.id, handler);
|
|
51
|
+
this.send(client, request);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async send(client, request) {
|
|
55
|
+
return client.send(JSON.stringify(request));
|
|
56
|
+
}
|
|
57
|
+
pubsub(client) {
|
|
58
|
+
return {
|
|
59
|
+
publish: (topic = 'pubsub', value) => {
|
|
60
|
+
return this.send(client, { url: 'pubsub', params: { topic, value } });
|
|
61
|
+
},
|
|
62
|
+
subscribe: (topic = 'pubsub', cb) => {
|
|
63
|
+
this.subscribe(topic, cb);
|
|
64
|
+
return this.send(client, { url: 'pubsub', params: { topic, subscribe: true } });
|
|
65
|
+
},
|
|
66
|
+
unsubscribe: (topic = 'pubsub', cb) => {
|
|
67
|
+
this.unsubscribe(topic, cb);
|
|
68
|
+
return this.send(client, { url: 'pubsub', params: { topic, unsubscribe: true } });
|
|
69
|
+
},
|
|
70
|
+
subscribers: this._pubsub.subscribers
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
server(client) {
|
|
74
|
+
return {
|
|
75
|
+
uptime: async () => {
|
|
76
|
+
try {
|
|
77
|
+
const { result, id, handler } = await this.request(client, { url: 'uptime' });
|
|
78
|
+
this.unsubscribe(id, handler);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
ping: async () => {
|
|
86
|
+
try {
|
|
87
|
+
const now = new Date().getTime();
|
|
88
|
+
const { result, id, handler } = await this.request(client, { url: 'ping' });
|
|
89
|
+
this.unsubscribe(id, handler);
|
|
90
|
+
return (Number(result) - now);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
peernet(client) {
|
|
99
|
+
return {
|
|
100
|
+
join: async (params) => {
|
|
101
|
+
try {
|
|
102
|
+
params.join = true;
|
|
103
|
+
const requested = { url: 'peernet', params };
|
|
104
|
+
const { result, id, handler } = await this.request(client, requested);
|
|
105
|
+
this.unsubscribe(id, handler);
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
leave: async (params) => {
|
|
113
|
+
try {
|
|
114
|
+
params.join = false;
|
|
115
|
+
const requested = { url: 'peernet', params };
|
|
116
|
+
const { result, id, handler } = await this.request(client, requested);
|
|
117
|
+
this.unsubscribe(id, handler);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
throw e;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class ClientConnection {
|
|
129
|
+
client;
|
|
130
|
+
api;
|
|
131
|
+
#startTime;
|
|
132
|
+
constructor(client, api) {
|
|
133
|
+
this.#startTime = new Date().getTime();
|
|
134
|
+
this.client = client;
|
|
135
|
+
this.api = api;
|
|
136
|
+
}
|
|
137
|
+
request = async (req) => {
|
|
138
|
+
const { result, id, handler } = await this.api.request(this.client, req);
|
|
139
|
+
globalThis.pubsub.unsubscribe(id, handler);
|
|
140
|
+
return result;
|
|
141
|
+
};
|
|
142
|
+
send = (req) => this.api.send(this.client, req);
|
|
143
|
+
get subscribe() {
|
|
144
|
+
return this.api.subscribe;
|
|
145
|
+
}
|
|
146
|
+
get unsubscribe() {
|
|
147
|
+
return this.api.unsubscribe;
|
|
148
|
+
}
|
|
149
|
+
get subscribers() {
|
|
150
|
+
return this.api.subscribers;
|
|
151
|
+
}
|
|
152
|
+
get publish() {
|
|
153
|
+
return this.api.publish;
|
|
154
|
+
}
|
|
155
|
+
get pubsub() {
|
|
156
|
+
return this.api.pubsub(this.client);
|
|
157
|
+
}
|
|
158
|
+
uptime = () => {
|
|
159
|
+
const now = new Date().getTime();
|
|
160
|
+
return (now - this.#startTime);
|
|
161
|
+
};
|
|
162
|
+
get peernet() {
|
|
163
|
+
return this.api.peernet(this.client);
|
|
164
|
+
}
|
|
165
|
+
get server() {
|
|
166
|
+
return this.api.server(this.client);
|
|
167
|
+
}
|
|
168
|
+
connectionState = () => this.api.connectionState(this.client.readyState);
|
|
169
|
+
close = exit => {
|
|
170
|
+
// client.onclose = message => {
|
|
171
|
+
// if (exit) process.exit()
|
|
172
|
+
// }
|
|
173
|
+
this.client.close();
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!globalThis.PubSub)
|
|
178
|
+
globalThis.PubSub = LittlePubSub;
|
|
179
|
+
if (!globalThis.pubsub)
|
|
180
|
+
globalThis.pubsub = new LittlePubSub(false);
|
|
181
|
+
class SocketRequestClient {
|
|
182
|
+
api;
|
|
183
|
+
clientConnection;
|
|
184
|
+
#tries = 0;
|
|
185
|
+
#retry = false;
|
|
186
|
+
#timeout = 10000;
|
|
187
|
+
#times = 10;
|
|
188
|
+
#options;
|
|
189
|
+
#protocol;
|
|
190
|
+
#url;
|
|
191
|
+
constructor(url, protocol, options) {
|
|
192
|
+
let { retry, timeout, times } = options || {};
|
|
193
|
+
if (retry !== undefined)
|
|
194
|
+
this.#retry = retry;
|
|
195
|
+
if (timeout !== undefined)
|
|
196
|
+
this.#timeout = timeout;
|
|
197
|
+
if (times !== undefined)
|
|
198
|
+
this.#times = times;
|
|
199
|
+
this.#url = url;
|
|
200
|
+
this.#protocol = protocol;
|
|
201
|
+
this.#options = options;
|
|
202
|
+
this.api = new Api(globalThis.pubsub);
|
|
203
|
+
}
|
|
204
|
+
init() {
|
|
205
|
+
return new Promise(async (resolve, reject) => {
|
|
206
|
+
const init = async () => {
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
if (!globalThis.WebSocket)
|
|
209
|
+
globalThis.WebSocket = (await import('./browser-rHvRu5xW.js').then(function (n) { return n.b; })).default.w3cwebsocket;
|
|
210
|
+
const client = new WebSocket(this.#url, this.#protocol);
|
|
211
|
+
client.onmessage = this.onmessage;
|
|
212
|
+
client.onerror = this.onerror;
|
|
213
|
+
client.onopen = () => {
|
|
214
|
+
this.#tries = 0;
|
|
215
|
+
resolve(new ClientConnection(client, this.api));
|
|
216
|
+
};
|
|
217
|
+
client.onclose = message => {
|
|
218
|
+
this.#tries++;
|
|
219
|
+
if (!this.#retry)
|
|
220
|
+
return reject(this.#options);
|
|
221
|
+
if (this.#tries > this.#times) {
|
|
222
|
+
console.log(`${this.#options.protocol} Client Closed`);
|
|
223
|
+
console.error(`could not connect to - ${this.#url}/`);
|
|
224
|
+
return resolve(new ClientConnection(client, this.api));
|
|
225
|
+
}
|
|
226
|
+
if (message.code === 1006) {
|
|
227
|
+
console.log(`Retrying in ${this.#timeout} ms`);
|
|
228
|
+
setTimeout(() => {
|
|
229
|
+
return init();
|
|
230
|
+
}, this.#timeout);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
return init();
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
onerror = error => {
|
|
238
|
+
if (globalThis.pubsub.subscribers['error']) {
|
|
239
|
+
globalThis.pubsub.publish('error', error);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.error(error);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
onmessage(message) {
|
|
246
|
+
const { value, url, status, id } = JSON.parse(message.data.toString());
|
|
247
|
+
const publisher = id ? id : url;
|
|
248
|
+
if (status === 200) {
|
|
249
|
+
globalThis.pubsub.publish(publisher, value);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
globalThis.pubsub.publish(publisher, { error: value });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const MAX_MESSAGE_SIZE = 16000;
|
|
258
|
+
const defaultOptions = {
|
|
259
|
+
networkVersion: 'peach',
|
|
260
|
+
version: 'v1',
|
|
261
|
+
stars: ['wss://star.leofcoin.org'],
|
|
262
|
+
connectEvent: 'peer:connected'
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const iceServers = [
|
|
266
|
+
{
|
|
267
|
+
urls: 'stun:stun.l.google.com:19302' // Google's public STUN server
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
urls: 'stun:openrelay.metered.ca:80'
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
urls: 'turn:openrelay.metered.ca:443',
|
|
274
|
+
username: 'openrelayproject',
|
|
275
|
+
credential: 'openrelayproject'
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
urls: 'turn:openrelay.metered.ca:443?transport=tcp',
|
|
279
|
+
username: 'openrelayproject',
|
|
280
|
+
credential: 'openrelayproject'
|
|
281
|
+
}
|
|
282
|
+
];
|
|
283
|
+
const SimplePeer = (await import('./index-jZbVSPhQ.js').then(function (n) { return n.i; })).default;
|
|
284
|
+
class Peer extends SimplePeer {
|
|
285
|
+
peerId;
|
|
286
|
+
channelName;
|
|
287
|
+
version;
|
|
288
|
+
bw = { up: 0, down: 0 };
|
|
289
|
+
get connected() {
|
|
290
|
+
return super.connected;
|
|
291
|
+
}
|
|
292
|
+
constructor(options) {
|
|
293
|
+
const { from, to, initiator, trickle, config, version } = options;
|
|
294
|
+
const channelName = initiator ? `${from}:${to}` : `${to}:${from}`;
|
|
295
|
+
super({
|
|
296
|
+
channelName,
|
|
297
|
+
initiator,
|
|
298
|
+
trickle: trickle || true,
|
|
299
|
+
config: { iceServers, ...config },
|
|
300
|
+
wrtc: globalThis.wrtc
|
|
301
|
+
});
|
|
302
|
+
this.version = String(version);
|
|
303
|
+
this.peerId = to;
|
|
304
|
+
this.channelName = channelName;
|
|
305
|
+
}
|
|
306
|
+
async #chunkit(data, id) {
|
|
307
|
+
this.bw.up = data.length;
|
|
308
|
+
const size = data.length;
|
|
309
|
+
// no needles chunking, keep it simple, if data is smaller then max size just send it
|
|
310
|
+
if (data.length <= MAX_MESSAGE_SIZE) {
|
|
311
|
+
return super.send(JSON.stringify({ chunk: data, id, size: data.length }));
|
|
312
|
+
}
|
|
313
|
+
async function* chunks(data) {
|
|
314
|
+
while (data.length !== 0) {
|
|
315
|
+
const amountToSlice = data.length >= MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : data.length;
|
|
316
|
+
const subArray = data.subarray(0, amountToSlice);
|
|
317
|
+
data = data.subarray(amountToSlice, data.length);
|
|
318
|
+
yield subArray;
|
|
319
|
+
// super.send(JSON.stringify({ chunk: subArray, id, size }))
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// while (data.length !== 0) {
|
|
323
|
+
// const amountToSlice =
|
|
324
|
+
// data.length >= MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : data.length
|
|
325
|
+
// const subArray = data.subarray(0, amountToSlice)
|
|
326
|
+
// data = data.subarray(amountToSlice, data.length)
|
|
327
|
+
// super.send(JSON.stringify({ chunk: subArray, id, size }))
|
|
328
|
+
// }
|
|
329
|
+
for await (const chunk of chunks(data)) {
|
|
330
|
+
super.send(JSON.stringify({ chunk, id, size }));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* send to peer
|
|
335
|
+
* @param data ArrayLike
|
|
336
|
+
* @param id custom id to listen to
|
|
337
|
+
*/
|
|
338
|
+
send(data, id = crypto.randomUUID()) {
|
|
339
|
+
// send chuncks till ndata support for SCTP is added
|
|
340
|
+
// wraps data
|
|
341
|
+
this.#chunkit(data, id);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* send to peer & wait for response
|
|
345
|
+
* @param data ArrayLike
|
|
346
|
+
* @param id custom id to listen to
|
|
347
|
+
*/
|
|
348
|
+
request(data, id = crypto.randomUUID()) {
|
|
349
|
+
return new Promise((resolve, reject) => {
|
|
350
|
+
const timeout = setTimeout(() => reject(`request for ${id} timed out`), 30000);
|
|
351
|
+
const onrequest = ({ data }) => {
|
|
352
|
+
clearTimeout(timeout);
|
|
353
|
+
resolve(data);
|
|
354
|
+
globalThis.pubsub.unsubscribe(id, onrequest);
|
|
355
|
+
};
|
|
356
|
+
globalThis.pubsub.subscribe(id, onrequest);
|
|
357
|
+
this.send(data, id);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const debug = globalThis.createDebugger('@peernet/swarm/client');
|
|
363
|
+
class Client {
|
|
364
|
+
#peerId;
|
|
365
|
+
#connections = {};
|
|
366
|
+
#stars = {};
|
|
367
|
+
#connectEvent = 'peer:connected';
|
|
368
|
+
id;
|
|
369
|
+
networkVersion;
|
|
370
|
+
starsConfig;
|
|
371
|
+
socketClient;
|
|
372
|
+
messageSize = 262144;
|
|
373
|
+
version;
|
|
374
|
+
#messagesToHandle = {};
|
|
375
|
+
get peerId() {
|
|
376
|
+
return this.#peerId;
|
|
377
|
+
}
|
|
378
|
+
get connections() {
|
|
379
|
+
return { ...this.#connections };
|
|
380
|
+
}
|
|
381
|
+
get peers() {
|
|
382
|
+
return Object.entries(this.#connections);
|
|
383
|
+
}
|
|
384
|
+
getPeer(peerId) {
|
|
385
|
+
return this.#connections[peerId];
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
*
|
|
389
|
+
* @param options {object}
|
|
390
|
+
* @param options.peerId {string}
|
|
391
|
+
* @param options.networkVersion {string}
|
|
392
|
+
* @param options.version {string}
|
|
393
|
+
* @param options.stars {string[]}
|
|
394
|
+
* @param options.connectEvent {string} defaults to peer:connected, can be renamed to handle different protocols, like peer:discovered (setup peer props before fireing the connect event)
|
|
395
|
+
*/
|
|
396
|
+
constructor(options) {
|
|
397
|
+
const { peerId, networkVersion, version, connectEvent, stars } = {
|
|
398
|
+
...defaultOptions,
|
|
399
|
+
...options
|
|
400
|
+
};
|
|
401
|
+
this.#peerId = peerId;
|
|
402
|
+
this.networkVersion = networkVersion;
|
|
403
|
+
this.version = version;
|
|
404
|
+
this.#connectEvent = connectEvent;
|
|
405
|
+
this.starsConfig = stars;
|
|
406
|
+
this._init();
|
|
407
|
+
}
|
|
408
|
+
async _init() {
|
|
409
|
+
// reconnectJob()
|
|
410
|
+
if (!globalThis.RTCPeerConnection)
|
|
411
|
+
globalThis.wrtc = (await import('./browser-AyxSBUXj.js').then(function (n) { return n.b; })).default;
|
|
412
|
+
for (const star of this.starsConfig) {
|
|
413
|
+
try {
|
|
414
|
+
const client = new SocketRequestClient(star, this.networkVersion);
|
|
415
|
+
this.#stars[star] = await client.init();
|
|
416
|
+
this.setupStarListeners(this.#stars[star]);
|
|
417
|
+
this.#stars[star].send({
|
|
418
|
+
url: 'join',
|
|
419
|
+
params: { version: this.version, peerId: this.peerId }
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
catch (e) {
|
|
423
|
+
if (this.starsConfig.indexOf(star) === this.starsConfig.length - 1 &&
|
|
424
|
+
!this.socketClient)
|
|
425
|
+
throw new Error(`No star available to connect`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (globalThis.process?.versions?.node) {
|
|
429
|
+
process.on('SIGINT', async () => {
|
|
430
|
+
process.stdin.resume();
|
|
431
|
+
await this.close();
|
|
432
|
+
process.exit();
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
globalThis.addEventListener('beforeunload', async () => this.close());
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
setupStarListeners(star) {
|
|
440
|
+
star.pubsub.subscribe('peer:joined', (id) => this.#peerJoined(id, star));
|
|
441
|
+
star.pubsub.subscribe('peer:left', (id) => this.#peerLeft(id, star));
|
|
442
|
+
star.pubsub.subscribe('star:joined', this.#starJoined);
|
|
443
|
+
star.pubsub.subscribe('star:left', this.#starLeft);
|
|
444
|
+
star.pubsub.subscribe('signal', (message) => this.#inComingSignal(message, star));
|
|
445
|
+
}
|
|
446
|
+
#starJoined = (id) => {
|
|
447
|
+
if (this.#stars[id]) {
|
|
448
|
+
this.#stars[id].close(0);
|
|
449
|
+
delete this.#stars[id];
|
|
450
|
+
}
|
|
451
|
+
console.log(`star ${id} joined`);
|
|
452
|
+
};
|
|
453
|
+
#starLeft = async (id) => {
|
|
454
|
+
if (this.#stars[id]) {
|
|
455
|
+
this.#stars[id].close(0);
|
|
456
|
+
delete this.#stars[id];
|
|
457
|
+
}
|
|
458
|
+
if (Object.keys(this.#stars).length === 0) {
|
|
459
|
+
for (const star of this.starsConfig) {
|
|
460
|
+
try {
|
|
461
|
+
const socketClient = await new SocketRequestClient(star, this.networkVersion).init();
|
|
462
|
+
if (!socketClient?.client?.OPEN)
|
|
463
|
+
return;
|
|
464
|
+
this.#stars[star] = socketClient;
|
|
465
|
+
this.#stars[star].send({
|
|
466
|
+
url: 'join',
|
|
467
|
+
params: { peerId: this.peerId, version: this.version }
|
|
468
|
+
});
|
|
469
|
+
this.setupStarListeners(socketClient);
|
|
470
|
+
}
|
|
471
|
+
catch (e) {
|
|
472
|
+
if (this.starsConfig.indexOf(star) === this.starsConfig.length - 1)
|
|
473
|
+
throw new Error(`No star available to connect`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
debug(`star ${id} left`);
|
|
478
|
+
};
|
|
479
|
+
#peerLeft = (peer, star) => {
|
|
480
|
+
const id = peer.peerId || peer;
|
|
481
|
+
if (this.#connections[id]) {
|
|
482
|
+
this.#connections[id].destroy();
|
|
483
|
+
delete this.#connections[id];
|
|
484
|
+
}
|
|
485
|
+
debug(`peer ${id} left`);
|
|
486
|
+
};
|
|
487
|
+
#createRTCPeerConnection = (peerId, star, version, initiator = false) => {
|
|
488
|
+
const peer = new Peer({
|
|
489
|
+
initiator: initiator,
|
|
490
|
+
from: this.peerId,
|
|
491
|
+
to: peerId,
|
|
492
|
+
version
|
|
493
|
+
});
|
|
494
|
+
peer.on('signal', (signal) => this.#peerSignal(peer, signal, star, this.version));
|
|
495
|
+
peer.on('connect', () => this.#peerConnect(peer));
|
|
496
|
+
peer.on('close', () => this.#peerClose(peer));
|
|
497
|
+
peer.on('data', (data) => this.#peerData(peer, data));
|
|
498
|
+
peer.on('error', (error) => this.#peerError(peer, error));
|
|
499
|
+
this.#connections[peerId] = peer;
|
|
500
|
+
};
|
|
501
|
+
#peerJoined = async ({ peerId, version }, star) => {
|
|
502
|
+
// check if peer rejoined before the previous connection closed
|
|
503
|
+
if (this.#connections[peerId]) {
|
|
504
|
+
this.#connections[peerId].destroy();
|
|
505
|
+
delete this.#connections[peerId];
|
|
506
|
+
}
|
|
507
|
+
// RTCPeerConnection
|
|
508
|
+
this.#createRTCPeerConnection(peerId, star, version, true);
|
|
509
|
+
debug(`peer ${peerId} joined`);
|
|
510
|
+
};
|
|
511
|
+
#inComingSignal = async ({ from, signal, channelName, version }, star) => {
|
|
512
|
+
if (version !== this.version) {
|
|
513
|
+
console.warn(`${from} joined using the wrong version.\nexpected: ${this.version} but got:${version}`);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
let peer = this.#connections[from];
|
|
517
|
+
if (!peer) {
|
|
518
|
+
this.#createRTCPeerConnection(from, star, version);
|
|
519
|
+
peer = this.#connections[from];
|
|
520
|
+
}
|
|
521
|
+
if (String(peer.channelName) !== String(channelName))
|
|
522
|
+
console.warn(`channelNames don't match: got ${peer.channelName}, expected: ${channelName}`);
|
|
523
|
+
peer.signal(signal);
|
|
524
|
+
};
|
|
525
|
+
#peerSignal = (peer, signal, star, version) => {
|
|
526
|
+
let client = this.#stars[star];
|
|
527
|
+
if (!client)
|
|
528
|
+
client = this.#stars[Object.keys(this.#stars)[0]];
|
|
529
|
+
client.send({
|
|
530
|
+
url: 'signal',
|
|
531
|
+
params: {
|
|
532
|
+
from: this.peerId,
|
|
533
|
+
to: peer.peerId,
|
|
534
|
+
channelName: peer.channelName,
|
|
535
|
+
version,
|
|
536
|
+
signal
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
};
|
|
540
|
+
#peerClose = (peer) => {
|
|
541
|
+
if (this.#connections[peer.peerId]) {
|
|
542
|
+
peer.destroy();
|
|
543
|
+
delete this.#connections[peer.peerId];
|
|
544
|
+
}
|
|
545
|
+
debug(`closed ${peer.peerId}'s connection`);
|
|
546
|
+
};
|
|
547
|
+
#peerConnect = (peer) => {
|
|
548
|
+
debug(`${peer.peerId} connected`);
|
|
549
|
+
globalThis.pubsub.publishVerbose(this.#connectEvent, peer.peerId);
|
|
550
|
+
};
|
|
551
|
+
#noticeMessage = (message, id, from, peer) => {
|
|
552
|
+
if (globalThis.pubsub.subscribers[id]) {
|
|
553
|
+
globalThis.pubsub.publish(id, {
|
|
554
|
+
data: new Uint8Array(Object.values(message)),
|
|
555
|
+
id,
|
|
556
|
+
from,
|
|
557
|
+
peer
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
globalThis.pubsub.publish('peer:data', {
|
|
562
|
+
data: new Uint8Array(Object.values(message)),
|
|
563
|
+
id,
|
|
564
|
+
from,
|
|
565
|
+
peer
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
#peerData = (peer, data) => {
|
|
570
|
+
const { id, size, chunk } = JSON.parse(new TextDecoder().decode(data));
|
|
571
|
+
peer.bw.down += size;
|
|
572
|
+
if (size <= MAX_MESSAGE_SIZE) {
|
|
573
|
+
this.#noticeMessage(chunk, id, peer.peerId, peer);
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
if (!this.#messagesToHandle[id])
|
|
577
|
+
this.#messagesToHandle[id] = [];
|
|
578
|
+
this.#messagesToHandle[id] = [
|
|
579
|
+
...this.#messagesToHandle[id],
|
|
580
|
+
...Object.values(chunk)
|
|
581
|
+
];
|
|
582
|
+
if (this.#messagesToHandle[id].length === Number(size)) {
|
|
583
|
+
this.#noticeMessage(this.#messagesToHandle[id], id, peer.peerId, peer);
|
|
584
|
+
delete this.#messagesToHandle[id];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
#peerError = (peer, error) => {
|
|
589
|
+
console.warn(`Connection error: ${error.message}`);
|
|
590
|
+
peer.destroy();
|
|
591
|
+
};
|
|
592
|
+
async close() {
|
|
593
|
+
for (const star in this.#stars) {
|
|
594
|
+
if (this.#stars[star].connectionState() === 'open')
|
|
595
|
+
await this.#stars[star].send({ url: 'leave', params: this.peerId });
|
|
596
|
+
}
|
|
597
|
+
const promises = [
|
|
598
|
+
Object.values(this.#connections).map((connection) => connection.destroy()),
|
|
599
|
+
Object.values(this.#stars).map((connection) => connection.close(0))
|
|
600
|
+
];
|
|
601
|
+
return Promise.allSettled(promises);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export { Client as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { base58String } from '@vandeurenglenn/base58';
|
|
2
|
+
export default class Identity {
|
|
3
|
+
#private;
|
|
4
|
+
network: any;
|
|
5
|
+
id: string;
|
|
6
|
+
selectedAccount: string;
|
|
7
|
+
constructor(network: string);
|
|
8
|
+
get accounts(): Promise<[[name: string, externalAddress: string, internalAddress: string]]>;
|
|
9
|
+
getAccounts(): Promise<[[name: string, externalAddress: string, internalAddress: string]]>;
|
|
10
|
+
load(password?: string): Promise<void>;
|
|
11
|
+
selectAccount(account: string): Promise<void> | Promise<IDBValidKey> | Promise<any[]>;
|
|
12
|
+
sign(hash: Uint8Array): any;
|
|
13
|
+
lock(password: string): void;
|
|
14
|
+
unlock(password: string): void;
|
|
15
|
+
export(password: string): Promise<any>;
|
|
16
|
+
import(password: any, encrypted: base58String): Promise<void>;
|
|
17
|
+
exportQR(password: string): Promise<string>;
|
|
18
|
+
importQR(image: File | Blob, password: string): Promise<void>;
|
|
19
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MultiWallet, e as encrypt, b as base58$1 } from './peernet-
|
|
2
|
-
import './value-
|
|
1
|
+
import { M as MultiWallet, e as encrypt, b as base58$1 } from './peernet-w0f2V8kl.js';
|
|
2
|
+
import './value-wzPYMxsX.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @params {String} network
|