Commit Graph

10863 Commits

Author SHA1 Message Date
Crowdin Bot b070bbb98f New Crowdin translations by GitHub Action 2026-04-03 20:50:19 +00:00
Claude b2d31aab72 fix: Add proposal test format and minor test cleanups
The add_proposal field in messages.json contains a raw KeyPackage
(the body of an Add proposal) without the uint16 proposal type prefix.
Fixed the test to decode the KeyPackage directly with round-trip
verification.

Test results: 36/41 passing (88%).

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:48:56 +00:00
Vitor Pamplona 2159bcff6b Merge pull request #2119 from vitorpamplona/claude/fix-video-call-ui-kNo2m
Improve video call UI to show active peer videos with fallback avatars
2026-04-03 16:48:40 -04:00
Claude 9c94344399 feat: add AAD support to AESGCM for MLS AEAD compliance
Added encrypt(data, aad) and decrypt(data, aad) overloads to the
AESGCM expect/actual class across all platforms:

- JVM/Android: Uses Cipher.updateAAD() with AES/GCM/NoPadding
- Apple: Uses whyoleg.cryptography encryptWithIvBlocking(iv, data, aad)
- Linux: Same as Apple via whyoleg.cryptography

Updated HPKE aeadSeal/aeadOpen and MlsCryptoProvider aeadEncrypt/aeadDecrypt
to use the AAD-aware methods instead of ignoring the AAD parameter.

The EncryptWithLabel test still fails due to an X25519 DH computation
discrepancy between Python reference and the Quartz JVM implementation.
The HPKE implementation is internally consistent (MlsGroupTest passes).

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:46:22 +00:00
Claude 9af306282b fix: video call UI per-peer video activity and layout improvements
- Track per-peer video activity in CallController so each peer's video
  state is independent (fixes frozen frames and incorrect fallback to
  phone-call UI when one peer disables video)
- Replace single RemoteVideoGrid with PeerVideoGrid that shows video
  for active peers and avatar/name for inactive peers
- Use call type (VIDEO vs VOICE) to determine layout instead of relying
  solely on isRemoteVideoActive boolean
- Remove extra spacing in AddParticipantDialog between search field and
  user list
- Fix group video monitor using separate job to avoid conflict with P2P
  monitor

https://claude.ai/code/session_01EFDCu97SLYp3TCeBSAttAe
2026-04-03 20:45:08 +00:00
davotoula 4ecc471d82 update translations: CZ, DE, PT, SE 2026-04-03 22:38:09 +02:00
Claude 9d34bb8b2e fix: tree hash type discriminant and leaf count from rightmost node
RFC 9420 Section 7.9 tree hash input includes a type discriminant byte:
- Leaf: H(uint8(1) || uint32(leaf_index) || optional<LeafNode>)
- Parent: H(uint8(2) || optional<ParentNode> || opaque left<V> || opaque right<V>)

Also fixed RatchetTree leaf count computation to use the rightmost
non-blank node position instead of total serialized node count,
since trees may be serialized with trailing blank nodes.

Test results: 35/41 passing (85%).

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:23:16 +00:00
Vitor Pamplona 136e6a4121 Merge pull request #2117 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-04-03 16:18:10 -04:00
Claude 449d998064 fix: tree hash computation, proposal test format, parent_hash cleanup
1. Tree hash (RFC 9420 Section 7.9): Leaf hash now includes
   uint32(leaf_index) before optional<LeafNode>. Parent hash wraps
   left_hash and right_hash with VarInt-prefixed opaques.

2. Message serialization tests: Fixed Add/Remove proposal tests to
   match the messages.json format (Add includes type prefix,
   Remove is just uint32 body without type prefix).

Test results: 34/41 passing (83%).

Remaining 7 failures:
- EncryptWithLabel: HPKE AEAD needs AAD support
- Add proposal: KeyPackage decode issue in test data
- Transcript hashes (2): Need AuthenticatedContent parsing
- Tree hash (1): May need per-node hash verification
- Tree operations (2): Tree hash still mismatches after operations

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:17:02 +00:00
davotoula 51b38349c6 Merge branch 'main-upstream' into ci-use-built-in-gradle-cache 2026-04-03 22:15:12 +02:00
Claude fe7a4d6f9f fix: MLS-Exporter label encoding and remove unused raw-byte overload
The exporter test vector labels are hex-encoded strings used AS-IS
(as string labels), not decoded from hex to bytes. The test was
incorrectly hex-decoding the label before passing it.

Also removed the now-unused expandWithLabelRaw and ByteArray mlsExporter
overloads since the string-based API is correct for all MLS usage.

Test results: 33/41 passing (80%).

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:13:48 +00:00
Vitor Pamplona 98d652401d Merge pull request #2116 from davotoula/fix-intermittent-test-failure-desktop-feed-filter
Fix intermittent test failure, DesktopFeedFilters.kt
2026-04-03 16:13:01 -04:00
Crowdin Bot fa688db50b New Crowdin translations by GitHub Action 2026-04-03 20:12:03 +00:00
Vitor Pamplona e36a6e4ae2 Merge pull request #2115 from vitorpamplona/claude/fix-webrtc-multiple-videos-EXBGs
Support multiple remote video tracks in group calls
2026-04-03 16:10:58 -04:00
Claude 621196b74f fix: VarInt encoding migration and LeafNode parent_hash for COMMIT
Major interop fixes discovered by IETF test vectors:

1. VarInt migration: All MLS TLS struct serialization now uses
   QUIC-style VarInt encoding for opaque<V> and vector<V> fields,
   matching OpenMLS and mls-rs wire format. Added readVarInt(),
   readOpaqueVarInt(), readVectorVarInt() to TlsReader and
   putVectorVarInt() to TlsWriter.

2. SecretTree left/right derivation: Fixed tree secret splitting
   to use "left"/"right" as context strings per RFC 9420 Section 9,
   instead of byte(0)/byte(1).

3. LeafNode parent_hash: Added parent_hash<V> field for COMMIT
   source per RFC 9420 Section 7.2. The COMMIT case is NOT empty -
   it includes a parent_hash opaque field.

4. MLS-Exporter: Added ByteArray overload for raw byte labels
   (test vectors use non-UTF-8 label bytes).

Test results: 32/41 passing (78%), up from 25/41 (61%).
Newly passing: SecretTree (2), TreeValidation deserialization (1),
TreeValidation resolution (1), TreeKem deserialization (1),
Commit deserialization (1), RatchetTree deserialization (1).

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 20:10:40 +00:00
Vitor Pamplona 4cf9418582 Merge pull request #2113 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-04-03 16:10:36 -04:00
Vitor Pamplona 3eb72200f6 Merge pull request #2114 from greenart7c3/claude/implement-payment-targets-VzxXc
Add payment targets feature with NIP-A3 support
2026-04-03 16:10:28 -04:00
Vitor Pamplona 171907d1cd Merge pull request #2112 from greenart7c3/claude/add-relay-setting-kxeIb
Add option to forward profile events to local relays
2026-04-03 16:10:13 -04:00
Claude 6bb464e768 fix: render all remote video tracks in group WebRTC calls
The UI was only showing the first connected peer's video track
(remoteVideoTrack) instead of all tracks from the remoteVideoTracks
map. This adds a grid layout that renders all remote videos and
per-peer frame activity monitoring so the controller correctly
detects video activity from any participant.

https://claude.ai/code/session_01E4ASQDLSu5CSjiAiAmrNeK
2026-04-03 19:58:06 +00:00
Claude c803c06607 feat: show error dialog when payto:// URI fails to open
- Use Intent(ACTION_VIEW) + startActivity instead of LocalUriHandler so
  ActivityNotFoundException is catchable
- Show ErrorMessageDialog with title/message when no app handles the URI,
  matching the pattern used by zap payment errors
- Always show the wallet icon (profile button + reactions row), showing a
  disabled "no targets" row in the dialog when the author has none set
- Add no_payment_app_found and error_dialog_payment_error string resources

https://claude.ai/code/session_018G4g1cChqjeNEM5TztD3FE
2026-04-03 19:54:29 +00:00
Claude 5796cac947 fix: republish NIP-78 AppSpecificDataEvent when sendKind0EventsToLocalRelay changes
Add Account.updateSendKind0EventsToLocalRelay() suspend fun that calls
sendNewAppSpecificData() after updating the setting, matching the pattern
used by updateFilterSpam/updateWarnReports. Update AccountViewModel to
call this via launchSigner instead of directly mutating settings.

https://claude.ai/code/session_01Er9VV7nHyDb5pihrunb81F
2026-04-03 16:52:09 -03:00
Claude 68623a43f9 fix: remove unused destroy() from ForwardKind0ToLocalRelayState
EventCollector lives for the lifetime of Account, matching the same
pattern used by CacheClientConnector — no explicit teardown needed.

https://claude.ai/code/session_01Er9VV7nHyDb5pihrunb81F
2026-04-03 16:52:09 -03:00
Claude 30aa997a93 refactor: move sendKind0EventsToLocalRelay to AccountSyncedSettings
- Move the setting from a raw AccountSettings field into
  AccountSyncedSettingsInternal / AccountSecurityPreferences so it is
  serialised with the rest of the synced app-specific data (NIP-78)
- Remove one-off LocalPreferences persistence (no longer needed)
- Update ForwardKind0ToLocalRelayState to read from syncedSettings.security
- Move the UI toggle from inside renderLocalItems into the relay
  settings screen (AllRelayListScreen) as a proper SettingsRow item
  in the local-relay section, with title and description
- Fix Account initialisation order so localRelayList is declared before
  ForwardKind0ToLocalRelayState

https://claude.ai/code/session_01Er9VV7nHyDb5pihrunb81F
2026-04-03 16:52:02 -03:00
Claude 4fc99021ae fix: correct key schedule welcome_secret derivation order
The welcome_secret must be derived from member_secret (the Extract of
joiner_secret and psk_secret), not directly from joiner_secret. This
matches the RFC 9420 key schedule diagram where welcome_secret is
derived after the psk extraction step.

Before: welcome = DeriveSecret(joiner_secret, "welcome")
After:  member = Extract(joiner_secret, psk_secret)
        welcome = DeriveSecret(member, "welcome")
        epoch = ExpandWithLabel(member, "epoch", GroupContext, Nh)

This fix was discovered and validated by the IETF interop test vectors.
Key schedule tests now pass all 11 derived secrets across multiple epochs.

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 19:51:54 +00:00
Claude e82e1ee226 feat: add account setting to forward kind 0 events to local relay
Adds a toggle in the Local Relays settings section that, when enabled,
forwards all received kind 0 (profile/metadata) events to the user's
configured local relays.

- AccountSettings: add sendKind0EventsToLocalRelay MutableStateFlow + toggle method
- LocalPreferences: persist the new setting
- ForwardKind0ToLocalRelayState: uses EventCollector to intercept kind 0
  events from any relay and publish them to local relays when enabled
- Account: instantiate ForwardKind0ToLocalRelayState
- AccountViewModel: expose toggleSendKind0ToLocalRelay
- LocalRelayListView: add Switch toggle above the relay list
- strings.xml: add label and description strings

https://claude.ai/code/session_01Er9VV7nHyDb5pihrunb81F
2026-04-03 16:49:13 -03:00
Crowdin Bot 39088bfffc New Crowdin translations by GitHub Action 2026-04-03 19:47:59 +00:00
Vitor Pamplona 843f557fee Merge pull request #2111 from vitorpamplona/claude/debug-webrtc-calls-ZPFIV
Improve peer disconnection handling in calls
2026-04-03 15:46:31 -04:00
Claude d1409c84bc fix: correct MLS wire format encoding for interop with OpenMLS/mls-rs
Three encoding bugs found by IETF interop test vectors:

1. ExpandWithLabel: label and context length prefixes must use
   QUIC-style variable-length integer encoding (VarInt), not fixed-size
   opaque prefixes. Values < 64 use 1 byte, 64-16383 use 2 bytes with
   0x40 prefix. This is critical when GroupContext (112+ bytes) is
   passed as context.

2. RefHash: label and value also use VarInt-prefixed opaque fields,
   matching the MLS TLS codec convention.

3. SecretTree: DeriveTreeSecret must pass the generation counter as a
   uint32 big-endian context parameter, not empty context. This affects
   key/nonce derivation and ratchet advancement.

Also fixes:
- SignContent and EncryptWithLabel/DecryptWithLabel info encoding
  updated to use VarInt
- KeySchedule test updated to use initial_init_secret from test vector
  (not hardcoded zeros)
- Added putOpaqueVarInt() to TlsWriter for QUIC-style VarInt encoding

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 19:42:27 +00:00
Claude 303e68331a fix: clean up rejected peer's PeerSession to prevent stale sessions blocking hangup
When a peer rejects a group call, CallManager updated its state but never
notified CallController to dispose the peer's PeerSession. This caused two
issues:

1. The rejected peer's PeerConnection lingered in HAVE_LOCAL_OFFER state
   until the entire call ended (resource leak visible as "disposing 2 peer
   sessions" when only 1 should exist).

2. In onPeerDisconnected, the allDisconnected check required ALL sessions
   to be CLOSED. The stale session blocked this check, preventing automatic
   hangup when ICE failed — meaning the remote peer never received a hangup
   event and kept ringing.

Fix: invoke onPeerLeft when a peer rejects in Offering/Connecting/Connected
states, and make onPeerDisconnected treat sessions without a remote
description as inactive.

https://claude.ai/code/session_01UXaFKmHVPDyTzfHL8fkSw1
2026-04-03 19:33:30 +00:00
davotoula c0bdde0ce4 ?: 0L forces Long regardless of nullability, so all comparisons are Long vs Long — no cast issue. 2026-04-03 21:08:05 +02:00
Vitor Pamplona 35a1a20bde Merge pull request #2110 from vitorpamplona/claude/debug-webrtc-calls-KqELh
Improve group call peer management and signaling robustness
2026-04-03 15:01:22 -04:00
Claude fe505c2fb9 feat: add IETF RFC 9420 MLS interop test vectors and test suite
Import the canonical IETF MLS test vectors from mlswg/mls-implementations
to verify wire-format compatibility with OpenMLS and mls-rs. These are
the same test vectors used by both Rust implementations for cross-
implementation interop validation.

Phase 1 (Foundations):
- crypto-basics.json: RefHash, ExpandWithLabel, DeriveSecret,
  DeriveTreeSecret, SignWithLabel, EncryptWithLabel
- tree-math.json: Binary tree arithmetic for all tree sizes
- key-schedule.json: Full 12-secret epoch key derivation chain
- secret-tree.json: Per-sender handshake/application ratchet keys

Phase 2 (Wire Format):
- messages.json: Round-trip serialization of all MLS message types
- message-protection.json: PublicMessage/PrivateMessage framing
- transcript-hashes.json: Confirmed/interim transcript hash computation

Phase 3 (TreeKEM):
- treekem.json: UpdatePath processing, path secret derivation
- tree-validation.json: Tree hash and resolution verification
- tree-operations.json: Add/remove/update proposal application
- welcome.json: Welcome message deserialization

Phase 4 (End-to-End Protocol):
- passive-client-welcome.json: Join via Welcome, follow epochs
- passive-client-handling-commit.json: Process varied commit types
- passive-client-random.json: Randomized multi-epoch scenarios

Initial test results reveal ExpandWithLabel encoding discrepancy
in HkdfLabel context field that cascades to most crypto operations.
Tree math tests pass fully. These findings demonstrate the value of
importing standard interop vectors.

https://claude.ai/code/session_01NocQDWj2Y92FugjfgazzL3
2026-04-03 19:00:05 +00:00
Claude bde17099a4 fix: WebRTC group call bugs — self-event filtering, mesh setup, per-peer cleanup
Four bugs fixed in group call signaling:

1. Self-event filtering: Own answer/ICE/hangup events echoed from relays
   were processed as if from another peer, causing callees to attempt
   callee-to-callee connections with themselves.

2. Lost peer discovery: When a callee received another callee's answer
   while still ringing (IncomingCall state), the peer was silently
   discarded. Now stored in discoveredCalleePeers and used for mesh
   setup after accepting.

3. Duplicate onNewPeerInGroupCall: Both CallManager and CallController
   triggered mesh setup for the same peer, causing duplicate log entries
   and wasted work. Removed CallManager's redundant calls since
   CallController handles this internally via onCallAnswerReceived.

4. No per-peer session cleanup: When a peer hung up but the call
   continued, their WebRTC PeerSession was never disposed — it lingered
   until ICE timeout. Added onPeerLeft callback and disposePeerSession
   to cleanly close individual sessions and update video tracks.

Also added strategic debug logging for session lifecycle, peer
discovery, and disconnect handling.

https://claude.ai/code/session_01SWDsQJibYi1MMgvu55puSY
2026-04-03 19:00:04 +00:00
Vitor Pamplona 49932edc62 Merge pull request #2109 from vitorpamplona/claude/fix-group-call-rejection-yPDlk
Handle peer rejections in incoming group calls
2026-04-03 14:49:24 -04:00
Claude d08d101b7d fix: remove rejecting peer from group members in IncomingCall state
When a group member (e.g. Bob) rejects a call, the rejection event is
sent to all group members. The caller (Alice) correctly removes Bob,
but other callees (Charlie) were not removing Bob because the
IncomingCall handler in onCallRejected only handled self-rejection
for multi-device sync. Now it also removes the rejecting peer from
groupMembers, matching the behavior already present in onPeerHangup.

https://claude.ai/code/session_01PMwKCEU1fRDGNQ8WdX8CFW
2026-04-03 18:47:04 +00:00
Vitor Pamplona 397cdb6a6b Making sure the instance is created before running cleaup 2026-04-03 14:32:36 -04:00
Vitor Pamplona 32f6815fb5 Merge pull request #2108 from vitorpamplona/claude/implement-mls-engine-kotlin-Jz9RL
test: add comprehensive MLS engine tests and fix self-decrypt ratchet
2026-04-03 14:20:24 -04:00
Vitor Pamplona 5622d0d531 Merge pull request #2107 from vitorpamplona/claude/fix-call-ringing-issue-OGVEG
Fix call audio state transitions and notification handling
2026-04-03 14:19:23 -04:00
Claude fe13b77e22 fix: harden call cleanup to guarantee nothing is left running
Three issues addressed:

1. Make cleanup() exception-safe: wrap each WebRTC dispose call in
   its own try-catch so that a failure in one (e.g. native crash
   disposing a PeerConnection) does not skip releasing the camera,
   audio mode, foreground service, or EGL context.

2. Upgrade the Idle safety net to call cleanup() instead of only
   stopping ringing/notifications. If the Ended state is missed due
   to StateFlow conflation, the Idle handler now performs full
   resource cleanup (camera, WebRTC, audio mode, foreground service,
   proximity wake lock). cleanup() is idempotent since all resources
   are null-checked and nulled out.

3. Call cleanup() in AccountViewModel.onCleared() so that WebRTC
   resources, camera, audio mode, and foreground service are released
   when the ViewModel is destroyed (e.g. logout, activity recreation).

4. Clear processedEventIds when transitioning to Idle to prevent
   unbounded memory growth across calls.

https://claude.ai/code/session_01GWRdrVAa29BsDkv8R7Z3Y9
2026-04-03 18:16:09 +00:00
Claude 286685c0bd fix: stop ringback tone when Connecting state is skipped by StateFlow conflation
StateFlow is conflated — when the state transitions rapidly from
Offering → Connecting → Connected, the collector may skip Connecting
entirely and only see Connected. Since stopRingbackTone() was only
called in the Connecting handler, the ringback tone would keep playing
through the entire call.

Fix: duplicate the ringing/notification cleanup in the Connected handler
so the tone is always stopped regardless of which state the collector
sees first. Also make switchToCallAudioMode() idempotent and clean up
the previous ToneGenerator in startRingbackTone() to prevent leaks.

https://claude.ai/code/session_01GWRdrVAa29BsDkv8R7Z3Y9
2026-04-03 18:11:22 +00:00
Claude b9db4f8e38 test: add comprehensive MLS engine tests and fix self-decrypt ratchet
Add interop-focused tests for all MLS engine components:
- Ed25519 sign/verify round-trips (JVM)
- X25519 DH key agreement verification (JVM)
- HPKE seal/open encryption cycle (JVM)
- Key schedule determinism and secret derivation (commonMain)
- MlsGroup integration: create, encrypt/decrypt, add/remove members

Fix MlsGroup self-decrypt by caching sent key/nonce generations to
avoid ratchet conflict when decrypting own messages on the same instance.

https://claude.ai/code/session_01966YzookEUQDwszM3YCgeR
2026-04-03 18:10:57 +00:00
Vitor Pamplona 9be9117362 Merge pull request #2106 from vitorpamplona/claude/implement-mls-engine-kotlin-Jz9RL
Add MLS (Messaging Layer Security) implementation for Marmot
2026-04-03 13:55:36 -04:00
Vitor Pamplona f01fb9e70a Merge pull request #2105 from vitorpamplona/claude/fix-call-ringing-bug-aZlur
Fix call state handling to prevent missed cleanup due to StateFlow conflation
2026-04-03 13:34:43 -04:00
Claude a1f8817fce fix: stop call ringing when Ended state is missed due to StateFlow conflation
The state collector in CallController was blocking on
showIncomingCallNotification() which downloads the caller's profile
picture over the network. Because StateFlow is conflated, if the call
ended (peer hangup, reject, timeout) while the collector was suspended,
the Ended→Idle transition would cause the Ended emission to be lost.
Since cleanup/stopRinging only ran in the Ended handler, the ringtone
and vibration would continue indefinitely.

Two fixes:
1. Launch showIncomingCallNotification in a separate coroutine so the
   collector is never blocked by network I/O.
2. Add a safety-net Idle handler that stops ringing, ringback tone,
   and cancels the call notification.

https://claude.ai/code/session_01NfyLNgR4d8yjnxaQJ6FUt5
2026-04-03 17:31:06 +00:00
Vitor Pamplona 5250ef0abd Merge pull request #2104 from vitorpamplona/claude/fix-endcall-ui-user-81baC
Exclude current user from peer lists in call UI
2026-04-03 13:22:09 -04:00
Claude a6c1909602 fix: filter out logged-in user from call member pictures in all call states
The Offering, Ended, Connected, and PipConnected call states were showing
the logged-in user's picture alongside other call members. IncomingCall and
Connecting already filtered correctly. Now all states consistently exclude
the current user via `- accountViewModel.account.signer.pubKey`.

https://claude.ai/code/session_01PFzKU8Y3nUQXhshA3MT5EM
2026-04-03 17:20:53 +00:00
Claude 119f9dd966 feat: implement MLS cryptographic engine in pure Kotlin (Phase 3)
Implements the core MLS (RFC 9420) engine for Marmot Protocol integration,
targeting ciphersuite 0x0001 (DHKEM-X25519, AES-128-GCM, SHA-256, Ed25519).

Components:
- codec/: TLS presentation language encoder/decoder (RFC 8446 Section 3)
- crypto/: Ed25519 signatures, X25519 ECDH, HPKE (RFC 9180), MlsCryptoProvider
  with ExpandWithLabel, DeriveSecret, SignWithLabel, EncryptWithLabel
- tree/: Left-balanced binary tree, LeafNode/ParentNode, RatchetTree with
  TreeKEM encap/decap, tree hashing, resolution, path secret derivation
- schedule/: Key schedule (epoch secret derivation chain), SecretTree
  (per-sender encryption ratchets), MLS-Exporter function
- framing/: MLSMessage, PublicMessage, PrivateMessage, content types
- messages/: Proposal (Add/Remove/Update/SelfRemove), Commit, UpdatePath,
  Welcome, GroupInfo, GroupContext, KeyPackage, GroupSecrets
- group/: MlsGroup high-level API (create, join via Welcome, add/remove
  members, encrypt/decrypt messages, export keys for Marmot outer layer)

Crypto uses expect/actual pattern: JVM/Android via java.security (EdDSA, XDH),
native platforms stubbed for future implementation. Reuses existing Quartz
primitives (AESGCM, HKDF, SHA-256, HMAC, ChaCha20-Poly1305).

Includes tests for TLS codec, binary tree arithmetic, and MLS type roundtrips.

https://claude.ai/code/session_01966YzookEUQDwszM3YCgeR
2026-04-03 17:00:41 +00:00
Vitor Pamplona 31448ad1f6 Makes sure relays and tor are available if just the call activity starts. 2026-04-03 12:59:34 -04:00
Vitor Pamplona 858f13d60f Merge pull request #2103 from vitorpamplona/claude/debug-webrtc-connecting-Q7Jo8
Refactor CallController for multi-peer group calls with mesh topology
2026-04-03 12:58:14 -04:00
Claude fcecb5241c feat: implement full-mesh WebRTC group calls with per-peer PeerConnections
Replaces the single-PeerConnection architecture with full mesh topology
where each participant maintains one PeerConnection per peer, as
specified by NIP-AC.

WebRtcCallSession: Refactored to a pure PeerConnection wrapper that
accepts a shared PeerConnectionFactory. No longer manages media sources,
tracks, or camera — those are now shared across all peer sessions.

CallController: Manages per-peer sessions via ConcurrentHashMap. Shared
resources (PeerConnectionFactory, EglBase, audio/video sources, camera)
are initialized once and reused. Each peer gets its own WebRtcCallSession
with per-peer ICE candidate routing. Supports callee-to-callee mesh
connections with pubkey-based tie-breaking to avoid ofer glare.

CallManager: New methods for per-peer offer/answer publishing
(publishOfferToPeer, publishAnswerToPeer, beginOffering). Forwards ALL
answers to CallController (not just the first). New callbacks
onNewPeerInGroupCall and onMidCallOfferReceived for mesh setup. Handles
mid-call offers (same call-id) when already in Connecting/Connected state.

AccountViewModel: Updated callback wiring to pass peer pubkey with
answer events and register new group call callbacks.

https://claude.ai/code/session_01J5fJx9YbSBx1BsBMctiAm8
2026-04-03 16:54:00 +00:00