From 0896eeac64fe348b4a9a4f330f7883ceb60a7e00 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Tue, 20 Aug 2024 16:39:44 -0600 Subject: [PATCH 1/5] Drop the db connection before deleting the db (#389) * bump to latest * add the try --- Package.swift | 2 +- Sources/XMTPiOS/Client.swift | 1 + XMTP.podspec | 4 ++-- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index 7a1c3498..f69541a6 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), - .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.7-beta3"), + .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.7-beta4"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/XMTPiOS/Client.swift b/Sources/XMTPiOS/Client.swift index 146c854b..7e3273a3 100644 --- a/Sources/XMTPiOS/Client.swift +++ b/Sources/XMTPiOS/Client.swift @@ -543,6 +543,7 @@ public final class Client { } public func deleteLocalDatabase() throws { + try dropLocalDatabaseConnection() let fm = FileManager.default try fm.removeItem(atPath: dbPath) } diff --git a/XMTP.podspec b/XMTP.podspec index fd724250..dd81f389 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "XMTP" - spec.version = "0.14.6" + spec.version = "0.14.7" spec.summary = "XMTP SDK Cocoapod" # This description is used to generate tags and improve search results. @@ -44,5 +44,5 @@ Pod::Spec.new do |spec| spec.dependency "web3.swift" spec.dependency "GzipSwift" spec.dependency "Connect-Swift", "= 0.12.0" - spec.dependency 'LibXMTP', '= 0.5.7-beta3' + spec.dependency 'LibXMTP', '= 0.5.7-beta4' end diff --git a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 77adf40f..5f1e124e 100644 --- a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "0b2d92a8da6caa2e5f16a2ea060b099278354d74", - "version" : "0.5.7-beta3" + "revision" : "39a3bfd39adc93cf3207946ab302a3579014f369", + "version" : "0.5.7-beta4" } }, { From 2b3e409b87c9b1092d7b5924eae3e5a351703b1e Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Wed, 21 Aug 2024 17:32:25 -0600 Subject: [PATCH 2/5] Add ability to revoke installations (#391) * add revokaction ability and inbox state * write a test for it * get the test passing * update the resolved --- Package.swift | 2 +- Sources/XMTPiOS/Client.swift | 22 +++++++++++ Sources/XMTPiOS/Mls/InboxState.swift | 34 +++++++++++++++++ Tests/XMTPTests/ClientTests.swift | 37 +++++++++++++++++++ XMTP.podspec | 4 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- 6 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 Sources/XMTPiOS/Mls/InboxState.swift diff --git a/Package.swift b/Package.swift index f69541a6..4f2a16d0 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), - .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.7-beta4"), + .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.8-beta0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/XMTPiOS/Client.swift b/Sources/XMTPiOS/Client.swift index 7e3273a3..62071acf 100644 --- a/Sources/XMTPiOS/Client.swift +++ b/Sources/XMTPiOS/Client.swift @@ -603,4 +603,26 @@ public final class Client { } try await client.requestHistorySync() } + + public func revokeAllOtherInstallations(signingKey: SigningKey) async throws { + guard let client = v3Client else { + throw ClientError.noV3Client("Error: No V3 client initialized") + } + + let signatureRequest = try await client.revokeAllOtherInstallations() + do { + let signedData = try await signingKey.sign(message: signatureRequest.signatureText()) + try await signatureRequest.addEcdsaSignature(signatureBytes: signedData.rawData) + try await client.applySignatureRequest(signatureRequest: signatureRequest) + } catch { + throw ClientError.creationError("Failed to sign the message: \(error.localizedDescription)") + } + } + + public func inboxState(refreshFromNetwork: Bool) async throws -> InboxState { + guard let client = v3Client else { + throw ClientError.noV3Client("Error: No V3 client initialized") + } + return InboxState(ffiInboxState: try await client.inboxState(refreshFromNetwork: refreshFromNetwork)) + } } diff --git a/Sources/XMTPiOS/Mls/InboxState.swift b/Sources/XMTPiOS/Mls/InboxState.swift new file mode 100644 index 00000000..f604f15c --- /dev/null +++ b/Sources/XMTPiOS/Mls/InboxState.swift @@ -0,0 +1,34 @@ +// +// InboxState.swift +// +// +// Created by Naomi Plasterer on 8/21/24. +// + +import Foundation +import LibXMTP + +public struct InboxState { + var ffiInboxState: FfiInboxState + + init(ffiInboxState: FfiInboxState) { + self.ffiInboxState = ffiInboxState + } + + public var inboxId: String { + ffiInboxState.inboxId + } + + public var addresses: [String] { + ffiInboxState.accountAddresses + } + + public var installationIds: [String] { + ffiInboxState.installationIds.map { $0.toHex } + } + + public var recoveryAddress: String { + ffiInboxState.recoveryAddress + } + +} diff --git a/Tests/XMTPTests/ClientTests.swift b/Tests/XMTPTests/ClientTests.swift index 6ecdf6bd..27c0381a 100644 --- a/Tests/XMTPTests/ClientTests.swift +++ b/Tests/XMTPTests/ClientTests.swift @@ -455,4 +455,41 @@ class ClientTests: XCTestCase { XCTAssertEqual(inboxId, alixClient.inboxID) } + + func testRevokesAllOtherInstallations() async throws { + let key = try Crypto.secureRandomBytes(count: 32) + let alix = try PrivateKey.generate() + let options = ClientOptions.init( + api: .init(env: .local, isSecure: false), + enableV3: true, + encryptionKey: key + ) + + let alixClient = try await Client.create( + account: alix, + options: options + ) + try alixClient.dropLocalDatabaseConnection() + try alixClient.deleteLocalDatabase() + + let alixClient2 = try await Client.create( + account: alix, + options: options + ) + try alixClient2.dropLocalDatabaseConnection() + try alixClient2.deleteLocalDatabase() + + let alixClient3 = try await Client.create( + account: alix, + options: options + ) + + let state = try await alixClient3.inboxState(refreshFromNetwork: true) + XCTAssertEqual(state.installationIds.count, 3) + + try await alixClient3.revokeAllOtherInstallations(signingKey: alix) + + let newState = try await alixClient3.inboxState(refreshFromNetwork: true) + XCTAssertEqual(newState.installationIds.count, 1) + } } diff --git a/XMTP.podspec b/XMTP.podspec index dd81f389..04c6fc6d 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "XMTP" - spec.version = "0.14.7" + spec.version = "0.14.8" spec.summary = "XMTP SDK Cocoapod" # This description is used to generate tags and improve search results. @@ -44,5 +44,5 @@ Pod::Spec.new do |spec| spec.dependency "web3.swift" spec.dependency "GzipSwift" spec.dependency "Connect-Swift", "= 0.12.0" - spec.dependency 'LibXMTP', '= 0.5.7-beta4' + spec.dependency 'LibXMTP', '= 0.5.8-beta0' end diff --git a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 5f1e124e..44ba5919 100644 --- a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "39a3bfd39adc93cf3207946ab302a3579014f369", - "version" : "0.5.7-beta4" + "revision" : "5ff057ed6ab42ba8cdc9cb9c107dddfc5fb4746b", + "version" : "0.5.8-beta0" } }, { From 2e34f53ec5f6ef04c4b19ed6762c0d4700de3618 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Wed, 21 Aug 2024 18:06:19 -0600 Subject: [PATCH 3/5] add ability to sync all groups (#392) --- Sources/XMTPiOS/Conversations.swift | 7 +++++++ Tests/XMTPTests/GroupTests.swift | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Sources/XMTPiOS/Conversations.swift b/Sources/XMTPiOS/Conversations.swift index b0c34042..5cf8e419 100644 --- a/Sources/XMTPiOS/Conversations.swift +++ b/Sources/XMTPiOS/Conversations.swift @@ -103,6 +103,13 @@ public actor Conversations { } try await v3Client.conversations().sync() } + + public func syncAllGroups() async throws { + guard let v3Client = client.v3Client else { + return + } + try await v3Client.conversations().syncAllGroups() + } public func groups(createdAfter: Date? = nil, createdBefore: Date? = nil, limit: Int? = nil) async throws -> [Group] { guard let v3Client = client.v3Client else { diff --git a/Tests/XMTPTests/GroupTests.swift b/Tests/XMTPTests/GroupTests.swift index 1eb3bd97..9628d546 100644 --- a/Tests/XMTPTests/GroupTests.swift +++ b/Tests/XMTPTests/GroupTests.swift @@ -838,6 +838,34 @@ class GroupTests: XCTestCase { XCTAssertEqual(preparedMessageId, messages.first!.id) } + func testCanSyncManyGroupsInUnderASecond() async throws { + let fixtures = try await localFixtures() + var groups: [Group] = [] + + for _ in 0..<100 { + var group = try await fixtures.aliceClient.conversations.newGroup(with: [fixtures.bob.address]) + groups.append(group) + } + try await fixtures.bobClient.conversations.sync() + let bobGroup = try fixtures.bobClient.findGroup(groupId: groups[0].id) + try await groups[0].send(content: "hi") + let messageCount = try await bobGroup!.messages().count + XCTAssertEqual(messageCount, 0) + do { + let start = Date() + let _ = try await fixtures.bobClient.conversations.syncAllGroups() + let end = Date() + print(end.timeIntervalSince(start)) + XCTAssert(end.timeIntervalSince(start) < 1) + } catch { + print("Failed to list groups members: \(error)") + throw error // Rethrow the error to fail the test if group creation fails + } + + let messageCount2 = try await bobGroup!.messages().count + XCTAssertEqual(messageCount2, 1) + } + func testCanListManyMembersInParallelInUnderASecond() async throws { let fixtures = try await localFixtures() var groups: [Group] = [] From f40d43efd989b7f8a4dde4dfcce9a0d3e46a0909 Mon Sep 17 00:00:00 2001 From: Cameron Voell <1103838+cameronvoell@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:47:38 -0700 Subject: [PATCH 4/5] return number of active groups synced from sync all groups function. possible fork fixes (#393) Co-authored-by: cameronvoell --- Package.resolved | 4 ++-- Package.swift | 2 +- Sources/XMTPiOS/Conversations.swift | 6 +++--- Tests/XMTPTests/GroupTests.swift | 19 ++++++++++++++++++- XMTP.podspec | 4 ++-- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Package.resolved b/Package.resolved index 1447583c..03d36b46 100644 --- a/Package.resolved +++ b/Package.resolved @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "6ddc5a583663560698d66a7f99852ccb093cf4a5", - "version" : "0.5.7-beta2" + "revision" : "c27b586925714a253e5e9b3875788571552f46d6", + "version" : "0.5.8-beta1" } }, { diff --git a/Package.swift b/Package.swift index 4f2a16d0..6ca0524b 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), - .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.8-beta0"), + .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.8-beta1"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/XMTPiOS/Conversations.swift b/Sources/XMTPiOS/Conversations.swift index 5cf8e419..4cb0d1ea 100644 --- a/Sources/XMTPiOS/Conversations.swift +++ b/Sources/XMTPiOS/Conversations.swift @@ -104,11 +104,11 @@ public actor Conversations { try await v3Client.conversations().sync() } - public func syncAllGroups() async throws { + public func syncAllGroups() async throws -> UInt32 { guard let v3Client = client.v3Client else { - return + return 0 } - try await v3Client.conversations().syncAllGroups() + return try await v3Client.conversations().syncAllGroups() } public func groups(createdAfter: Date? = nil, createdBefore: Date? = nil, limit: Int? = nil) async throws -> [Group] { diff --git a/Tests/XMTPTests/GroupTests.swift b/Tests/XMTPTests/GroupTests.swift index 9628d546..5ea5ec48 100644 --- a/Tests/XMTPTests/GroupTests.swift +++ b/Tests/XMTPTests/GroupTests.swift @@ -853,10 +853,11 @@ class GroupTests: XCTestCase { XCTAssertEqual(messageCount, 0) do { let start = Date() - let _ = try await fixtures.bobClient.conversations.syncAllGroups() + let numGroupsSynced = try await fixtures.bobClient.conversations.syncAllGroups() let end = Date() print(end.timeIntervalSince(start)) XCTAssert(end.timeIntervalSince(start) < 1) + XCTAssert(numGroupsSynced == 100) } catch { print("Failed to list groups members: \(error)") throw error // Rethrow the error to fail the test if group creation fails @@ -864,6 +865,22 @@ class GroupTests: XCTestCase { let messageCount2 = try await bobGroup!.messages().count XCTAssertEqual(messageCount2, 1) + + for aliceConv in try await fixtures.aliceClient.conversations.list(includeGroups: true) { + guard case let .group(aliceGroup) = aliceConv else { + XCTFail("failed converting conversation to group") + return + } + try await aliceGroup.removeMembers(addresses: [fixtures.bobClient.address]) + } + + // first syncAllGroups after removal still sync groups in order to process the removal + var numGroupsSynced = try await fixtures.bobClient.conversations.syncAllGroups() + XCTAssert(numGroupsSynced == 100) + + // next syncAllGroups only will sync active groups + numGroupsSynced = try await fixtures.bobClient.conversations.syncAllGroups() + XCTAssert(numGroupsSynced == 0) } func testCanListManyMembersInParallelInUnderASecond() async throws { diff --git a/XMTP.podspec b/XMTP.podspec index 04c6fc6d..6cac320d 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "XMTP" - spec.version = "0.14.8" + spec.version = "0.14.9" spec.summary = "XMTP SDK Cocoapod" # This description is used to generate tags and improve search results. @@ -44,5 +44,5 @@ Pod::Spec.new do |spec| spec.dependency "web3.swift" spec.dependency "GzipSwift" spec.dependency "Connect-Swift", "= 0.12.0" - spec.dependency 'LibXMTP', '= 0.5.8-beta0' + spec.dependency 'LibXMTP', '= 0.5.8-beta1' end From 3fe600e493b3d2964d91d4a54047d9c56fd5ec46 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Thu, 29 Aug 2024 22:02:18 -0600 Subject: [PATCH 5/5] Bump to latest versions of libxmtp (#394) * bump the libraries * bump the package resolved --- Package.swift | 2 +- XMTP.podspec | 4 ++-- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index 6ca0524b..047691bf 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), - .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.8-beta1"), + .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.8-beta3"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/XMTP.podspec b/XMTP.podspec index 6cac320d..a86e32d8 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "XMTP" - spec.version = "0.14.9" + spec.version = "0.14.10" spec.summary = "XMTP SDK Cocoapod" # This description is used to generate tags and improve search results. @@ -44,5 +44,5 @@ Pod::Spec.new do |spec| spec.dependency "web3.swift" spec.dependency "GzipSwift" spec.dependency "Connect-Swift", "= 0.12.0" - spec.dependency 'LibXMTP', '= 0.5.8-beta1' + spec.dependency 'LibXMTP', '= 0.5.8-beta3' end diff --git a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 44ba5919..a874b2a3 100644 --- a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "5ff057ed6ab42ba8cdc9cb9c107dddfc5fb4746b", - "version" : "0.5.8-beta0" + "revision" : "06e890646a32c3ae9b9ac78150a7ec4971e54c9d", + "version" : "0.5.8-beta3" } }, {