Skip to main content

Module invite

Module invite 

Source
Expand description

Phase C: invite-link encoding / decoding.

Format: huddle://invite#<base64url-no-pad JSON>. The fragment (#) keeps the payload out of HTTP Referer headers if someone pastes through a web form somewhere.

What’s in the JSON:

  • v: format version. 1 was the original unsigned shape (still accepted on decode for back-compat); 2 (huddle 0.7.11+) adds an Ed25519 signature over the rest of the payload so tampering with any field — salt, owner list, room name — is detected by the receiver. host_multiaddr’s /p2p/<peer-id> suffix remains the primary MITM defense at the libp2p layer, but the signature now also catches edits that don’t touch the multiaddr.
  • host_multiaddr: the dial target, WITH /p2p/<peer-id> suffix — libp2p enforces remote-pubkey-matches-this on dial, so this is the cryptographic anchor for “who you actually connect to.”
  • fingerprint: the host’s 24-char Ed25519 fingerprint, shown in the confirmation modal so the receiver can verify (“yep, that’s the fp Alice texted me out-of-band”).
  • room: optional — when present, the receiver auto-joins after the dial completes and the room announcement arrives.
  • creator_pubkey_b64 (v2+): the host’s raw Ed25519 pubkey. The receiver re-derives the fingerprint from it and rejects the invite if compute_fingerprint(pubkey) != fingerprint.
  • signed_at_ms (v2+): epoch-ms at signing time. Used to keep replays of stale invites loosely bounded (24h window by default).
  • signature_b64 (v2+): Ed25519 signature over a deterministic serialization of the other fields.

Important: the passphrase is NEVER in the link. Encrypted rooms still require the joiner to type the passphrase separately; including it would defeat the point of OOB sharing.

Structs§

InviteLink
InviteRoom

Constants§

INVITE_MAX_AGE_MS
Max accepted age for a v2 signed invite. 24h. Long enough that the recipient can act in their own time, short enough that captured invites can’t be re-used indefinitely (and they’re invalidated completely after the inviter’s listen address changes anyway).
INVITE_PREFIX

Functions§

decode
Parse a huddle://invite#... URL back into an InviteLink.
encode
Build the huddle://invite#... URL form from a parsed InviteLink.
is_legacy_unsigned
True if this invite came in unsigned (legacy v=1). UI should show a “this invite is unsigned — verify the fingerprint out-of-band” warning when this returns true.
sign_invite
huddle 0.7.11: sign an invite. Sets v=2, creator_pubkey_b64, signed_at_ms, and signature_b64. The input invite’s v and signature fields are overwritten.