Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V3] Remove the ability to create a V2 client #315

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions example/src/main/java/org/xmtp/android/example/ClientManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,22 @@ import org.xmtp.android.library.Client
import org.xmtp.android.library.ClientOptions
import org.xmtp.android.library.XMTPEnvironment
import org.xmtp.android.library.codecs.GroupUpdatedCodec
import org.xmtp.android.library.messages.PrivateKeyBundleV1Builder
import org.xmtp.android.library.messages.walletAddress
import java.security.SecureRandom

object ClientManager {

fun clientOptions(appContext: Context, address: String): ClientOptions {
val keyUtil = KeyUtil(appContext)
var encryptionKey = keyUtil.retrieveKey(address)
if (encryptionKey == null || encryptionKey.isEmpty()) {
encryptionKey = SecureRandom().generateSeed(32)
keyUtil.storeKey(address, encryptionKey)
}
val encryptionKey = keyUtil.retrieveKey(address)?.takeUnless { it.isEmpty() }
?: SecureRandom().generateSeed(32).also { keyUtil.storeKey(address, it) }

return ClientOptions(
api = ClientOptions.Api(
XMTPEnvironment.DEV,
appVersion = "XMTPAndroidExample/v1.0.0",
isSecure = true
),
enableV3 = true,
appContext = appContext,
dbEncryptionKey = encryptionKey
)
Expand All @@ -51,14 +46,12 @@ object ClientManager {
}

@UiThread
fun createClient(encodedPrivateKeyData: String, appContext: Context) {
fun createClient(address: String, appContext: Context) {
if (clientState.value is ClientState.Ready) return
GlobalScope.launch(Dispatchers.IO) {
try {
val v1Bundle =
PrivateKeyBundleV1Builder.fromEncodedData(data = encodedPrivateKeyData)
_client =
Client().buildFrom(v1Bundle, clientOptions(appContext, v1Bundle.walletAddress))
Client().build(address, clientOptions(appContext, address))
Client.register(codec = GroupUpdatedCodec())
_clientState.value = ClientState.Ready
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class MainActivity : AppCompatActivity(),
ConversationDetailActivity.intent(
this,
topic = conversation.topic,
peerAddress = conversation.peerAddress
peerAddress = conversation.id
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class MainViewModel : ViewModel() {
viewModelScope.launch(Dispatchers.IO) {
val listItems = mutableListOf<MainListItem>()
try {
val conversations = ClientManager.client.conversations.list(includeGroups = true)
val conversations = ClientManager.client.conversations.list()
val hmacKeysResult = ClientManager.client.conversations.getHmacKeys()
val subscriptions: MutableList<Service.Subscription> = conversations.map {
val hmacKeys = hmacKeysResult.hmacKeysMap
Expand All @@ -61,7 +61,6 @@ class MainViewModel : ViewModel() {
sub.addAllHmacKeys(result)
}
sub.topic = it.topic
sub.isSilent = it.version == Conversation.Version.V1
}.build()
}.toMutableList()

Expand Down Expand Up @@ -105,7 +104,7 @@ class MainViewModel : ViewModel() {
val stream: StateFlow<MainListItem?> =
stateFlow(viewModelScope, null) { subscriptionCount ->
if (ClientManager.clientState.value is ClientManager.ClientState.Ready) {
ClientManager.client.conversations.streamAll()
ClientManager.client.conversations.stream()
.flowWhileShared(
subscriptionCount,
SharingStarted.WhileSubscribed(1000L)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,7 @@ class ConnectWalletFragment : Fragment() {
when (uiState) {
is ConnectWalletViewModel.ConnectUiState.Error -> showError(uiState.message)
ConnectWalletViewModel.ConnectUiState.Loading -> showLoading()
is ConnectWalletViewModel.ConnectUiState.Success -> signIn(
uiState.address,
uiState.encodedKeyData
)
is ConnectWalletViewModel.ConnectUiState.Success -> signIn(uiState.address)

ConnectWalletViewModel.ConnectUiState.Unknown -> Unit
}
Expand All @@ -103,10 +100,10 @@ class ConnectWalletFragment : Fragment() {
}
}

private fun signIn(address: String, encodedKey: String) {
private fun signIn(address: String) {
val accountManager = AccountManager.get(requireContext())
Account(address, resources.getString(R.string.account_type)).also { account ->
accountManager.addAccountExplicitly(account, encodedKey, null)
accountManager.addAccountExplicitly(account, address, null)
}
requireActivity().startActivity(Intent(requireActivity(), MainActivity::class.java))
requireActivity().finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import org.xmtp.android.library.Client
import org.xmtp.android.library.XMTPException
import org.xmtp.android.library.codecs.GroupUpdatedCodec
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.PrivateKeyBundleV1Builder

class ConnectWalletViewModel(application: Application) : AndroidViewModel(application) {

Expand Down Expand Up @@ -89,8 +88,7 @@ class ConnectWalletViewModel(application: Application) : AndroidViewModel(applic
val client = Client().create(wallet, ClientManager.clientOptions(getApplication(), wallet.address))
Client.register(codec = GroupUpdatedCodec())
_uiState.value = ConnectUiState.Success(
wallet.address,
PrivateKeyBundleV1Builder.encodeData(client.v1keys)
wallet.address
)
} catch (e: XMTPException) {
_uiState.value = ConnectUiState.Error(e.message.orEmpty())
Expand All @@ -114,8 +112,7 @@ class ConnectWalletViewModel(application: Application) : AndroidViewModel(applic
val client = Client().create(wallet, ClientManager.clientOptions(getApplication(), wallet.address))
Client.register(codec = GroupUpdatedCodec())
_uiState.value = ConnectUiState.Success(
wallet.address,
PrivateKeyBundleV1Builder.encodeData(client.v1keys)
wallet.address
)
} catch (e: Exception) {
_uiState.value = ConnectUiState.Error(e.message.orEmpty())
Expand All @@ -132,7 +129,7 @@ class ConnectWalletViewModel(application: Application) : AndroidViewModel(applic
sealed class ConnectUiState {
object Unknown : ConnectUiState()
object Loading : ConnectUiState()
data class Success(val address: String, val encodedKeyData: String) : ConnectUiState()
data class Success(val address: String) : ConnectUiState()
data class Error(val message: String) : ConnectUiState()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ class ConversationDetailViewModel(private val savedStateHandle: SavedStateHandle
val listItems = mutableListOf<MessageListItem>()
try {
if (conversation == null) {
conversation = ClientManager.client.fetchConversation(
conversationTopic,
includeGroups = true
)
conversation = ClientManager.client.findConversationByTopic(conversationTopic!!)
}
conversation?.let {
if (conversation is Conversation.Group) {
Expand All @@ -79,10 +76,7 @@ class ConversationDetailViewModel(private val savedStateHandle: SavedStateHandle
if (conversation == null) {
conversation =
runBlocking {
ClientManager.client.fetchConversation(
conversationTopic,
includeGroups = false
)
ClientManager.client.findConversationByTopic(conversationTopic!!)
}
}
if (conversation != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,7 @@ class ConversationViewHolder(

fun bind(item: MainViewModel.MainListItem.ConversationItem) {
conversation = item.conversation
binding.peerAddress.text = if (item.conversation.peerAddress.contains(",")) {
val addresses = item.conversation.peerAddress.split(",")
addresses.joinToString(" & ") {
it.truncatedAddress()
}
} else {
item.conversation.peerAddress.truncatedAddress()
}
binding.peerAddress.text = item.conversation.id.truncatedAddress()

val messageBody: String = if (item.mostRecentMessage?.content<Any>() is String) {
item.mostRecentMessage.body.orEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class NewConversationBottomSheet : BottomSheetDialogFragment() {
ConversationDetailActivity.intent(
requireContext(),
topic = uiState.conversation.topic,
peerAddress = uiState.conversation.peerAddress
peerAddress = uiState.conversation.id
)
)
dismiss()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class NewGroupBottomSheet : BottomSheetDialogFragment() {
ConversationDetailActivity.intent(
requireContext(),
topic = uiState.conversation.topic,
peerAddress = uiState.conversation.peerAddress
peerAddress = uiState.conversation.id
)
)
dismiss()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@ import org.xmtp.android.example.R
import org.xmtp.android.example.conversation.ConversationDetailActivity
import org.xmtp.android.example.extension.truncatedAddress
import org.xmtp.android.example.utils.KeyUtil
import org.xmtp.android.library.Conversation
import org.xmtp.android.library.codecs.GroupUpdated
import org.xmtp.android.library.messages.EnvelopeBuilder
import org.xmtp.android.library.messages.Topic
import java.util.Date

class PushNotificationsService : FirebaseMessagingService() {

Expand Down Expand Up @@ -70,14 +67,14 @@ class PushNotificationsService : FirebaseMessagingService() {
ConversationDetailActivity.intent(
this,
topic = group.topic,
peerAddress = Conversation.Group(group).peerAddress
peerAddress = group.id
),
(PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
)

NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_xmtp_white)
.setContentTitle(Conversation.Group(group).peerAddress.truncatedAddress())
.setContentTitle(group.id.truncatedAddress())
.setContentText("New Group Chat")
.setAutoCancel(true)
.setColor(ContextCompat.getColor(this, R.color.black))
Expand All @@ -86,19 +83,15 @@ class PushNotificationsService : FirebaseMessagingService() {
.setContentIntent(pendingIntent)
} else {
val conversation =
runBlocking { ClientManager.client.fetchConversation(topic, includeGroups = true) }
runBlocking { ClientManager.client.findConversationByTopic(topic) }
if (conversation == null) {
Log.e(TAG, topic)
Log.e(TAG, "No keys or conversation persisted")
return
}
val decodedMessage = if (conversation is Conversation.Group) {
runBlocking { conversation.group.processMessage(encryptedMessageData).decode() }
} else {
val envelope = EnvelopeBuilder.buildFromString(topic, Date(), encryptedMessageData)
conversation.decode(envelope)
}
val peerAddress = conversation.peerAddress
val decodedMessage =
runBlocking { conversation.processMessage(encryptedMessageData).decode() }
val peerAddress = conversation.id

val body: String = if (decodedMessage.content<Any>() is String) {
decodedMessage.body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ class KeyUtil(val context: Context) {
return accountManager.getPassword(account)
}

fun storeKey(address: String, key: ByteArray?) {
fun storeKey(address: String, dbEncryptionKey: ByteArray?) {
val alias = "xmtp-dev-${address.lowercase()}"

val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
val editor = prefs.edit()
editor.putString(alias, encodeToString(key, NO_WRAP))
editor.putString(alias, encodeToString(dbEncryptionKey, NO_WRAP))
editor.apply()
}

Expand Down
1 change: 1 addition & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ dependencies {
api 'org.xmtp:proto-kotlin:3.71.0'

testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test:monitor:1.7.2'
androidTestImplementation 'app.cash.turbine:turbine:1.1.0'
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class AttachmentTest {
Client.register(codec = AttachmentCodec())

val fixtures = fixtures()
val aliceClient = fixtures.aliceClient
val aliceClient = fixtures.alixClient
val aliceConversation = runBlocking {
aliceClient.conversations.newConversation(fixtures.bob.walletAddress)
aliceClient.conversations.newConversation(fixtures.bo.walletAddress)
}

runBlocking {
Expand All @@ -36,8 +36,8 @@ class AttachmentTest {
)
}
val messages = runBlocking { aliceConversation.messages() }
assertEquals(messages.size, 1)
if (messages.size == 1) {
assertEquals(messages.size, 2)
if (messages.size == 2) {
val content: Attachment? = messages[0].content()
assertEquals("test.txt", content?.filename)
assertEquals("text/plain", content?.mimeType)
Expand Down
Loading
Loading