Commit Graph
8 Commits
Author SHA1 Message Date
f9032cf2b9 Add mesh diagnostics: /ping, /trace, and topology map (#1377)
* Add mesh diagnostics: /ping, /trace, and topology map

- New protocol types ping=0x26 / pong=0x27 (9-byte payload: 8-byte nonce
  + origin TTL) with per-peer inbound rate limiting (5 per 10s)
- /ping @name reports RTT and hop count, 10s timeout
- /trace @name prints the estimated path from gossiped directNeighbors
- Topology map sheet (circular Canvas layout) reachable from App Info
- Ping/pong ride the deterministic directed-relay path like DMs
- Tests: payload round-trip, hop-count math, command output, edge
  normalization, layout

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix CI media-wipe race, per-link ping rate limiting, and /ping output routing

Three fixes for PR #1377 review:

1. CI flake (sendImage_privateChatProcessesAndTransfersImage): the
   panicClearAllData / clearCurrentPublicTimeline detached utility-priority
   tasks delete the real ~/Library/Application Support/files tree, which the
   test process shares. The wipe fires at a nondeterministic time and raced
   the sendImage test's JPEG in files/images/outgoing (write then re-read),
   so prepareImagePacket threw and the test timed out. Both wipes are now
   skipped under tests (existing TestEnvironment.isRunningTests pattern);
   this also stops test runs from deleting the developer's real media.

2. Codex P1: ping packets are unsigned, so keying the pong rate limiter on
   packet.senderID let one connected peer rotate forged sender IDs to bypass
   the 5-per-10s budget. The limiter now keys on the ingress link (the
   directly connected peer that delivered the packet); the pong still goes
   to the claimed sender. Regression test proves rotating senders over one
   link exhaust one budget (fails 10 vs 5 pongs on the old code).

3. Codex P2: /ping output arrived up to 10s later and was routed from
   selectedPrivateChatPeer at callback time, misrouting the result after a
   chat switch. The origin conversation is now captured when the command is
   issued (CommandOutputDestination) and deferred output is routed there:
   a DM result lands in the origin chat's history even if deselected, and a
   mesh-timeline result pins to #mesh instead of the active channel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* App Info: move NETWORK section under HOW TO USE and uppercase NETWORK/SYMBOLS headers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Conform DiagnosticsMockContext to sendPublicMessage

CommandContextProvider gained sendPublicMessage (Cashu /pay, #1376) after
this branch forked, so the diagnostics test mock no longer conformed once
main was merged in. Add the no-op stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 15:08:22 +02:00
7341696280 Expand store-and-forward: open couriers, spray-and-wait, persistent outbox, 6h public history (#1372)
Store-and-forward previously delivered to an out-of-range peer only if a
mutual favorite happened to be connected at send time and later met the
recipient directly, and everything except courier envelopes died with the
app process. This closes those gaps end to end:

- Persist the MessageRouter outbox to disk, sealed with a ChaChaPoly key
  held only in the Keychain (no plaintext at rest); queued private
  messages now survive an app kill and flush on next launch.
- Deposit retry: queued messages are re-deposited whenever a new eligible
  courier connects, tracked per message so the same courier is never
  double-burned, until 3 distinct couriers carry it or it expires.
- Tiered open couriering: signature-verified strangers can now carry mail
  (2 envelopes/depositor into a 20-slot pool) alongside mutual favorites
  (5 each); overflow evicts verified-tier mail before favorites'.
- Spray-and-wait: envelopes carry a copy budget (4, capped 8, new TLV,
  wire-compatible with old clients); couriers split half their remaining
  budget with each newly encountered courier so mail diffuses through a
  moving crowd.
- Remote handover: a verified relayed announce now floods a copy toward
  the multi-hop recipient (directed-relay treatment, 10-min per-envelope
  cooldown) while the carried original stays put for a direct encounter.
- Public history: gossip-sync window for whole public messages widened
  from 15 min to 6 h, matched on the receive-acceptance side, and the
  message store persists to disk so devices bridge partitions and
  restarts ("town crier").
- Privacy-safe local delivery counters (bare tallies, log-only) so the
  store-and-forward stack is measurable on-device.
- Panic wipe now also clears the sealed outbox, gossip archive, and
  counters.
- Rewrite WHITEPAPER.md to describe the app as implemented (Noise XX/X,
  actual flood control, courier system, gossip sync, Nostr path); the old
  document described a bloom filter, three fragment types, and a
  MessageRetryService that don't exist.

1037 macOS tests pass (17 new); iOS builds.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:33:16 +02:00
jackandClaude Fable 5 8a867a17a1 Remove noise service exposure; single-owner selection state
Transport callers no longer reach the raw NoiseEncryptionService:
getNoiseService() is deleted in favor of narrow purpose-named Transport
methods (session public key, identity fingerprint, static/signing keys,
sign/verify, callback installation). VerificationService now reaches
crypto through the transport, so it can no longer pin a stale service
across a panic reset. myPeerID/myNickname become private(set); the
existing setNickname mutator is the sole nickname path.

ConversationStore is now the sole owner of private-chat selection:
PrivateChatManager.selectedPeer is a published read-only mirror, and
startChat/endChat mutate through the store intent. The bridge method
and its five call sites are deleted, removing a latent bug where a
stale manager selection pushed back into the store could resurrect a
just-removed conversation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 15:29:07 +02:00
ab0da61533 [codex] Refactor BLE transport event handling (#1266)
* Refactor BLE transport event handling

* Make image output paths unique

* Keep queued Nostr read receipts alive

* Allow self-authored RSR ingress replies

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2026-05-31 13:58:27 +02:00
IslamandGitHub 4cfcefcda6 BitFoundation module to centralize shared components (#1089)
* Run local packages’ tests as well on CI

* BitFoundation module to centralize shared components
2026-04-14 14:10:03 -05:00
7e86d2061f Expand coverage for transport, chat, and media flows (#1056)
* Expand coverage for transport, chat, and media flows

* Stabilize transport and media coverage tests

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2026-03-12 16:20:19 -10:00
806c420313 Add comprehensive test coverage for ChatViewModel and BLEService (#962)
* Add comprehensive test coverage for ChatViewModel and BLEService

This commit adds 14 new tests to improve the safety net for future
refactoring of ChatViewModel and BLEService:

New test files:
- ChatViewModelTorTests: Tor lifecycle notification handlers (8 tests)
- ChatViewModelDeliveryStatusTests: Delivery status state machine (6 tests)
- ChatViewModelRefactoringTests: Command routing and message handling (4 tests)
- BLEServiceCoreTests: Packet deduplication and stale broadcast filtering (2 tests)
- PublicMessagePipelineTests: Message ordering and deduplication (4 tests)
- MessageRouterTests: Transport selection and outbox behavior (4 tests)
- PrivateChatManagerTests: Chat selection and read receipts (2 tests)
- UnifiedPeerServiceTests: Fingerprint resolution and blocking (2 tests)
- RelayControllerTests: TTL, handshake, and fragment relay logic (4 tests)

Modified files:
- MockTransport: Added peer snapshot publishing on connect/disconnect
- TestHelpers: Added waitUntil polling helper for async tests
- MockIdentityManager: Extended for new test scenarios

Total: 454 tests across 64 suites (was 440)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix flaky test by using waitUntil instead of fixed sleep

Replace fixed 200ms sleep with waitUntil helper for more reliable
async assertion in routing tests. This prevents timing issues on CI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 16:02:13 -10:00
jack 3e680f40bf Add ChatViewModel testability and unit tests
- Add testable ChatViewModel initializer accepting Transport dependency
- Create MockTransport implementing full Transport protocol for testing
- Add 21 unit tests covering:
  - Initialization (delegate, services, nickname)
  - Message sending (basic, empty, mentions, commands)
  - Message receiving (delegate calls, public messages)
  - Peer connections (connect, disconnect, isPeerConnected)
  - Deduplication service integration
  - Private chat routing
  - Bluetooth state handling
  - Panic clear functionality
- Guard NotificationService methods against test environment crashes
- Make deduplicationService internal for test access

All 303 tests pass.
2025-11-25 09:20:38 -10:00