Whispr v1.1.10 — Whispr v1.1.10 — chat delivery fix (round-trip add)
Bug fix
Chat now actually delivers between contacts added via invite link.
v1.1.9 added the signed pre-key (SPK) to the invite link itself so
the invitee could bootstrap X3DH against the inviter. That fixed one
half. This release fixes the other half — the round-trip add.
What was still broken in v1.1.9
When B taps A's invite link:
- B's side: adds A with SPK (from the link). B → A works.
- B then fires a
contact_requestback to A so A gets an "accepted
your invite" banner. But that envelope carried no SPK. - A taps Accept → A adds B without SPK → A's first chat send
fails to encrypt (X3DH has no pre-key to fingerprint against).
End result: messages never left A's device. Email worked because
ECIES is a one-shot encryption that only needs the identity key.
What changed
The sender's SPK + signature now ride along on every outgoing
envelope (LAN and Tor) — contact_request, contact_accepted,
text, voice, presence, all of it. Two follow-ons:
- The pending-request banner captures the SPK from
contact_requestdirectly, so accept-timeaddContactManual
gets it without waiting for a follow-up message. - Self-healing for already-added contacts. If your contact list
has someone with a null SPK column (added via an older build, or
via the round-trip in v1.1.9), the next single envelope from them
populates it. Stale sessions are deactivated on SPK rotation so
the next send re-runs X3DH against the fresh pre-key.
No re-add required. Open the app, send each other a message — even
a contact_request ping is enough — and chat starts working.
End-to-end test (cross-network)
Two devices on different networks, fresh installs:
- A → Share invite link → send to B
- B taps link → banner → Add (A is added on B's side with SPK)
- A's chat list → "X accepted your invite" banner → Accept
(B is added on A's side with SPK captured from the
contact_requestenvelope) - Either side types a chat message → delivered via Tor or LAN
- Reply from the other side → delivered
Email and chat now have parity for cross-network delivery on
both directions of the invite-link flow.
Wire format
Two new optional inner-body fields on every v1/v2/w3 envelope:
sk=<hex>— sender's signed pre-key public key (~64 chars)ss=<hex>— Ed25519 signature oversk(~128 chars)
Older clients that don't read these still parse the envelope normally
(unrecognised fields are ignored). Newer clients receiving an envelope
without sk/ss fall back to whatever SPK they already had stored
for the contact, or refuse to encrypt if none — same behaviour as
before.
Verification
- Architecture: arm64-v8a
- Signed: release keystore (CN=Whispr)
SHA-256: a77ded14db19cdd848c891705e868f71f4c557d8999a9f921f1bb3e33c7e2bca