Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/xmtp/xmtp-ios into np/frame…
Browse files Browse the repository at this point in the history
…s-client
  • Loading branch information
nplasterer committed Dec 19, 2024
2 parents 7d55704 + 0127d21 commit 8d83a74
Show file tree
Hide file tree
Showing 20 changed files with 247 additions and 175 deletions.
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ GEM

PLATFORMS
arm64-darwin-22
arm64-darwin-23

DEPENDENCIES
jazzy
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/xmtp/libxmtp-swift.git",
"state" : {
"revision" : "bab83b5de3ed4713d50535e61bca281179bf04fd",
"version" : "3.0.10"
"revision" : "203fd6d67bb72e3114b273ce9bbddd6fc747d583",
"version" : "3.0.13"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
.package(url: "https://github.com/bufbuild/connect-swift", exact: "1.0.0"),
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.4.3"),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", exact: "1.8.3"),
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.10")
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.13")
],
targets: [
.target(
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ try await conversation.send("gm")
// Listen for new messages in the conversation
Task {
for await message in try await conversation.streamMessages() {
print("\(message.senderAddress): \(message.body)")
print("\(message.senderInboxId): \(message.body)")
}
}
```
Expand Down Expand Up @@ -193,7 +193,7 @@ let nextPage = try await conversation.messages(limit: 25, before: messages.first

You can listen for any new messages (incoming or outgoing) in a conversation by calling `conversation.streamMessages()`.

A successfully received message (that makes it through the decoding and decryption without throwing) can be trusted to be authentic. Authentic means that it was sent by the owner of the `message.senderAddress` account and that it wasn't modified in transit. The `message.sent` timestamp can be trusted to have been set by the sender.
A successfully received message (that makes it through the decoding and decryption without throwing) can be trusted to be authentic. Authentic means that it was sent by the owner of the `message.senderInboxId` account and that it wasn't modified in transit. The `message.sent` timestamp can be trusted to have been set by the sender.

The flow returned by the `stream` methods is an asynchronous data stream that sequentially emits values and completes normally or with an exception.

Expand All @@ -202,10 +202,10 @@ The flow returned by the `stream` methods is an asynchronous data stream that se

Task {
for await message in try await conversation.streamMessages() {
if message.senderAddress == client.address {
if message.senderInboxId == client.address {
// This message was sent from me
}
print("New message from \(message.senderAddress): \(message.body)")
print("New message from \(message.senderInboxId): \(message.body)")
}
}
```
Expand Down
71 changes: 50 additions & 21 deletions Sources/XMTPiOS/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public final class Client {
public let dbPath: String
public let installationID: String
public let environment: XMTPEnvironment
public let apiClient: XmtpApiClient
private let ffiClient: LibXMTP.FfiXmtpClient

public lazy var conversations: Conversations = .init(
Expand All @@ -108,13 +109,15 @@ public final class Client {
accountAddress: String,
options: ClientOptions,
signingKey: SigningKey?,
inboxId: String
inboxId: String,
apiClient: XmtpApiClient? = nil
) async throws -> Client {
let (libxmtpClient, dbPath) = try await initFFiClient(
let (libxmtpClient, dbPath, apiClient) = try await initFFiClient(
accountAddress: accountAddress.lowercased(),
options: options,
signingKey: signingKey,
inboxId: inboxId
inboxId: inboxId,
apiClient: apiClient
)

let client = try Client(
Expand All @@ -123,7 +126,8 @@ public final class Client {
dbPath: dbPath,
installationID: libxmtpClient.installationId().toHex,
inboxID: libxmtpClient.inboxId(),
environment: options.api.env
environment: options.api.env,
apiClient: apiClient
)

// Register codecs
Expand All @@ -134,7 +138,10 @@ public final class Client {
return client
}

public static func create(account: SigningKey, options: ClientOptions)
public static func create(
account: SigningKey, options: ClientOptions,
apiClient: XmtpApiClient? = nil
)
async throws -> Client
{
let accountAddress = account.address.lowercased()
Expand All @@ -145,12 +152,14 @@ public final class Client {
accountAddress: accountAddress,
options: options,
signingKey: account,
inboxId: inboxId
inboxId: inboxId,
apiClient: apiClient
)
}

public static func build(
address: String, options: ClientOptions, inboxId: String? = nil
address: String, options: ClientOptions, inboxId: String? = nil,
apiClient: XmtpApiClient? = nil
)
async throws -> Client
{
Expand All @@ -167,16 +176,18 @@ public final class Client {
accountAddress: accountAddress,
options: options,
signingKey: nil,
inboxId: resolvedInboxId
inboxId: resolvedInboxId,
apiClient: apiClient
)
}

private static func initFFiClient(
accountAddress: String,
options: ClientOptions,
signingKey: SigningKey?,
inboxId: String
) async throws -> (FfiXmtpClient, String) {
inboxId: String,
apiClient: XmtpApiClient? = nil
) async throws -> (FfiXmtpClient, String, XmtpApiClient) {
let address = accountAddress.lowercased()

let mlsDbDirectory = options.dbDirectory
Expand All @@ -203,9 +214,15 @@ public final class Client {
let alias = "xmtp-\(options.api.env.rawValue)-\(inboxId).db3"
let dbURL = directoryURL.appendingPathComponent(alias).path

let xmtpApiClient: XmtpApiClient
if let existingApiClient = apiClient {
xmtpApiClient = existingApiClient
} else {
xmtpApiClient = try await connectToApiBackend(api: options.api)
}

let ffiClient = try await LibXMTP.createClient(
host: options.api.env.url,
isSecure: options.api.env.isSecure == true,
api: xmtpApiClient,
db: dbURL,
encryptionKey: options.dbEncryptionKey,
inboxId: inboxId,
Expand Down Expand Up @@ -235,7 +252,7 @@ public final class Client {
}
}

return (ffiClient, dbURL)
return (ffiClient, dbURL, xmtpApiClient)
}

private static func handleSignature(
Expand Down Expand Up @@ -265,6 +282,14 @@ public final class Client {
}
}

public static func connectToApiBackend(
api: ClientOptions.Api
) async throws -> XmtpApiClient {
return try await connectToBackend(
host: api.env.url,
isSecure: api.env.isSecure == true)
}

public static func getOrCreateInboxId(
api: ClientOptions.Api, address: String
) async throws -> String {
Expand Down Expand Up @@ -292,13 +317,12 @@ public final class Client {
let address = "0x0000000000000000000000000000000000000000"
let inboxId = try await getOrCreateInboxId(api: api, address: address)

var directoryURL: URL = URL.documentsDirectory
let directoryURL: URL = URL.documentsDirectory
let alias = "xmtp-\(api.env.rawValue)-\(inboxId).db3"
let dbURL = directoryURL.appendingPathComponent(alias).path

let ffiClient = try await LibXMTP.createClient(
host: api.env.url,
isSecure: api.env.isSecure == true,
api: connectToApiBackend(api: api),
db: dbURL,
encryptionKey: nil,
inboxId: inboxId,
Expand All @@ -320,14 +344,16 @@ public final class Client {

init(
address: String, ffiClient: LibXMTP.FfiXmtpClient, dbPath: String,
installationID: String, inboxID: String, environment: XMTPEnvironment
installationID: String, inboxID: String, environment: XMTPEnvironment,
apiClient: XmtpApiClient
) throws {
self.address = address
self.ffiClient = ffiClient
self.dbPath = dbPath
self.installationID = installationID
self.inboxID = inboxID
self.environment = environment
self.apiClient = apiClient
}

public func addAccount(newAccount: SigningKey)
Expand Down Expand Up @@ -448,18 +474,21 @@ public final class Client {
}
}

public func findConversation(conversationId: String) throws -> Conversation?
public func findConversation(conversationId: String) async throws
-> Conversation?
{
do {
let conversation = try ffiClient.conversation(
conversationId: conversationId.hexToData)
return try conversation.toConversation(client: self)
return try await conversation.toConversation(client: self)
} catch {
return nil
}
}

public func findConversationByTopic(topic: String) throws -> Conversation? {
public func findConversationByTopic(topic: String) async throws
-> Conversation?
{
do {
let regexPattern = #"/xmtp/mls/1/g-(.*?)/proto"#
if let regex = try? NSRegularExpression(pattern: regexPattern) {
Expand All @@ -471,7 +500,7 @@ public final class Client {
with: match.range(at: 1))
let conversation = try ffiClient.conversation(
conversationId: conversationId.hexToData)
return try conversation.toConversation(client: self)
return try await conversation.toConversation(client: self)
}
}
} catch {
Expand Down
4 changes: 2 additions & 2 deletions Sources/XMTPiOS/Conversation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public enum Conversation: Identifiable, Equatable, Hashable {
public func isCreator() async throws -> Bool {
switch self {
case let .group(group):
return try group.isCreator()
return try await group.isCreator()
case let .dm(dm):
return try dm.isCreator()
return try await dm.isCreator()
}
}

Expand Down
Loading

0 comments on commit 8d83a74

Please sign in to comment.