Skip to content

Commit

Permalink
Merge branch 'main' into fix/typos
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer authored Dec 19, 2024
2 parents ede35a6 + 021ea9f commit 1446192
Show file tree
Hide file tree
Showing 30 changed files with 1,825 additions and 491 deletions.
9 changes: 0 additions & 9 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,3 @@ jobs:
with:
name: lint
path: 'app/build/reports/library/lint-results-**.html'

- name: Gradle Android lint example
run: ./gradlew :example:lintDebug
- uses: actions/upload-artifact@v3
name: Upload example lint report
if: ${{ failure() }}
with:
name: lint
path: 'app/build/reports/example/lint-results-**.html'
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ conversation.send(text = "gm")

// Listen for new messages in the conversation
conversation.streamMessages().collect {
print("${it.senderAddress}: ${it.body}")
print("${it.senderInboxId}: ${it.body}")
}
```

Expand Down Expand Up @@ -199,17 +199,17 @@ val nextPage = conversation.messages(limit = 25, beforeNs = messages[0].sentNs)

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.

```kotlin
conversation.streamMessages().collect {
if (it.senderAddress == client.address) {
if (it.senderInboxId == client.address) {
// This message was sent from me
}

print("New message from ${it.senderAddress}: ${it.body}")
print("New message from ${it.senderInboxId}: ${it.body}")
}
```

Expand Down
35 changes: 0 additions & 35 deletions dev/local/test/script.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class ConversationViewHolder(
} else {
""
}
val isMe = item.mostRecentMessage?.senderAddress == ClientManager.client.address
val isMe = item.mostRecentMessage?.senderInboxId == ClientManager.client.address
if (messageBody.isNotBlank()) {
binding.messageBody.text = if (isMe) binding.root.resources.getString(
R.string.your_message_body,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MessageViewHolder(
@SuppressLint("SetTextI18n")
fun bind(item: ConversationDetailViewModel.MessageListItem.Message) {
val isFromMe =
ClientManager.client.address.lowercase() == item.message.senderAddress.lowercase()
ClientManager.client.address.lowercase() == item.message.senderInboxId.lowercase()
val params = binding.messageContainer.layoutParams as ConstraintLayout.LayoutParams
if (isFromMe) {
params.rightToRight = PARENT_ID
Expand Down
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ dependencies {
implementation 'org.web3j:crypto:4.9.4'
implementation "net.java.dev.jna:jna:5.14.0@aar"
api 'com.google.protobuf:protobuf-kotlin-lite:3.22.3'
api 'org.xmtp:proto-kotlin:3.71.0'
api 'org.xmtp:proto-kotlin:3.72.3'

testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test:monitor:1.7.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import uniffi.xmtpv3.GenericException
import java.io.File
import java.security.SecureRandom
import java.util.Date
import java.util.concurrent.CompletableFuture
Expand Down Expand Up @@ -315,19 +316,16 @@ class ClientTest {
dbEncryptionKey = key
)
)
alixClient.dropLocalDatabaseConnection()
alixClient.deleteLocalDatabase()

val alixClient2 = Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
alixClient2.dropLocalDatabaseConnection()
alixClient2.deleteLocalDatabase()
}

val alixClient3 = runBlocking {
Expand All @@ -336,7 +334,8 @@ class ClientTest {
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
dbEncryptionKey = key,
dbDirectory = File(context.filesDir.absolutePath, "xmtp_db3").toPath().toString()
)
)
}
Expand Down Expand Up @@ -557,10 +556,31 @@ class ClientTest {
val time3 = end3.time - start3.time
Log.d("PERF", "Built a client with inboxId in ${time3 / 1000.0}s")

val start4 = Date()
val buildClient3 = runBlocking {
Client().build(
fakeWallet.address,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.DEV, true),
appContext = context,
dbEncryptionKey = key
),
inboxId = client.inboxId,
apiClient = client.apiClient
)
}
val end4 = Date()
val time4 = end4.time - start4.time
Log.d("PERF", "Built a client with inboxId and apiClient in ${time4 / 1000.0}s")

assert(time2 < time1)
assert(time3 < time1)
assert(time3 < time2)
assert(time4 < time1)
assert(time4 < time2)
assert(time4 < time3)
assertEquals(client.inboxId, buildClient1.inboxId)
assertEquals(client.inboxId, buildClient2.inboxId)
assertEquals(client.inboxId, buildClient3.inboxId)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.xmtp.android.library

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -13,7 +12,6 @@ import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import java.security.SecureRandom

@RunWith(AndroidJUnit4::class)
class ConversationsTest {
Expand Down Expand Up @@ -49,8 +47,8 @@ class ConversationsTest {
runBlocking { boClient.conversations.newGroup(listOf(caro.walletAddress)) }
val dm = runBlocking { boClient.conversations.findOrCreateDm(caro.walletAddress) }

val sameDm = boClient.findConversationByTopic(dm.topic)
val sameGroup = boClient.findConversationByTopic(group.topic)
val sameDm = runBlocking { boClient.findConversationByTopic(dm.topic) }
val sameGroup = runBlocking { boClient.findConversationByTopic(group.topic) }
assertEquals(group.id, sameGroup?.id)
assertEquals(dm.id, sameDm?.id)
}
Expand Down Expand Up @@ -112,6 +110,28 @@ class ConversationsTest {
assertEquals(conversationsOrdered.map { it.id }, listOf(group2.id, dm.id, group1.id))
}

@Test
fun testsCanSyncAllConversationsFiltered() {
runBlocking { boClient.conversations.findOrCreateDm(caro.walletAddress) }
val group =
runBlocking { boClient.conversations.newGroup(listOf(caro.walletAddress)) }
assertEquals(runBlocking { boClient.conversations.syncAllConversations() }.toInt(), 2)
assertEquals(
runBlocking { boClient.conversations.syncAllConversations(consentState = ConsentState.ALLOWED) }.toInt(),
2
)
runBlocking { group.updateConsentState(ConsentState.DENIED) }
assertEquals(
runBlocking { boClient.conversations.syncAllConversations(consentState = ConsentState.ALLOWED) }.toInt(),
1
)
assertEquals(
runBlocking { boClient.conversations.syncAllConversations(consentState = ConsentState.DENIED) }.toInt(),
1
)
assertEquals(runBlocking { boClient.conversations.syncAllConversations() }.toInt(), 2)
}

@Test
fun testCanStreamAllMessages() {
val group =
Expand Down Expand Up @@ -166,133 +186,4 @@ class ConversationsTest {
assertEquals(2, allMessages.size)
job.cancel()
}

@Test
fun testSyncConsent() {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext
val alixWallet = PrivateKeyBuilder()

val alixClient = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
)
)
}
val dm = runBlocking { alixClient.conversations.findOrCreateDm(bo.walletAddress) }
runBlocking {
dm.updateConsentState(ConsentState.DENIED)
assertEquals(dm.consentState(), ConsentState.DENIED)
boClient.conversations.sync()
}
val boDm = runBlocking { boClient.findConversation(dm.id) }

val alixClient2 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
}

val state = runBlocking { alixClient2.inboxState(true) }
assertEquals(state.installations.size, 2)

runBlocking {
boClient.conversations.sync()
boDm?.sync()
alixClient2.preferences.syncConsent()
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.setConsentState(
listOf(
ConsentRecord(
dm2.id,
EntryType.CONVERSATION_ID,
ConsentState.ALLOWED
)
)
)
assertEquals(
alixClient2.preferences.conversationState(dm2.id),
ConsentState.ALLOWED
)
assertEquals(dm2.consentState(), ConsentState.ALLOWED)
}
}

@Test
fun testStreamConsent() {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext
val alixWallet = PrivateKeyBuilder()

val alixClient = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
)
)
}
val alixGroup = runBlocking { alixClient.conversations.newGroup(listOf(bo.walletAddress)) }

val alixClient2 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
}

runBlocking {
alixGroup.send("Hello")
alixClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
}
val alix2Group = alixClient2.findGroup(alixGroup.id)!!
val consent = mutableListOf<ConsentRecord>()
val job = CoroutineScope(Dispatchers.IO).launch {
try {
alixClient.preferences.streamConsent()
.collect { entry ->
consent.add(entry)
}
} catch (e: Exception) {
}
}

Thread.sleep(1000)

runBlocking {
alix2Group.updateConsentState(ConsentState.DENIED)
val dm3 = alixClient2.conversations.newConversation(caro.walletAddress)
dm3.updateConsentState(ConsentState.DENIED)
alixClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
}

Thread.sleep(2000)
assertEquals(3, consent.size)
assertEquals(alixGroup.consentState(), ConsentState.DENIED)
job.cancel()
}
}
Loading

0 comments on commit 1446192

Please sign in to comment.