@decentnetwork/peer 0.1.26 → 0.1.28

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.
Files changed (2) hide show
  1. package/dist/peer.js +40 -9
  2. package/package.json +1 -1
package/dist/peer.js CHANGED
@@ -551,7 +551,25 @@ export class Peer {
551
551
  if (this.#selfAnnouncePromise) {
552
552
  await this.#selfAnnouncePromise.catch(() => { });
553
553
  }
554
- await this.#announceSelfBestEffort(false, Date.now() + 4000);
554
+ // An onion friend-request only has a return path once OUR OWN announce
555
+ // has actually STORED on the DHT. The old code fired a single 4s
556
+ // best-effort announce and pushed on regardless — so a request sent
557
+ // before the announce propagated (right after join, DHT not yet settled)
558
+ // had nowhere for the reply to come back and silently failed. That, not
559
+ // Carrier, is why client→exit friend-requests never landed. Match the C
560
+ // SDK: keep announcing until at least one node stores us (up to ~8s)
561
+ // before sending. If it genuinely never stores, we fall through to the
562
+ // express fallback below — but normally it stores within a couple of
563
+ // seconds and the plain onion friend-request just works.
564
+ const announceDeadline = Date.now() + 8000;
565
+ while (this.#lastSelfAnnounceStoredCount === 0 &&
566
+ Date.now() < announceDeadline) {
567
+ await this.#announceSelfBestEffort(true, Math.min(Date.now() + 3000, announceDeadline));
568
+ if (this.#lastSelfAnnounceStoredCount > 0)
569
+ break;
570
+ await sleep(500);
571
+ }
572
+ this.#debugLog(`friend-request: announce stored on ${this.#lastSelfAnnounceStoredCount} node(s) before send`);
555
573
  const appPayload = encodeFriendRequestPacket({
556
574
  name: PEER_NICKNAME,
557
575
  descr: PEER_STATUS_MESSAGE || "decent peer",
@@ -611,20 +629,33 @@ export class Peer {
611
629
  errors.push(`${route.node.host}:${route.node.port} ${error.message}`);
612
630
  }
613
631
  }
614
- if (sent === 0) {
632
+ // Record locally so the connection loop keeps retrying, then ALWAYS
633
+ // queue via express — even when every onion send failed. Onion delivery
634
+ // is unreliable (broken DHT onion-announce), and the old code threw on
635
+ // `sent === 0` BEFORE this express fallback ran, so a friend-request to
636
+ // a peer with stale-but-dead onion routes was silently dropped: the node
637
+ // "sent" it, nothing reached the relay, the recipient never friended
638
+ // back, and the session could never bridge. That stranded 2nd/3rd exits.
639
+ this.#recordOutgoingFriendRequest(friendId, pubkey, friendAddress.nospam, hello);
640
+ let expressOk = false;
641
+ if (this.#express?.hasNodes()) {
642
+ try {
643
+ await this.#express.sendOfflineFriendRequest(pubkey, appPayload);
644
+ expressOk = true;
645
+ }
646
+ catch (error) {
647
+ this.#debugLog(`offline friend request dispatch failed: ${error.message}`);
648
+ }
649
+ }
650
+ // Only a true failure if BOTH transports got nothing out.
651
+ if (sent === 0 && !expressOk) {
615
652
  throw new Error(`friend request dispatch failed: ${errors.join("; ")}`);
616
653
  }
617
654
  this.#lastFriendRequestDispatch = {
618
- transport: "onion",
655
+ transport: sent > 0 ? "onion" : "express",
619
656
  routes: routes.length,
620
657
  targets: sent
621
658
  };
622
- this.#recordOutgoingFriendRequest(friendId, pubkey, friendAddress.nospam, hello);
623
- if (this.#express?.hasNodes()) {
624
- void this.#express.sendOfflineFriendRequest(pubkey, appPayload).catch((error) => {
625
- this.#debugLog(`offline friend request dispatch failed: ${error.message}`);
626
- });
627
- }
628
659
  }
629
660
  finally {
630
661
  resumeSelfAnnounce();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
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",