diff --git a/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt b/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt index 8dac7c006..f1004dd9a 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt @@ -36,8 +36,8 @@ class AttachmentTest { ) } val messages = runBlocking { aliceConversation.messages() } - assertEquals(messages.size, 2) - if (messages.size == 2) { + assertEquals(messages.size, 1) + if (messages.size == 1) { val content: Attachment? = messages[0].content() assertEquals("test.txt", content?.filename) assertEquals("text/plain", content?.mimeType) diff --git a/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt b/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt index b25d160af..0bb08eed5 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt @@ -60,8 +60,8 @@ class CodecTest { ) } val messages = runBlocking { aliceConversation.messages() } - assertEquals(messages.size, 2) - if (messages.size == 2) { + assertEquals(messages.size, 1) + if (messages.size == 1) { val content: Double? = messages[0].content() assertEquals(3.14, content) assertEquals("Error: This app does not support numbers.", messages[0].fallbackContent) diff --git a/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt index 3445effef..6eaad4072 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt @@ -209,10 +209,15 @@ class ConversationsTest { runBlocking { boClient.conversations.sync() boDm?.sync() + alixClient.conversations.sync() alixClient2.conversations.sync() - val dm2 = alixClient2.findConversation(dm.id)!! alixClient2.syncConsent() - assertEquals(dm2.consentState(), ConsentState.DENIED) + alixClient.conversations.syncAllConversations() + Thread.sleep(2000) + alixClient2.conversations.syncAllConversations() + Thread.sleep(2000) + val dm2 = alixClient2.findConversation(dm.id)!! + assertEquals(ConsentState.DENIED, dm2.consentState()) alixClient2.preferences.consentList.setConsentState( listOf( ConsentListEntry( diff --git a/library/src/androidTest/java/org/xmtp/android/library/DmTest.kt b/library/src/androidTest/java/org/xmtp/android/library/DmTest.kt index c1b144253..7945dc540 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/DmTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/DmTest.kt @@ -198,7 +198,7 @@ class DmTest { assertEquals(dm.messages().first().body, "gm") assertEquals(dm.messages().first().id, messageId) assertEquals(dm.messages().first().deliveryStatus, MessageDeliveryStatus.PUBLISHED) - assertEquals(dm.messages().size, 3) + assertEquals(dm.messages().size, 2) runBlocking { alixClient.conversations.sync() } val sameDm = runBlocking { alixClient.conversations.listDms().last() } @@ -215,12 +215,12 @@ class DmTest { dm.send("gm") } - assertEquals(dm.messages().size, 3) - assertEquals(dm.messages(deliveryStatus = MessageDeliveryStatus.PUBLISHED).size, 3) + assertEquals(dm.messages().size, 2) + assertEquals(dm.messages(deliveryStatus = MessageDeliveryStatus.PUBLISHED).size, 2) runBlocking { dm.sync() } - assertEquals(dm.messages().size, 3) + assertEquals(dm.messages().size, 2) assertEquals(dm.messages(deliveryStatus = MessageDeliveryStatus.UNPUBLISHED).size, 0) - assertEquals(dm.messages(deliveryStatus = MessageDeliveryStatus.PUBLISHED).size, 3) + assertEquals(dm.messages(deliveryStatus = MessageDeliveryStatus.PUBLISHED).size, 2) runBlocking { alixClient.conversations.sync() } val sameDm = runBlocking { alixClient.conversations.listDms().last() } @@ -253,7 +253,7 @@ class DmTest { runBlocking { dm.sync() } val messages = dm.messages() - assertEquals(messages.size, 3) + assertEquals(messages.size, 2) val content: Reaction? = messages.first().content() assertEquals("U+1F603", content?.content) assertEquals(messageToReact.id, content?.reference) diff --git a/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt b/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt index fe9f91fc9..1c89792cd 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt @@ -924,7 +924,7 @@ class GroupTest { assertEquals(alixGroup.messages().size, 1) assertEquals(alixGroup2.messages().size, 1) - assertEquals(numGroups, 2u) + assertEquals(numGroups, 3u) runBlocking { boGroup2.removeMembers(listOf(alix.walletAddress)) @@ -933,17 +933,18 @@ class GroupTest { boGroup2.send("hi") boGroup2.send("hi") numGroups = alixClient.conversations.syncAllConversations() + Thread.sleep(2000) } assertEquals(alixGroup.messages().size, 3) assertEquals(alixGroup2.messages().size, 2) // First syncAllGroups after remove includes the group you're removed from - assertEquals(numGroups, 2u) + assertEquals(numGroups, 3u) runBlocking { numGroups = alixClient.conversations.syncAllConversations() } // Next syncAllGroups will not include the inactive group - assertEquals(numGroups, 1u) + assertEquals(numGroups, 2u) } } diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt index 94f292961..dc653c07d 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt @@ -89,8 +89,8 @@ class ReactionTest { ) } val messages = runBlocking { aliceConversation.messages() } - assertEquals(messages.size, 3) - if (messages.size == 3) { + assertEquals(messages.size, 2) + if (messages.size == 2) { val content: Reaction? = messages.first().content() assertEquals("U+1F603", content?.content) assertEquals(messageToReact.id, content?.reference) diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt index 058506a2d..a3941457f 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt @@ -34,8 +34,8 @@ class ReadReceiptTest { ) } val messages = runBlocking { aliceConversation.messages() } - assertEquals(messages.size, 3) - if (messages.size == 3) { + assertEquals(messages.size, 2) + if (messages.size == 2) { val contentType: String = messages.first().encodedContent.type.typeId assertEquals(contentType, "readReceipt") } diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt index 413a9644a..ba5e6bf5f 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt @@ -41,8 +41,8 @@ class ReplyTest { ) } val messages = runBlocking { aliceConversation.messages() } - assertEquals(messages.size, 3) - if (messages.size == 3) { + assertEquals(messages.size, 2) + if (messages.size == 2) { val content: Reply? = messages.first().content() assertEquals("Hello", content?.content) assertEquals(messageToReact.id, content?.reference) diff --git a/library/src/main/java/libxmtp-version.txt b/library/src/main/java/libxmtp-version.txt index 72f149798..7584779a6 100644 --- a/library/src/main/java/libxmtp-version.txt +++ b/library/src/main/java/libxmtp-version.txt @@ -1,3 +1,3 @@ -Version: ae7a267d +Version: 29a955a1 Branch: main -Date: 2024-11-07 20:55:17 +0000 +Date: 2024-11-14 22:21:21 +0000 diff --git a/library/src/main/java/org/xmtp/android/library/Client.kt b/library/src/main/java/org/xmtp/android/library/Client.kt index 38636af1d..0bc5246c1 100644 --- a/library/src/main/java/org/xmtp/android/library/Client.kt +++ b/library/src/main/java/org/xmtp/android/library/Client.kt @@ -7,6 +7,7 @@ import org.xmtp.android.library.codecs.TextCodec import org.xmtp.android.library.libxmtp.Message import org.xmtp.android.library.libxmtp.XMTPLogger import org.xmtp.android.library.messages.rawData +import uniffi.xmtpv3.FfiConversationType import uniffi.xmtpv3.FfiDeviceSyncKind import uniffi.xmtpv3.FfiXmtpClient import uniffi.xmtpv3.createClient @@ -25,7 +26,7 @@ data class ClientOptions( val dbEncryptionKey: ByteArray, val historySyncUrl: String = when (api.env) { XMTPEnvironment.PRODUCTION -> "https://message-history.production.ephemera.network/" - XMTPEnvironment.LOCAL -> "http://0.0.0.0:5558" + XMTPEnvironment.LOCAL -> "http://10.0.2.2:5558" else -> "https://message-history.dev.ephemera.network/" }, val dbDirectory: String? = null, @@ -63,10 +64,10 @@ class Client() { logger = XMTPLogger(), host = environment.env.getUrl(), isSecure = environment.isSecure, - accountAddress = address + accountAddress = address.lowercase() ) if (inboxId.isNullOrBlank()) { - inboxId = generateInboxId(address, 0.toULong()) + inboxId = generateInboxId(address.lowercase(), 0.toULong()) } return inboxId } @@ -84,7 +85,7 @@ class Client() { inboxId: String, environment: XMTPEnvironment, ) : this() { - this.address = address + this.address = address.lowercase() this.preferences = PrivatePreferences(client = this, ffiClient = libXMTPClient) this.ffiClient = libXMTPClient this.conversations = @@ -169,7 +170,7 @@ class Client() { isSecure = options.api.isSecure, db = dbPath, encryptionKey = options.dbEncryptionKey, - accountAddress = accountAddress, + accountAddress = accountAddress.lowercase(), inboxId = inboxId, nonce = 0.toULong(), legacySignedPrivateKeyProto = null, @@ -218,12 +219,10 @@ class Client() { fun findConversation(conversationId: String): Conversation? { return try { val conversation = ffiClient.conversation(conversationId.hexToByteArray()) - if (conversation.groupMetadata().conversationType() == "dm") { - Conversation.Dm(Dm(this, conversation)) - } else if (conversation.groupMetadata().conversationType() == "group") { - Conversation.Group(Group(this, conversation)) - } else { - null + when (conversation.conversationType()) { + FfiConversationType.GROUP -> Conversation.Group(Group(this, conversation)) + FfiConversationType.DM -> Conversation.Dm(Dm(this, conversation)) + else -> null } } catch (e: Exception) { null @@ -236,12 +235,10 @@ class Client() { val conversationId = matchResult?.groupValues?.get(1) ?: "" return try { val conversation = ffiClient.conversation(conversationId.hexToByteArray()) - if (conversation.groupMetadata().conversationType() == "dm") { - Conversation.Dm(Dm(this, conversation)) - } else if (conversation.groupMetadata().conversationType() == "group") { - Conversation.Group(Group(this, conversation)) - } else { - null + when (conversation.conversationType()) { + FfiConversationType.GROUP -> Conversation.Group(Group(this, conversation)) + FfiConversationType.DM -> Conversation.Dm(Dm(this, conversation)) + else -> null } } catch (e: Exception) { null diff --git a/library/src/main/java/org/xmtp/android/library/Conversations.kt b/library/src/main/java/org/xmtp/android/library/Conversations.kt index 84199873d..35619a15b 100644 --- a/library/src/main/java/org/xmtp/android/library/Conversations.kt +++ b/library/src/main/java/org/xmtp/android/library/Conversations.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.callbackFlow import org.xmtp.android.library.libxmtp.Message import uniffi.xmtpv3.FfiConversation import uniffi.xmtpv3.FfiConversationCallback +import uniffi.xmtpv3.FfiConversationType import uniffi.xmtpv3.FfiConversations import uniffi.xmtpv3.FfiCreateGroupOptions import uniffi.xmtpv3.FfiDirection @@ -41,10 +42,9 @@ data class Conversations( suspend fun fromWelcome(envelopeBytes: ByteArray): Conversation { val conversation = ffiConversations.processStreamedWelcomeMessage(envelopeBytes) - return if (conversation.groupMetadata().conversationType() == "dm") { - Conversation.Dm(Dm(client, conversation)) - } else { - Conversation.Group(Group(client, conversation)) + return when (conversation.conversationType()) { + FfiConversationType.DM -> Conversation.Dm(Dm(client, conversation)) + else -> Conversation.Group(Group(client, conversation)) } } @@ -250,10 +250,9 @@ data class Conversations( } private fun FfiConversation.toConversation(): Conversation { - return if (groupMetadata().conversationType() == "dm") { - Conversation.Dm(Dm(client, this)) - } else { - Conversation.Group(Group(client, this)) + return when (conversationType()) { + FfiConversationType.DM -> Conversation.Dm(Dm(client, this)) + else -> Conversation.Group(Group(client, this)) } } @@ -261,10 +260,9 @@ data class Conversations( callbackFlow { val conversationCallback = object : FfiConversationCallback { override fun onConversation(conversation: FfiConversation) { - if (conversation.groupMetadata().conversationType() == "dm") { - trySend(Conversation.Dm(Dm(client, conversation))) - } else { - trySend(Conversation.Group(Group(client, conversation))) + when (conversation.conversationType()) { + FfiConversationType.DM -> trySend(Conversation.Dm(Dm(client, conversation))) + else -> trySend(Conversation.Group(Group(client, conversation))) } } diff --git a/library/src/main/java/xmtpv3.kt b/library/src/main/java/xmtpv3.kt index 0776fb069..3039e2cb2 100644 --- a/library/src/main/java/xmtpv3.kt +++ b/library/src/main/java/xmtpv3.kt @@ -959,6 +959,10 @@ internal interface UniffiLib : Library { `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue + fun uniffi_xmtpv3_fn_method_fficonversation_conversation_type( + `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, + ): RustBuffer.ByValue + fun uniffi_xmtpv3_fn_method_fficonversation_created_at_ns( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Long @@ -1843,6 +1847,9 @@ internal interface UniffiLib : Library { fun uniffi_xmtpv3_checksum_method_fficonversation_consent_state( ): Short + fun uniffi_xmtpv3_checksum_method_fficonversation_conversation_type( + ): Short + fun uniffi_xmtpv3_checksum_method_fficonversation_created_at_ns( ): Short @@ -2223,6 +2230,9 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_method_fficonversation_consent_state() != 25033.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_conversation_type() != 16402.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_xmtpv3_checksum_method_fficonversation_created_at_ns() != 17973.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -2322,7 +2332,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_method_fficonversationcallback_on_error() != 461.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversationmetadata_conversation_type() != 48024.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversationmetadata_conversation_type() != 22241.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_xmtpv3_checksum_method_fficonversationmetadata_creator_inbox_id() != 61067.toShort()) { @@ -2977,6 +2987,8 @@ public interface FfiConversationInterface { fun `consentState`(): FfiConsentState + fun `conversationType`(): FfiConversationType + fun `createdAtNs`(): kotlin.Long fun `dmPeerInboxId`(): kotlin.String @@ -3308,6 +3320,20 @@ open class FfiConversation : Disposable, AutoCloseable, FfiConversationInterface } + @Throws(GenericException::class) + override fun `conversationType`(): FfiConversationType { + return FfiConverterTypeFfiConversationType.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_conversation_type( + it, _status + ) + } + } + ) + } + + override fun `createdAtNs`(): kotlin.Long { return FfiConverterLong.lift( callWithPointer { @@ -4497,7 +4523,7 @@ public object FfiConverterTypeFfiConversationCallback : public interface FfiConversationMetadataInterface { - fun `conversationType`(): kotlin.String + fun `conversationType`(): FfiConversationType fun `creatorInboxId`(): kotlin.String @@ -4585,8 +4611,8 @@ open class FfiConversationMetadata : Disposable, AutoCloseable, FfiConversationM } } - override fun `conversationType`(): kotlin.String { - return FfiConverterString.lift( + override fun `conversationType`(): FfiConversationType { + return FfiConverterTypeFfiConversationType.lift( callWithPointer { uniffiRustCall() { _status -> UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversationmetadata_conversation_type( @@ -9307,6 +9333,34 @@ public object FfiConverterTypeFfiConversationMessageKind : } +enum class FfiConversationType { + + GROUP, + DM, + SYNC; + + companion object +} + + +/** + * @suppress + */ +public object FfiConverterTypeFfiConversationType : FfiConverterRustBuffer { + override fun read(buf: ByteBuffer) = try { + FfiConversationType.values()[buf.getInt() - 1] + } catch (e: IndexOutOfBoundsException) { + throw RuntimeException("invalid enum value, something is very wrong!!", e) + } + + override fun allocationSize(value: FfiConversationType) = 4UL + + override fun write(value: FfiConversationType, buf: ByteBuffer) { + buf.putInt(value.ordinal + 1) + } +} + + enum class FfiDeliveryStatus { UNPUBLISHED, diff --git a/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so b/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so index 12fca4c60..a8e8ba509 100644 Binary files a/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so b/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so index 28032887f..453e13caf 100644 Binary files a/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so b/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so index 91f460a92..27ecfa2c6 100644 Binary files a/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so b/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so index 5508685d4..72faddf76 100644 Binary files a/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so differ