diff --git a/app/src/main/java/com/algorand/android/MainActivity.kt b/app/src/main/java/com/algorand/android/MainActivity.kt index e86c4a90..022a339b 100644 --- a/app/src/main/java/com/algorand/android/MainActivity.kt +++ b/app/src/main/java/com/algorand/android/MainActivity.kt @@ -363,7 +363,11 @@ class MainActivity : xnote = deepLink.xnote ) - nav(HomeNavigationDirections.actionGlobalConfirmKeyRegAccountSelectionFragment(txnDetail)) + if (qrScannerViewModel.hasAccountAuthority(deepLink.senderAddress)) { + nav(HomeNavigationDirections.actionGlobalKeyRegTransactionFragment(txnDetail)) + } else { + showGlobalError(getString(R.string.you_dont_have_any, deepLink.senderAddress), tag = activityTag) + } } } } diff --git a/app/src/main/java/com/algorand/android/MainViewModel.kt b/app/src/main/java/com/algorand/android/MainViewModel.kt index 5d5e55e2..1d2f6eb5 100644 --- a/app/src/main/java/com/algorand/android/MainViewModel.kt +++ b/app/src/main/java/com/algorand/android/MainViewModel.kt @@ -25,6 +25,7 @@ import com.algorand.android.models.AssetOperationResult import com.algorand.android.models.Node import com.algorand.android.models.SignedTransactionDetail import com.algorand.android.models.TransactionData +import com.algorand.android.modules.accountstatehelper.domain.usecase.AccountStateHelperUseCase import com.algorand.android.modules.appopencount.domain.usecase.IncreaseAppOpeningCountUseCase import com.algorand.android.modules.autolockmanager.ui.usecase.AutoLockManagerUseCase import com.algorand.android.modules.deeplink.ui.DeeplinkHandler @@ -36,7 +37,6 @@ import com.algorand.android.network.IndexerInterceptor import com.algorand.android.network.MobileHeaderInterceptor import com.algorand.android.repository.NodeRepository import com.algorand.android.usecase.AccountCacheStatusUseCase -import com.algorand.android.usecase.AccountDetailUseCase import com.algorand.android.usecase.SendSignedTransactionUseCase import com.algorand.android.utils.AccountCacheManager import com.algorand.android.utils.AssetName @@ -75,11 +75,11 @@ class MainViewModel @Inject constructor( private val tutorialUseCase: TutorialUseCase, private val swapNavigationDestinationHelper: SwapNavigationDestinationHelper, private val sendSignedTransactionUseCase: SendSignedTransactionUseCase, - private val accountDetailUseCase: AccountDetailUseCase, private val accountDetailCacheManager: AccountDetailCacheManager, private val nodeRepository: NodeRepository, accountCacheStatusUseCase: AccountCacheStatusUseCase, - private val autoLockManagerUseCase: AutoLockManagerUseCase + private val autoLockManagerUseCase: AutoLockManagerUseCase, + private val accountStateHelperUseCase: AccountStateHelperUseCase ) : BaseViewModel() { // TODO: Replace this with Flow whenever have time @@ -295,4 +295,8 @@ class MainViewModel @Inject constructor( } } } + + fun hasAccountAuthority(accountAddress: String): Boolean { + return accountStateHelperUseCase.hasAccountAuthority(accountAddress) + } } diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/domain/usecase/KeyRegAccountSelectionPreviewUseCase.kt b/app/src/main/java/com/algorand/android/modules/keyreg/domain/usecase/KeyRegAccountSelectionPreviewUseCase.kt deleted file mode 100644 index 8a281cc2..00000000 --- a/app/src/main/java/com/algorand/android/modules/keyreg/domain/usecase/KeyRegAccountSelectionPreviewUseCase.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.algorand.android.modules.keyreg.domain.usecase - -import com.algorand.android.R -import com.algorand.android.core.AccountManager -import com.algorand.android.models.AnnotatedString -import com.algorand.android.models.ScreenState -import com.algorand.android.modules.accounticon.ui.usecase.CreateAccountIconDrawableUseCase -import com.algorand.android.modules.accounts.domain.usecase.AccountDisplayNameUseCase -import com.algorand.android.modules.accounts.domain.usecase.GetAccountValueUseCase -import com.algorand.android.modules.accountstatehelper.domain.usecase.AccountStateHelperUseCase -import com.algorand.android.modules.basesingleaccountselection.ui.mapper.SingleAccountSelectionListItemMapper -import com.algorand.android.modules.basesingleaccountselection.ui.model.SingleAccountSelectionListItem -import com.algorand.android.modules.basesingleaccountselection.ui.usecase.BaseSingleAccountSelectionUsePreviewCase -import com.algorand.android.modules.currency.domain.usecase.CurrencyUseCase -import com.algorand.android.modules.parity.domain.usecase.ParityUseCase -import com.algorand.android.modules.rekey.rekeytostandardaccount.accountselection.ui.mapper.RekeyToStandardAccountSelectionPreviewMapper -import com.algorand.android.modules.rekey.rekeytostandardaccount.accountselection.ui.model.RekeyToStandardAccountSelectionPreview -import com.algorand.android.modules.sorting.accountsorting.domain.usecase.AccountSortPreferenceUseCase -import com.algorand.android.usecase.AccountDetailUseCase -import com.algorand.android.usecase.GetSortedLocalAccountsUseCase -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.map -import javax.inject.Inject - -@SuppressWarnings("LongParameterList") -class KeyRegAccountSelectionPreviewUseCase @Inject constructor( - private val rekeyToStandardAccountSelectionPreviewMapper: RekeyToStandardAccountSelectionPreviewMapper, - private val accountStateHelperUseCase: AccountStateHelperUseCase, - accountDetailUseCase: AccountDetailUseCase, - getAccountValueUseCase: GetAccountValueUseCase, - accountSortPreferenceUseCase: AccountSortPreferenceUseCase, - accountDisplayNameUseCase: AccountDisplayNameUseCase, - parityUseCase: ParityUseCase, - currencyUseCase: CurrencyUseCase, - singleAccountSelectionListItemMapper: SingleAccountSelectionListItemMapper, - getSortedLocalAccountsUseCase: GetSortedLocalAccountsUseCase, - accountManager: AccountManager, - createAccountIconDrawableUseCase: CreateAccountIconDrawableUseCase -) : BaseSingleAccountSelectionUsePreviewCase( - singleAccountSelectionListItemMapper = singleAccountSelectionListItemMapper, - getSortedLocalAccountsUseCase = getSortedLocalAccountsUseCase, - accountDisplayNameUseCase = accountDisplayNameUseCase, - getAccountValueUseCase = getAccountValueUseCase, - parityUseCase = parityUseCase, - currencyUseCase = currencyUseCase, - accountManager = accountManager, - accountSortPreferenceUseCase = accountSortPreferenceUseCase, - accountDetailUseCase = accountDetailUseCase, - createAccountIconDrawableUseCase = createAccountIconDrawableUseCase -) { - - fun getInitialKeyRegSingleAccountSelectionPreview(): RekeyToStandardAccountSelectionPreview { - return rekeyToStandardAccountSelectionPreviewMapper.mapToRekeyToStandardAccountSelectionPreview( - screenState = null, - singleAccountSelectionListItems = emptyList(), - isLoading = true - ) - } - - fun getKeyRegSingleAccountSelectionPreviewFlow() = channelFlow { - getSortedCachedAccountDetailFlow().map { accountsDetails -> - accountsDetails.map { accountDetail -> - createAccountItemListFromAccountDetail(accountDetail) - } - }.collectLatest { singleAccountItems -> - val screenState = if (singleAccountItems.isEmpty()) { - ScreenState.CustomState(title = R.string.no_account_found) - } else { - null - } - val titleItem = createTitleItem(textResId = R.string.select_account) - val descriptionItem = createDescriptionItem( - descriptionAnnotatedString = AnnotatedString( - stringResId = R.string.choose_account_for_txn_signature_request - ) - ) - val singleAccountSelectionListItems = mutableListOf().apply { - add(titleItem) - add(descriptionItem) - addAll(singleAccountItems) - } - val preview = rekeyToStandardAccountSelectionPreviewMapper.mapToRekeyToStandardAccountSelectionPreview( - screenState = screenState, - singleAccountSelectionListItems = singleAccountSelectionListItems, - isLoading = false - ) - send(preview) - } - } -} diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionFragment.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionFragment.kt deleted file mode 100644 index e3d91800..00000000 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionFragment.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.algorand.android.modules.keyreg.ui - -import androidx.fragment.app.viewModels -import com.algorand.android.R -import com.algorand.android.models.FragmentConfiguration -import com.algorand.android.models.ToolbarConfiguration -import com.algorand.android.modules.basesingleaccountselection.ui.BaseSingleAccountSelectionFragment -import com.algorand.android.modules.basesingleaccountselection.ui.BaseSingleAccountSelectionViewModel -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class KeyRegAccountSelectionFragment : BaseSingleAccountSelectionFragment() { - - override val toolbarConfiguration = ToolbarConfiguration( - startIconResId = R.drawable.ic_left_arrow, - startIconClick = ::navBack - ) - override val fragmentConfiguration = FragmentConfiguration(toolbarConfiguration = toolbarConfiguration) - - override val singleAccountSelectionViewModel: BaseSingleAccountSelectionViewModel - get() = keyRegAccountSelectionViewModel - private val keyRegAccountSelectionViewModel by viewModels() - - override fun onAccountSelected(accountAddress: String) { - nav( - KeyRegAccountSelectionFragmentDirections - .actionKeyRegAccountSelectionFragmentToKeyRegTransactionFragment( - keyRegTransactionDetail = keyRegAccountSelectionViewModel.keyRegTransactionDetail, - signingAccountAddress = accountAddress - ) - ) - } -} diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionViewModel.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionViewModel.kt deleted file mode 100644 index f1b14e03..00000000 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegAccountSelectionViewModel.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.algorand.android.modules.keyreg.ui - -import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.viewModelScope -import com.algorand.android.modules.basesingleaccountselection.ui.BaseSingleAccountSelectionViewModel -import com.algorand.android.modules.keyreg.domain.usecase.KeyRegAccountSelectionPreviewUseCase -import com.algorand.android.modules.keyreg.ui.model.KeyRegTransactionDetail -import com.algorand.android.modules.rekey.rekeytostandardaccount.accountselection.ui.model.RekeyToStandardAccountSelectionPreview -import com.algorand.android.utils.getOrThrow -import com.algorand.android.utils.launchIO -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.collectLatest -import javax.inject.Inject - -@HiltViewModel -class KeyRegAccountSelectionViewModel @Inject constructor( - private val keyRegAccountSelectionPreviewUseCase: KeyRegAccountSelectionPreviewUseCase, - savedStateHandle: SavedStateHandle -) : BaseSingleAccountSelectionViewModel() { - - var keyRegTransactionDetail = savedStateHandle.getOrThrow( - KEY_REG_DETAIL - ) - - override val singleAccountSelectionFieldsFlow: StateFlow - get() = keyRegToAccountSingleAccountSelectionPreview - private val keyRegToAccountSingleAccountSelectionPreview = MutableStateFlow(getInitialPreview()) - - init { - initPreviewFlow() - } - - private fun initPreviewFlow() { - viewModelScope.launchIO { - keyRegAccountSelectionPreviewUseCase.getKeyRegSingleAccountSelectionPreviewFlow().collectLatest { preview -> - keyRegToAccountSingleAccountSelectionPreview.emit(preview) - } - } - } - - private fun getInitialPreview(): RekeyToStandardAccountSelectionPreview { - return keyRegAccountSelectionPreviewUseCase - .getInitialKeyRegSingleAccountSelectionPreview() - } - - companion object { - const val KEY_REG_DETAIL = "keyRegTransactionDetail" - } -} diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegTransactionViewModel.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegTransactionViewModel.kt index 233a68c0..94c0f015 100644 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegTransactionViewModel.kt +++ b/app/src/main/java/com/algorand/android/modules/keyreg/ui/KeyRegTransactionViewModel.kt @@ -39,9 +39,6 @@ class KeyRegTransactionViewModel @Inject constructor( savedStateHandle: SavedStateHandle ) : ViewModel() { - private var signingAccountAddress = savedStateHandle.getOrThrow( - SIGNING_ACCOUNT_ADDRSS - ) private var keyRegTransactionDetail = savedStateHandle.getOrThrow( KEY_REG_DETAIL ) @@ -55,7 +52,7 @@ class KeyRegTransactionViewModel @Inject constructor( get() = _previewState.asStateFlow() fun initUi() { - _previewState.value = previewMapper.createInitialPreview(keyRegTransactionDetail, signingAccountAddress) + _previewState.value = previewMapper.createInitialPreview(keyRegTransactionDetail) } fun confirmTransaction() { @@ -97,7 +94,6 @@ class KeyRegTransactionViewModel @Inject constructor( } companion object { - const val SIGNING_ACCOUNT_ADDRSS = "signingAccountAddress" const val KEY_REG_DETAIL = "keyRegTransactionDetail" const val TAG = "KeyRegTransactionViewModel" const val TRANSACTION_ERROR = "transaction_error" diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/components/KeyRegTable.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/components/KeyRegTable.kt index b5a8ba74..6be082bf 100644 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/components/KeyRegTable.kt +++ b/app/src/main/java/com/algorand/android/modules/keyreg/ui/components/KeyRegTable.kt @@ -63,7 +63,6 @@ fun keyRegTable( "Last Valid Round" to keyRegTransactionDetail.lastValid, "xNote" to keyRegTransactionDetail.xNote, "Note" to keyRegTransactionDetail.note, - "Signing Address" to keyRegTransactionDetail.signingAddress, ) val fabHeight by remember { diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/mapper/KeyRegTransactionPreviewMapper.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/mapper/KeyRegTransactionPreviewMapper.kt index b2a32769..82b4c1d5 100644 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/mapper/KeyRegTransactionPreviewMapper.kt +++ b/app/src/main/java/com/algorand/android/modules/keyreg/ui/mapper/KeyRegTransactionPreviewMapper.kt @@ -20,7 +20,6 @@ class KeyRegTransactionPreviewMapper @Inject constructor() { fun createInitialPreview( detail: KeyRegTransactionDetail, - signingAddress: String ): KeyRegTransactionPreview { return KeyRegTransactionPreview( isLoadingVisible = false, @@ -35,7 +34,6 @@ class KeyRegTransactionPreviewMapper @Inject constructor() { lastValid = detail.voteLastRound.orEmpty(), xNote = detail.xnote, note = detail.note, - signingAddress = signingAddress, signTransactionEvent = null, showErrorEvent = null ) diff --git a/app/src/main/java/com/algorand/android/modules/keyreg/ui/model/KeyRegTransactionPreview.kt b/app/src/main/java/com/algorand/android/modules/keyreg/ui/model/KeyRegTransactionPreview.kt index 3d7b16d4..4a2e1062 100644 --- a/app/src/main/java/com/algorand/android/modules/keyreg/ui/model/KeyRegTransactionPreview.kt +++ b/app/src/main/java/com/algorand/android/modules/keyreg/ui/model/KeyRegTransactionPreview.kt @@ -29,7 +29,6 @@ data class KeyRegTransactionPreview( val lastValid: String, val xNote: String?, val note: String?, - val signingAddress: String, val signTransactionEvent: Event?, val showErrorEvent: Event? ) diff --git a/app/src/main/java/com/algorand/android/modules/qrscanning/BaseQrScannerFragment.kt b/app/src/main/java/com/algorand/android/modules/qrscanning/BaseQrScannerFragment.kt index f75deb43..6f6d8d34 100644 --- a/app/src/main/java/com/algorand/android/modules/qrscanning/BaseQrScannerFragment.kt +++ b/app/src/main/java/com/algorand/android/modules/qrscanning/BaseQrScannerFragment.kt @@ -205,8 +205,11 @@ abstract class BaseQrScannerFragment( xnote = deepLink.xnote ) - nav(HomeNavigationDirections.actionGlobalConfirmKeyRegAccountSelectionFragment(txnDetail)) - + if (qrScannerViewModel.hasAccountAuthority(deepLink.senderAddress)) { + nav(HomeNavigationDirections.actionGlobalKeyRegTransactionFragment(txnDetail)) + } else { + showGlobalError(getString(R.string.you_dont_have_any, deepLink.senderAddress)) + } return true } diff --git a/app/src/main/java/com/algorand/android/modules/qrscanning/QrScannerViewModel.kt b/app/src/main/java/com/algorand/android/modules/qrscanning/QrScannerViewModel.kt index ce067b2b..efd2e6aa 100644 --- a/app/src/main/java/com/algorand/android/modules/qrscanning/QrScannerViewModel.kt +++ b/app/src/main/java/com/algorand/android/modules/qrscanning/QrScannerViewModel.kt @@ -14,6 +14,7 @@ package com.algorand.android.modules.qrscanning import androidx.lifecycle.viewModelScope import com.algorand.android.core.BaseViewModel +import com.algorand.android.modules.accountstatehelper.domain.usecase.AccountStateHelperUseCase import com.algorand.android.modules.deeplink.ui.DeeplinkHandler import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -23,7 +24,8 @@ import kotlinx.coroutines.launch @HiltViewModel class QrScannerViewModel @Inject constructor( - private val deeplinkHandler: DeeplinkHandler + private val deeplinkHandler: DeeplinkHandler, + private val accountStateHelperUseCase: AccountStateHelperUseCase, ) : BaseViewModel() { private val _isQrCodeInProgressFlow = MutableSharedFlow() @@ -46,4 +48,8 @@ class QrScannerViewModel @Inject constructor( fun removeDeeplinkHandlerListener() { deeplinkHandler.setListener(null) } + + fun hasAccountAuthority(accountAddress: String): Boolean { + return accountStateHelperUseCase.hasAccountAuthority(accountAddress) + } } diff --git a/app/src/main/java/com/algorand/android/usecase/GetLocalAccountsUseCase.kt b/app/src/main/java/com/algorand/android/usecase/GetLocalAccountsUseCase.kt index 57a260f7..0952adbb 100644 --- a/app/src/main/java/com/algorand/android/usecase/GetLocalAccountsUseCase.kt +++ b/app/src/main/java/com/algorand/android/usecase/GetLocalAccountsUseCase.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.MutableStateFlow class GetLocalAccountsUseCase @Inject constructor( private val accountManager: AccountManager, - private val accountDetailUseCase: AccountDetailUseCase, private val accountStateHelperUseCase: AccountStateHelperUseCase ) { fun getLocalAccountsFromAccountManagerCache(): List { diff --git a/app/src/main/res/navigation/home_navigation.xml b/app/src/main/res/navigation/home_navigation.xml index 754eb6db..2e9f2695 100644 --- a/app/src/main/res/navigation/home_navigation.xml +++ b/app/src/main/res/navigation/home_navigation.xml @@ -323,12 +323,8 @@ - - + android:id="@+id/action_global_keyRegTransactionFragment" + app:destination="@id/keyRegTransactionFragment" /> - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 66e23505..7be625e1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1434,4 +1434,6 @@ Pera Wallet now provides an easy and fast way to stake with various dApps. Stake in Pera + You don\'t have any authorized account matching with %1$s + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ba557695..a4cc4500 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ android-minSdk = "26" android-namespace = "com.algorand.android" android-targetSdk = "34" android-versionCode = "124" -android-versionName = "5.15.0" +android-versionName = "5.16.0" algosdk = "2.5.0" androidx-compose-activity = "1.9.3" androidx-compose-fragment = "1.8.5"