diff --git a/src/signer/nip46_client.rs b/src/signer/nip46_client.rs index 9313caf..c413aa0 100644 --- a/src/signer/nip46_client.rs +++ b/src/signer/nip46_client.rs @@ -64,6 +64,18 @@ fn pairing_trace(msg: &str) { } } +/// Whether a relay set touches the public network. Loopback-only sets +/// belong to the e2e harness, and their traffic must never land in the +/// live pairing forensics files: a test-run "identity adopted — CONNECTED" +/// line sitting among real ones was twice mistaken for a live Amber +/// pairing during debugging. +fn live_relays(relays: &[String]) -> bool { + relays.iter().any(|u| { + let u = u.to_lowercase(); + !(u.contains("127.0.0.1") || u.contains("localhost") || u.contains("[::1]")) + }) +} + /// Internal state for a pending approval. struct PendingApprovalInner { method: String, @@ -803,6 +815,9 @@ impl Nip46ClientSigner { // status) and move the session state where send_rpc expects it. The // phase stays `Connecting` — identity is still unverified — and the // demux loop (which answers the handshake's RPCs) takes over. + if live_capture { + pairing_trace("paired: connection stored; handing over to identity handshake"); + } let demux_uri = ConnectUri { peer, relays, @@ -1713,11 +1728,17 @@ impl Nip46ClientSigner { conn.profile_npub = Some(identity_npub.clone()); } inner.phase = Nip46Phase::Connected; - pairing_trace(&format!( - "identity adopted: npub={} peer={} — CONNECTED", - identity_npub, - peer.to_hex() - )); + // Only trace LIVE pairings: adopt_identity runs in the e2e harness + // too, and an un-gated line here put test-run "CONNECTED" entries + // into the forensics log where they were mistaken for a live Amber + // scan during debugging. + if live_relays(&connection.relays) { + pairing_trace(&format!( + "identity adopted: npub={} peer={} — CONNECTED", + identity_npub, + peer.to_hex() + )); + } drop(inner); // Background enrichment (post-Connected by design): look up the