From fc63b39ef72219ac758fe5122efb4ba03d6cb483 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Mon, 11 Nov 2024 11:38:13 -0800 Subject: [PATCH] update the ios and android bindings to line up more closely --- .../modules/xmtpreactnativesdk/XMTPModule.kt | 186 +++++++++--------- ios/XMTPModule.swift | 172 ++++++++-------- 2 files changed, 179 insertions(+), 179 deletions(-) diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index 22bee6a6b..9aef8223a 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -276,6 +276,11 @@ class XMTPModule : Module() { } } + Function("preAuthenticateToInboxCallbackCompleted") { + logV("preAuthenticateToInboxCallbackCompleted") + preAuthenticateToInboxCallbackDeferred?.complete(Unit) + } + // // Auth functions // @@ -289,6 +294,23 @@ class XMTPModule : Module() { signer?.handleSCW(id = requestID, signature = signature) } + AsyncFunction("createRandom") Coroutine { hasPreAuthenticateToInboxCallback: Boolean?, dbEncryptionKey: List, authParams: String -> + withContext(Dispatchers.IO) { + logV("createRandom") + val privateKey = PrivateKeyBuilder() + val options = clientOptions( + dbEncryptionKey, + authParams, + hasPreAuthenticateToInboxCallback, + ) + val randomClient = Client().create(account = privateKey, options = options) + + ContentJson.Companion + clients[randomClient.inboxId] = randomClient + ClientWrapper.encodeToObj(randomClient) + } + } + AsyncFunction("create") Coroutine { address: String, hasAuthInboxCallback: Boolean?, dbEncryptionKey: List, authParams: String -> withContext(Dispatchers.IO) { logV("create") @@ -310,7 +332,7 @@ class XMTPModule : Module() { clients[client.inboxId] = client ContentJson.Companion signer = null - sendEvent("authedV3", ClientWrapper.encodeToObj(client)) + sendEvent("authed", ClientWrapper.encodeToObj(client)) } } @@ -328,23 +350,6 @@ class XMTPModule : Module() { } } - AsyncFunction("createRandom") Coroutine { hasPreAuthenticateToInboxCallback: Boolean?, dbEncryptionKey: List, authParams: String -> - withContext(Dispatchers.IO) { - logV("createRandom") - val privateKey = PrivateKeyBuilder() - val options = clientOptions( - dbEncryptionKey, - authParams, - hasPreAuthenticateToInboxCallback, - ) - val randomClient = Client().create(account = privateKey, options = options) - - ContentJson.Companion - clients[randomClient.inboxId] = randomClient - ClientWrapper.encodeToObj(randomClient) - } - } - AsyncFunction("dropClient") Coroutine { inboxId: String -> withContext(Dispatchers.IO) { logV("dropClient") @@ -375,7 +380,7 @@ class XMTPModule : Module() { } } - AsyncFunction("encryptAttachment") { fileJson: String -> + AsyncFunction("encryptAttachment") { inboxId: String, fileJson: String -> logV("encryptAttachment") val file = DecryptedLocalAttachment.fromJson(fileJson) val uri = Uri.parse(file.fileUri) @@ -401,7 +406,7 @@ class XMTPModule : Module() { ).toJson() } - AsyncFunction("decryptAttachment") { encryptedFileJson: String -> + AsyncFunction("decryptAttachment") { inboxId: String, encryptedFileJson: String -> logV("decryptAttachment") val encryptedFile = EncryptedLocalAttachment.fromJson(encryptedFileJson) val encryptedData = appContext.reactContext?.contentResolver @@ -440,6 +445,19 @@ class XMTPModule : Module() { } } + AsyncFunction("listDms") Coroutine { inboxId: String, groupParams: String?, sortOrder: String?, limit: Int? -> + withContext(Dispatchers.IO) { + logV("listDms") + val client = clients[inboxId] ?: throw XMTPException("No client") + val params = ConversationParamsWrapper.conversationParamsFromJson(groupParams ?: "") + val order = getConversationSortOrder(sortOrder ?: "") + val dms = client.conversations.listDms(order = order, limit = limit) + dms.map { dm -> + DmWrapper.encode(client, dm, params) + } + } + } + AsyncFunction("listConversations") Coroutine { inboxId: String, conversationParams: String?, sortOrder: String?, limit: Int? -> withContext(Dispatchers.IO) { logV("listConversations") @@ -455,19 +473,6 @@ class XMTPModule : Module() { } } - AsyncFunction("listDms") Coroutine { inboxId: String, groupParams: String?, sortOrder: String?, limit: Int? -> - withContext(Dispatchers.IO) { - logV("listDms") - val client = clients[inboxId] ?: throw XMTPException("No client") - val params = ConversationParamsWrapper.conversationParamsFromJson(groupParams ?: "") - val order = getConversationSortOrder(sortOrder ?: "") - val dms = client.conversations.listDms(order = order, limit = limit) - dms.map { dm -> - DmWrapper.encode(client, dm, params) - } - } - } - AsyncFunction("conversationMessages") Coroutine { inboxId: String, conversationId: String, limit: Int?, beforeNs: Long?, afterNs: Long?, direction: String? -> withContext(Dispatchers.IO) { logV("conversationMessages") @@ -577,6 +582,15 @@ class XMTPModule : Module() { } } + AsyncFunction("findOrCreateDm") Coroutine { inboxId: String, peerAddress: String -> + withContext(Dispatchers.IO) { + logV("findOrCreateDm") + val client = clients[inboxId] ?: throw XMTPException("No client") + val dm = client.conversations.findOrCreateDm(peerAddress) + DmWrapper.encode(client, dm) + } + } + AsyncFunction("createGroup") Coroutine { inboxId: String, peerAddresses: List, permission: String, groupOptionsJson: String -> withContext(Dispatchers.IO) { logV("createGroup") @@ -599,15 +613,6 @@ class XMTPModule : Module() { } } - AsyncFunction("findOrCreateDm") Coroutine { inboxId: String, peerAddress: String -> - withContext(Dispatchers.IO) { - logV("findOrCreateDm") - val client = clients[inboxId] ?: throw XMTPException("No client") - val dm = client.conversations.findOrCreateDm(peerAddress) - DmWrapper.encode(client, dm) - } - } - AsyncFunction("createGroupCustomPermissions") Coroutine { inboxId: String, peerAddresses: List, permissionPolicySetJson: String, groupOptionsJson: String -> withContext(Dispatchers.IO) { logV("createGroup") @@ -1038,29 +1043,6 @@ class XMTPModule : Module() { } } - Function("registerPushToken") { pushServer: String, token: String -> - logV("registerPushToken") - xmtpPush = XMTPPush(appContext.reactContext!!, pushServer) - xmtpPush?.register(token) - } - - Function("subscribePushTopics") { topics: List -> - logV("subscribePushTopics") - if (topics.isNotEmpty()) { - if (xmtpPush == null) { - throw XMTPException("Push server not registered") - } - - val subscriptions = topics.map { - Service.Subscription.newBuilder().also { sub -> - sub.topic = it - }.build() - } - - xmtpPush?.subscribeWithMetadata(subscriptions) - } - } - AsyncFunction("setConsentState") Coroutine { inboxId: String, value: String, entryType: String, consentType: String -> withContext(Dispatchers.IO) { val client = clients[inboxId] ?: throw XMTPException("No client") @@ -1106,11 +1088,6 @@ class XMTPModule : Module() { } } - Function("preAuthenticateToInboxCallbackCompleted") { - logV("preAuthenticateToInboxCallbackCompleted") - preAuthenticateToInboxCallbackDeferred?.complete(Unit) - } - AsyncFunction("updateConversationConsent") Coroutine { inboxId: String, conversationId: String, state: String -> withContext(Dispatchers.IO) { logV("updateConversationConsent") @@ -1122,24 +1099,6 @@ class XMTPModule : Module() { } } - AsyncFunction("exportNativeLogs") Coroutine { -> - withContext(Dispatchers.IO) { - try { - val process = Runtime.getRuntime().exec("logcat -d") - val bufferedReader = BufferedReader(InputStreamReader(process.inputStream)) - - val log = StringBuilder() - var line: String? - while (bufferedReader.readLine().also { line = it } != null) { - log.append(line).append("\n") - } - log.toString() - } catch (e: Exception) { - e.message - } - } - } - Function("subscribeToConversations") { inboxId: String, type: String -> logV("subscribeToConversations") @@ -1161,16 +1120,16 @@ class XMTPModule : Module() { } } - Function("unsubscribeFromAllMessages") { inboxId: String -> - logV("unsubscribeFromAllMessages") - subscriptions[getMessagesKey(inboxId)]?.cancel() - } - Function("unsubscribeFromConversations") { inboxId: String -> logV("unsubscribeFromConversations") subscriptions[getConversationsKey(inboxId)]?.cancel() } + Function("unsubscribeFromAllMessages") { inboxId: String -> + logV("unsubscribeFromAllMessages") + subscriptions[getMessagesKey(inboxId)]?.cancel() + } + AsyncFunction("unsubscribeFromMessages") Coroutine { inboxId: String, id: String -> withContext(Dispatchers.IO) { logV("unsubscribeFromMessages") @@ -1180,6 +1139,47 @@ class XMTPModule : Module() { ) } } + + Function("registerPushToken") { pushServer: String, token: String -> + logV("registerPushToken") + xmtpPush = XMTPPush(appContext.reactContext!!, pushServer) + xmtpPush?.register(token) + } + + Function("subscribePushTopics") { topics: List -> + logV("subscribePushTopics") + if (topics.isNotEmpty()) { + if (xmtpPush == null) { + throw XMTPException("Push server not registered") + } + + val subscriptions = topics.map { + Service.Subscription.newBuilder().also { sub -> + sub.topic = it + }.build() + } + + xmtpPush?.subscribeWithMetadata(subscriptions) + } + } + + AsyncFunction("exportNativeLogs") Coroutine { -> + withContext(Dispatchers.IO) { + try { + val process = Runtime.getRuntime().exec("logcat -d") + val bufferedReader = BufferedReader(InputStreamReader(process.inputStream)) + + val log = StringBuilder() + var line: String? + while (bufferedReader.readLine().also { line = it } != null) { + log.append(line).append("\n") + } + log.toString() + } catch (e: Exception) { + e.message + } + } + } } // diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index 896deee57..a4968e1fd 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -173,6 +173,13 @@ public class XMTPModule: Module { return try InboxStateWrapper.encode(inboxState) } + Function("preAuthenticateToInboxCallbackCompleted") { + DispatchQueue.global().async { + self.preAuthenticateToInboxCallbackDeferred?.signal() + self.preAuthenticateToInboxCallbackDeferred = nil + } + } + // // Auth functions // @@ -255,7 +262,7 @@ public class XMTPModule: Module { self.sendEvent("authed", try ClientWrapper.encodeToObj(client)) } - AsyncFunction("buildV3") { + AsyncFunction("build") { (address: String, dbEncryptionKey: [UInt8], authParams: String) -> [String: String] in let authOptions = AuthParamsWrapper.authParamsFromJson(authParams) @@ -1291,63 +1298,28 @@ public class XMTPModule: Module { conversation, client: client) } - AsyncFunction("subscribeToConversations") { - (inboxId: String, type: String) in - - try await subscribeToConversations( - inboxId: inboxId, type: getConversationType(type: type)) - } - - AsyncFunction("subscribeToAllMessages") { - (inboxId: String, type: String) in - try await subscribeToAllMessages( - inboxId: inboxId, type: getConversationType(type: type)) - } - - AsyncFunction("subscribeToMessages") { - (inboxId: String, id: String) in - try await subscribeToMessages(inboxId: inboxId, id: id) - } - - AsyncFunction("unsubscribeFromConversations") { (inboxId: String) in - await subscriptionsManager.get( - getConversationsKey(inboxId: inboxId))?.cancel() - } - - AsyncFunction("unsubscribeFromAllMessages") { (inboxId: String) in - await subscriptionsManager.get(getMessagesKey(inboxId: inboxId))? - .cancel() - } - - AsyncFunction("unsubscribeFromMessages") { - (inboxId: String, id: String) in - try await unsubscribeFromMessages(inboxId: inboxId, id: id) - } - - AsyncFunction("registerPushToken") { - (pushServer: String, token: String) in - XMTPPush.shared.setPushServer(pushServer) - do { - try await XMTPPush.shared.register(token: token) - } catch { - print("Error registering: \(error)") + AsyncFunction("setConsentState") { + ( + inboxId: String, value: String, entryType: String, + consentType: String + ) in + guard let client = await clientsManager.getClient(key: inboxId) + else { + throw Error.noClient } - } - AsyncFunction("subscribePushTopics") { (topics: [String]) in - do { - let subscriptions = topics.map { - topic -> NotificationSubscription in - return NotificationSubscription.with { sub in - sub.topic = topic - } - } + let resolvedEntryType = try getEntryType(type: entryType) + let resolvedConsentState = try getConsentState(state: consentType) - try await XMTPPush.shared.subscribeWithMetadata( - subscriptions: subscriptions) - } catch { - print("Error subscribing: \(error)") - } + try await client.preferences.consentList.setConsentState( + entries: [ + ConsentListEntry( + value: value, + entryType: resolvedEntryType, + consentType: resolvedConsentState + ) + ] + ) } AsyncFunction("consentAddressState") { @@ -1384,30 +1356,6 @@ public class XMTPModule: Module { conversationId)) } - AsyncFunction("setConsentState") { - ( - inboxId: String, value: String, entryType: String, - consentType: String - ) in - guard let client = await clientsManager.getClient(key: inboxId) - else { - throw Error.noClient - } - - let resolvedEntryType = try getEntryType(type: entryType) - let resolvedConsentState = try getConsentState(state: consentType) - - try await client.preferences.consentList.setConsentState( - entries: [ - ConsentListEntry( - value: value, - entryType: resolvedEntryType, - consentType: resolvedConsentState - ) - ] - ) - } - AsyncFunction("conversationConsentState") { (inboxId: String, conversationId: String) -> String in guard let client = await clientsManager.getClient(key: inboxId) @@ -1426,13 +1374,6 @@ public class XMTPModule: Module { state: conversation.consentState()) } - Function("preAuthenticateToInboxCallbackCompleted") { - DispatchQueue.global().async { - self.preAuthenticateToInboxCallbackDeferred?.signal() - self.preAuthenticateToInboxCallbackDeferred = nil - } - } - AsyncFunction("updateConversationConsent") { (inboxId: String, conversationId: String, state: String) in guard let client = await clientsManager.getClient(key: inboxId) @@ -1452,6 +1393,65 @@ public class XMTPModule: Module { state: getConsentState(state: state)) } + AsyncFunction("subscribeToConversations") { + (inboxId: String, type: String) in + + try await subscribeToConversations( + inboxId: inboxId, type: getConversationType(type: type)) + } + + AsyncFunction("subscribeToAllMessages") { + (inboxId: String, type: String) in + try await subscribeToAllMessages( + inboxId: inboxId, type: getConversationType(type: type)) + } + + AsyncFunction("subscribeToMessages") { + (inboxId: String, id: String) in + try await subscribeToMessages(inboxId: inboxId, id: id) + } + + AsyncFunction("unsubscribeFromConversations") { (inboxId: String) in + await subscriptionsManager.get( + getConversationsKey(inboxId: inboxId))?.cancel() + } + + AsyncFunction("unsubscribeFromAllMessages") { (inboxId: String) in + await subscriptionsManager.get(getMessagesKey(inboxId: inboxId))? + .cancel() + } + + AsyncFunction("unsubscribeFromMessages") { + (inboxId: String, id: String) in + try await unsubscribeFromMessages(inboxId: inboxId, id: id) + } + + AsyncFunction("registerPushToken") { + (pushServer: String, token: String) in + XMTPPush.shared.setPushServer(pushServer) + do { + try await XMTPPush.shared.register(token: token) + } catch { + print("Error registering: \(error)") + } + } + + AsyncFunction("subscribePushTopics") { (topics: [String]) in + do { + let subscriptions = topics.map { + topic -> NotificationSubscription in + return NotificationSubscription.with { sub in + sub.topic = topic + } + } + + try await XMTPPush.shared.subscribeWithMetadata( + subscriptions: subscriptions) + } catch { + print("Error subscribing: \(error)") + } + } + AsyncFunction("exportNativeLogs") { () -> String in var logOutput = "" if #available(iOS 15.0, *) {