fix(identity): Node npub in Web5 Identities matches Settings (#49)
Settings shows the node-level Nostr key (HKDF derive_node_nostr_key, read via node.nostr-pubkey) while Web5 > Identities showed the identity record's own key — the mirrored "Node" identity stores nostr=None and seed identities use a different BIP-32 NIP-06 key, so the two surfaces disagreed. Resolve the node-level Nostr key once in identity.list and override it onto whichever identity record is the node's own (ed25519 == server_info .pubkey). Display-only — no stored key is rewritten, so it self-applies to existing nodes with no migration and the discovery identity is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6de8173d18
commit
56752ebfc0
@ -14,10 +14,39 @@ impl RpcHandler {
|
|||||||
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||||||
let (identities, default_id) = manager.list().await?;
|
let (identities, default_id) = manager.list().await?;
|
||||||
|
|
||||||
|
// #49: The canonical node Nostr key is the node-level HKDF key
|
||||||
|
// (`derive_node_nostr_key`) that Settings and Nostr discovery both use
|
||||||
|
// via `node.nostr-pubkey`. The mirrored "Node" identity stores
|
||||||
|
// nostr=None, and seed identities use a different BIP-32 NIP-06 key, so
|
||||||
|
// the "Node" entry in Web5 > Identities disagreed with Settings. Resolve
|
||||||
|
// the node-level key once and override it onto whichever identity record
|
||||||
|
// is the node's own (its ed25519 matches `server_info.pubkey`), so both
|
||||||
|
// surfaces always show the same npub. Display-only — no key is rewritten.
|
||||||
|
let identity_dir = self.config.data_dir.join("identity");
|
||||||
|
let node_nostr_hex = crate::nostr_discovery::get_nostr_pubkey(&identity_dir)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
let node_nostr_npub = node_nostr_hex.as_ref().and_then(|h| {
|
||||||
|
nostr_sdk::PublicKey::from_hex(h)
|
||||||
|
.ok()
|
||||||
|
.and_then(|pk| pk.to_bech32().ok())
|
||||||
|
});
|
||||||
|
let (snapshot, _) = self.state_manager.get_snapshot().await;
|
||||||
|
let node_pubkey_hex = snapshot.server_info.pubkey.clone();
|
||||||
|
|
||||||
let items: Vec<serde_json::Value> = identities
|
let items: Vec<serde_json::Value> = identities
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|id| {
|
.map(|id| {
|
||||||
let is_default = default_id.as_deref() == Some(&id.id);
|
let is_default = default_id.as_deref() == Some(&id.id);
|
||||||
|
let is_node = !node_pubkey_hex.is_empty() && id.pubkey_hex == node_pubkey_hex;
|
||||||
|
let (nostr_pubkey, nostr_npub) = if is_node {
|
||||||
|
(
|
||||||
|
node_nostr_hex.clone().or(id.nostr_pubkey),
|
||||||
|
node_nostr_npub.clone().or(id.nostr_npub),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(id.nostr_pubkey, id.nostr_npub)
|
||||||
|
};
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
"id": id.id,
|
"id": id.id,
|
||||||
"name": id.name,
|
"name": id.name,
|
||||||
@ -26,8 +55,8 @@ impl RpcHandler {
|
|||||||
"did": id.did,
|
"did": id.did,
|
||||||
"created_at": id.created_at,
|
"created_at": id.created_at,
|
||||||
"is_default": is_default,
|
"is_default": is_default,
|
||||||
"nostr_pubkey": id.nostr_pubkey,
|
"nostr_pubkey": nostr_pubkey,
|
||||||
"nostr_npub": id.nostr_npub,
|
"nostr_npub": nostr_npub,
|
||||||
"profile": id.profile,
|
"profile": id.profile,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user