Users can link one or more phone numbers to their Hermes identity by
publishing a kind:30078 claim event whose d-tag is a SHA-256 hash of the
E.164 number. The number itself never leaves the device. Add-contact and
message-send now also accept a +phone input directly — the client hashes it
and queries relays for the matching Hermes identity.
- lib/hermes.js: normalisePhone(str) strips separators + a leading 00
into E.164, rejects anything that doesn't fit +[country][7-15 digits].
hashPhone(str) → base64url-truncated-to-32 SHA-256 digest, used as the
d-tag suffix under PHONE_DTAG_PREFIX. buildPhoneClaimEvent /
buildPhoneRetractEvent emit the signed kind:30078 / NIP-09 kind:5.
- main.js: _hermesAPI.getPhone / setPhone / clearPhone / findByPhones.
Plaintext phone persists in the identity meta (locally only) so the
user can see what's linked and retract it; event ids are kept so a
retract can reference the exact wire event. hermesResolveTo takes a
phone-shaped input and does the discovery lookup transparently, so
contactsAdd and send accept phones without a new entry point.
- panel.html: Settings → Phone discovery (link / unlink + privacy note),
add-contact placeholder now lists +phone alongside the other forms.
Privacy stance stated in the UI: "anyone who already knows your number
can find you — same tradeoff as number-based messengers." No PSI tricks
yet; plain hash. Users who don't want it just don't link, which is the
default. Future slice can add a pepper if operators want to narrow the
brute-force window.