From 55eb1293540a78efe4b7356b83e47687c5c0a5b1 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Tue, 17 Dec 2024 21:57:25 -0800 Subject: [PATCH 1/2] fix the fork and add consent sync filtering --- android/build.gradle | 2 +- .../modules/xmtpreactnativesdk/XMTPModule.kt | 7 +-- example/ios/Podfile.lock | 16 +++---- ios/XMTPModule.swift | 44 +++++++++++-------- ios/XMTPReactNative.podspec | 2 +- src/index.ts | 5 ++- src/lib/Conversations.ts | 9 +++- 7 files changed, 49 insertions(+), 36 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 297784f9..19442663 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -98,7 +98,7 @@ repositories { dependencies { implementation project(':expo-modules-core') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}" - implementation "org.xmtp:android:3.0.16" + implementation "org.xmtp:android:3.0.17" implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.facebook.react:react-native:0.71.3' implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1" diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index a707c428..854d8a32 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -826,12 +826,13 @@ class XMTPModule : Module() { } } - AsyncFunction("syncAllConversations") Coroutine { installationId: String -> + AsyncFunction("syncAllConversations") Coroutine { installationId: String, consentState: String? -> withContext(Dispatchers.IO) { logV("syncAllConversations") val client = clients[installationId] ?: throw XMTPException("No client") + val consent = consentState?.let { getConsentState(it) } val numGroupsSyncedInt: Int = - client.conversations.syncAllConversations().toInt() + client.conversations.syncAllConversations(consent).toInt() numGroupsSyncedInt } } @@ -1513,7 +1514,7 @@ class XMTPModule : Module() { return "conversations:$installationId" } - private fun unsubscribeFromMessages( + private suspend fun unsubscribeFromMessages( installationId: String, id: String, ) { diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 69a69e06..21fcf17c 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -55,7 +55,7 @@ PODS: - hermes-engine/Pre-built (= 0.71.14) - hermes-engine/Pre-built (0.71.14) - libevent (2.1.12) - - LibXMTP (3.0.12) + - LibXMTP (3.0.13) - MessagePacker (0.4.7) - MMKV (2.0.0): - MMKVCore (~> 2.0.0) @@ -448,18 +448,18 @@ PODS: - SQLCipher/standard (4.5.7): - SQLCipher/common - SwiftProtobuf (1.28.2) - - XMTP (3.0.17): + - XMTP (3.0.18): - Connect-Swift (= 1.0.0) - CryptoSwift (= 1.8.3) - CSecp256k1 (~> 0.2) - - LibXMTP (= 3.0.12) + - LibXMTP (= 3.0.13) - SQLCipher (= 4.5.7) - - XMTPReactNative (3.1.2): + - XMTPReactNative (3.1.3): - CSecp256k1 (~> 0.2) - ExpoModulesCore - MessagePacker - SQLCipher (= 4.5.7) - - XMTP (= 3.0.17) + - XMTP (= 3.0.18) - Yoga (1.14.0) DEPENDENCIES: @@ -711,7 +711,7 @@ SPEC CHECKSUMS: glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - LibXMTP: 7e7607786ccc82c0230960964aa00843a5d47094 + LibXMTP: 3b4b45c0edd404de164e26c7920af5ea0ebb3e17 MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02 MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801 MMKVCore: c04b296010fcb1d1638f2c69405096aac12f6390 @@ -762,8 +762,8 @@ SPEC CHECKSUMS: RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396 SQLCipher: 5e6bfb47323635c8b657b1b27d25c5f1baf63bf5 SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d - XMTP: 5be6a8212c789e828b6eeef9edae84a227c61f22 - XMTPReactNative: 72e92330c1d9883a93c4a1be62ac4342e95dd80d + XMTP: a15bc6d07ab387b6ac70fbd3234189dc174ca024 + XMTPReactNative: 8010ff326eb0cbc69ece5ac6e9f7ca4acc9f3bf8 Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9 PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index 34e36224..e44e79ad 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -604,7 +604,7 @@ public class XMTPModule: Module { } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -667,7 +667,7 @@ public class XMTPModule: Module { throw Error.noClient } - if let conversation = try client.findConversation( + if let conversation = try await client.findConversation( conversationId: conversationId) { return try await ConversationWrapper.encode( @@ -684,7 +684,7 @@ public class XMTPModule: Module { else { throw Error.noClient } - if let conversation = try client.findConversationByTopic( + if let conversation = try await client.findConversationByTopic( topic: topic) { return try await ConversationWrapper.encode( @@ -733,7 +733,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -754,7 +754,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: id) else { throw Error.conversationNotFound( @@ -776,7 +776,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: id) else { throw Error.conversationNotFound( @@ -795,7 +795,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: id) else { throw Error.conversationNotFound( @@ -821,7 +821,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -944,7 +944,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: dmId) else { throw Error.conversationNotFound( @@ -973,7 +973,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -994,13 +994,19 @@ public class XMTPModule: Module { } AsyncFunction("syncAllConversations") { - (installationId: String) -> UInt32 in + (installationId: String, consentState: String?) -> UInt32 in guard let client = await clientsManager.getClient(key: installationId) else { throw Error.noClient } - return try await client.conversations.syncAllConversations() + let consent: ConsentState? + if let state = consentState { + consent = try getConsentState(state: state) + } else { + consent = nil + } + return try await client.conversations.syncAllConversations(consentState: consent) } AsyncFunction("syncConversation") { @@ -1011,7 +1017,7 @@ public class XMTPModule: Module { throw Error.noClient } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: id) else { throw Error.conversationNotFound( @@ -1241,7 +1247,7 @@ public class XMTPModule: Module { throw Error.conversationNotFound( "no conversation found for \(id)") } - return try group.creatorInboxId() + return try await group.creatorInboxId() } AsyncFunction("isAdmin") { @@ -1528,7 +1534,7 @@ public class XMTPModule: Module { } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: id) else { throw Error.conversationNotFound( @@ -1652,7 +1658,7 @@ public class XMTPModule: Module { } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -1671,7 +1677,7 @@ public class XMTPModule: Module { } guard - let conversation = try client.findConversation( + let conversation = try await client.findConversation( conversationId: conversationId) else { throw Error.conversationNotFound( @@ -2033,7 +2039,7 @@ public class XMTPModule: Module { throw Error.noClient } - guard let converation = try client.findConversation(conversationId: id) + guard let converation = try await client.findConversation(conversationId: id) else { return } @@ -2077,7 +2083,7 @@ public class XMTPModule: Module { throw Error.noClient } - guard let converation = try client.findConversation(conversationId: id) + guard let converation = try await client.findConversation(conversationId: id) else { return } diff --git a/ios/XMTPReactNative.podspec b/ios/XMTPReactNative.podspec index 80ef7bee..967079bb 100644 --- a/ios/XMTPReactNative.podspec +++ b/ios/XMTPReactNative.podspec @@ -26,7 +26,7 @@ Pod::Spec.new do |s| s.source_files = "**/*.{h,m,swift}" s.dependency "MessagePacker" - s.dependency "XMTP", "= 3.0.17" + s.dependency "XMTP", "= 3.0.18" s.dependency 'CSecp256k1', '~> 0.2' s.dependency "SQLCipher", "= 4.5.7" end diff --git a/src/index.ts b/src/index.ts index 29e87b54..a48bb7c9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -713,9 +713,10 @@ export async function syncConversations(installationId: InstallationId) { } export async function syncAllConversations( - installationId: InstallationId + installationId: InstallationId, + consentState?: ConsentState | undefined ): Promise { - return await XMTPModule.syncAllConversations(installationId) + return await XMTPModule.syncAllConversations(installationId, consentState) } export async function syncConversation( diff --git a/src/lib/Conversations.ts b/src/lib/Conversations.ts index dd25aebc..e8bfc2cd 100644 --- a/src/lib/Conversations.ts +++ b/src/lib/Conversations.ts @@ -279,8 +279,13 @@ export default class Conversations< * * @returns {Promise} A Promise that resolves to the number of conversations synced. */ - async syncAllConversations(): Promise { - return await XMTPModule.syncAllConversations(this.client.installationId) + async syncAllConversations( + consentState: ConsentState | undefined = undefined + ): Promise { + return await XMTPModule.syncAllConversations( + this.client.installationId, + consentState + ) } /** From 2209ff09ac4e9fef740e6b86ae50701daff4a68a Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Tue, 17 Dec 2024 22:00:51 -0800 Subject: [PATCH 2/2] write a test for it --- example/src/tests/conversationTests.ts | 30 ++++++++++++++++++++++++++ ios/XMTPModule.swift | 11 +++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/example/src/tests/conversationTests.ts b/example/src/tests/conversationTests.ts index 711bea28..de291169 100644 --- a/example/src/tests/conversationTests.ts +++ b/example/src/tests/conversationTests.ts @@ -398,6 +398,36 @@ test('can filter conversations by consent', async () => { return true }) +test('can filter sync all by consent', async () => { + const [alixClient, boClient, caroClient] = await createClients(3) + + await boClient.conversations.newGroup([alixClient.address]) + const otherGroup = await alixClient.conversations.newGroup([boClient.address]) + await boClient.conversations.findOrCreateDm(alixClient.address) + await caroClient.conversations.findOrCreateDm(boClient.address) + await boClient.conversations.sync() + await boClient.conversations.findDmByInboxId(caroClient.inboxId) + await boClient.conversations.findGroup(otherGroup.id) + + const boConvos = await boClient.conversations.syncAllConversations() + const boConvosFilteredAllowed = + await boClient.conversations.syncAllConversations('allowed') + const boConvosFilteredUnknown = + await boClient.conversations.syncAllConversations('unknown') + + assert(boConvos === 4, `Conversation length should be 4 but was ${boConvos}`) + assert( + boConvosFilteredAllowed === 2, + `Conversation length should be 2 but was ${boConvosFilteredAllowed}` + ) + assert( + boConvosFilteredUnknown === 2, + `Conversation length should be 2 but was ${boConvosFilteredUnknown}` + ) + + return true +}) + test('can list conversations with params', async () => { const [alixClient, boClient, caroClient] = await createClients(3) diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index e44e79ad..c0f335cb 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -1006,7 +1006,8 @@ public class XMTPModule: Module { } else { consent = nil } - return try await client.conversations.syncAllConversations(consentState: consent) + return try await client.conversations.syncAllConversations( + consentState: consent) } AsyncFunction("syncConversation") { @@ -2039,7 +2040,9 @@ public class XMTPModule: Module { throw Error.noClient } - guard let converation = try await client.findConversation(conversationId: id) + guard + let converation = try await client.findConversation( + conversationId: id) else { return } @@ -2083,7 +2086,9 @@ public class XMTPModule: Module { throw Error.noClient } - guard let converation = try await client.findConversation(conversationId: id) + guard + let converation = try await client.findConversation( + conversationId: id) else { return }