Skip to content

Commit 5990335

Browse files
DocNRclaude
andcommitted
chore(LightSigner): add NIP-46 wire-trace observability
Three observability-only additions to make Clave a cleaner reference signer for debugging NIP-46 client implementations. No behavior change. - Append `id=<8-char>` to the existing `[LightSigner] Method:` log line so every wire-trace step in iOS logs can be cross-correlated to a single RPC by request id. - Warn (don't reject) when `connect` params[0] doesn't match Clave's signer pubkey. Spec says params[0] is the remote-signer-pubkey; routing already worked via the kind:24133 #p tag, so a mismatch is informational — but it's a useful diagnostic for clients that target the wrong signer in multi-account flows. Closes BACKLOG Audit-2. - Log when `params` cast falls through (client sent mixed-type instead of [String]). Without this, a shape-mismatch silently degrades to "missing params" downstream and the wire trace can't tell shape-issues from genuinely-missing params. Reports the actual type for easier client-side debug. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1e081e7 commit 5990335

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

Shared/LightSigner.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,21 @@ enum LightSigner {
118118
return result
119119
}
120120

121-
let params = json["params"] as? [String] ?? []
122-
logger.notice("[LightSigner] Method: \(method, privacy: .public)")
121+
let params: [String]
122+
if let strs = json["params"] as? [String] {
123+
params = strs
124+
} else {
125+
// Some clients send mixed-type params (e.g. an object for sign_event
126+
// instead of the spec-required JSON-stringified string). Without
127+
// this log, the request silently degrades to "missing params"
128+
// downstream and the wire trace can't tell shape-mismatch from
129+
// genuinely-missing-params. Helps client-side debugging.
130+
if let raw = json["params"] {
131+
logger.warning("[LightSigner] params not [String]: type=\(String(describing: type(of: raw)), privacy: .public) method=\(method, privacy: .public) id=\(requestId.prefix(8), privacy: .public)")
132+
}
133+
params = []
134+
}
135+
logger.notice("[LightSigner] Method: \(method, privacy: .public) id=\(requestId.prefix(8), privacy: .public)")
123136

124137
// Extract event kind for sign_event
125138
let eventKind = extractEventKind(method: method, params: params)
@@ -130,6 +143,13 @@ enum LightSigner {
130143
// --- Per-client permission checks ---
131144
if method == "connect" {
132145
// connect params: [remote-signer-pubkey, optional-secret, optional-perms]
146+
// Audit-2: warn (don't reject) when params[0] doesn't match this
147+
// signer's pubkey. Routing already worked via the kind:24133 #p
148+
// tag so a mismatch is informational — but it's a useful diagnostic
149+
// for clients that pick the wrong target in multi-account flows.
150+
if let target = params.first, !target.isEmpty, target != signerPubkey {
151+
logger.warning("[LightSigner] connect target mismatch: params[0]=\(target.prefix(8), privacy: .public) signer=\(signerPubkey.prefix(8), privacy: .public)")
152+
}
133153
let providedSecret = params.count >= 2 ? params[1] : ""
134154
let expectedSecret = SharedStorage.getBunkerSecret(for: signerPubkey)
135155

0 commit comments

Comments
 (0)