@cryptforge/key-exchange 0.1.0

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.
@@ -0,0 +1,768 @@
1
+ // src/types/messages.ts
2
+ var MESSAGES = {
3
+ enableBroadcast: "admin:broadcast:enable",
4
+ connect: "client:topic:connect",
5
+ onClientConnection: "admin:topic:connected",
6
+ requestKeystore: "client:keystore:request",
7
+ onKeystoreRequestInvalidPIN: "admin:pin:invalid",
8
+ onKeystoreRequestValidPIN: "admin:pin:valid",
9
+ onKeystoreRequest: "admin:request:received",
10
+ approveRequest: "admin:request:approve",
11
+ onClientApproval: "client:request:approved",
12
+ denyRequest: "admin:request:deny",
13
+ onClientDenial: "client:request:denied",
14
+ onCompletion: "server:link:complete",
15
+ disableBroadcast: "admin:broadcast:disable",
16
+ onBroadcastDisable: "client:broadcast:disabled",
17
+ getDeviceInfo: "client:request:deviceInfo",
18
+ getHostname: "client:request:hostname",
19
+ // Presence/Network messages
20
+ connectPresence: "network:connect",
21
+ broadcastClientState: "network:broadcast",
22
+ onClientStateRequest: "network:request",
23
+ onClientStateUpdate: "network:update"
24
+ };
25
+
26
+ // src/electron/main/setupExhangeHandlers.ts
27
+ import { ipcMain } from "electron";
28
+
29
+ // src/useNetworkPresenceServer.ts
30
+ import Hyperswarm from "hyperswarm";
31
+ import b4a from "b4a";
32
+ function useNetworkPresence(onUpdate, onRequest) {
33
+ const deviceIDs = /* @__PURE__ */ new Map();
34
+ const swarm = new Hyperswarm();
35
+ swarm.on("connection", (connection) => {
36
+ const name = b4a.toString(connection.remotePublicKey, "hex");
37
+ console.log("Presence: * got a connection from:", name, "*");
38
+ connections.push(connection);
39
+ sendStateRequestMessage(connection);
40
+ connection.once("close", () => {
41
+ console.log(
42
+ `Presence: Connection closed. Removing connection ${b4a.toString(
43
+ connection.remotePublicKey,
44
+ "hex"
45
+ )}`
46
+ );
47
+ connections.splice(connections.indexOf(connection), 1);
48
+ const id = deviceIDs.get(b4a.toString(connection.remotePublicKey, "hex"));
49
+ if (id) {
50
+ broadcastStatusMessage(id, "unknown");
51
+ }
52
+ deviceIDs.delete(b4a.toString(connection.remotePublicKey, "hex"));
53
+ });
54
+ connection.on("data", (data) => {
55
+ let parsedData;
56
+ try {
57
+ parsedData = JSON.parse(data);
58
+ } catch (error) {
59
+ console.error("Error parsing data:", error);
60
+ return;
61
+ }
62
+ const header = parsedData;
63
+ console.log(
64
+ "Presence: got data for ",
65
+ connection.publicKey.toString("hex")
66
+ );
67
+ if (header.type === "update") {
68
+ const payload = parsedData;
69
+ onUpdate({ id: payload.id, state: payload.state });
70
+ deviceIDs.set(
71
+ b4a.toString(connection.remotePublicKey, "hex"),
72
+ payload.id
73
+ );
74
+ } else if (header.type === "request") {
75
+ onRequest();
76
+ }
77
+ });
78
+ connection.on("error", (error) => {
79
+ console.error(
80
+ `Presence: Connection error on connection ${b4a.toString(
81
+ connection.remotePublicKey,
82
+ "hex"
83
+ )}: ${error}`
84
+ );
85
+ });
86
+ });
87
+ const connections = [];
88
+ const connect = async (topic, id) => {
89
+ console.log("Presence: connecting to topic: ", topic);
90
+ const key = b4a.from(topic, "hex");
91
+ console.log("key: ", key);
92
+ const discovery = swarm.join(key, { client: true, server: true });
93
+ console.log("got discovery: ");
94
+ const publicKey = b4a.toString(
95
+ discovery.swarm.keyPair?.publicKey || discovery.swarm.publicKey || Buffer.alloc(32),
96
+ "hex"
97
+ );
98
+ console.log("Presence: public key is ", publicKey);
99
+ deviceIDs.set(publicKey, id);
100
+ discovery.flushed().then(() => {
101
+ console.log("Presence: joined topic:", b4a.toString(key, "hex"));
102
+ });
103
+ };
104
+ const sendStateRequestMessage = async (connection) => {
105
+ const message = {
106
+ type: "request"
107
+ };
108
+ const payload = JSON.stringify(message);
109
+ console.log(
110
+ "sending state request message to: ",
111
+ connection.publicKey.toString("hex")
112
+ );
113
+ connection.write(payload);
114
+ };
115
+ const receiveStatusMessage = async (id, state) => {
116
+ return broadcastStatusMessage(id, state);
117
+ };
118
+ const broadcastStatusMessage = (id, state) => {
119
+ console.log(`server got connection state message for ${id}: `, state);
120
+ const message = {
121
+ type: "update",
122
+ id,
123
+ state
124
+ };
125
+ console.log("active connections: ", connections.length);
126
+ const payload = JSON.stringify(message);
127
+ for (const connection of connections) {
128
+ console.log("sending message to: ", connection.publicKey.toString("hex"));
129
+ connection.write(payload);
130
+ }
131
+ onUpdate(message);
132
+ };
133
+ return {
134
+ connect,
135
+ receiveStatusMessage
136
+ };
137
+ }
138
+
139
+ // src/client/useKeyExchangeClient.ts
140
+ import DHT from "hyperdht";
141
+ import b4a3 from "b4a";
142
+
143
+ // src/server/messages.ts
144
+ import b4a2 from "b4a";
145
+ var syncSetupEventRoutes = {
146
+ onClientConnection: MESSAGES.onClientConnection,
147
+ onKeystoreRequest: MESSAGES.onKeystoreRequest,
148
+ onClientApproval: MESSAGES.onClientApproval,
149
+ onClientDenial: MESSAGES.onClientDenial,
150
+ onCompletion: MESSAGES.onCompletion,
151
+ onBroadcastDisable: MESSAGES.onBroadcastDisable,
152
+ onKeystoreRequestInvalidPIN: MESSAGES.onKeystoreRequestInvalidPIN,
153
+ onKeystoreRequestValidPIN: MESSAGES.onKeystoreRequestValidPIN
154
+ };
155
+ var requestHeaders = [
156
+ {
157
+ code: 1e3,
158
+ name: "Request PIN",
159
+ description: "The Client is asking the Server to show UI of a PIN screen for the user to enter on the Client"
160
+ },
161
+ {
162
+ code: 2e3,
163
+ name: "Request Keystore",
164
+ description: "The Client is asking the Server to show UI for the user to approve or reject the request"
165
+ }
166
+ ];
167
+ var sendRequest = async (options) => {
168
+ const index = requestHeaders.findIndex(
169
+ (response) => response.name === options.header
170
+ );
171
+ if (index !== -1) {
172
+ const header = requestHeaders[index];
173
+ const body = options.body();
174
+ const request = {
175
+ header,
176
+ body
177
+ };
178
+ const payload = JSON.stringify(request);
179
+ for (const socket of options.to) {
180
+ console.log(
181
+ `hyperswarm: sending ${header.name} to connection ${b4a2.toString(
182
+ socket.remotePublicKey,
183
+ "hex"
184
+ )}`
185
+ );
186
+ socket.write(payload);
187
+ }
188
+ } else {
189
+ console.log(`Request with name \`${options.header}\` not found`);
190
+ }
191
+ };
192
+ var responseHeaders = [
193
+ {
194
+ code: 1501,
195
+ name: "Connection Failure: Broadcast disabled",
196
+ type: "Failure"
197
+ },
198
+ { code: 2200, name: "Authentication Succeeded", type: "Success" },
199
+ { code: 2400, name: "Authentication Error: Invalid PIN", type: "Error" },
200
+ { code: 3200, name: "Transmition Succeeded: Approved", type: "Success" },
201
+ { code: 3201, name: "Transmition Succeeded: Rejected", type: "Success" },
202
+ { code: 4200, name: "Setup Succeeded", type: "Success" }
203
+ ];
204
+ var sendResponse = (options) => {
205
+ const index = responseHeaders.findIndex(
206
+ (response) => response.name === options.header
207
+ );
208
+ if (index !== -1) {
209
+ const header = responseHeaders[index];
210
+ const data = options.body();
211
+ const response = {
212
+ header,
213
+ body: data
214
+ };
215
+ const payload = JSON.stringify(response);
216
+ for (const socket of options.to) {
217
+ console.log(
218
+ `hyperswarm: sending ${header.name} to connection ${b4a2.toString(
219
+ socket.remotePublicKey,
220
+ "hex"
221
+ )}`
222
+ );
223
+ socket.write(payload);
224
+ }
225
+ } else {
226
+ console.log(`Response with name \`${options.header}\` not found`);
227
+ }
228
+ };
229
+
230
+ // src/client/useKeyExchangeClient.ts
231
+ function useKeyExchangeClient(onEvent) {
232
+ let socket;
233
+ let deviceName;
234
+ let appName;
235
+ const connect = async (options) => {
236
+ deviceName = options.name;
237
+ appName = options.app;
238
+ return new Promise((resolve) => {
239
+ console.log(`client: connecting to server on ${options.key}`);
240
+ const publicKey = b4a3.from(options.key, "hex");
241
+ const dht = new DHT();
242
+ socket = dht.connect(publicKey);
243
+ socket.once("open", () => {
244
+ const name = b4a3.toString(socket.remotePublicKey, "hex");
245
+ console.log(`client: got a connection on ${name}`);
246
+ resolve();
247
+ });
248
+ socket.on("data", (data) => {
249
+ parseResponse(data);
250
+ });
251
+ socket.on("error", (error) => {
252
+ onConnectionError(error);
253
+ });
254
+ });
255
+ };
256
+ const parseResponse = async (data) => {
257
+ console.log(`client: got data: ${data}`);
258
+ const parsedData = JSON.parse(data);
259
+ const payload = parsedData;
260
+ console.log("payload");
261
+ console.log(payload);
262
+ switch (payload.header.name) {
263
+ case "Connection Failure: Broadcast disabled":
264
+ onEvent({
265
+ route: syncSetupEventRoutes["onBroadcastDisable"],
266
+ data: {}
267
+ });
268
+ break;
269
+ case "Transmition Succeeded: Approved":
270
+ const identity = payload.body.identity;
271
+ const appId = payload.body.appId;
272
+ onEvent({
273
+ route: syncSetupEventRoutes["onClientApproval"],
274
+ data: { identity, appId }
275
+ });
276
+ break;
277
+ case "Transmition Succeeded: Rejected":
278
+ onEvent({ route: syncSetupEventRoutes["onClientDenial"], data: {} });
279
+ break;
280
+ case "Setup Succeeded":
281
+ onEvent({ route: syncSetupEventRoutes["onCompletion"], data: {} });
282
+ break;
283
+ case "Authentication Error: Invalid PIN":
284
+ onEvent({
285
+ route: syncSetupEventRoutes["onKeystoreRequestInvalidPIN"],
286
+ data: {
287
+ reason: "Invalid PIN Entered"
288
+ }
289
+ });
290
+ break;
291
+ case "Authentication Succeeded":
292
+ onEvent({
293
+ route: syncSetupEventRoutes["onKeystoreRequestValidPIN"],
294
+ data: {}
295
+ });
296
+ break;
297
+ default:
298
+ console.error(`error: response ${payload} not handled in client`);
299
+ break;
300
+ }
301
+ };
302
+ const onConnectionError = async (error) => {
303
+ console.log(`client: Connection error: ${error}`);
304
+ const route = syncSetupEventRoutes["onBroadcastDisable"];
305
+ switch (error.code) {
306
+ case "PEER_NOT_FOUND":
307
+ onEvent({
308
+ route,
309
+ data: {
310
+ title: "Peer Not Found",
311
+ description: "Another device with the specified broadcast key could not be located."
312
+ }
313
+ });
314
+ break;
315
+ default:
316
+ onEvent({
317
+ route,
318
+ data: {
319
+ title: "Client Disconnected",
320
+ description: "The connection to your other device was lost. Please ensure you have another device that is broadcasting"
321
+ }
322
+ });
323
+ break;
324
+ }
325
+ };
326
+ const requestPIN = async () => {
327
+ await sendRequest({
328
+ to: [socket],
329
+ header: "Request PIN",
330
+ body: () => {
331
+ return { deviceName, appName };
332
+ }
333
+ });
334
+ };
335
+ const requestKeystore = async (pin) => {
336
+ await sendRequest({
337
+ to: [socket],
338
+ header: "Request Keystore",
339
+ body: () => {
340
+ return {
341
+ pin
342
+ };
343
+ }
344
+ });
345
+ const route = syncSetupEventRoutes["onKeystoreRequest"];
346
+ onEvent({ route, data: {} });
347
+ };
348
+ return {
349
+ connect,
350
+ requestPIN,
351
+ requestKeystore
352
+ };
353
+ }
354
+
355
+ // src/server/useKeyExchangeServer.ts
356
+ import DHT2 from "hyperdht";
357
+ import b4a4 from "b4a";
358
+ function useKeyExchangeServer(onEvent) {
359
+ let client;
360
+ let dht;
361
+ const keyPair = DHT2.keyPair();
362
+ const getKey = () => {
363
+ return b4a4.toString(keyPair.publicKey, "hex");
364
+ };
365
+ const generateRandomPIN = () => {
366
+ return Math.floor(1e5 + Math.random() * 9e5);
367
+ };
368
+ const pin = generateRandomPIN();
369
+ const getPIN = () => {
370
+ return `${pin}`;
371
+ };
372
+ let server;
373
+ const createServer = async () => {
374
+ dht = new DHT2();
375
+ server = await dht.createServer((socket) => {
376
+ const name = b4a4.toString(socket.remotePublicKey, "hex");
377
+ console.log(`server: got a connection on \`${name}\``);
378
+ socket.on("data", (data) => {
379
+ parseRequest(data);
380
+ });
381
+ socket.on("error", (error) => {
382
+ onConnectionError(error);
383
+ });
384
+ client = socket;
385
+ });
386
+ };
387
+ const parseRequest = (data) => {
388
+ console.log(`server: got data: ${data}`);
389
+ const parsedData = JSON.parse(data);
390
+ const payload = parsedData;
391
+ console.log("payload");
392
+ console.log(payload);
393
+ switch (payload.header.name) {
394
+ case "Request PIN":
395
+ onRequestPin(payload.body);
396
+ break;
397
+ case "Request Keystore":
398
+ onRequestKeystore(payload.body);
399
+ break;
400
+ }
401
+ };
402
+ const onConnectionError = (error) => {
403
+ console.log(`server: Connection error: ${error}`);
404
+ };
405
+ const onRequestPin = (body) => {
406
+ const route = syncSetupEventRoutes["onClientConnection"];
407
+ onEvent({
408
+ route,
409
+ data: {
410
+ pin: getPIN(),
411
+ name: body.deviceName,
412
+ app: body.appName
413
+ }
414
+ });
415
+ };
416
+ const onRequestKeystore = (body) => {
417
+ const pin2 = body.pin;
418
+ if (pin2 !== getPIN()) {
419
+ sendResponse({
420
+ to: [client],
421
+ header: "Authentication Error: Invalid PIN",
422
+ body: () => {
423
+ return {};
424
+ }
425
+ });
426
+ return;
427
+ } else {
428
+ sendResponse({
429
+ to: [client],
430
+ header: "Authentication Succeeded",
431
+ body: () => {
432
+ return {};
433
+ }
434
+ });
435
+ }
436
+ const route = syncSetupEventRoutes["onKeystoreRequest"];
437
+ onEvent({
438
+ route,
439
+ data: {}
440
+ });
441
+ };
442
+ const onRequestDenied = () => {
443
+ const route = syncSetupEventRoutes["onClientDenial"];
444
+ onEvent({ route, data: {} });
445
+ };
446
+ const onSetupComplete = () => {
447
+ const route = syncSetupEventRoutes["onCompletion"];
448
+ onEvent({ route, data: {} });
449
+ };
450
+ const beginBroadcast = async () => {
451
+ await createServer();
452
+ await server.listen(keyPair);
453
+ await server.refresh();
454
+ console.log(`server: opened connection to ${getKey()}`);
455
+ };
456
+ const endBroadcast = async () => {
457
+ if (server) {
458
+ await server.close();
459
+ console.log(`server: closed connection to ${getKey()}`);
460
+ }
461
+ if (dht) {
462
+ await dht.destroy();
463
+ console.log(`server: destroyed dht`);
464
+ }
465
+ };
466
+ const approveRequest = async (identity, appId) => {
467
+ sendResponse({
468
+ to: [client],
469
+ header: "Transmition Succeeded: Approved",
470
+ body: () => {
471
+ return {
472
+ identity,
473
+ appId
474
+ };
475
+ }
476
+ });
477
+ };
478
+ const completeSetupSuccess = async () => {
479
+ console.log("sending compltion message to client");
480
+ sendResponse({
481
+ to: [client],
482
+ header: "Setup Succeeded",
483
+ body: () => {
484
+ return {};
485
+ }
486
+ });
487
+ onSetupComplete();
488
+ };
489
+ const rejectRequest = async () => {
490
+ sendResponse({
491
+ to: [client],
492
+ header: "Transmition Succeeded: Rejected",
493
+ body: () => {
494
+ return {};
495
+ }
496
+ });
497
+ onRequestDenied();
498
+ };
499
+ const broadcastDisabled = async () => {
500
+ if (client) {
501
+ sendResponse({
502
+ to: [client],
503
+ header: "Connection Failure: Broadcast disabled",
504
+ body: () => {
505
+ return {};
506
+ }
507
+ });
508
+ }
509
+ };
510
+ return {
511
+ getKey,
512
+ getPIN,
513
+ beginBroadcast,
514
+ endBroadcast,
515
+ approveRequest,
516
+ completeSetupSuccess,
517
+ rejectRequest,
518
+ broadcastDisabled
519
+ };
520
+ }
521
+
522
+ // src/CoreTransportLogic.ts
523
+ import crypto from "crypto";
524
+ import os from "os";
525
+ import si from "systeminformation";
526
+ var CoreTransportLogic = class {
527
+ syncServer;
528
+ syncClient;
529
+ presence;
530
+ deviceInfo = null;
531
+ handleEvent;
532
+ presenceConnected = false;
533
+ constructor(handleEvent = () => {
534
+ }) {
535
+ this.handleEvent = handleEvent;
536
+ this.syncServer = useKeyExchangeServer(this.handleEvent);
537
+ this.syncClient = useKeyExchangeClient(this.handleEvent);
538
+ this.presence = useNetworkPresence(
539
+ this.onStateUpdate.bind(this),
540
+ this.onStateRequest.bind(this)
541
+ );
542
+ this.initializeDeviceInfo();
543
+ }
544
+ async initializeDeviceInfo() {
545
+ this.deviceInfo = await this.getDeviceInfo();
546
+ }
547
+ onStateUpdate(response) {
548
+ console.log("received state message for:", response.id);
549
+ this.handleEvent({ route: MESSAGES.onClientStateUpdate, data: response });
550
+ }
551
+ onStateRequest() {
552
+ console.log("received state request");
553
+ this.handleEvent({ route: MESSAGES.onClientStateRequest, data: {} });
554
+ }
555
+ delay(ms) {
556
+ return new Promise((resolve) => setTimeout(resolve, ms));
557
+ }
558
+ // Sync methods
559
+ async enableBroadcast() {
560
+ console.log(`admin: enabled broadcast`);
561
+ try {
562
+ await this.syncServer.beginBroadcast();
563
+ return this.syncServer.getKey();
564
+ } catch (error) {
565
+ const code = error && typeof error === "object" && "code" in error ? error.code : "UNKNOWN";
566
+ console.error("Error on broadcast enable during topic sync setup:", code);
567
+ if (code === "ALREADY_LISTENING") {
568
+ return this.syncServer.getKey();
569
+ }
570
+ throw error;
571
+ }
572
+ }
573
+ async connect(topic, name, app) {
574
+ console.log(`client: requested connection to ${topic}`);
575
+ try {
576
+ await this.syncClient.connect({ key: topic, name, app });
577
+ await this.syncClient.requestPIN();
578
+ } catch (error) {
579
+ console.error("Error on topic connect during sync setup:", error);
580
+ throw error;
581
+ }
582
+ }
583
+ async requestKeystore(pin) {
584
+ console.log(`client: requested keystore using pin \`${pin}\``);
585
+ try {
586
+ await this.syncClient.requestKeystore(pin);
587
+ } catch (error) {
588
+ console.error("Error on keystore request during sync setup:", error);
589
+ throw error;
590
+ }
591
+ }
592
+ async approveRequest(data) {
593
+ console.log(`admin: request approved`);
594
+ try {
595
+ await this.syncServer.approveRequest(data.identity, data.appId);
596
+ await this.delay(3e3);
597
+ await this.syncServer.completeSetupSuccess();
598
+ } catch (error) {
599
+ console.error("Error on request approve during sync setup:", error);
600
+ throw error;
601
+ }
602
+ }
603
+ async denyRequest() {
604
+ console.log(`admin: request denied`);
605
+ try {
606
+ await this.syncServer.rejectRequest();
607
+ } catch (error) {
608
+ console.error("Error on request deny during sync setup:", error);
609
+ throw error;
610
+ }
611
+ }
612
+ async disableBroadcast() {
613
+ try {
614
+ await this.syncServer.endBroadcast();
615
+ await this.syncServer.broadcastDisabled();
616
+ } catch (error) {
617
+ console.error("Error on broadcast disable during sync setup:", error);
618
+ throw error;
619
+ }
620
+ }
621
+ // Device methods
622
+ async getDeviceInfo() {
623
+ if (this.deviceInfo) {
624
+ return this.deviceInfo;
625
+ }
626
+ const hostname = os.hostname();
627
+ const osInfo = await si.osInfo();
628
+ const uuid = await si.uuid();
629
+ const serial = osInfo.serial;
630
+ const distro = osInfo.distro;
631
+ const arch = osInfo.arch;
632
+ const hardwareUUID = uuid.hardware;
633
+ const key = serial + distro + arch + hardwareUUID;
634
+ const hash = crypto.createHash("sha256").update(key).digest("hex");
635
+ return { id: hash, name: hostname };
636
+ }
637
+ async getHostname() {
638
+ return os.hostname();
639
+ }
640
+ // Network methods
641
+ async connectPresence(topic) {
642
+ if (this.presenceConnected) {
643
+ console.log("Presence already connected, skipping");
644
+ return;
645
+ }
646
+ const deviceInfo = await this.getDeviceInfo();
647
+ const topicHash = crypto.createHash("sha256").update(topic).digest("hex");
648
+ console.log(`Connecting presence network to topic: ${topicHash}`);
649
+ await this.presence.connect(topicHash, deviceInfo.id);
650
+ this.presenceConnected = true;
651
+ }
652
+ broadcastClientState(id, state) {
653
+ this.presence.receiveStatusMessage(id, state);
654
+ }
655
+ };
656
+
657
+ // src/electron/main/keyTransportMain.ts
658
+ import { BrowserWindow } from "electron";
659
+ var KeyTransportMain = class {
660
+ core;
661
+ peers = /* @__PURE__ */ new Map();
662
+ constructor() {
663
+ this.core = new CoreTransportLogic(this.handleEvent.bind(this));
664
+ }
665
+ /**
666
+ * Electron-specific event routing via IPC
667
+ */
668
+ handleEvent = (options) => {
669
+ console.log(
670
+ `received event with route: \`${options.route}\` data:`,
671
+ options.data
672
+ );
673
+ const allWindows = BrowserWindow.getAllWindows();
674
+ allWindows.forEach((window) => {
675
+ window.webContents.send(options.route, options.data);
676
+ });
677
+ };
678
+ // Sync namespace - delegate to core for logic, no-ops for callbacks
679
+ enableBroadcast = () => this.core.enableBroadcast();
680
+ connect = (topic, name, app) => this.core.connect(topic, name, app);
681
+ onClientConnection = async (_callback) => {
682
+ };
683
+ requestKeystore = (pin) => this.core.requestKeystore(pin);
684
+ onKeystoreRequestInvalidPIN = async (_callback) => {
685
+ };
686
+ onKeystoreRequestValidPIN = async (_callback) => {
687
+ };
688
+ onKeystoreRequest = async (_callback) => {
689
+ };
690
+ approveRequest = (data) => this.core.approveRequest(data);
691
+ onClientApproval = async (_callback) => {
692
+ };
693
+ denyRequest = () => this.core.denyRequest();
694
+ onClientDenial = async (_callback) => {
695
+ };
696
+ onCompletion = async (_callback) => {
697
+ };
698
+ disableBroadcast = () => this.core.disableBroadcast();
699
+ onBroadcastDisable = async (_callback) => {
700
+ };
701
+ getDeviceInfo = () => this.core.getDeviceInfo();
702
+ getHostname = () => this.core.getHostname();
703
+ connectPresence = async (topic) => {
704
+ return this.core.connectPresence(topic);
705
+ };
706
+ broadcastClientState = async (id, state) => {
707
+ this.peers.set(id, state);
708
+ this.core.broadcastClientState(id, state);
709
+ };
710
+ onClientStateRequest = async (_callback) => {
711
+ };
712
+ onClientStateUpdate = async (_callback) => {
713
+ };
714
+ getPeerState = (id) => {
715
+ return this.peers.get(id);
716
+ };
717
+ getAllPeers = () => {
718
+ return this.peers;
719
+ };
720
+ };
721
+
722
+ // src/electron/main/setupExhangeHandlers.ts
723
+ var setupKeyExchangeHandlers = () => {
724
+ const transport = new KeyTransportMain();
725
+ ipcMain.handle(MESSAGES.enableBroadcast, async () => {
726
+ return transport.enableBroadcast();
727
+ });
728
+ ipcMain.handle(
729
+ MESSAGES.connect,
730
+ async (_event, topic, name, app) => {
731
+ return transport.connect(topic, name, app);
732
+ }
733
+ );
734
+ ipcMain.handle(MESSAGES.requestKeystore, async (_event, pin) => {
735
+ return transport.requestKeystore(pin);
736
+ });
737
+ ipcMain.handle(
738
+ MESSAGES.approveRequest,
739
+ async (_event, data) => {
740
+ return transport.approveRequest(data);
741
+ }
742
+ );
743
+ ipcMain.handle(MESSAGES.denyRequest, async () => {
744
+ return transport.denyRequest();
745
+ });
746
+ ipcMain.handle(MESSAGES.disableBroadcast, async () => {
747
+ return transport.disableBroadcast();
748
+ });
749
+ ipcMain.handle(MESSAGES.getDeviceInfo, async () => {
750
+ return transport.getDeviceInfo();
751
+ });
752
+ ipcMain.handle(MESSAGES.getHostname, async () => {
753
+ return transport.getHostname();
754
+ });
755
+ ipcMain.handle(MESSAGES.connectPresence, async (_event, topic) => {
756
+ return transport.connectPresence(topic);
757
+ });
758
+ ipcMain.handle(
759
+ MESSAGES.broadcastClientState,
760
+ async (_event, id, state) => {
761
+ return transport.broadcastClientState(id, state);
762
+ }
763
+ );
764
+ };
765
+ export {
766
+ CoreTransportLogic,
767
+ setupKeyExchangeHandlers
768
+ };