diff --git a/AlphaWallet/Common/Types/Error.swift b/AlphaWallet/Common/Types/Error.swift index 42250a6b8..5ee150c8e 100644 --- a/AlphaWallet/Common/Types/Error.swift +++ b/AlphaWallet/Common/Types/Error.swift @@ -59,16 +59,12 @@ extension Error { return error.localizedDescription case let error as TransactionConfiguratorError: return error.localizedDescription - case let error as RequestCanceledDueToWatchWalletError: - return error.localizedDescription case let error as KeystoreError: return error.errorDescription ?? UnknownError().localizedDescription case let error as SendInputErrors: return error.errorDescription ?? UnknownError().localizedDescription case let error as RpcNodeRetryableRequestError: return error.errorDescription ?? UnknownError().localizedDescription - case let error as DelayWalletConnectResponseError: - return error.localizedDescription case let error as OpenURLError: return error.localizedDescription case let error as ConfigureTransactionError: diff --git a/AlphaWallet/Transfer/Collectibles/ViewModels/SendSemiFungibleTokenViewModel.swift b/AlphaWallet/Transfer/Collectibles/ViewModels/SendSemiFungibleTokenViewModel.swift index cb9d5265f..f93a3431d 100644 --- a/AlphaWallet/Transfer/Collectibles/ViewModels/SendSemiFungibleTokenViewModel.swift +++ b/AlphaWallet/Transfer/Collectibles/ViewModels/SendSemiFungibleTokenViewModel.swift @@ -133,18 +133,6 @@ extension WalletApiError { } } -extension DelayWalletConnectResponseError { - var localizedDescription: String { - return "Request Rejected! Switch to non watched wallet" - } -} - -extension RequestCanceledDueToWatchWalletError { - var localizedDescription: String { - return R.string.localizable.walletConnectFailureMustNotBeWatchedWallet() - } -} - extension OpenURLError { var localizedDescription: String { switch self { diff --git a/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift b/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift index c87c0f185..920a5256f 100644 --- a/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift +++ b/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift @@ -189,7 +189,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { if let data = Data(fromHexEncodedString: String(format: "%02X", nonce)) { return .just(.value(data)) } else { - return .fail(PromiseError(error: PMKError.badInput)) + return .fail(PromiseError(error: DAppError.cancelled)) } }.receive(on: RunLoop.main) .eraseToAnyPublisher() @@ -216,7 +216,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { }.map { data in switch data { case .signedTransaction, .sentTransaction: - throw PMKError.cancelled + throw DAppError.cancelled case .sentRawTransaction(let transactionId, _): return .value(Data(_hex: transactionId)) } @@ -228,7 +228,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { } func requestSendTransaction(session: WalletSession, requester: DappRequesterViewModel, transaction: UnconfirmedTransaction, configuration: TransactionType.Configuration) -> AnyPublisher { - guard let dependency = dependencies[session.account] else { return .fail(PromiseError(error: PMKError.cancelled)) } + guard let dependency = dependencies[session.account] else { return .fail(PromiseError(error: DAppError.cancelled)) } infoLog("[WalletConnect] sendTransaction: \(transaction) type: \(configuration.confirmType)") @@ -242,7 +242,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { return .value(Data(_hex: transaction.id)) case .sentRawTransaction: //NOTE: Doesn't support sentRawTransaction for TransactionConfirmationCoordinator, for it we are using another function - throw PMKError.cancelled + throw DAppError.cancelled } }.get { _ in TransactionInProgressCoordinator.promise(self.navigationController, coordinator: self).done { _ in }.cauterize() @@ -250,7 +250,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { } func requestSingTransaction(session: WalletSession, requester: DappRequesterViewModel, transaction: UnconfirmedTransaction, configuration: TransactionType.Configuration) -> AnyPublisher { - guard let dependency = dependencies[session.account] else { return .fail(PromiseError(error: PMKError.cancelled)) } + guard let dependency = dependencies[session.account] else { return .fail(PromiseError(error: DAppError.cancelled)) } infoLog("[WalletConnect] singTransaction: \(transaction) type: \(configuration.confirmType)") return firstly { @@ -263,7 +263,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { return .value(Data(_hex: transaction.id)) case .sentRawTransaction: //NOTE: Doesn't support sentRawTransaction for TransactionConfirmationCoordinator, for it we are using another function - throw PMKError.cancelled + throw DAppError.cancelled } }.publisher(queue: .main) } @@ -273,7 +273,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { delegate?.requestAddCustomChain(server: server, callbackId: callbackId, customChain: customChain) - return .fail(PromiseError(error: DelayWalletConnectResponseError())) + return .fail(PromiseError(error: WalletConnectError.delayedOperation)) } func requestSwitchChain(server: RPCServer, currentUrl: URL?, callbackID: SwitchCustomChainCallbackId, targetChain: WalletSwitchEthereumChainObject) -> AnyPublisher { @@ -281,7 +281,7 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { delegate?.requestSwitchChain(server: server, currentUrl: nil, callbackID: callbackID, targetChain: targetChain) - return .fail(PromiseError(error: DelayWalletConnectResponseError())) + return .fail(PromiseError(error: WalletConnectError.delayedOperation)) } private func resetSessionsToRemoveLoadingIfNeeded() { @@ -308,11 +308,8 @@ extension WalletConnectCoordinator: WalletConnectProviderDelegate { func provider(_ provider: WalletConnectProvider, didFail error: WalletConnectError) { infoLog("[WalletConnect] didFail error: \(error)") - if error.isCancellationError { - //no-op - } else { - displayErrorMessage(error.localizedDescription) - } + guard let description = error.localizedDescription else { return } + displayErrorMessage(description) } func provider(_ provider: WalletConnectProvider, tookTooLongToConnectToUrl url: AlphaWallet.WalletConnect.ConnectionUrl) { diff --git a/AlphaWallet/WalletConnect/Providers/v1/WalletConnectV1Provider.swift b/AlphaWallet/WalletConnect/Providers/v1/WalletConnectV1Provider.swift index 2386fc3f9..382febf9e 100644 --- a/AlphaWallet/WalletConnect/Providers/v1/WalletConnectV1Provider.swift +++ b/AlphaWallet/WalletConnect/Providers/v1/WalletConnectV1Provider.swift @@ -153,7 +153,7 @@ extension WalletConnectV1Provider: WalletConnectV1ClientDelegate { do { let action = AlphaWallet.WalletConnect.Action(type: try decoder.decode(request: request, session: session)) delegate?.server(self, action: action, request: .v1(request: request, server: session.server), session: .init(session: session)) - } catch let error as AlphaWallet.WalletConnect.ResponseError { + } catch let error as JsonRpcError { delegate?.server(self, didFail: error) //NOTE: we need to reject request if there is some arrays client.send(.reject(request)) diff --git a/AlphaWallet/WalletConnect/Providers/v2/WalletConnectV2Provider.swift b/AlphaWallet/WalletConnect/Providers/v2/WalletConnectV2Provider.swift index 1a3d552e0..87c98bef6 100644 --- a/AlphaWallet/WalletConnect/Providers/v2/WalletConnectV2Provider.swift +++ b/AlphaWallet/WalletConnect/Providers/v2/WalletConnectV2Provider.swift @@ -146,7 +146,7 @@ final class WalletConnectV2Provider: WalletConnectServer { }) } - private func reject(request: WalletConnectSwiftV2.Request, error: AlphaWallet.WalletConnect.ResponseError) { + private func reject(request: WalletConnectSwiftV2.Request, error: JsonRpcError) { infoLog("[WalletConnect2] WC: Did reject session proposal: \(request) with error: \(error.message)") client.respond(topic: request.topic, requestId: request.id, response: .error(.init(code: error.code, message: error.message))) @@ -169,7 +169,7 @@ final class WalletConnectV2Provider: WalletConnectServer { let request: AlphaWallet.WalletConnect.Session.Request = .v2(request: request) let action = AlphaWallet.WalletConnect.Action(type: try decoder.decode(request: request)) self.delegate?.server(self, action: action, request: request, session: .init(multiServerSession: session)) - } catch let error as AlphaWallet.WalletConnect.ResponseError { + } catch let error as JsonRpcError { self.delegate?.server(self, didFail: error) //NOTE: we need to reject request if there is some arrays self.reject(request: request, error: error) diff --git a/AlphaWallet/WalletConnect/Types/WalletConnectActionType.swift b/AlphaWallet/WalletConnect/Types/WalletConnectActionType.swift index 7a798bbe7..03f685053 100644 --- a/AlphaWallet/WalletConnect/Types/WalletConnectActionType.swift +++ b/AlphaWallet/WalletConnect/Types/WalletConnectActionType.swift @@ -40,7 +40,7 @@ extension AlphaWallet.WalletConnect { self = .error(code: code, message: message) } - init(error: AlphaWallet.WalletConnect.ResponseError) { + init(error: JsonRpcError) { self = .error(code: error.code, message: error.message) } diff --git a/AlphaWallet/WalletConnect/Types/WalletConnectRequestConverter.swift b/AlphaWallet/WalletConnect/Types/WalletConnectRequestConverter.swift index b724ab4c2..cab131848 100644 --- a/AlphaWallet/WalletConnect/Types/WalletConnectRequestConverter.swift +++ b/AlphaWallet/WalletConnect/Types/WalletConnectRequestConverter.swift @@ -14,7 +14,7 @@ struct WalletConnectRequestDecoder { func decode(request: AlphaWallet.WalletConnect.Session.Request) throws -> AlphaWallet.WalletConnect.Action.ActionType { guard let server: RPCServer = request.server else { - throw AlphaWallet.WalletConnect.ResponseError.invalidParams + throw JsonRpcError.invalidParams } infoLog("[WalletConnect] convert request: \(request.method) url: \(request.description)") @@ -23,7 +23,7 @@ struct WalletConnectRequestDecoder { do { data = try AlphaWallet.WalletConnect.Request(request: request) } catch { - throw AlphaWallet.WalletConnect.ResponseError.invalidParams + throw JsonRpcError.invalidParams } switch data { @@ -36,7 +36,7 @@ struct WalletConnectRequestDecoder { let transaction = try TransactionType.prebuilt(server).buildAnyDappTransaction(walletConnectTransaction: walletConnectTransaction) return .signTransaction(transaction) } catch { - throw AlphaWallet.WalletConnect.ResponseError.invalidParams + throw JsonRpcError.invalidParams } case .signTypedMessage(let data): return .typedMessage(data) @@ -47,7 +47,7 @@ struct WalletConnectRequestDecoder { let transaction = try TransactionType.prebuilt(server).buildAnyDappTransaction(walletConnectTransaction: walletConnectTransaction) return .sendTransaction(transaction) } catch { - throw AlphaWallet.WalletConnect.ResponseError.invalidParams + throw JsonRpcError.invalidParams } case .sendRawTransaction(let rawValue): return .sendRawTransaction(rawValue) @@ -58,7 +58,7 @@ struct WalletConnectRequestDecoder { case .walletAddEthereumChain(let data): return .walletAddEthereumChain(data) case .custom: - throw AlphaWallet.WalletConnect.ResponseError.methodNotFound + throw JsonRpcError.methodNotFound } } } diff --git a/AlphaWallet/WalletConnect/Types/WalletConnectServerRequest.swift b/AlphaWallet/WalletConnect/Types/WalletConnectServerRequest.swift index 7f33b8444..7c675169d 100644 --- a/AlphaWallet/WalletConnect/Types/WalletConnectServerRequest.swift +++ b/AlphaWallet/WalletConnect/Types/WalletConnectServerRequest.swift @@ -11,47 +11,6 @@ import AlphaWalletFoundation extension WalletConnectV1Request: PositionedJSONRPC_2_0_RequestType { } extension AlphaWallet.WalletConnect { - - enum ResponseError: Error { - case invalidJSON - case invalidRequest - case methodNotFound - case invalidParams - case internalError - case errorResponse - case requestRejected - case unsupportedChain(chainId: String) - case custom(code: Int, message: String) - - public var code: Int { - switch self { - case .invalidJSON: return -32700 - case .invalidRequest: return -32600 - case .methodNotFound: return -32601 - case .invalidParams: return -32602 - case .internalError: return -32603 - case .errorResponse: return -32010 - case .requestRejected: return -32050 - case .unsupportedChain: return 4902 - case .custom(let code, _): return code - } - } - - public var message: String { - switch self { - case .invalidJSON: return "Parse error" - case .invalidRequest: return "Invalid Request" - case .methodNotFound: return "Method not found" - case .invalidParams: return "Invalid params" - case .internalError: return "Internal error" - case .errorResponse: return "Error response" - case .requestRejected: return "Request rejected" - case .unsupportedChain(let chainId): return "Unrecognized chain ID \(chainId). Try adding the chain using wallet_addEthereumChain first." - case .custom(_, let message): return message - } - } - } - enum Request { case signTransaction(_ transaction: WalletConnectTransaction) case sign(address: AlphaWallet.Address, message: String) @@ -89,14 +48,14 @@ extension AlphaWallet.WalletConnect { let addressRawValue = try request.parameter(of: String.self, at: 1) let data = try request.parameter(of: String.self, at: 0) - guard let address = AlphaWallet.Address(string: addressRawValue) else { throw ResponseError.invalidRequest } + guard let address = AlphaWallet.Address(string: addressRawValue) else { throw JsonRpcError.invalidRequest } return .signPersonalMessage(address: address, message: data) case .sign: let addressRawValue = try request.parameter(of: String.self, at: 0) let data = try request.parameter(of: String.self, at: 1) - guard let address = AlphaWallet.Address(string: addressRawValue) else { throw ResponseError.invalidRequest } + guard let address = AlphaWallet.Address(string: addressRawValue) else { throw JsonRpcError.invalidRequest } return .sign(address: address, message: data) case .signTransaction: @@ -108,13 +67,13 @@ extension AlphaWallet.WalletConnect { let addressRawValue = try request.parameter(of: String.self, at: 0) let rawValue = try request.parameter(of: String.self, at: 1) - guard let address = AlphaWallet.Address(string: addressRawValue), let data = rawValue.data(using: .utf8) else { throw ResponseError.invalidRequest } + guard let address = AlphaWallet.Address(string: addressRawValue), let data = rawValue.data(using: .utf8) else { throw JsonRpcError.invalidRequest } let typed = try JSONDecoder().decode(EIP712TypedData.self, from: data) return .signTypedData(address: address, data: typed) } catch { let rawValue = try request.parameter(of: String.self, at: 1) - guard let data = rawValue.data(using: .utf8) else { throw ResponseError.invalidRequest } + guard let data = rawValue.data(using: .utf8) else { throw JsonRpcError.invalidRequest } let typed = try JSONDecoder().decode([EthTypedData].self, from: data) return .signTypedMessage(data: typed) diff --git a/AlphaWallet/WalletConnect/WalletConnectProvider.swift b/AlphaWallet/WalletConnect/WalletConnectProvider.swift index f773e1806..545110ff8 100644 --- a/AlphaWallet/WalletConnect/WalletConnectProvider.swift +++ b/AlphaWallet/WalletConnect/WalletConnectProvider.swift @@ -11,6 +11,7 @@ import CombineExt import AlphaWalletFoundation import AlphaWalletLogger import AlphaWalletCore +import PromiseKit protocol WalletConnectProviderDelegate: AnyObject { func provider(_ provider: WalletConnectProvider, didConnect session: AlphaWallet.WalletConnect.Session) @@ -152,37 +153,40 @@ extension WalletConnectProvider: WalletConnectServerDelegate { infoLog("[WalletConnect] action: \(action)") do { - let wallet = try self.wallet(session: session) + let wallet = try wallet(session: session) - guard let dep = dependencies[wallet] else { throw DAppError.cancelled } - guard let walletSession = request.server.flatMap({ dep.sessionsProvider.session(for: $0) }) else { throw DAppError.cancelled } + guard let dep = dependencies[wallet] else { throw WalletConnectError.cancelled } + guard let walletSession = request.server.flatMap({ dep.sessionsProvider.session(for: $0) }) else { throw WalletConnectError.cancelled } let requester = DappRequesterViewModel(requester: Requester(walletConnectSession: session, request: request)) buildOperation(for: action, walletSession: walletSession, dep: dep, request: request, session: session, requester: requester) .sink(receiveCompletion: { result in if case .failure(let error) = result { - if error.embedded is DelayWalletConnectResponseError { - //no-op - } else { - self.delegate?.provider(self, didFail: WalletConnectError(error: error.embedded)) - try? server.respond(.init(error: .requestRejected), request: request) + switch error { + case .internal, .cancelled, .walletsNotFound, .onlyForWatchWallet, .callbackIdMissing, .connectionFailure: + self.delegate?.provider(self, didFail: error) + try? server.respond(.init(error: error.asJsonRpcError), request: request) + JumpBackToPreviousApp.goBack(forWalletConnectAction: action) + case .delayedOperation: + break } + } else { + JumpBackToPreviousApp.goBack(forWalletConnectAction: action) } - JumpBackToPreviousApp.goBack(forWalletConnectAction: action) }, receiveValue: { response in try? server.respond(response, request: request) }).store(in: &cancellable) - } catch { + } catch let error as WalletConnectError { JumpBackToPreviousApp.goBack(forWalletConnectAction: action) - delegate?.provider(self, didFail: WalletConnectError(error: error)) - try? server.respond(.init(error: .requestRejected), request: request) - } + delegate?.provider(self, didFail: error) + try? server.respond(.init(error: error.asJsonRpcError), request: request) + } catch { /*no-op*/ } } func server(_ server: WalletConnectServer, didFail error: Error) { - delegate?.provider(self, didFail: WalletConnectError(error: error)) + delegate?.provider(self, didFail: WalletConnectError(error: PromiseError(error: error))) } func server(_ server: WalletConnectServer, @@ -212,24 +216,26 @@ extension WalletConnectProvider: WalletConnectServerDelegate { private func addCustomChain(object customChain: WalletAddEthereumChainObject, request: AlphaWallet.WalletConnect.Session.Request, - walletConnectSession: AlphaWallet.WalletConnect.Session) -> AnyPublisher { - guard let dappRequestProvider = delegate else { return .fail(PromiseError(error: DAppError.cancelled)) } + walletConnectSession: AlphaWallet.WalletConnect.Session) -> AnyPublisher { + guard let dappRequestProvider = delegate else { return .fail(.cancelled) } infoLog("[WalletConnect] addCustomChain: \(customChain)") guard let server = walletConnectSession.servers.first else { - return .fail(PromiseError(error: AlphaWallet.WalletConnect.ResponseError.requestRejected)) + return .fail(.internal(.requestRejected)) } let callbackId: SwitchCustomChainCallbackId = .walletConnect(request: request) return dappRequestProvider.requestAddCustomChain(server: server, callbackId: callbackId, customChain: customChain) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() } private func switchChain(object targetChain: WalletSwitchEthereumChainObject, request: AlphaWallet.WalletConnect.Session.Request, walletConnectSession: AlphaWallet.WalletConnect.Session, - dep: AppCoordinator.WalletDependencies) -> AnyPublisher { + dep: AppCoordinator.WalletDependencies) -> AnyPublisher { - guard let dappRequestProvider = delegate else { return .fail(PromiseError(error: DAppError.cancelled)) } + guard let dappRequestProvider = delegate else { return .fail(.cancelled) } infoLog("[WalletConnect] switchChain: \(targetChain)") @@ -242,12 +248,14 @@ extension WalletConnectProvider: WalletConnectServerDelegate { guard let server = firstEnabledRPCServer(), targetChain.server != nil else { //TODO: implement switch chain if its available, but disabled - return .fail(PromiseError(error: AlphaWallet.WalletConnect.ResponseError.unsupportedChain(chainId: targetChain.chainId))) + return .fail(.internal(.unsupportedChain(chainId: targetChain.chainId))) } let callbackID: SwitchCustomChainCallbackId = .walletConnect(request: request) return dappRequestProvider.requestSwitchChain(server: server, currentUrl: nil, callbackID: callbackID, targetChain: targetChain) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() } private func buildOperation(for action: AlphaWallet.WalletConnect.Action, @@ -255,9 +263,9 @@ extension WalletConnectProvider: WalletConnectServerDelegate { dep: AppCoordinator.WalletDependencies, request: AlphaWallet.WalletConnect.Session.Request, session: AlphaWallet.WalletConnect.Session, - requester: DappRequesterViewModel) -> AnyPublisher { + requester: DappRequesterViewModel) -> AnyPublisher { - guard let dappRequestProvider = delegate else { return .fail(PromiseError(error: DAppError.cancelled)) } + guard let dappRequestProvider = delegate else { return .fail(.cancelled) } switch action.type { case .signTransaction(let transaction): @@ -266,40 +274,56 @@ extension WalletConnectProvider: WalletConnectServerDelegate { requester: requester, transaction: transaction, configuration: .walletConnect(confirmType: .sign, requester: requester)) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .sendTransaction(let transaction): return dappRequestProvider.requestSendTransaction( session: walletSession, requester: requester, transaction: transaction, configuration: .walletConnect(confirmType: .signThenSend, requester: requester)) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .signMessage(let hexMessage): return dappRequestProvider.requestSignMessage( message: .message(hexMessage.asSignableMessageData), account: walletSession.account.address, requester: requester) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .signPersonalMessage(let hexMessage): return dappRequestProvider.requestSignMessage( message: .personalMessage(hexMessage.asSignableMessageData), account: walletSession.account.address, requester: requester) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .signEip712v3And4(let typedData): return dappRequestProvider.requestSignMessage( message: .eip712v3And4(typedData), account: walletSession.account.address, requester: requester) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .typedMessage(let typedData): return dappRequestProvider.requestSignMessage( message: .typedMessage(typedData), account: walletSession.account.address, requester: requester) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .sendRawTransaction(let transaction): return dappRequestProvider.requestSendRawTransaction( session: walletSession, requester: requester, transaction: transaction, configuration: .approve) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .getTransactionCount: return dappRequestProvider.requestGetTransactionCount(session: walletSession) + .mapError { WalletConnectError(error: $0) } + .eraseToAnyPublisher() case .walletAddEthereumChain(let object): return addCustomChain(object: object, request: request, walletConnectSession: session) case .walletSwitchEthereumChain(let object): diff --git a/AlphaWallet/WalletConnect/WalletConnectServer.swift b/AlphaWallet/WalletConnect/WalletConnectServer.swift index 2debd3bd3..44fc8c345 100644 --- a/AlphaWallet/WalletConnect/WalletConnectServer.swift +++ b/AlphaWallet/WalletConnect/WalletConnectServer.swift @@ -9,46 +9,52 @@ import Foundation import Combine import AlphaWalletFoundation import PromiseKit +import AlphaWalletCore -enum WalletConnectError: Error, LocalizedError { +enum WalletConnectError: Error { case onlyForWatchWallet(address: AlphaWallet.Address) case walletsNotFound(addresses: [AlphaWallet.Address]) case callbackIdMissing case connectionFailure(WalletConnectV1URL) - case `internal`(Error) + case cancelled + case delayedOperation + case `internal`(JsonRpcError) - init(error: Error) { - if let value = error as? WalletConnectError { - self = value - } else { + init(error: PromiseError) { + if case DAppError.cancelled = error.embedded { + self = .cancelled + } else if case PMKError.cancelled = error.embedded { + self = .cancelled + } else if let error = error.embedded as? JsonRpcError { self = .internal(error) + } else if let error = error.embedded as? WalletConnectError { + self = error + } else { + self = .internal(.init(code: -32051, message: error.embedded.prettyError)) } } - var isCancellationError: Bool { + var asJsonRpcError: JsonRpcError { switch self { case .internal(let error): - if case DAppError.cancelled = error { - return true - } else if case PMKError.cancelled = error { - return true - } - return false - case .walletsNotFound, .onlyForWatchWallet, .callbackIdMissing, .connectionFailure: - return false + return error + case .delayedOperation, .cancelled, .walletsNotFound, .onlyForWatchWallet, .callbackIdMissing, .connectionFailure: + return .requestRejected } } - var localizedDescription: String { + var localizedDescription: String? { switch self { case .internal(let error): - return error.localizedDescription + return error.message case .callbackIdMissing, .connectionFailure: return R.string.localizable.walletConnectFailureTitle() case .onlyForWatchWallet: return R.string.localizable.walletConnectFailureMustNotBeWatchedWallet() case .walletsNotFound: return R.string.localizable.walletConnectFailureWalletsNotFound() + case .delayedOperation, .cancelled: + return nil } } } diff --git a/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/AppErrors.swift b/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/AppErrors.swift index 6b040f1df..aa9f364aa 100644 --- a/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/AppErrors.swift +++ b/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/AppErrors.swift @@ -29,10 +29,3 @@ public enum WalletApiError: LocalizedError { case requestedServerDisabled case cancelled } - -public struct RequestCanceledDueToWatchWalletError: Error { - public init() {} -} -public struct DelayWalletConnectResponseError: Error { - public init() {} -} diff --git a/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/RpcJson/JsonRpcError.swift b/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/RpcJson/JsonRpcError.swift new file mode 100644 index 000000000..1677b4577 --- /dev/null +++ b/modules/AlphaWalletFoundation/AlphaWalletFoundation/Types/RpcJson/JsonRpcError.swift @@ -0,0 +1,32 @@ +// +// JsonRpcError.swift +// Alamofire +// +// Created by Vladyslav Shepitko on 16.02.2023. +// + +import Foundation + +public struct JsonRpcError: Error, Equatable, Codable { + public let code: Int + public let message: String + + public init(code: Int, message: String) { + self.code = code + self.message = message + } +} + +public extension JsonRpcError { + static let invalidJson = JsonRpcError(code: -32700, message: "An error occurred on the server while parsing the JSON text.") + static let invalidRequest = JsonRpcError(code: -32600, message: "The JSON sent is not a valid Request object.") + static let methodNotFound = JsonRpcError(code: -32601, message: "The method does not exist / is not available.") + static let invalidParams = JsonRpcError(code: -32602, message: "Invalid method parameter(s).") + static let internalError = JsonRpcError(code: -32603, message: "Internal JSON-RPC error.") + static let responseError = JsonRpcError(code: -32010, message: "Response error.") + static let requestRejected = JsonRpcError(code: -32050, message: "Request rejected") + + static func unsupportedChain(chainId: String) -> JsonRpcError { + JsonRpcError(code: 4902, message: "Unrecognized chain ID \(chainId). Try adding the chain using wallet_addEthereumChain first.") + } +}