diff --git a/.github/actions/ci/action.yml b/.github/actions/ci/action.yml index 4e6735c13..1e887a78c 100644 --- a/.github/actions/ci/action.yml +++ b/.github/actions/ci/action.yml @@ -16,7 +16,8 @@ runs: -project Example/ExampleApp.xcodeproj \ -scheme WalletConnect \ -clonedSourcePackagesDirPath SourcePackages \ - -sdk iphonesimulator" + -destination 'platform=iOS Simulator,name=iPhone 13' \ + test" # Integration tests - name: Run integration tests diff --git a/Sources/Auth/Services/App/AuthRespondSubscriber.swift b/Sources/Auth/Services/App/AuthRespondSubscriber.swift new file mode 100644 index 000000000..a6f1f8b57 --- /dev/null +++ b/Sources/Auth/Services/App/AuthRespondSubscriber.swift @@ -0,0 +1,39 @@ +import Combine +import Foundation +import WalletConnectUtils +import JSONRPC + +class AuthRespondSubscriber { + private let networkingInteractor: NetworkInteracting + private let logger: ConsoleLogging + private let rpcHistory: RPCHistory + private var publishers = [AnyCancellable]() + var onResponse: ((_ id: RPCID, _ cacao: Cacao) -> Void)? + + init(networkingInteractor: NetworkInteracting, + logger: ConsoleLogging, + rpcHistory: RPCHistory) { + self.networkingInteractor = networkingInteractor + self.logger = logger + self.rpcHistory = rpcHistory + subscribeForResponse() + } + + private func subscribeForResponse() { + networkingInteractor.responsePublisher.sink { [unowned self] subscriptionPayload in + guard let request = rpcHistory.get(recordId: subscriptionPayload.request.id!)?.request, + request.method == "wc_authRequest" else { return } + networkingInteractor.unsubscribe(topic: subscriptionPayload.topic) + guard let cacao = try? subscriptionPayload.request.result?.get(Cacao.self) else { + logger.debug("Malformed auth response params") + return + } + do { + try CacaoSignatureVerifier().verifySignature(cacao) + onResponse?(subscriptionPayload.request.id!, cacao) + } catch { + logger.debug("Received response with invalid signature") + } + }.store(in: &publishers) + } +} diff --git a/Sources/Auth/Services/Common/CacaoSignatureVerifier.swift b/Sources/Auth/Services/Common/CacaoSignatureVerifier.swift new file mode 100644 index 000000000..64f70488b --- /dev/null +++ b/Sources/Auth/Services/Common/CacaoSignatureVerifier.swift @@ -0,0 +1,15 @@ +import Foundation + +protocol CacaoSignatureVerifying { + func verifySignature(_ cacao: Cacao) throws +} + +class CacaoSignatureVerifier: CacaoSignatureVerifying { + enum Errors: Error { + case signatureInvalid + } + + func verifySignature(_ cacao: Cacao) throws { + fatalError("not implemented") + } +} diff --git a/Sources/Auth/Services/Common/NetworkingInteractor.swift b/Sources/Auth/Services/Common/NetworkingInteractor.swift index c81420b26..fd480db62 100644 --- a/Sources/Auth/Services/Common/NetworkingInteractor.swift +++ b/Sources/Auth/Services/Common/NetworkingInteractor.swift @@ -7,7 +7,9 @@ import JSONRPC protocol NetworkInteracting { var requestPublisher: AnyPublisher {get} + var responsePublisher: AnyPublisher {get} func subscribe(topic: String) async throws + func unsubscribe(topic: String) func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws func respond(topic: String, response: RPCResponse, tag: Int, envelopeType: Envelope.EnvelopeType) async throws } @@ -26,6 +28,10 @@ class NetworkingInteractor: NetworkInteracting { requestPublisherSubject.eraseToAnyPublisher() } private let requestPublisherSubject = PassthroughSubject() + var responsePublisher: AnyPublisher { + responsePublisherSubject.eraseToAnyPublisher() + } + private let responsePublisherSubject = PassthroughSubject() init(relayClient: RelayClient, serializer: Serializing, @@ -39,6 +45,10 @@ class NetworkingInteractor: NetworkInteracting { try await relayClient.subscribe(topic: topic) } + func unsubscribe(topic: String) { + fatalError("not implemented") + } + func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws { try rpcHistory.set(request, forTopic: topic, emmitedBy: .local) let message = try! serializer.serialize(topic: topic, encodable: request, envelopeType: envelopeType) diff --git a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift index edf489f74..733198e33 100644 --- a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift +++ b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift @@ -1,11 +1,76 @@ import Foundation +import WalletConnectUtils protocol SIWEMessageFormatting { - func formatMessage(from request: AuthRequestParams) throws -> String + func formatMessage(from authPayload: AuthPayload, address: String) -> String } struct SIWEMessageFormatter: SIWEMessageFormatting { - func formatMessage(from request: AuthRequestParams) throws -> String { - fatalError("not implemented") + func formatMessage(from authPayload: AuthPayload, address: String) -> String { + SIWEMessage(domain: authPayload.domain, + uri: authPayload.aud, + address: address, + version: authPayload.version, + nonce: authPayload.nonce, + chainId: authPayload.chainId, + iat: authPayload.iat, + nbf: authPayload.nbf, + exp: authPayload.exp, + statement: authPayload.statement, + requestId: authPayload.requestId, + resources: authPayload.resources).formatted + } +} + +fileprivate struct SIWEMessage: Equatable { + let domain: String + let uri: String //aud + let address: String + let version: Int + let nonce: String + let chainId: String + let iat: String + let nbf: String? + let exp: String? + let statement: String? + let requestId: String? + let resources: [String]? + + var formatted: String { + return """ + \(domain) wants you to sign in with your Ethereum account: + \(address) + \(statementLine) + URI: \(uri) + Version: \(version) + Chain ID: \(chainId) + Nonce: \(nonce) + Issued At: \(iat)\(expLine)\(nbfLine)\(requestIdLine)\(resourcesSection) + """ + } + + var expLine: String { + guard let exp = exp else { return "" } + return "\nExpiration Time: \(exp)" + } + + var statementLine: String { + guard let statement = statement else { return "" } + return "\n\(statement)\n" + } + + var nbfLine: String { + guard let nbf = nbf else { return "" } + return "\nNot Before: \(nbf)" + } + + var requestIdLine: String { + guard let requestId = requestId else { return "" } + return "\nRequest ID: \(requestId)" + } + + var resourcesSection: String { + guard let resources = resources else { return "" } + return resources.reduce("\nResources:") { $0 + "\n- \($1)" } } } diff --git a/Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift b/Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift index d65a56bae..a2a5f9b29 100644 --- a/Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift +++ b/Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift @@ -6,15 +6,18 @@ import JSONRPC class AuthRequestSubscriber { private let networkingInteractor: NetworkInteracting private let logger: ConsoleLogging + private let address: String private var publishers = [AnyCancellable]() private let messageFormatter: SIWEMessageFormatting var onRequest: ((_ id: RPCID, _ message: String)->())? init(networkingInteractor: NetworkInteracting, logger: ConsoleLogging, - messageFormatter: SIWEMessageFormatting) { + messageFormatter: SIWEMessageFormatting, + address: String) { self.networkingInteractor = networkingInteractor self.logger = logger + self.address = address self.messageFormatter = messageFormatter subscribeForRequest() } @@ -27,7 +30,7 @@ class AuthRequestSubscriber { return } do { - let message = try messageFormatter.formatMessage(from: authRequestParams) + let message = try messageFormatter.formatMessage(from: authRequestParams.payloadParams, address: address) guard let requestId = subscriptionPayload.request.id else { return } onRequest?(requestId, message) } catch { diff --git a/Sources/Auth/Types/AuthPayload.swift b/Sources/Auth/Types/AuthPayload.swift index b281c19d0..35a4b2338 100644 --- a/Sources/Auth/Types/AuthPayload.swift +++ b/Sources/Auth/Types/AuthPayload.swift @@ -1,25 +1,25 @@ import Foundation struct AuthPayload: Codable, Equatable { - let type: String - let chainId: String let domain: String let aud: String - let version: String + let version: Int let nonce: String + let chainId: String + let type: String let iat: String let nbf: String? let exp: String? let statement: String? let requestId: String? - let resources: String? + let resources: [String]? init(requestParams: RequestParams, iat: String) { self.type = "eip4361" self.chainId = requestParams.chainId self.domain = requestParams.domain self.aud = requestParams.aud - self.version = "1" + self.version = 1 self.nonce = requestParams.nonce self.iat = iat self.nbf = requestParams.nbf diff --git a/Sources/Auth/Types/Cacao/Cacao.swift b/Sources/Auth/Types/Cacao/Cacao.swift index 95a2d59c5..80e7ce8b0 100644 --- a/Sources/Auth/Types/Cacao/Cacao.swift +++ b/Sources/Auth/Types/Cacao/Cacao.swift @@ -1,6 +1,6 @@ import Foundation -struct Cacao: Codable, Equatable { +public struct Cacao: Codable, Equatable { let header: CacaoHeader let payload: CacaoPayload let signature: CacaoSignature diff --git a/Sources/Auth/Types/RequestParams.swift b/Sources/Auth/Types/RequestParams.swift index 7a6082f52..24e7afab9 100644 --- a/Sources/Auth/Types/RequestParams.swift +++ b/Sources/Auth/Types/RequestParams.swift @@ -9,5 +9,5 @@ struct RequestParams { let exp: String? let statement: String? let requestId: String? - let resources: String? + let resources: [String]? } diff --git a/Sources/Auth/Types/RequestSubscriptionPayload.swift b/Sources/Auth/Types/RequestSubscriptionPayload.swift index b7865d715..00a5cdcb4 100644 --- a/Sources/Auth/Types/RequestSubscriptionPayload.swift +++ b/Sources/Auth/Types/RequestSubscriptionPayload.swift @@ -1,7 +1,7 @@ import Foundation import JSONRPC -struct RequestSubscriptionPayload: Codable { - let id: Int64 +struct RequestSubscriptionPayload: Codable, Equatable { + let topic: String let request: RPCRequest } diff --git a/Sources/Auth/Types/ResponseSubscriptionPayload.swift b/Sources/Auth/Types/ResponseSubscriptionPayload.swift new file mode 100644 index 000000000..94c77ff86 --- /dev/null +++ b/Sources/Auth/Types/ResponseSubscriptionPayload.swift @@ -0,0 +1,7 @@ +import Foundation +import JSONRPC + +struct ResponseSubscriptionPayload: Codable, Equatable { + let topic: String + let request: RPCResponse +} diff --git a/Sources/WalletConnectRelay/EnvironmentInfo.swift b/Sources/WalletConnectRelay/EnvironmentInfo.swift index f726b7578..1348a621d 100644 --- a/Sources/WalletConnectRelay/EnvironmentInfo.swift +++ b/Sources/WalletConnectRelay/EnvironmentInfo.swift @@ -18,7 +18,7 @@ enum EnvironmentInfo { } static var sdkVersion: String { - "v0.9.2-rc.0" + "v0.9.3-rc.0" } static var operatingSystem: String { diff --git a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift index 1211c63f5..84d871f48 100644 --- a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift +++ b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift @@ -207,7 +207,7 @@ private extension ApproveEngine { ) settlingProposal = proposal - Task(priority: .background) { + Task(priority: .high) { try? await networkingInteractor.subscribe(topic: sessionTopic) } } catch { diff --git a/Tests/AuthTests/AuthRequstSubscriberTests.swift b/Tests/AuthTests/AuthRequstSubscriberTests.swift index c457d9246..990a9cb4f 100644 --- a/Tests/AuthTests/AuthRequstSubscriberTests.swift +++ b/Tests/AuthTests/AuthRequstSubscriberTests.swift @@ -17,7 +17,7 @@ class AuthRequstSubscriberTests: XCTestCase { messageFormatter = SIWEMessageFormatterMock() sut = AuthRequestSubscriber(networkingInteractor: networkingInteractor, logger: ConsoleLoggerMock(), - messageFormatter: messageFormatter) + messageFormatter: messageFormatter, address: "") } func testSubscribeRequest() { diff --git a/Tests/AuthTests/Mocks/NetworkingInteractorMock.swift b/Tests/AuthTests/Mocks/NetworkingInteractorMock.swift index 32e8abe85..2ccd19b84 100644 --- a/Tests/AuthTests/Mocks/NetworkingInteractorMock.swift +++ b/Tests/AuthTests/Mocks/NetworkingInteractorMock.swift @@ -6,6 +6,11 @@ import WalletConnectKMS struct NetworkingInteractorMock: NetworkInteracting { + var responsePublisher: AnyPublisher { + responsePublisherSubject.eraseToAnyPublisher() + } + private let responsePublisherSubject = PassthroughSubject() + let requestPublisherSubject = PassthroughSubject() var requestPublisher: AnyPublisher { requestPublisherSubject.eraseToAnyPublisher() @@ -15,6 +20,10 @@ struct NetworkingInteractorMock: NetworkInteracting { } + func unsubscribe(topic: String) { + + } + func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws { } diff --git a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift index b576bfc68..bce7c4824 100644 --- a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift +++ b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift @@ -3,7 +3,7 @@ import Foundation class SIWEMessageFormatterMock: SIWEMessageFormatting { var formattedMessage: String! - func formatMessage(from request: AuthRequestParams) throws -> String { + func formatMessage(from authPayload: AuthPayload, address: String) -> String { return formattedMessage } } diff --git a/Tests/AuthTests/SIWEMessageFormatterTests.swift b/Tests/AuthTests/SIWEMessageFormatterTests.swift new file mode 100644 index 000000000..98e9945b0 --- /dev/null +++ b/Tests/AuthTests/SIWEMessageFormatterTests.swift @@ -0,0 +1,97 @@ +import Foundation +@testable import Auth +import XCTest + +class SIWEMessageFormatterTests: XCTestCase { + var sut: SIWEMessageFormatter! + let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + + + override func setUp() { + sut = SIWEMessageFormatter() + } + + func testFormatMessage() { + let expectedMessage = + """ + service.invalid wants you to sign in with your Ethereum account: + 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + + I accept the ServiceOrg Terms of Service: https://service.invalid/tos + + URI: https://service.invalid/login + Version: 1 + Chain ID: 1 + Nonce: 32891756 + Issued At: 2021-09-30T16:25:24Z + Resources: + - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ + - https://example.com/my-web2-claim.json + """ + let message = sut.formatMessage(from: AuthPayload.stub(), address: address) + XCTAssertEqual(message, expectedMessage) + } + + func testNilStatement() { + let expectedMessage = + """ + service.invalid wants you to sign in with your Ethereum account: + 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + + URI: https://service.invalid/login + Version: 1 + Chain ID: 1 + Nonce: 32891756 + Issued At: 2021-09-30T16:25:24Z + Resources: + - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ + - https://example.com/my-web2-claim.json + """ + let message = sut.formatMessage( + from: AuthPayload.stub( + requestParams: RequestParams.stub(statement: nil)), + address: address) + XCTAssertEqual(message, expectedMessage) + } + + func testNilResources() { + let expectedMessage = + """ + service.invalid wants you to sign in with your Ethereum account: + 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + + I accept the ServiceOrg Terms of Service: https://service.invalid/tos + + URI: https://service.invalid/login + Version: 1 + Chain ID: 1 + Nonce: 32891756 + Issued At: 2021-09-30T16:25:24Z + """ + let message = sut.formatMessage( + from: AuthPayload.stub( + requestParams: RequestParams.stub(resources: nil)), + address: address) + XCTAssertEqual(message, expectedMessage) + } + + func testNilAllOptionalParams() { + let expectedMessage = + """ + service.invalid wants you to sign in with your Ethereum account: + 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + + URI: https://service.invalid/login + Version: 1 + Chain ID: 1 + Nonce: 32891756 + Issued At: 2021-09-30T16:25:24Z + """ + let message = sut.formatMessage( + from: AuthPayload.stub( + requestParams: RequestParams.stub(statement: nil, + resources: nil)), + address: address) + XCTAssertEqual(message, expectedMessage) + } +} diff --git a/Tests/AuthTests/Stubs/AuthPayload.swift b/Tests/AuthTests/Stubs/AuthPayload.swift new file mode 100644 index 000000000..c305aee03 --- /dev/null +++ b/Tests/AuthTests/Stubs/AuthPayload.swift @@ -0,0 +1,8 @@ +import Foundation +@testable import Auth + +extension AuthPayload { + static func stub(requestParams: RequestParams = RequestParams.stub()) -> AuthPayload { + AuthPayload(requestParams: requestParams, iat: "2021-09-30T16:25:24Z") + } +} diff --git a/Tests/AuthTests/Stubs/RequestParams.swift b/Tests/AuthTests/Stubs/RequestParams.swift index 9a3890289..e594798ee 100644 --- a/Tests/AuthTests/Stubs/RequestParams.swift +++ b/Tests/AuthTests/Stubs/RequestParams.swift @@ -2,7 +2,23 @@ import Foundation @testable import Auth extension RequestParams { - static func stub() -> RequestParams { - return RequestParams(domain: "", chainId: "", nonce: "", aud: "", nbf: nil, exp: nil, statement: nil, requestId: nil, resources: nil) + static func stub(domain: String = "service.invalid", + chainId: String = "1", + nonce: String = "32891756", + aud: String = "https://service.invalid/login", + nbf: String? = nil, + exp: String? = nil, + statement: String? = "I accept the ServiceOrg Terms of Service: https://service.invalid/tos", + requestId: String? = nil, + resources: [String]? = ["ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/", "https://example.com/my-web2-claim.json"]) -> RequestParams { + return RequestParams(domain: domain, + chainId: chainId, + nonce: nonce, + aud: aud, + nbf: nbf, + exp: exp, + statement: statement, + requestId: requestId, + resources: resources) } } diff --git a/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift b/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift index afeb1c281..48ded537d 100644 --- a/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift +++ b/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift @@ -10,6 +10,6 @@ extension RequestSubscriptionPayload { let payload = AuthPayload(requestParams: RequestParams.stub(), iat: issueAt) let params = AuthRequestParams(requester: requester, payloadParams: payload) let request = RPCRequest(method: "wc_authRequest", params: params, rpcid: id) - return RequestSubscriptionPayload(id: 123, request: request) + return RequestSubscriptionPayload(topic: "123", request: request) } } diff --git a/Tests/JSONRPCTests/Helpers.swift b/Tests/JSONRPCTests/Helpers.swift index 9ffc0b45c..df20bab6b 100644 --- a/Tests/JSONRPCTests/Helpers.swift +++ b/Tests/JSONRPCTests/Helpers.swift @@ -3,14 +3,14 @@ import Commons final class TestIdentifierGenerator: IdentifierGenerator { - var id: RPCID = .right(Int.random()) + var id: RPCID = .right(Int64.random()) func next() -> RPCID { return id } } -extension Either where L == String, R == Int { +extension Either where L == String, R == Int64 { var isString: Bool { left != nil diff --git a/Tests/JSONRPCTests/RPCRequestTests.swift b/Tests/JSONRPCTests/RPCRequestTests.swift index be2460bee..f34d365ba 100644 --- a/Tests/JSONRPCTests/RPCRequestTests.swift +++ b/Tests/JSONRPCTests/RPCRequestTests.swift @@ -5,13 +5,13 @@ import TestingUtils private func makeRequests() -> [RPCRequest] { return [ - RPCRequest(method: String.random(), id: Int.random()), + RPCRequest(method: String.random(), id: Int64.random()), RPCRequest(method: String.random(), id: String.random()), - RPCRequest(method: String.random(), params: EmptyCodable(), id: Int.random()), + RPCRequest(method: String.random(), params: EmptyCodable(), id: Int64.random()), RPCRequest(method: String.random(), params: EmptyCodable(), id: String.random()), - RPCRequest(method: String.random(), params: [0, 1, 2], id: Int.random()), + RPCRequest(method: String.random(), params: [0, 1, 2], id: Int64.random()), RPCRequest(method: String.random(), params: ["0", "1", "2"], id: String.random()), - RPCRequest(method: String.random(), params: [AnyCodable(0), AnyCodable("0")], id: Int.random()), + RPCRequest(method: String.random(), params: [AnyCodable(0), AnyCodable("0")], id: Int64.random()), RPCRequest(method: String.random(), params: [AnyCodable(0), AnyCodable("0")], id: String.random()) ] } @@ -38,21 +38,21 @@ final class RPCRequestTests: XCTestCase { func testCheckedParamsInit() { XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: [0])) - XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: [0], id: Int.random())) + XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: [0], id: Int64.random())) XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: [0], id: String.random())) XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: EmptyCodable())) - XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: EmptyCodable(), id: Int.random())) + XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: EmptyCodable(), id: Int64.random())) XCTAssertNoThrow(try RPCRequest(method: "method", checkedParams: EmptyCodable(), id: String.random())) } func testCheckedParamsInitFailsWithPrimitives() { - XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: 0, id: Int.random())) + XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: 0, id: Int64.random())) XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: 0, id: String.random())) - XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: "string", id: Int.random())) + XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: "string", id: Int64.random())) XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: "string", id: String.random())) - XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: Double.pi, id: Int.random())) + XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: Double.pi, id: Int64.random())) XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: Double.pi, id: String.random())) - XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: true, id: Int.random())) + XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: true, id: Int64.random())) XCTAssertThrowsError(try RPCRequest(method: "method", checkedParams: true, id: String.random())) } diff --git a/Tests/JSONRPCTests/RPCResponseTests.swift b/Tests/JSONRPCTests/RPCResponseTests.swift index 954dcc322..d067761b3 100644 --- a/Tests/JSONRPCTests/RPCResponseTests.swift +++ b/Tests/JSONRPCTests/RPCResponseTests.swift @@ -5,20 +5,20 @@ import TestingUtils private func makeResultResponses() -> [RPCResponse] { return [ - RPCResponse(id: Int.random(), result: Int.random()), - RPCResponse(id: Int.random(), result: Bool.random()), - RPCResponse(id: Int.random(), result: String.random()), - RPCResponse(id: Int.random(), result: (1...10).map { String($0) }), - RPCResponse(id: Int.random(), result: EmptyCodable()), + RPCResponse(id: Int64.random(), result: Int.random()), + RPCResponse(id: Int64.random(), result: Bool.random()), + RPCResponse(id: Int64.random(), result: String.random()), + RPCResponse(id: Int64.random(), result: (1...10).map { String($0) }), + RPCResponse(id: Int64.random(), result: EmptyCodable()), RPCResponse(id: String.random(), result: Int.random()) ] } private func makeErrorResponses() -> [RPCResponse] { return [ - RPCResponse(id: Int.random(), error: JSONRPCError.stub()), + RPCResponse(id: Int64.random(), error: JSONRPCError.stub()), RPCResponse(id: String.random(), error: JSONRPCError.stub(data: AnyCodable(Int.random()))), - RPCResponse(id: Int.random(), errorCode: Int.random(), message: String.random(), associatedData: AnyCodable(String.random())), + RPCResponse(id: Int64.random(), errorCode: Int.random(), message: String.random(), associatedData: AnyCodable(String.random())), RPCResponse(id: String.random(), errorCode: Int.random(), message: String.random(), associatedData: nil) ] } diff --git a/Tests/TestingUtils/Helpers.swift b/Tests/TestingUtils/Helpers.swift index dbe46147d..00cd925e1 100644 --- a/Tests/TestingUtils/Helpers.swift +++ b/Tests/TestingUtils/Helpers.swift @@ -9,6 +9,12 @@ public extension Int { } } +public extension Int64 { + static func random() -> Int64 { + random(in: Int64.min...Int64.max) + } +} + public extension Double { // Do not use this function when testing Codables: https://bugs.swift.org/browse/SR-7054 diff --git a/Tests/WalletConnectSignTests/Mocks/NetworkingInteractorMock.swift b/Tests/WalletConnectSignTests/Mocks/NetworkingInteractorMock.swift index 49d220625..a76d6ef91 100644 --- a/Tests/WalletConnectSignTests/Mocks/NetworkingInteractorMock.swift +++ b/Tests/WalletConnectSignTests/Mocks/NetworkingInteractorMock.swift @@ -76,8 +76,8 @@ class NetworkingInteractorMock: NetworkInteracting { } func subscribe(topic: String) { - didCallSubscribe = true subscriptions.append(topic) + didCallSubscribe = true } func unsubscribe(topic: String) { diff --git a/Tests/WalletConnectSignTests/PairingEngineTests.swift b/Tests/WalletConnectSignTests/PairingEngineTests.swift index f31a6ab2c..785be6dc2 100644 --- a/Tests/WalletConnectSignTests/PairingEngineTests.swift +++ b/Tests/WalletConnectSignTests/PairingEngineTests.swift @@ -85,8 +85,6 @@ final class PairingEngineTests: XCTestCase { XCTAssertEqual(publishTopic, topicA) } - // Flaky test: asserting `topicB` and `sessionTopic` failed once, couldn't reproduce - @MainActor func testHandleSessionProposeResponse() async { let uri = try! await engine.create() let pairing = storageMock.getPairing(forTopic: uri.topic)! diff --git a/Tests/WalletConnectUtilsTests/RPCHistoryTests.swift b/Tests/WalletConnectUtilsTests/RPCHistoryTests.swift index 10bfbc049..37b05ccdd 100644 --- a/Tests/WalletConnectUtilsTests/RPCHistoryTests.swift +++ b/Tests/WalletConnectUtilsTests/RPCHistoryTests.swift @@ -65,7 +65,7 @@ final class RPCHistoryTests: XCTestCase { func testSetDuplicateRequest() throws { let expectedError = RPCHistory.HistoryError.requestDuplicateNotAllowed - let id = Int.random() + let id = Int64.random() let requestA = RPCRequest.stub(method: "method-1", id: id) let requestB = RPCRequest.stub(method: "method-2", id: id) let topic = String.randomTopic()