From 7be75f37c6b707b98be54783553fb319ab94f216 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:50:25 -0800 Subject: [PATCH] Fix: Gracefully ignore unsupported NWC response types (e.g. get_info) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When another NWC client (e.g. Alby) connected to the same relay calls `get_info`, Damus receives the response and previously threw a DecodingError.typeMismatch, causing an "Oops" error dialog to be shown. Fix: Make `result_type` optional in `WalletConnect.Response`. Unknown result types now decode without throwing — `result_type` and `result` are set to `nil`, and the rest of the existing nil-guarded code paths handle this silently. Adds a test to verify `get_info` (and any future unknown result type) is decoded gracefully. Closes: #2204 Changelog-Fixed: Fixed issue where the app could display an error message when using another NWC wallet in parallel Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danieldaquino <24692108+danieldaquino@users.noreply.github.com> Signed-off-by: Daniel D’Aquino --- .../Models/WalletConnect/Response.swift | 14 ++++++---- damusTests/WalletConnectTests.swift | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/damus/Features/Wallet/Models/WalletConnect/Response.swift b/damus/Features/Wallet/Models/WalletConnect/Response.swift index 3e5e0728..67cb75df 100644 --- a/damus/Features/Wallet/Models/WalletConnect/Response.swift +++ b/damus/Features/Wallet/Models/WalletConnect/Response.swift @@ -10,7 +10,8 @@ import Combine extension WalletConnect { /// Models a response from the NWC provider struct Response: Decodable { - let result_type: Response.Result.ResultType + /// The type of the result. `nil` if the result type is unsupported/unknown. + let result_type: Response.Result.ResultType? let error: WalletResponseErr? let result: Response.Result? @@ -21,14 +22,17 @@ extension WalletConnect { init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let result_type_str = try container.decode(String.self, forKey: .result_type) - - guard let result_type = Response.Result.ResultType(rawValue: result_type_str) else { - throw DecodingError.typeMismatch(Response.Result.ResultType.self, .init(codingPath: decoder.codingPath, debugDescription: "result_type \(result_type_str) is unknown")) - } + let result_type = Response.Result.ResultType(rawValue: result_type_str) self.result_type = result_type self.error = try container.decodeIfPresent(WalletResponseErr.self, forKey: .error) + guard let result_type else { + // Unknown/unsupported result type — gracefully ignore without an error + self.result = nil + return + } + guard self.error == nil else { self.result = nil return diff --git a/damusTests/WalletConnectTests.swift b/damusTests/WalletConnectTests.swift index d4600985..0dd3f892 100644 --- a/damusTests/WalletConnectTests.swift +++ b/damusTests/WalletConnectTests.swift @@ -233,4 +233,30 @@ final class WalletConnectTests: XCTestCase { encodedRequest = try encoded_request_with_type(type: "outgoing") XCTAssertTrue(encodedRequest.contains("\"type\":\"outgoing\"")) } + + /// Tests that responses with an unknown `result_type` (e.g. `get_info` from a different NWC client) + /// are decoded gracefully without throwing an error. + func testDecodingUnknownResultTypeIsGraceful() throws { + let jsonData = """ + { + "result_type": "get_info", + "error": null, + "result": { + "alias": "some-wallet", + "color": "#3399FF", + "pubkey": "abc123", + "network": "mainnet", + "block_height": 800000, + "block_hash": "000000", + "methods": ["pay_invoice", "get_balance", "get_info"] + } + } + """.data(using: .utf8)! + + let response = try JSONDecoder().decode(WalletConnect.Response.self, from: jsonData) + + XCTAssertNil(response.result_type, "Unknown result_type should be nil") + XCTAssertNil(response.result, "Result should be nil for unknown result_type") + XCTAssertNil(response.error, "Error should be nil for a successful get_info response") + } }