Implement the XEdDSA packet-signing UI for Device UI (part of MUI), per the cross-platform spec in meshtastic/design#113 — that issue is the source of truth, read it first.
Summary
Surface when a node and its broadcast packets are cryptographically signed and verified (XEdDSA over the node's identity key). This is read-only — the radio does all crypto and drops invalid/stripped signatures before the client sees them, so there is no error state to render. Clients only ever affirm the good state.
Two distinct marks, kept separate:
- 🛡️ shield-with-check = authentic (a verified, signed broadcast) — the UI's nearest shield-with-check asset
- 🔒 lock = private (a PKI-encrypted DM) — keep the existing lock, unchanged
Flags from the radio (read-only — no client-side crypto)
| Field |
Meaning |
MeshPacket.xeddsa_signed (22) |
this received packet's signature is verified — primary signal |
NodeInfo.has_xeddsa_signed (14) |
this node signs its packets (≥1 verified) |
Data.xeddsa_signature (10) is not needed for v1.
What to build
v1 decisions (settled in #113)
- Two affordances (shield + lock), not merged into one "security" concept.
- Node: two distinct cells (manual key-verify + signature-verify), laid out per platform (Android pairs them in one row), not conflated.
- Per-data-field signed badges → deferred. Unsigned → strictly silent. Compose-time "will be signed" hint → out. "Signed but unverifiable" state → dropped (use the verified bool only).
Don'ts
- Don't reuse the lock icon for signing.
- Don't use red / error styling anywhere — nothing here is an error.
- Don't flag unsigned DMs / large / legacy traffic as insecure.
Reference
Android implementation: meshtastic/Meshtastic-Android#5976 (+ #5980 for making the shield green & prominent). Reference screenshots live in the parent spec.
Parent: meshtastic/design#113
Implement the XEdDSA packet-signing UI for Device UI (part of MUI), per the cross-platform spec in meshtastic/design#113 — that issue is the source of truth, read it first.
Summary
Surface when a node and its broadcast packets are cryptographically signed and verified (XEdDSA over the node's identity key). This is read-only — the radio does all crypto and drops invalid/stripped signatures before the client sees them, so there is no error state to render. Clients only ever affirm the good state.
Two distinct marks, kept separate:
Flags from the radio (read-only — no client-side crypto)
MeshPacket.xeddsa_signed(22)NodeInfo.has_xeddsa_signed(14)Data.xeddsa_signature(10) is not needed for v1.What to build
xeddsa_signedbubbles; reveal "Signed · verified" on tap. Per-message. Never on DMs — firmware never sets the flag on DMs, so gating on the boolean alone is sufficient (it can't false-positive on a DM).has_xeddsa_signed, in the existing security section, ordered most-trusted-first (manual-verified → signed → has-key → no-key). Label it as automatic trust (e.g. "Verified automatically"), distinct from user-asserted manual key verification. Phrase as observed ("signs its packets"), not "signing enabled".v1 decisions (settled in #113)
Don'ts
Reference
Android implementation: meshtastic/Meshtastic-Android#5976 (+ #5980 for making the shield green & prominent). Reference screenshots live in the parent spec.
Parent: meshtastic/design#113