The contact link behind Copy Import URL and Show QR Code on the node page never includes the node's public key. /api/node/{node_id}/qr builds a SharedContact with the node id, names, hardware model and role. It never sets user.public_key (meshview/web_api/api.py, api_node_qr).
Why it matters
Current Meshtastic apps refuse to import a contact that has no public key:
Android 2.8.2 and later shows "This contact has no public key, so it cannot be imported" and removes the Import button (Meshtastic-Android#7050).
iOS 2.7.22 and later shows "This contact does not include a public key, so it cannot be added."
On those apps the Meshview QR code does nothing.
Older apps send the contact to the radio as add_contact. On 2.7.x firmware, NodeDB::addFromContact copies the empty key over the key the radio already holds for that node. Direct messages to that node then fail with PKI_SEND_FAIL_PUBLIC_KEY until it broadcasts NodeInfo again. Firmware no longer falls back to the channel key for direct messages. The overwrite is fixed in firmware develop by firmware#11432.
meshtastic/design#145 sets the cross-client rule: never send add_contact with an empty public key, whether it comes from a QR code, a link or an NFC tag.
The apps' own Share Contact QR codes include the key.
Steps to reproduce
Open the page of a node that has sent NODEINFO with a public key. Any node on firmware 2.5 or later that is not in licensed mode will do.
Click Copy Import URL, or call /api/node/<node_id>/qr and take meshtastic_url.
Base64url-decode the part after # and parse it as meshtastic.protobuf.SharedContact.
Optionally, scan the QR code with a current Android or iOS Meshtastic app.
Expected:user.public_key holds the node's 32-byte public key, and the app imports the contact.
Actual:user.public_key is empty. Current apps refuse the import. Older apps on 2.7.x firmware erase the key the radio already knew.
Notes
Meshview dropped its node_public_key table in 3.0.7. The key is still available, though: packet.payload keeps each NODEINFO_APP packet, and its User.public_key is the node's key.
Seen on develop at aabb099 (3.0.9). It does not depend on the database backend; reproduced with SQLite.
## Summary
The contact link behind **Copy Import URL** and **Show QR Code** on the node page never includes the node's public key. `/api/node/{node_id}/qr` builds a `SharedContact` with the node id, names, hardware model and role. It never sets `user.public_key` (`meshview/web_api/api.py`, `api_node_qr`).
## Why it matters
- Current Meshtastic apps refuse to import a contact that has no public key:
- Android 2.8.2 and later shows "This contact has no public key, so it cannot be imported" and removes the Import button ([Meshtastic-Android#7050](https://github.com/meshtastic/Meshtastic-Android/pull/7050)).
- iOS 2.7.22 and later shows "This contact does not include a public key, so it cannot be added."
On those apps the Meshview QR code does nothing.
- Older apps send the contact to the radio as `add_contact`. On 2.7.x firmware, `NodeDB::addFromContact` copies the empty key over the key the radio already holds for that node. Direct messages to that node then fail with `PKI_SEND_FAIL_PUBLIC_KEY` until it broadcasts NodeInfo again. Firmware no longer falls back to the channel key for direct messages. The overwrite is fixed in firmware `develop` by [firmware#11432](https://github.com/meshtastic/firmware/pull/11432).
- [meshtastic/design#145](https://github.com/meshtastic/design/issues/145) sets the cross-client rule: never send `add_contact` with an empty public key, whether it comes from a QR code, a link or an NFC tag.
The apps' own **Share Contact** QR codes include the key.
## Steps to reproduce
1. Open the page of a node that has sent NODEINFO with a public key. Any node on firmware 2.5 or later that is not in licensed mode will do.
2. Click **Copy Import URL**, or call `/api/node/<node_id>/qr` and take `meshtastic_url`.
3. Base64url-decode the part after `#` and parse it as `meshtastic.protobuf.SharedContact`.
4. Optionally, scan the QR code with a current Android or iOS Meshtastic app.
**Expected:** `user.public_key` holds the node's 32-byte public key, and the app imports the contact.
**Actual:** `user.public_key` is empty. Current apps refuse the import. Older apps on 2.7.x firmware erase the key the radio already knew.
## Notes
- Meshview dropped its `node_public_key` table in 3.0.7. The key is still available, though: `packet.payload` keeps each NODEINFO_APP packet, and its `User.public_key` is the node's key.
- Seen on `develop` at aabb099 (3.0.9). It does not depend on the database backend; reproduced with SQLite.
<!-- github-sync-id:6046537937 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The contact link behind Copy Import URL and Show QR Code on the node page never includes the node's public key.
/api/node/{node_id}/qrbuilds aSharedContactwith the node id, names, hardware model and role. It never setsuser.public_key(meshview/web_api/api.py,api_node_qr).Why it matters
Current Meshtastic apps refuse to import a contact that has no public key:
On those apps the Meshview QR code does nothing.
Older apps send the contact to the radio as
add_contact. On 2.7.x firmware,NodeDB::addFromContactcopies the empty key over the key the radio already holds for that node. Direct messages to that node then fail withPKI_SEND_FAIL_PUBLIC_KEYuntil it broadcasts NodeInfo again. Firmware no longer falls back to the channel key for direct messages. The overwrite is fixed in firmwaredevelopby firmware#11432.meshtastic/design#145 sets the cross-client rule: never send
add_contactwith an empty public key, whether it comes from a QR code, a link or an NFC tag.The apps' own Share Contact QR codes include the key.
Steps to reproduce
/api/node/<node_id>/qrand takemeshtastic_url.#and parse it asmeshtastic.protobuf.SharedContact.Expected:
user.public_keyholds the node's 32-byte public key, and the app imports the contact.Actual:
user.public_keyis empty. Current apps refuse the import. Older apps on 2.7.x firmware erase the key the radio already knew.Notes
node_public_keytable in 3.0.7. The key is still available, though:packet.payloadkeeps each NODEINFO_APP packet, and itsUser.public_keyis the node's key.developataabb099(3.0.9). It does not depend on the database backend; reproduced with SQLite.this PR was added and will be in next version