From f6bf6a979aae01d52c714e092096906d0588b0c9 Mon Sep 17 00:00:00 2001 From: Avi Date: Mon, 21 Sep 2026 20:39:08 -0500 Subject: [PATCH] fix(pairing): keep e2e traffic out of the live pairing trace + trace the handover The trace log's "identity adopted - CONNECTED" line fired in the e2e harness too (adopt_identity had no relay gate), so every test run appended fake CONNECTED entries to the forensics log. Three such lines landed there during today's cron verification and had to be manually distinguished from a real Amber scan. Gate the line on live_relays() (same loopback test the capture already uses) and add a "paired: connection stored" trace line at the QR-pairing handover so a stall between connect-echo and get_public_key is visible in the trace. --- src/signer/nip46_client.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) 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