mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
fix(cli): resolve NIP-46 bunker identity via get_public_key
`amy login bunker://<pubkey>?…` was persisting the pubkey embedded in the bunker URI as the account identity. That pubkey is the remote-signer / connection key (Amber, nsec.app, nak all mint a dedicated one), not the user's identity key — so every "my events" fetch queried the wrong author (no kind-10002/10050/13302 found, empty timelines). After saving a provisional identity, connect the bunker and call the NIP-46 `get_public_key` RPC (already implemented on NostrSignerRemote), persisting the returned user pubkey as the account identity while keeping the bunker's remote key in Identity.bunker for RPC addressing. Best-effort: falls back to the URI pubkey if the bunker can't answer. Mirrors the app's NostrConnectLoginUseCase, which already stores the verified pubkey. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3d99f10058
commit
28e63e3d92
@@ -21,13 +21,17 @@
|
||||
package com.vitorpamplona.amethyst.cli.commands
|
||||
|
||||
import com.vitorpamplona.amethyst.cli.Args
|
||||
import com.vitorpamplona.amethyst.cli.Context
|
||||
import com.vitorpamplona.amethyst.cli.DataDir
|
||||
import com.vitorpamplona.amethyst.cli.Identity
|
||||
import com.vitorpamplona.amethyst.cli.Output
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.Nip05Client
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.OkHttpNip05Fetcher
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.resolveUserHexOrNull
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Nip06
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.signer.NostrSignerRemote
|
||||
import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
@@ -73,19 +77,53 @@ object LoginCommand {
|
||||
)
|
||||
|
||||
dataDir.saveIdentity(identity)
|
||||
|
||||
// For a bunker, the pubkey in the URI is the REMOTE SIGNER's key, which for many signer apps
|
||||
// (Amber, nsec.app) is a per-connection key distinct from the user's identity key. Resolve the
|
||||
// real identity via the NIP-46 get_public_key RPC and persist THAT (the bunker's remote key is
|
||||
// kept in Identity.bunker for transport addressing). Best-effort: if the bunker can't answer,
|
||||
// fall back to the URI pubkey so login still succeeds.
|
||||
val account = if (identity.bunker != null) resolveBunkerIdentity(dataDir, identity) else identity
|
||||
|
||||
Output.emit(
|
||||
mapOf(
|
||||
"npub" to identity.npub,
|
||||
"hex" to identity.pubKeyHex,
|
||||
"read_only" to !identity.canSign,
|
||||
"signer" to if (identity.bunker != null) "bunker" else "local",
|
||||
"bunker_relays" to identity.bunker?.relays,
|
||||
"npub" to account.npub,
|
||||
"hex" to account.pubKeyHex,
|
||||
"read_only" to !account.canSign,
|
||||
"signer" to if (account.bunker != null) "bunker" else "local",
|
||||
"bunker_relays" to account.bunker?.relays,
|
||||
"data_dir" to dataDir.root.absolutePath,
|
||||
),
|
||||
)
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the freshly-saved bunker and ask it (NIP-46 `get_public_key`) for the user's real
|
||||
* identity pubkey, re-persisting the [Identity] when it differs from the bunker's transport key.
|
||||
* Returns the corrected identity, or [provisional] unchanged if the RPC fails.
|
||||
*/
|
||||
private suspend fun resolveBunkerIdentity(
|
||||
dataDir: DataDir,
|
||||
provisional: Identity,
|
||||
): Identity =
|
||||
try {
|
||||
Context.open(dataDir).use { ctx ->
|
||||
ctx.prepare()
|
||||
val real = (ctx.signer as NostrSignerRemote).getPublicKey().lowercase()
|
||||
if (real == provisional.pubKeyHex.lowercase()) {
|
||||
provisional
|
||||
} else {
|
||||
val corrected = provisional.copy(pubKeyHex = real, npub = real.hexToByteArray().toNpub())
|
||||
dataDir.saveIdentity(corrected)
|
||||
corrected
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
System.err.println("[nip46] could not resolve identity via get_public_key (${e.message}); using the bunker URI pubkey")
|
||||
provisional
|
||||
}
|
||||
|
||||
private suspend fun resolveIdentity(
|
||||
key: String,
|
||||
args: Args,
|
||||
|
||||
Reference in New Issue
Block a user