Skip to content

Commit 56cd929

Browse files
authored
Update block to deny and add implicit consent for sending messages (#129)
* change block to deny * set state to allow automatically for sending message to conversation * add a test for it * fix up linter * fetch from the network in reverse instead * reformat
1 parent d42462b commit 56cd929

File tree

5 files changed

+54
-19
lines changed

5 files changed

+54
-19
lines changed

library/src/androidTest/java/org/xmtp/android/library/ContactsTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ class ContactsTest {
6262

6363
assert(!result)
6464

65-
contacts.block(listOf(fixtures.alice.walletAddress))
65+
contacts.deny(listOf(fixtures.alice.walletAddress))
6666

67-
result = contacts.isBlocked(fixtures.alice.walletAddress)
67+
result = contacts.isDenied(fixtures.alice.walletAddress)
6868
assert(result)
6969
}
7070
}

library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt

+29-5
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,11 @@ class ConversationTest {
406406
val messages2 = aliceConversation.messages(limit = 1, after = date)
407407
assertEquals(1, messages2.size)
408408
assertEquals("hey alice 1", messages2[0].body)
409-
val messagesAsc = aliceConversation.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_ASCENDING)
409+
val messagesAsc =
410+
aliceConversation.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_ASCENDING)
410411
assertEquals("hey alice 1", messagesAsc[0].body)
411-
val messagesDesc = aliceConversation.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_DESCENDING)
412+
val messagesDesc =
413+
aliceConversation.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_DESCENDING)
412414
assertEquals("hey alice 3", messagesDesc[0].body)
413415
}
414416

@@ -723,11 +725,11 @@ class ConversationTest {
723725
assertTrue(isAllowed)
724726
assertTrue(bobClient.contacts.isAllowed(alice.walletAddress))
725727

726-
bobClient.contacts.block(listOf(alice.walletAddress))
728+
bobClient.contacts.deny(listOf(alice.walletAddress))
727729
bobClient.contacts.refreshConsentList()
728730

729-
val isBlocked = bobConversation.consentState() == ConsentState.BLOCKED
730-
assertTrue(isBlocked)
731+
val isDenied = bobConversation.consentState() == ConsentState.DENIED
732+
assertTrue(isDenied)
731733

732734
val aliceConversation = aliceClient.conversations.list()[0]
733735
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN
@@ -750,4 +752,26 @@ class ConversationTest {
750752

751753
assertTrue(isBobAllowed2)
752754
}
755+
756+
@Test
757+
fun testCanHaveImplicitConsentOnMessageSend() {
758+
val bobConversation = bobClient.conversations.newConversation(alice.walletAddress, null)
759+
val isAllowed = bobConversation.consentState() == ConsentState.ALLOWED
760+
761+
// Conversations you start should start as allowed
762+
assertTrue(isAllowed)
763+
764+
val aliceConversation = aliceClient.conversations.list()[0]
765+
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN
766+
767+
// Conversations you receive should start as unknown
768+
assertTrue(isUnknown)
769+
770+
aliceConversation.send(content = "hey bob")
771+
aliceClient.contacts.refreshConsentList()
772+
val isNowAllowed = aliceConversation.consentState() == ConsentState.ALLOWED
773+
774+
// Conversations you send a message to get marked as allowed
775+
assertTrue(isNowAllowed)
776+
}
753777
}

library/src/main/java/org/xmtp/android/library/Contacts.kt

+17-12
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import kotlinx.coroutines.runBlocking
44
import org.xmtp.android.library.messages.ContactBundle
55
import org.xmtp.android.library.messages.ContactBundleBuilder
66
import org.xmtp.android.library.messages.EnvelopeBuilder
7+
import org.xmtp.android.library.messages.Pagination
78
import org.xmtp.android.library.messages.Topic
89
import org.xmtp.android.library.messages.walletAddress
10+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass
911
import org.xmtp.proto.message.contents.PrivatePreferences.PrivatePreferencesAction
1012
import java.util.Date
1113

1214
enum class ConsentState {
1315
ALLOWED,
14-
BLOCKED,
16+
DENIED,
1517
UNKNOWN
1618
}
1719

@@ -50,7 +52,10 @@ class ConsentList(val client: Client) {
5052

5153
@OptIn(ExperimentalUnsignedTypes::class)
5254
suspend fun load(): ConsentList {
53-
val envelopes = client.query(Topic.preferenceList(identifier))
55+
val envelopes = client.query(
56+
Topic.preferenceList(identifier),
57+
Pagination(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_ASCENDING)
58+
)
5459
val consentList = ConsentList(client)
5560
val preferences: MutableList<PrivatePreferencesAction> = mutableListOf()
5661

@@ -68,12 +73,12 @@ class ConsentList(val client: Client) {
6873
)
6974
}
7075

71-
preferences.reversed().iterator().forEach { preference ->
76+
preferences.iterator().forEach { preference ->
7277
preference.allow?.walletAddressesList?.forEach { address ->
7378
consentList.allow(address)
7479
}
7580
preference.block?.walletAddressesList?.forEach { address ->
76-
consentList.block(address)
81+
consentList.deny(address)
7782
}
7883
}
7984

@@ -88,7 +93,7 @@ class ConsentList(val client: Client) {
8893
PrivatePreferencesAction.Allow.newBuilder().addWalletAddresses(entry.value)
8994
)
9095

91-
ConsentState.BLOCKED -> it.setBlock(
96+
ConsentState.DENIED -> it.setBlock(
9297
PrivatePreferencesAction.Block.newBuilder().addWalletAddresses(entry.value)
9398
)
9499

@@ -117,10 +122,10 @@ class ConsentList(val client: Client) {
117122
return ConsentListEntry.address(address, ConsentState.ALLOWED)
118123
}
119124

120-
fun block(address: String): ConsentListEntry {
121-
entries[ConsentListEntry.address(address).key] = ConsentState.BLOCKED
125+
fun deny(address: String): ConsentListEntry {
126+
entries[ConsentListEntry.address(address).key] = ConsentState.DENIED
122127

123-
return ConsentListEntry.address(address, ConsentState.BLOCKED)
128+
return ConsentListEntry.address(address, ConsentState.DENIED)
124129
}
125130

126131
fun state(address: String): ConsentState {
@@ -148,8 +153,8 @@ data class Contacts(
148153
return consentList.state(address) == ConsentState.ALLOWED
149154
}
150155

151-
fun isBlocked(address: String): Boolean {
152-
return consentList.state(address) == ConsentState.BLOCKED
156+
fun isDenied(address: String): Boolean {
157+
return consentList.state(address) == ConsentState.DENIED
153158
}
154159

155160
fun allow(addresses: List<String>) {
@@ -158,9 +163,9 @@ data class Contacts(
158163
}
159164
}
160165

161-
fun block(addresses: List<String>) {
166+
fun deny(addresses: List<String>) {
162167
for (address in addresses) {
163-
ConsentList(client).publish(consentList.block(address))
168+
ConsentList(client).publish(consentList.deny(address))
164169
}
165170
}
166171

library/src/main/java/org/xmtp/android/library/ConversationV1.kt

+3
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ data class ConversationV1(
107107

108108
fun send(prepared: PreparedMessage): String {
109109
client.publish(envelopes = prepared.envelopes)
110+
if (client.contacts.consentList.state(address = peerAddress) == ConsentState.UNKNOWN) {
111+
client.contacts.allow(addresses = listOf(peerAddress))
112+
}
110113
return prepared.messageId
111114
}
112115

library/src/main/java/org/xmtp/android/library/ConversationV2.kt

+3
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ data class ConversationV2(
119119

120120
fun send(prepared: PreparedMessage): String {
121121
client.publish(envelopes = prepared.envelopes)
122+
if (client.contacts.consentList.state(address = peerAddress) == ConsentState.UNKNOWN) {
123+
client.contacts.allow(addresses = listOf(peerAddress))
124+
}
122125
return prepared.messageId
123126
}
124127

0 commit comments

Comments
 (0)