From 11c2def4e5bd20be475ad367659d887b530876e1 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Wed, 18 May 2022 09:59:32 +0200 Subject: [PATCH 1/3] remove code examples --- README.md | 64 +------------------------------------------------------ 1 file changed, 1 insertion(+), 63 deletions(-) diff --git a/README.md b/README.md index 7cdc2e9b2..22eaee5ee 100644 --- a/README.md +++ b/README.md @@ -5,75 +5,13 @@ Swift implementation of WalletConnect v.2 protocol for native iOS applications. - XCode 13 - Swift 5 -## Documentation +## Documentation & Usage - In order to build API documentation in XCode go to Product -> Build Documentation - [Getting started with wallet integration](https://docs.walletconnect.com/2.0/quick-start/wallets/swift) - [Beginner guide to WalletConnect v2.0 for iOS Developers](https://medium.com/walletconnect/beginner-guide-to-walletconnect-v2-0-for-swift-developers-4534b0975218) - [Protocol Documentation](https://docs.walletconnect.com/2.0/protocol/client-communication) - [Glossary](https://docs.walletconnect.com/2.0/protocol/glossary) -## Usage -### Responder -Responder client is usually a wallet. -##### Instantiate a Client -You usually want to have a single instance of a client in you app. -```Swift - let metadata = AppMetadata(name: String?, - description: String?, - url: String?, - icons: [String]?) - let client = AuthClient(metadata: AppMetadata, - projectId: String, - relayHost: String) -``` - -After instantiation of a client set its delegate. -#### Pair Clients -Pair client with a uri generated by the `proposer` client. -```Swift -let uri = "wc:..." -try! client.pair(uri: uri) -``` -#### Approve Session -Sessions are always proposed by the `Proposer` client so `Responder` client needs either reject or approve a session proposal. -```Swift -class ClientDelegate: AuthClientDelegate { -... - func didReceive(sessionProposal: Session.Proposal) { - client.approve(proposal: proposal, accounts: [String]) - } -... -``` -or -```Swift - func didReceive(sessionProposal: Session.Proposal) { - client.reject(proposal: proposal, reason: Reason) - } -``` -NOTE: addresses provided in `accounts` array should follow [CAPI10](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-10.md) semantics. -#### Handle Delegate methods -```Swift - func didReceive(sessionProposal: Session.Proposal) { - // handle session proposal - } - func didReceive(sessionRequest: Request) { - // handle session request - } -``` -#### JSON-RPC Payloads -#### Receive -You can parse JSON-RPC Requests received from "Requester" in `didReceive(sessionRequest: Request)` delegate function. - -Request parameters can be type casted based on request method as below: -```Swift - let params = try! sessionRequest.request.params.get([EthSendTransaction].self) -``` -##### Respond - -```Swift - let jsonrpcResponse = JSONRPCResponse(id: request.id, result: AnyCodable(responseParams)) - client.respond(topic: sessionRequest.topic, response: .response(jsonrpcResponse)) -``` ## Installation ### Swift Package Manager From cc886f064aed27fea724e660096f525886dd437c Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Wed, 18 May 2022 10:34:02 +0200 Subject: [PATCH 2/3] add Concurrency to extend and update functions --- Sources/WalletConnectAuth/AuthClient.swift | 8 ++++---- .../Engine/Controller/ControllerSessionStateMachine.swift | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/WalletConnectAuth/AuthClient.swift b/Sources/WalletConnectAuth/AuthClient.swift index 5a7f86d7b..622d67c1c 100644 --- a/Sources/WalletConnectAuth/AuthClient.swift +++ b/Sources/WalletConnectAuth/AuthClient.swift @@ -176,18 +176,18 @@ public final class AuthClient { /// - Parameters: /// - topic: Topic of the session that is intended to be updated. /// - methods: Sets of methods that will replace existing ones. - public func update(topic: String, namespaces: [String: SessionNamespace]) throws { - try controllerSessionStateMachine.update(topic: topic, namespaces: namespaces) + public func update(topic: String, namespaces: [String: SessionNamespace]) async throws { + try await controllerSessionStateMachine.update(topic: topic, namespaces: namespaces) } /// For controller to update expiry of a session /// - Parameters: /// - topic: Topic of the Session, it can be a pairing or a session topic. /// - ttl: Time in seconds that a target session is expected to be extended for. Must be greater than current time to expire and than 7 days - public func extend(topic: String) throws { + public func extend(topic: String) async throws { let ttl: Int64 = Session.defaultTimeToLive if sessionEngine.hasSession(for: topic) { - try controllerSessionStateMachine.extend(topic: topic, by: ttl) + try await controllerSessionStateMachine.extend(topic: topic, by: ttl) } } diff --git a/Sources/WalletConnectAuth/Engine/Controller/ControllerSessionStateMachine.swift b/Sources/WalletConnectAuth/Engine/Controller/ControllerSessionStateMachine.swift index fcb8fc321..328146465 100644 --- a/Sources/WalletConnectAuth/Engine/Controller/ControllerSessionStateMachine.swift +++ b/Sources/WalletConnectAuth/Engine/Controller/ControllerSessionStateMachine.swift @@ -28,23 +28,23 @@ final class ControllerSessionStateMachine: SessionStateMachineValidating { } // TODO: Change to new namespace spec - func update(topic: String, namespaces: [String: SessionNamespace]) throws { + func update(topic: String, namespaces: [String: SessionNamespace]) async throws { var session = try getSession(for: topic) try validateControlledAcknowledged(session) try Validator.validate(namespaces) logger.debug("Controller will update methods") session.updateNamespaces(namespaces) sessionStore.setSession(session) - networkingInteractor.request(.wcSessionUpdate(SessionType.UpdateParams(namespaces: namespaces)), onTopic: topic) + try await networkingInteractor.request(.wcSessionUpdate(SessionType.UpdateParams(namespaces: namespaces)), onTopic: topic) } - func extend(topic: String, by ttl: Int64) throws { + func extend(topic: String, by ttl: Int64) async throws { var session = try getSession(for: topic) try validateControlledAcknowledged(session) try session.updateExpiry(by: ttl) let newExpiry = Int64(session.expiryDate.timeIntervalSince1970 ) sessionStore.setSession(session) - networkingInteractor.request(.wcSessionExtend(SessionType.UpdateExpiryParams(expiry: newExpiry)), onTopic: topic) + try await networkingInteractor.request(.wcSessionExtend(SessionType.UpdateExpiryParams(expiry: newExpiry)), onTopic: topic) } // MARK: - Handle Response From ee955b42d13e3ba8649a32c90ef2bd8fba503ec7 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Wed, 18 May 2022 10:47:07 +0200 Subject: [PATCH 3/3] fix tests, add XCTAssertNoThrowAsync --- Tests/TestingUtils/XCTest.swift | 13 ++++++++ .../ControllerSessionStateMachineTests.swift | 32 +++++++++---------- .../WalletConnectTests/PairEngineTests.swift | 3 +- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Tests/TestingUtils/XCTest.swift b/Tests/TestingUtils/XCTest.swift index 890b2110c..e3048f849 100644 --- a/Tests/TestingUtils/XCTest.swift +++ b/Tests/TestingUtils/XCTest.swift @@ -17,4 +17,17 @@ extension XCTest { errorHandler(error) } } + + public func XCTAssertNoThrowAsync( + _ expression: @autoclosure () async throws -> T, + _ message: @autoclosure () -> String = "", + file: StaticString = #filePath, + line: UInt = #line + ) async { + do { + _ = try await expression() + } catch { + XCTFail(message(), file: file, line: line) + } + } } diff --git a/Tests/WalletConnectTests/ControllerSessionStateMachineTests.swift b/Tests/WalletConnectTests/ControllerSessionStateMachineTests.swift index 1eca9b489..a7756b17b 100644 --- a/Tests/WalletConnectTests/ControllerSessionStateMachineTests.swift +++ b/Tests/WalletConnectTests/ControllerSessionStateMachineTests.swift @@ -38,16 +38,16 @@ class ControllerSessionStateMachineTests: XCTestCase { // XCTAssertEqual(namespacesToUpdate, updatedSession?.namespaces) // } - func testUpdateNamespacesErrorSessionNotFound() { - XCTAssertThrowsError(try sut.update(topic: "", namespaces: SessionNamespace.stubDictionary())) { error in + func testUpdateNamespacesErrorSessionNotFound() async { + await XCTAssertThrowsErrorAsync( try await sut.update(topic: "", namespaces: SessionNamespace.stubDictionary())) { error in XCTAssertTrue(error.isNoSessionMatchingTopicError) } } - func testUpdateNamespacesErrorSessionNotAcknowledged() { + func testUpdateNamespacesErrorSessionNotAcknowledged() async { let session = WCSession.stub(acknowledged: false) storageMock.setSession(session) - XCTAssertThrowsError(try sut.update(topic: session.topic, namespaces: SessionNamespace.stubDictionary())) { error in + await XCTAssertThrowsErrorAsync( try await sut.update(topic: session.topic, namespaces: SessionNamespace.stubDictionary())) { error in XCTAssertTrue(error.isSessionNotAcknowledgedError) } } @@ -60,55 +60,55 @@ class ControllerSessionStateMachineTests: XCTestCase { // } // } - func testUpdateNamespacesErrorCalledByNonController() { + func testUpdateNamespacesErrorCalledByNonController() async { let session = WCSession.stub(isSelfController: false) storageMock.setSession(session) - XCTAssertThrowsError(try sut.update(topic: session.topic, namespaces: SessionNamespace.stubDictionary())) { error in + await XCTAssertThrowsErrorAsync( try await sut.update(topic: session.topic, namespaces: SessionNamespace.stubDictionary())) { error in XCTAssertTrue(error.isUnauthorizedNonControllerCallError) } } // MARK: - Update Expiry - func testUpdateExpirySuccess() { + func testUpdateExpirySuccess() async { let tomorrow = TimeTraveler.dateByAdding(days: 1) let session = WCSession.stub(isSelfController: true, expiryDate: tomorrow) storageMock.setSession(session) let twoDays = 2*Time.day - XCTAssertNoThrow(try sut.extend(topic: session.topic, by: Int64(twoDays))) + await XCTAssertNoThrowAsync(try await sut.extend(topic: session.topic, by: Int64(twoDays))) let extendedSession = storageMock.getAcknowledgedSessions().first{$0.topic == session.topic}! XCTAssertEqual(extendedSession.expiryDate.timeIntervalSinceReferenceDate, TimeTraveler.dateByAdding(days: 2).timeIntervalSinceReferenceDate, accuracy: 1) } - func testUpdateExpirySessionNotSettled() { + func testUpdateExpirySessionNotSettled() async { let tomorrow = TimeTraveler.dateByAdding(days: 1) let session = WCSession.stub(isSelfController: false, expiryDate: tomorrow, acknowledged: false) storageMock.setSession(session) let twoDays = 2*Time.day - XCTAssertThrowsError(try sut.extend(topic: session.topic, by: Int64(twoDays))) + await XCTAssertThrowsErrorAsync(try await sut.extend(topic: session.topic, by: Int64(twoDays))) } - func testUpdateExpiryOnNonControllerClient() { + func testUpdateExpiryOnNonControllerClient() async { let tomorrow = TimeTraveler.dateByAdding(days: 1) let session = WCSession.stub(isSelfController: false, expiryDate: tomorrow) storageMock.setSession(session) let twoDays = 2*Time.day - XCTAssertThrowsError(try sut.extend(topic: session.topic, by: Int64(twoDays))) + await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: Int64(twoDays))) } - func testUpdateExpiryTtlTooHigh() { + func testUpdateExpiryTtlTooHigh() async { let tomorrow = TimeTraveler.dateByAdding(days: 1) let session = WCSession.stub(isSelfController: true, expiryDate: tomorrow) storageMock.setSession(session) let tenDays = 10*Time.day - XCTAssertThrowsError(try sut.extend(topic: session.topic, by: Int64(tenDays))) + await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: Int64(tenDays))) } - func testUpdateExpiryTtlTooLow() { + func testUpdateExpiryTtlTooLow() async { let dayAfterTommorow = TimeTraveler.dateByAdding(days: 2) let session = WCSession.stub(isSelfController: true, expiryDate: dayAfterTommorow) storageMock.setSession(session) let oneDay = Int64(1*Time.day) - XCTAssertThrowsError(try sut.extend(topic: session.topic, by: oneDay)) + await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: oneDay)) } } diff --git a/Tests/WalletConnectTests/PairEngineTests.swift b/Tests/WalletConnectTests/PairEngineTests.swift index e819141ea..d22f98a47 100644 --- a/Tests/WalletConnectTests/PairEngineTests.swift +++ b/Tests/WalletConnectTests/PairEngineTests.swift @@ -42,9 +42,8 @@ final class PairEngineTests: XCTestCase { func testPairMultipleTimesOnSameURIThrows() async { let uri = WalletConnectURI.stub() for i in 1...10 { - usleep(100) if i == 1 { - XCTAssertNoThrow(Task{try await engine.pair(uri)}) + await XCTAssertNoThrowAsync(try await engine.pair(uri)) } else { await XCTAssertThrowsErrorAsync(try await engine.pair(uri)) }