@decentnetwork/peer 0.1.84 → 0.1.86
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/dist/compat/tcp-relay-pool.d.ts +11 -0
- package/dist/compat/tcp-relay-pool.js +22 -0
- package/dist/compat/tcp-relay.d.ts +13 -0
- package/dist/compat/tcp-relay.js +23 -0
- package/dist/compat/tox-onion.d.ts +27 -0
- package/dist/compat/tox-onion.js +38 -0
- package/dist/peer.d.ts +5 -0
- package/dist/peer.js +57 -1
- package/package.json +2 -1
|
@@ -17,6 +17,8 @@ export type TcpRelayPoolEvents = {
|
|
|
17
17
|
peerData: (friendPublicKey: Uint8Array, payload: Uint8Array) => void;
|
|
18
18
|
/** Inbound OOB_RECV (used for friend requests via TCP). */
|
|
19
19
|
oob: (senderPublicKey: Uint8Array, payload: Uint8Array) => void;
|
|
20
|
+
/** Inbound onion response routed back through a relay (announce / onion data). */
|
|
21
|
+
onionResponse: (packet: Uint8Array) => void;
|
|
20
22
|
/** Number of currently-connected relays changed (for diagnostics). */
|
|
21
23
|
status: (connected: number, total: number) => void;
|
|
22
24
|
};
|
|
@@ -67,6 +69,15 @@ export declare class TcpRelayPool extends EventEmitter {
|
|
|
67
69
|
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array, droppable?: boolean): number;
|
|
68
70
|
/** Diagnostics. */
|
|
69
71
|
connectedCount(): number;
|
|
72
|
+
/**
|
|
73
|
+
* Send an onion request (createOnionRequest0Tcp packet) through up to `fanout`
|
|
74
|
+
* connected relays. Each relay forwards it to node B over UDP and routes the
|
|
75
|
+
* onion response back over TCP (surfaced via the pool's "onionResponse"
|
|
76
|
+
* event). Returns the number of relays the request was handed to (0 = none
|
|
77
|
+
* connected). Fanning out across a few relays covers the case where one relay
|
|
78
|
+
* can't reach node B.
|
|
79
|
+
*/
|
|
80
|
+
sendOnionRequest(packet: Uint8Array, fanout?: number): number;
|
|
70
81
|
/**
|
|
71
82
|
* Snapshot of currently-connected relays for inclusion in DHT-PK
|
|
72
83
|
* announce extras. Mirrors toxcore's `tcp_copy_connected_relays`.
|
|
@@ -211,6 +211,25 @@ export class TcpRelayPool extends EventEmitter {
|
|
|
211
211
|
connectedCount() {
|
|
212
212
|
return this.#relays.filter((r) => r.client?.state() === "connected").length;
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Send an onion request (createOnionRequest0Tcp packet) through up to `fanout`
|
|
216
|
+
* connected relays. Each relay forwards it to node B over UDP and routes the
|
|
217
|
+
* onion response back over TCP (surfaced via the pool's "onionResponse"
|
|
218
|
+
* event). Returns the number of relays the request was handed to (0 = none
|
|
219
|
+
* connected). Fanning out across a few relays covers the case where one relay
|
|
220
|
+
* can't reach node B.
|
|
221
|
+
*/
|
|
222
|
+
sendOnionRequest(packet, fanout = 2) {
|
|
223
|
+
let sent = 0;
|
|
224
|
+
for (const r of this.#relays) {
|
|
225
|
+
if (sent >= fanout)
|
|
226
|
+
break;
|
|
227
|
+
if (r.client?.state() === "connected" && r.client.sendOnionRequest(packet)) {
|
|
228
|
+
sent += 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return sent;
|
|
232
|
+
}
|
|
214
233
|
/**
|
|
215
234
|
* Snapshot of currently-connected relays for inclusion in DHT-PK
|
|
216
235
|
* announce extras. Mirrors toxcore's `tcp_copy_connected_relays`.
|
|
@@ -304,6 +323,9 @@ export class TcpRelayPool extends EventEmitter {
|
|
|
304
323
|
client.on("oob", (senderKey, payload) => {
|
|
305
324
|
this.emit("oob", new Uint8Array(senderKey), payload);
|
|
306
325
|
});
|
|
326
|
+
client.on("onionResponse", (packet) => {
|
|
327
|
+
this.emit("onionResponse", new Uint8Array(packet));
|
|
328
|
+
});
|
|
307
329
|
try {
|
|
308
330
|
await client.connect(10_000);
|
|
309
331
|
}
|
|
@@ -54,6 +54,10 @@ export type TcpRelayEvents = {
|
|
|
54
54
|
oob: (senderPublicKey: Uint8Array, payload: Uint8Array) => void;
|
|
55
55
|
/** Pong (response to our ping). */
|
|
56
56
|
pong: (pingId: bigint) => void;
|
|
57
|
+
/** Inbound TCP_PACKET_ONION_RESPONSE — the raw onion packet (announce or
|
|
58
|
+
* onion-data response), routed back through this relay. Treat exactly like a
|
|
59
|
+
* UDP onion datagram. */
|
|
60
|
+
onionResponse: (packet: Uint8Array) => void;
|
|
57
61
|
};
|
|
58
62
|
export declare class TcpRelayClient extends EventEmitter {
|
|
59
63
|
#private;
|
|
@@ -85,6 +89,15 @@ export declare class TcpRelayClient extends EventEmitter {
|
|
|
85
89
|
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array, droppable?: boolean): boolean;
|
|
86
90
|
/** Send a PING; relay echoes it as PONG. ping_id is opaque 8 bytes. */
|
|
87
91
|
sendPing(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Send an onion request THROUGH this relay (toxcore TCP_client.c::
|
|
94
|
+
* send_onion_request). `packet` is a create_onion_packet_tcp payload
|
|
95
|
+
* (createOnionRequest0Tcp) — the relay acts as onion node A, forwards it to
|
|
96
|
+
* node B over UDP, and routes the onion response back to us over this TCP
|
|
97
|
+
* connection as TCP_PACKET_ONION_RESPONSE (surfaced via the "onionResponse"
|
|
98
|
+
* event). This is the NAT-resilient announce / friend-lookup path.
|
|
99
|
+
*/
|
|
100
|
+
sendOnionRequest(packet: Uint8Array): boolean;
|
|
88
101
|
/** Send DATA payload to the friend at `connectionId`. */
|
|
89
102
|
sendData(connectionId: number, payload: Uint8Array, droppable?: boolean): boolean;
|
|
90
103
|
/** Send OOB_SEND (used for delivering friend requests via TCP relay). */
|
package/dist/compat/tcp-relay.js
CHANGED
|
@@ -379,6 +379,16 @@ export class TcpRelayClient extends EventEmitter {
|
|
|
379
379
|
this.emit("oob", sender, payload);
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
|
+
case TCP_PACKET_ONION_RESPONSE: {
|
|
383
|
+
// The relay forwarded an onion response addressed to us (announce
|
|
384
|
+
// response / onion data response). `body` is the raw onion packet —
|
|
385
|
+
// identical to what would have arrived over UDP — so the Peer feeds it
|
|
386
|
+
// through the same NET_PACKET_ONION_* handling.
|
|
387
|
+
if (body.length === 0)
|
|
388
|
+
return;
|
|
389
|
+
this.emit("onionResponse", new Uint8Array(body));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
382
392
|
default: {
|
|
383
393
|
if (type >= 16) {
|
|
384
394
|
// DATA forwarded by relay from a connected peer. Resolve
|
|
@@ -445,6 +455,19 @@ export class TcpRelayClient extends EventEmitter {
|
|
|
445
455
|
const pingId = randomBytes(8);
|
|
446
456
|
return this.#sendFrame(concatBytes([Uint8Array.of(TCP_PACKET_PING), pingId]));
|
|
447
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* Send an onion request THROUGH this relay (toxcore TCP_client.c::
|
|
460
|
+
* send_onion_request). `packet` is a create_onion_packet_tcp payload
|
|
461
|
+
* (createOnionRequest0Tcp) — the relay acts as onion node A, forwards it to
|
|
462
|
+
* node B over UDP, and routes the onion response back to us over this TCP
|
|
463
|
+
* connection as TCP_PACKET_ONION_RESPONSE (surfaced via the "onionResponse"
|
|
464
|
+
* event). This is the NAT-resilient announce / friend-lookup path.
|
|
465
|
+
*/
|
|
466
|
+
sendOnionRequest(packet) {
|
|
467
|
+
if (packet.length === 0)
|
|
468
|
+
return false;
|
|
469
|
+
return this.#sendFrame(concatBytes([Uint8Array.of(TCP_PACKET_ONION_REQUEST), packet]));
|
|
470
|
+
}
|
|
448
471
|
/** Send DATA payload to the friend at `connectionId`. */
|
|
449
472
|
sendData(connectionId, payload, droppable = false) {
|
|
450
473
|
if (connectionId < 16 || connectionId > 0xff)
|
|
@@ -49,6 +49,33 @@ export declare function createOnionRequest0(opts: {
|
|
|
49
49
|
nodeDPort: number;
|
|
50
50
|
payloadForNodeD: Uint8Array;
|
|
51
51
|
}): Uint8Array;
|
|
52
|
+
/**
|
|
53
|
+
* Build an onion request to send OVER A TCP RELAY (toxcore
|
|
54
|
+
* onion.c::create_onion_packet_tcp). When the onion path's first hop is a TCP
|
|
55
|
+
* relay we're already connected to, the relay itself acts as node A — so the
|
|
56
|
+
* packet OMITS node A's layer and is sent as the payload of TCP_PACKET_ONION_
|
|
57
|
+
* REQUEST. The relay forwards it to node B over UDP and routes the response
|
|
58
|
+
* back to us over the same TCP connection (TCP_PACKET_ONION_RESPONSE).
|
|
59
|
+
*
|
|
60
|
+
* This is the NAT-resilient discovery path native Beagle uses as primary:
|
|
61
|
+
* self-announce and friend-route lookups survive a NAT that drops the UDP
|
|
62
|
+
* onion return path, because the TCP relay handles the round-trip.
|
|
63
|
+
*
|
|
64
|
+
* Layout (== create_onion_packet_tcp): the UDP builder's inner `bPart` with a
|
|
65
|
+
* bare nonce prepended (no NET_PACKET_ONION_REQUEST_0 type byte, no node-A box):
|
|
66
|
+
* [nonce 24][ipport(B)][tempPubB 32][box_B([ipport(C)][tempPubC 32][box_C([ipport(D)][payload])])]
|
|
67
|
+
*/
|
|
68
|
+
export declare function createOnionRequest0Tcp(opts: {
|
|
69
|
+
nodeBHost: string;
|
|
70
|
+
nodeBPort: number;
|
|
71
|
+
nodeBPublicKey: Uint8Array;
|
|
72
|
+
nodeCHost: string;
|
|
73
|
+
nodeCPort: number;
|
|
74
|
+
nodeCPublicKey: Uint8Array;
|
|
75
|
+
nodeDHost: string;
|
|
76
|
+
nodeDPort: number;
|
|
77
|
+
payloadForNodeD: Uint8Array;
|
|
78
|
+
}): Uint8Array;
|
|
52
79
|
export declare function openOnionDataResponse(packet: Uint8Array, opts: {
|
|
53
80
|
dataSecretKey: Uint8Array;
|
|
54
81
|
}): {
|
package/dist/compat/tox-onion.js
CHANGED
|
@@ -112,6 +112,44 @@ export function createOnionRequest0(opts) {
|
|
|
112
112
|
aEncrypted
|
|
113
113
|
]);
|
|
114
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Build an onion request to send OVER A TCP RELAY (toxcore
|
|
117
|
+
* onion.c::create_onion_packet_tcp). When the onion path's first hop is a TCP
|
|
118
|
+
* relay we're already connected to, the relay itself acts as node A — so the
|
|
119
|
+
* packet OMITS node A's layer and is sent as the payload of TCP_PACKET_ONION_
|
|
120
|
+
* REQUEST. The relay forwards it to node B over UDP and routes the response
|
|
121
|
+
* back to us over the same TCP connection (TCP_PACKET_ONION_RESPONSE).
|
|
122
|
+
*
|
|
123
|
+
* This is the NAT-resilient discovery path native Beagle uses as primary:
|
|
124
|
+
* self-announce and friend-route lookups survive a NAT that drops the UDP
|
|
125
|
+
* onion return path, because the TCP relay handles the round-trip.
|
|
126
|
+
*
|
|
127
|
+
* Layout (== create_onion_packet_tcp): the UDP builder's inner `bPart` with a
|
|
128
|
+
* bare nonce prepended (no NET_PACKET_ONION_REQUEST_0 type byte, no node-A box):
|
|
129
|
+
* [nonce 24][ipport(B)][tempPubB 32][box_B([ipport(C)][tempPubC 32][box_C([ipport(D)][payload])])]
|
|
130
|
+
*/
|
|
131
|
+
export function createOnionRequest0Tcp(opts) {
|
|
132
|
+
ensureLen(opts.nodeBPublicKey, KEY_SIZE, "node B public key");
|
|
133
|
+
ensureLen(opts.nodeCPublicKey, KEY_SIZE, "node C public key");
|
|
134
|
+
const nonce = randomBytes(NONCE_SIZE);
|
|
135
|
+
const dPart = concatBytes([packIpPort(opts.nodeDHost, opts.nodeDPort), opts.payloadForNodeD]);
|
|
136
|
+
const key2 = nacl.box.keyPair();
|
|
137
|
+
const cEncrypted = nacl.box(dPart, nonce, opts.nodeCPublicKey, key2.secretKey);
|
|
138
|
+
const cPart = concatBytes([
|
|
139
|
+
packIpPort(opts.nodeCHost, opts.nodeCPort),
|
|
140
|
+
key2.publicKey,
|
|
141
|
+
cEncrypted
|
|
142
|
+
]);
|
|
143
|
+
const key1 = nacl.box.keyPair();
|
|
144
|
+
const bEncrypted = nacl.box(cPart, nonce, opts.nodeBPublicKey, key1.secretKey);
|
|
145
|
+
// No node-A box: the relay is node A. Just [nonce][ipport(B)][tempPubB][box_B].
|
|
146
|
+
return concatBytes([
|
|
147
|
+
nonce,
|
|
148
|
+
packIpPort(opts.nodeBHost, opts.nodeBPort),
|
|
149
|
+
key1.publicKey,
|
|
150
|
+
bEncrypted
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
115
153
|
export function openOnionDataResponse(packet, opts) {
|
|
116
154
|
if (packet.length < 1 + NONCE_SIZE + KEY_SIZE + 16) {
|
|
117
155
|
return undefined;
|
package/dist/peer.d.ts
CHANGED
|
@@ -45,6 +45,11 @@ export declare class Peer {
|
|
|
45
45
|
selfAnnounceStoredOn: number;
|
|
46
46
|
udpLocalPort: number | null;
|
|
47
47
|
tcpRelayConnected: number;
|
|
48
|
+
/** TCP-relay onion diagnostics: requests handed to relays / responses
|
|
49
|
+
* routed back. If sent>0 but recv=0, relays aren't returning onion
|
|
50
|
+
* responses (relay doesn't forward, or wire mismatch). */
|
|
51
|
+
tcpOnionSent: number;
|
|
52
|
+
tcpOnionRecv: number;
|
|
48
53
|
/** The specific relay endpoints this peer has live connections to.
|
|
49
54
|
* Lets us compare two peers' relay sets — if there's NO overlap,
|
|
50
55
|
* net_crypto handshake packets between them have nowhere to route
|
package/dist/peer.js
CHANGED
|
@@ -6,7 +6,7 @@ import nacl from "tweetnacl";
|
|
|
6
6
|
import { carrierAddressFromPublicKey, carrierIdFromAddress, carrierIdFromPublicKey, parseCarrierAddress } from "./compat/address.js";
|
|
7
7
|
import { LegacyBootstrapClient } from "./compat/bootstrap.js";
|
|
8
8
|
import { PACKET_TYPE_MESSAGE, PACKET_TYPE_FRIEND_REQUEST, PACKET_TYPE_USERINFO, PACKET_TYPE_BULKMSG, PACKET_TYPE_INVITE_REQUEST, PACKET_TYPE_INVITE_RESPONSE, CARRIER_MAX_APP_MESSAGE_LEN, CARRIER_MAX_APP_BULKMSG_LEN, INVITE_DATA_UNIT, CARRIER_MAX_INVITE_DATA_LEN, CARRIER_EXTENSION_NAME, encodeUserInfoPacket, decodeCarrierPacket, encodeFriendMessagePacket, encodeFriendRequestPacket, encodeBulkMsgPacket, encodeInviteReqPacket } from "./compat/packet.js";
|
|
9
|
-
import { NET_PACKET_ONION_ANNOUNCE_RESPONSE, NET_PACKET_ONION_DATA_RESPONSE, ONION_FRIEND_REQUEST_ID, createOnionAnnounceRequest, createOnionDataPacket, createOnionDataRequest, createOnionRequest0, openOnionAnnounceResponse, openOnionDataPacket, openOnionDataResponse } from "./compat/tox-onion.js";
|
|
9
|
+
import { NET_PACKET_ONION_ANNOUNCE_RESPONSE, NET_PACKET_ONION_DATA_RESPONSE, ONION_FRIEND_REQUEST_ID, createOnionAnnounceRequest, createOnionDataPacket, createOnionDataRequest, createOnionRequest0, createOnionRequest0Tcp, openOnionAnnounceResponse, openOnionDataPacket, openOnionDataResponse } from "./compat/tox-onion.js";
|
|
10
10
|
import { CRYPTO_PACKET_DHTPK, CRYPTO_PACKET_FRIEND_REQ, NET_PACKET_CRYPTO, createToxDhtCryptoRequest, openToxDhtCryptoRequest } from "./compat/tox-dht-crypto.js";
|
|
11
11
|
import { NET_PACKET_PING_REQUEST, NET_PACKET_PING_RESPONSE, NET_PACKET_GET_NODES, NET_PACKET_SEND_NODES, encodeDhtRpc, decodeDhtRpc, buildPingPlain, parsePingPlain, buildGetNodesPlain, parseGetNodesPlain, buildSendNodesPlain, parseSendNodesNodeBytes, packUdpNodeV4 } from "./compat/dht-rpc.js";
|
|
12
12
|
import { FileTransferManager, PACKET_ID_FILE_SENDREQUEST, PACKET_ID_FILE_CONTROL, PACKET_ID_FILE_DATA, PACKET_ID_FILE_FEC } from "./compat/filetransfer.js";
|
|
@@ -280,6 +280,12 @@ export class Peer {
|
|
|
280
280
|
// 25s forever for stale persisted entries.
|
|
281
281
|
#dhtPkConsecutiveFailures = new Map();
|
|
282
282
|
#lastSelfAnnounceStoredCount = -1;
|
|
283
|
+
// Diagnostics for the TCP-relay onion path (announce/discovery over TCP).
|
|
284
|
+
// Surfaced in dhtHealth so `agentnet diag` shows whether it's active without
|
|
285
|
+
// needing verbose logs: sent = onion requests handed to relays, recv = onion
|
|
286
|
+
// responses routed back over TCP.
|
|
287
|
+
#diagTcpOnionSent = 0;
|
|
288
|
+
#diagTcpOnionRecv = 0;
|
|
283
289
|
// Per-friend last-logged route count from #discoverFriendRoutes so we
|
|
284
290
|
// only emit a "routes=N for friend=…" debug line when it changes.
|
|
285
291
|
#lastLoggedRoutesForFriend = new Map();
|
|
@@ -511,6 +517,24 @@ export class Peer {
|
|
|
511
517
|
this.#tcpRelays?.requestRoute(senderKey);
|
|
512
518
|
this.#handleTcpDatagram(senderKey, payload);
|
|
513
519
|
});
|
|
520
|
+
// Onion responses routed back through a TCP relay (announce responses,
|
|
521
|
+
// onion data responses). This is the NAT-resilient discovery path: when
|
|
522
|
+
// UDP onion is blocked, the relay does the round-trip. Inject the raw
|
|
523
|
+
// onion packet into the SAME "datagram" stream the UDP transport feeds,
|
|
524
|
+
// so #onDatagram AND the ad-hoc announce/route waiters
|
|
525
|
+
// (#waitForAnnounceResponse) process it identically. Synthetic remote so
|
|
526
|
+
// no real UDP endpoint is adopted from it.
|
|
527
|
+
this.#tcpRelays.on("onionResponse", (packet) => {
|
|
528
|
+
if (packet.length === 0)
|
|
529
|
+
return;
|
|
530
|
+
this.#diagTcpOnionRecv += 1;
|
|
531
|
+
this.#debugVerboseLog(`tcp onion response received (${packet.length} bytes, type=${packet[0]})`);
|
|
532
|
+
this.#udp.emit("datagram", {
|
|
533
|
+
data: Buffer.from(packet),
|
|
534
|
+
remote: { address: "tcp-relay", port: 0 },
|
|
535
|
+
viaRelay: true
|
|
536
|
+
});
|
|
537
|
+
});
|
|
514
538
|
// Don't await — pool reconnects on its own and we want start() to
|
|
515
539
|
// return promptly so the demo can call joinNetwork() in parallel.
|
|
516
540
|
void this.#tcpRelays.start().catch((error) => {
|
|
@@ -670,6 +694,8 @@ export class Peer {
|
|
|
670
694
|
selfAnnounceStoredOn: this.#lastSelfAnnounceStoredCount,
|
|
671
695
|
udpLocalPort: this.#udp?.localPort() ?? null,
|
|
672
696
|
tcpRelayConnected: relays.length,
|
|
697
|
+
tcpOnionSent: this.#diagTcpOnionSent,
|
|
698
|
+
tcpOnionRecv: this.#diagTcpOnionRecv,
|
|
673
699
|
tcpRelayEndpoints: relays.map((r) => ({ host: r.host, port: r.port })),
|
|
674
700
|
};
|
|
675
701
|
}
|
|
@@ -5243,6 +5269,36 @@ export class Peer {
|
|
|
5243
5269
|
payloadForNodeD
|
|
5244
5270
|
});
|
|
5245
5271
|
await this.#sendPacket(packet, path.nodeA.node);
|
|
5272
|
+
// NAT-resilient duplicate: ALSO send this onion request over connected TCP
|
|
5273
|
+
// relays (toxcore create_onion_packet_tcp). The relay acts as node A and
|
|
5274
|
+
// forwards to node B over UDP, routing the response back over TCP — so
|
|
5275
|
+
// self-announce AND friend-route discovery survive a NAT that drops the UDP
|
|
5276
|
+
// onion return path (the residential-ISP case where selfAnnounceStoredOn
|
|
5277
|
+
// stays 0 and native peers can never find us). Same sendBack as the UDP
|
|
5278
|
+
// attempt, so whichever transport answers first resolves the waiter.
|
|
5279
|
+
if (this.#tcpRelays && this.#tcpRelays.connectedCount() > 0) {
|
|
5280
|
+
try {
|
|
5281
|
+
const tcpPacket = createOnionRequest0Tcp({
|
|
5282
|
+
nodeBHost: path.nodeB.host,
|
|
5283
|
+
nodeBPort: path.nodeB.port,
|
|
5284
|
+
nodeBPublicKey: path.nodeB.publicKey,
|
|
5285
|
+
nodeCHost: path.nodeC.host,
|
|
5286
|
+
nodeCPort: path.nodeC.port,
|
|
5287
|
+
nodeCPublicKey: path.nodeC.publicKey,
|
|
5288
|
+
nodeDHost: nodeD.host,
|
|
5289
|
+
nodeDPort: nodeD.port,
|
|
5290
|
+
payloadForNodeD
|
|
5291
|
+
});
|
|
5292
|
+
const sent = this.#tcpRelays.sendOnionRequest(tcpPacket);
|
|
5293
|
+
if (sent > 0) {
|
|
5294
|
+
this.#diagTcpOnionSent += 1;
|
|
5295
|
+
this.#debugVerboseLog(`tcp onion request sent via ${sent} relay(s) to ${nodeD.host}:${nodeD.port} (B=${path.nodeB.host} C=${path.nodeC.host})`);
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
catch {
|
|
5299
|
+
/* malformed path node key — the UDP attempt above still stands */
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5246
5302
|
return path;
|
|
5247
5303
|
}
|
|
5248
5304
|
#selectOnionPath(nodeD, pathOffset = 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.86",
|
|
4
4
|
"description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"demo:tox-dht-crypto": "pnpm run build && node scripts/tox-dht-crypto-demo.mjs",
|
|
69
69
|
"test:compat": "pnpm run build && node scripts/compat-selftest.mjs",
|
|
70
70
|
"test:invite": "pnpm run build && node scripts/invite-selftest.mjs",
|
|
71
|
+
"test:tcp-onion": "pnpm run build && node scripts/tcp-onion-selftest.mjs",
|
|
71
72
|
"smoke:join": "node scripts/smoke-join.mjs",
|
|
72
73
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
73
74
|
"test:express": "pnpm run build && node scripts/express-scheme-selftest.mjs"
|