Fix: Gracefully ignore unsupported NWC response types (e.g. get_info)
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 <daniel@daquino.me>
This commit is contained in:
@@ -10,7 +10,8 @@ import Combine
|
|||||||
extension WalletConnect {
|
extension WalletConnect {
|
||||||
/// Models a response from the NWC provider
|
/// Models a response from the NWC provider
|
||||||
struct Response: Decodable {
|
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 error: WalletResponseErr?
|
||||||
let result: Response.Result?
|
let result: Response.Result?
|
||||||
|
|
||||||
@@ -21,14 +22,17 @@ extension WalletConnect {
|
|||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
let result_type_str = try container.decode(String.self, forKey: .result_type)
|
let result_type_str = try container.decode(String.self, forKey: .result_type)
|
||||||
|
let result_type = Response.Result.ResultType(rawValue: result_type_str)
|
||||||
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"))
|
|
||||||
}
|
|
||||||
|
|
||||||
self.result_type = result_type
|
self.result_type = result_type
|
||||||
self.error = try container.decodeIfPresent(WalletResponseErr.self, forKey: .error)
|
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 {
|
guard self.error == nil else {
|
||||||
self.result = nil
|
self.result = nil
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -233,4 +233,30 @@ final class WalletConnectTests: XCTestCase {
|
|||||||
encodedRequest = try encoded_request_with_type(type: "outgoing")
|
encodedRequest = try encoded_request_with_type(type: "outgoing")
|
||||||
XCTAssertTrue(encodedRequest.contains("\"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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user