Skip to content

Commit

Permalink
update to support V3
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer committed Sep 13, 2024
1 parent d5bb86d commit 02022c1
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 84 deletions.
4 changes: 1 addition & 3 deletions library/src/main/java/org/xmtp/android/library/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,9 @@ class Client() {
var logger: XMTPLogger = XMTPLogger()
val libXMTPVersion: String = getVersionInfo()
var installationId: String = ""
private var v3Client: FfiXmtpClient? = null
var v3Client: FfiXmtpClient? = null
var dbPath: String = ""
lateinit var inboxId: String
var hasV3Client: Boolean = false
var hasV2Client: Boolean = false

companion object {
Expand Down Expand Up @@ -359,7 +358,6 @@ class Client() {
}

if (v3Client != null) {
hasV3Client = true
options.preAuthenticateToInboxCallback?.let {
runBlocking {
it.invoke()
Expand Down
198 changes: 122 additions & 76 deletions library/src/main/java/org/xmtp/android/library/Contacts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.xmtp.android.library.messages.Topic
import org.xmtp.android.library.messages.walletAddress
import org.xmtp.proto.message.api.v1.MessageApiOuterClass
import org.xmtp.proto.message.contents.PrivatePreferences.PrivatePreferencesAction
import uniffi.xmtpv3.FfiConsentEntityType
import uniffi.xmtpv3.FfiConsentState
import uniffi.xmtpv3.FfiGroupPermissionsOptions
import java.util.Date
Expand Down Expand Up @@ -37,17 +38,35 @@ enum class ConsentState {
}
}

enum class EntryType {
ADDRESS,
GROUP_ID,
INBOX_ID;
companion object {
fun toFfiConsentEntityType(option: EntryType): FfiConsentEntityType {
return when (option) {
EntryType.ADDRESS -> FfiConsentEntityType.ADDRESS
EntryType.GROUP_ID -> FfiConsentEntityType.GROUP_ID
EntryType.INBOX_ID -> FfiConsentEntityType.INBOX_ID
}
}

fun fromFfiConsentEntityType(option: FfiConsentEntityType): EntryType {
return when (option) {
FfiConsentEntityType.ADDRESS -> EntryType.ADDRESS
FfiConsentEntityType.GROUP_ID -> EntryType.GROUP_ID
FfiConsentEntityType.INBOX_ID -> EntryType.INBOX_ID
}
}
}
}


data class ConsentListEntry(
val value: String,
val entryType: EntryType,
val consentType: ConsentState,
) {
enum class EntryType {
ADDRESS,
GROUP_ID,
INBOX_ID
}

companion object {
fun address(
address: String,
Expand Down Expand Up @@ -145,80 +164,82 @@ class ConsentList(
}

suspend fun publish(entries: List<ConsentListEntry>) {
val payload = PrivatePreferencesAction.newBuilder().also {
entries.iterator().forEach { entry ->
when (entry.entryType) {
ConsentListEntry.EntryType.ADDRESS -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowAddress(
PrivatePreferencesAction.AllowAddress.newBuilder()
.addWalletAddresses(entry.value),
)

ConsentState.DENIED ->
it.setDenyAddress(
PrivatePreferencesAction.DenyAddress.newBuilder()
.addWalletAddresses(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
if (client.hasV2Client) {
val payload = PrivatePreferencesAction.newBuilder().also {
entries.iterator().forEach { entry ->
when (entry.entryType) {
EntryType.ADDRESS -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowAddress(
PrivatePreferencesAction.AllowAddress.newBuilder()
.addWalletAddresses(entry.value),
)

ConsentState.DENIED ->
it.setDenyAddress(
PrivatePreferencesAction.DenyAddress.newBuilder()
.addWalletAddresses(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
}
}
}

ConsentListEntry.EntryType.GROUP_ID -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowGroup(
PrivatePreferencesAction.AllowGroup.newBuilder()
.addGroupIds(entry.value),
)

ConsentState.DENIED ->
it.setDenyGroup(
PrivatePreferencesAction.DenyGroup.newBuilder()
.addGroupIds(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
EntryType.GROUP_ID -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowGroup(
PrivatePreferencesAction.AllowGroup.newBuilder()
.addGroupIds(entry.value),
)

ConsentState.DENIED ->
it.setDenyGroup(
PrivatePreferencesAction.DenyGroup.newBuilder()
.addGroupIds(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
}
}
}

ConsentListEntry.EntryType.INBOX_ID -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowInboxId(
PrivatePreferencesAction.AllowInboxId.newBuilder()
.addInboxIds(entry.value),
)

ConsentState.DENIED ->
it.setDenyInboxId(
PrivatePreferencesAction.DenyInboxId.newBuilder()
.addInboxIds(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
EntryType.INBOX_ID -> {
when (entry.consentType) {
ConsentState.ALLOWED ->
it.setAllowInboxId(
PrivatePreferencesAction.AllowInboxId.newBuilder()
.addInboxIds(entry.value),
)

ConsentState.DENIED ->
it.setDenyInboxId(
PrivatePreferencesAction.DenyInboxId.newBuilder()
.addInboxIds(entry.value),
)

ConsentState.UNKNOWN -> it.clearMessageType()
}
}
}
}
}
}.build()
}.build()

val message =
uniffi.xmtpv3.userPreferencesEncrypt(
publicKey.toByteArray(),
privateKey.toByteArray(),
payload.toByteArray(),
)
val message =
uniffi.xmtpv3.userPreferencesEncrypt(
publicKey.toByteArray(),
privateKey.toByteArray(),
payload.toByteArray(),
)

val envelope = EnvelopeBuilder.buildFromTopic(
Topic.preferenceList(identifier),
Date(),
ByteArray(message.size) { message[it] },
)
val envelope = EnvelopeBuilder.buildFromTopic(
Topic.preferenceList(identifier),
Date(),
ByteArray(message.size) { message[it] },
)

client.publish(listOf(envelope))
client.publish(listOf(envelope))
}
}

fun allow(address: String): ConsentListEntry {
Expand Down Expand Up @@ -296,67 +317,92 @@ data class Contacts(

suspend fun allow(addresses: List<String>) {
val entries = addresses.map {
client.v3Client?.setConsentState(FfiConsentState.ALLOWED, FfiConsentEntityType.ADDRESS, it)
consentList.allow(it)

}
consentList.publish(entries)
}

suspend fun deny(addresses: List<String>) {
val entries = addresses.map {
client.v3Client?.setConsentState(FfiConsentState.DENIED, FfiConsentEntityType.ADDRESS, it)
consentList.deny(it)
}
consentList.publish(entries)
}

suspend fun allowGroups(groupIds: List<String>) {
val entries = groupIds.map {
client.v3Client?.setConsentState(FfiConsentState.ALLOWED, FfiConsentEntityType.GROUP_ID, it)
consentList.allowGroup(it)
}
consentList.publish(entries)
}

suspend fun denyGroups(groupIds: List<String>) {
val entries = groupIds.map {
client.v3Client?.setConsentState(FfiConsentState.DENIED, FfiConsentEntityType.GROUP_ID, it)
consentList.denyGroup(it)
}
consentList.publish(entries)
}

suspend fun allowInboxes(inboxIds: List<String>) {
val entries = inboxIds.map {
client.v3Client?.setConsentState(FfiConsentState.ALLOWED, FfiConsentEntityType.INBOX_ID, it)
consentList.allowInboxId(it)
}
consentList.publish(entries)
}

suspend fun denyInboxes(inboxIds: List<String>) {
val entries = inboxIds.map {
client.v3Client?.setConsentState(FfiConsentState.DENIED, FfiConsentEntityType.INBOX_ID, it)
consentList.denyInboxId(it)
}
consentList.publish(entries)
}

fun isAllowed(address: String): Boolean {
suspend fun isAllowed(address: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.ADDRESS, address) == FfiConsentState.ALLOWED
}
return consentList.state(address) == ConsentState.ALLOWED
}

fun isDenied(address: String): Boolean {
suspend fun isDenied(address: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.ADDRESS, address) == FfiConsentState.DENIED
}
return consentList.state(address) == ConsentState.DENIED
}

fun isGroupAllowed(groupId: String): Boolean {
suspend fun isGroupAllowed(groupId: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.GROUP_ID, groupId) == FfiConsentState.ALLOWED
}
return consentList.groupState(groupId) == ConsentState.ALLOWED
}

fun isGroupDenied(groupId: String): Boolean {
suspend fun isGroupDenied(groupId: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.GROUP_ID, groupId) == FfiConsentState.DENIED
}
return consentList.groupState(groupId) == ConsentState.DENIED
}

fun isInboxAllowed(inboxId: String): Boolean {
suspend fun isInboxAllowed(inboxId: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.INBOX_ID, inboxId) == FfiConsentState.ALLOWED
}
return consentList.inboxIdState(inboxId) == ConsentState.ALLOWED
}

fun isInboxDenied(inboxId: String): Boolean {
suspend fun isInboxDenied(inboxId: String): Boolean {
client.v3Client?.let {
return it.getConsentState(FfiConsentEntityType.INBOX_ID, inboxId) == FfiConsentState.DENIED
}
return consentList.inboxIdState(inboxId) == ConsentState.DENIED
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ sealed class Conversation {
return when (this) {
is V1 -> conversationV1.client.contacts.consentList.state(address = peerAddress)
is V2 -> conversationV2.client.contacts.consentList.state(address = peerAddress)
is Group -> group.client.contacts.consentList.groupState(groupId = group.id)
is Group -> group.consentState()
}
}

Expand Down
8 changes: 4 additions & 4 deletions library/src/main/java/org/xmtp/android/library/Group.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class Group(val client: Client, private val libXMTPGroup: FfiGroup) {
}

suspend fun send(encodedContent: EncodedContent): String {
if (client.contacts.consentList.groupState(groupId = id) == ConsentState.UNKNOWN) {
client.contacts.allowGroups(groupIds = listOf(id))
if (consentState() == ConsentState.UNKNOWN) {
updateConsentState(ConsentState.ALLOWED)
}
val messageId = libXMTPGroup.send(contentBytes = encodedContent.toByteArray())
return messageId.toHex()
Expand Down Expand Up @@ -100,8 +100,8 @@ class Group(val client: Client, private val libXMTPGroup: FfiGroup) {
}

suspend fun <T> prepareMessage(content: T, options: SendOptions? = null): String {
if (client.contacts.consentList.groupState(groupId = id) == ConsentState.UNKNOWN) {
client.contacts.allowGroups(groupIds = listOf(id))
if (consentState() == ConsentState.UNKNOWN) {
updateConsentState(ConsentState.ALLOWED)
}
val encodeContent = encodeContent(content = content, options = options)
return libXMTPGroup.sendOptimistic(encodeContent.toByteArray()).toHex()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.xmtp.android.library.libxmtp

import org.xmtp.android.library.ConsentState
import uniffi.xmtpv3.FfiGroupMember
import uniffi.xmtpv3.FfiPermissionLevel

Expand All @@ -18,4 +19,7 @@ class Member(private val ffiMember: FfiGroupMember) {
FfiPermissionLevel.ADMIN -> PermissionLevel.ADMIN
FfiPermissionLevel.SUPER_ADMIN -> PermissionLevel.SUPER_ADMIN
}

val consentState: ConsentState
get() = ConsentState.fromFfiConsentState(ffiMember.consentState)
}

0 comments on commit 02022c1

Please sign in to comment.