From 01f5cc80c5abbf967bc6a9a83ac2807ea39c7ebb Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Wed, 4 Dec 2024 10:01:55 -0800 Subject: [PATCH] Static Can Message (#444) * add the ability to static can message check * reformat --- Sources/XMTPiOS/Client.swift | 46 +++++++++++++++++++++++--- Tests/XMTPTests/ClientTests.swift | 54 +++++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/Sources/XMTPiOS/Client.swift b/Sources/XMTPiOS/Client.swift index 89b841a0..584d3abe 100644 --- a/Sources/XMTPiOS/Client.swift +++ b/Sources/XMTPiOS/Client.swift @@ -149,7 +149,9 @@ public final class Client { ) } - public static func build(address: String, options: ClientOptions, inboxId: String? = nil) + public static func build( + address: String, options: ClientOptions, inboxId: String? = nil + ) async throws -> Client { let accountAddress = address.lowercased() @@ -157,9 +159,10 @@ public final class Client { if let existingInboxId = inboxId { resolvedInboxId = existingInboxId } else { - resolvedInboxId = try await getOrCreateInboxId(api: options.api, address: accountAddress) + resolvedInboxId = try await getOrCreateInboxId( + api: options.api, address: accountAddress) } - + return try await initializeClient( accountAddress: accountAddress, options: options, @@ -284,6 +287,40 @@ public final class Client { return inboxId } + public static func canMessage( + accountAddresses: [String], + api: ClientOptions.Api + ) async throws -> [String: Bool] { + let address = "0x0000000000000000000000000000000000000000" + let inboxId = try await getOrCreateInboxId(api: api, address: address) + + var directoryURL: URL = URL.documentsDirectory + let alias = "xmtp-\(api.env.rawValue)-\(inboxId).db3" + let dbURL = directoryURL.appendingPathComponent(alias).path + + let ffiClient = try await LibXMTP.createClient( + logger: XMTPLogger(), + host: api.env.url, + isSecure: api.env.isSecure == true, + db: dbURL, + encryptionKey: nil, + inboxId: inboxId, + accountAddress: address, + nonce: 0, + legacySignedPrivateKeyProto: nil, + historySyncUrl: nil + ) + + let result = try await ffiClient.canMessage( + accountAddresses: accountAddresses) + + try ffiClient.releaseDbConnection() + let fm = FileManager.default + try fm.removeItem(atPath: dbURL) + + return result + } + init( address: String, ffiClient: LibXMTP.FfiXmtpClient, dbPath: String, installationID: String, inboxID: String, environment: XMTPEnvironment @@ -299,7 +336,8 @@ public final class Client { public func addAccount(newAccount: SigningKey) async throws { - let signatureRequest = try await ffiClient.addWallet(newWalletAddress: newAccount.address.lowercased()) + let signatureRequest = try await ffiClient.addWallet( + newWalletAddress: newAccount.address.lowercased()) do { try await Client.handleSignature( for: signatureRequest, signingKey: newAccount) diff --git a/Tests/XMTPTests/ClientTests.swift b/Tests/XMTPTests/ClientTests.swift index dfbf1ca8..0614f918 100644 --- a/Tests/XMTPTests/ClientTests.swift +++ b/Tests/XMTPTests/ClientTests.swift @@ -31,6 +31,32 @@ class ClientTests: XCTestCase { ) } + func testStaticCanMessage() async throws { + let fixtures = try await fixtures() + let notOnNetwork = try PrivateKey.generate() + + let canMessageList = try await Client.canMessage( + accountAddresses: [ + fixtures.alix.walletAddress, + notOnNetwork.address, + fixtures.bo.walletAddress, + ], + api: ClientOptions.Api(env: .local, isSecure: false) + ) + + let expectedResults: [String: Bool] = [ + fixtures.alix.walletAddress.lowercased(): true, + notOnNetwork.address.lowercased(): false, + fixtures.bo.walletAddress.lowercased(): true, + ] + + for (address, expected) in expectedResults { + XCTAssertEqual( + canMessageList[address.lowercased()], expected, + "Failed for address: \(address)") + } + } + func testCanDeleteDatabase() async throws { let key = try Crypto.secureRandomBytes(count: 32) let bo = try PrivateKey.generate() @@ -460,7 +486,7 @@ class ClientTests: XCTestCase { installationId: alixInstallationId )) } - + func testCreatesADevClientPerformance() async throws { let key = try Crypto.secureRandomBytes(count: 32) let fakeWallet = try PrivateKey.generate() @@ -506,13 +532,27 @@ class ClientTests: XCTestCase { print("PERF: Built a client with inboxId in \(time3)s") // Assert performance comparisons - XCTAssertTrue(time2 < time1, "Building a client should be faster than creating one.") - XCTAssertTrue(time3 < time1, "Building a client with inboxId should be faster than creating one.") - XCTAssertTrue(time3 < time2, "Building a client with inboxId should be faster than building one without.") - + XCTAssertTrue( + time2 < time1, + "Building a client should be faster than creating one.") + XCTAssertTrue( + time3 < time1, + "Building a client with inboxId should be faster than creating one." + ) + XCTAssertTrue( + time3 < time2, + "Building a client with inboxId should be faster than building one without." + ) + // Assert that inbox IDs match - XCTAssertEqual(client.inboxID, buildClient1.inboxID, "Inbox ID of the created client and first built client should match.") - XCTAssertEqual(client.inboxID, buildClient2.inboxID, "Inbox ID of the created client and second built client should match.") + XCTAssertEqual( + client.inboxID, buildClient1.inboxID, + "Inbox ID of the created client and first built client should match." + ) + XCTAssertEqual( + client.inboxID, buildClient2.inboxID, + "Inbox ID of the created client and second built client should match." + ) } }