feat(creation): Implement joint account creation flow#517
feat(creation): Implement joint account creation flow#517yasin-ce wants to merge 14 commits intomultisig/06-account-pages-supportfrom
Conversation
4b6f926 to
f44cf3b
Compare
5b34bb9 to
9fa3c15
Compare
f44cf3b to
c787611
Compare
9fa3c15 to
91daf6f
Compare
- Fix duplicate DI bindings for joint account repository - Add missing interface implementations - Update transaction signer handling for joint accounts - Fix import statements and code organization
- Add CreateJointAccountFragment and ViewModel - Add NameJointAccountFragment for account naming - Add AddJointAccountFragment for participant selection - Implement JointAccountTransactionSignHelper - Add CreateJointAccountUseCase - Add participant selection UI components - Handle contact creation for external addresses
- Update AccountAssetsFragment to use onInboxClick - Update AccountAssetsAccountDetailAdapter to call listener.onInboxClick - Update AccountDetailQuickActionsView to match Inbox sealed class
c787611 to
8bd9179
Compare
91daf6f to
ab2aecc
Compare
…ation-flow * multisig/06-account-pages-support: fix(di): Add missing GetJointAccount and GetJointAccountParticipantCount bindings fix(test): Use correct domain model class names in HasInboxItemsForAddressUseCaseTest
Architecture: - app module (UI only): Fragments, Screens, ViewModels that use interfaces - common-sdk domain layer (public): UseCase interfaces, Domain models - common-sdk data layer (internal): Repository (internal), UseCase implementations, Services, Mappers Changes: - Make JointAccountRepository internal - Create use case interfaces for each repository function: - CreateJointAccount - GetInboxMessages - DeleteInboxJointInvitationNotification - Create internal use case implementations - Delete duplicate data layer from app module - Update app module to use common-sdk use cases - Add Dagger bindings for new use cases
Fix Fragment lifecycle violations where initSavedStateListener was called in onResume instead of onViewCreated: - ContactInfoFragment: Remove duplicate call in onResume (was in both) - AccountHistoryFragment: Move to onViewCreated - Arc59SendSummaryFragment: Move to onViewCreated, remove empty onResume - InAppPinFragment: Move to onViewCreated, remove empty onResume This ensures SavedState listeners are registered early in the lifecycle and prevents missing initial state emissions.
…tion The existing GetInboxMessages in InboxUseCases.kt gets cached data. The new FetchInboxMessages fetches from the API via repository.
- Replace *DTO suffix with actual domain model names - ParticipantSignatureDTO -> ParticipantSignature - JointSignRequestDTO -> JointSignRequest - SignRequestWithFullSignatureDTO -> SignRequestWithFullSignature - TransactionListWithFullSignatureDTO -> TransactionListWithFullSignature - SignRequestTransactionListResponseDTO -> AddSignatureInput - Fix PeraResult.Success/Error usage in DefaultJointAccountDetailProcessor
| private val isThereAnyLocalAccount: IsThereAnyLocalAccount | ||
| ) : GetAddAccountIntroPreview { | ||
|
|
||
| override fun invoke(isShowingCloseButton: Boolean): Flow<AddAccountIntroPreview> = flow { |
There was a problem hiding this comment.
unnecessary flow. We can return the result as AddAccountIntroPreview
| import com.algorand.android.R | ||
| import javax.inject.Inject | ||
|
|
||
| class AddAccountIntroPreviewDecider @Inject constructor() { |
There was a problem hiding this comment.
We can move these functions in mapper
| sealed interface ViewState { | ||
| data object Idle : ViewState | ||
| data class Content( | ||
| val preview: AddAccountIntroPreview |
There was a problem hiding this comment.
We can remove preview class move fields here
| fun onSearchQueryUpdate(query: String) { | ||
| stateDelegate.updateState { it.copy(searchQuery = query) } | ||
| searchJob?.cancel() | ||
| searchJob = viewModelScope.launch { |
There was a problem hiding this comment.
We should use flow.debounce instead of creating scope and waiting
|
|
||
| fun getAccountSelectionList( | ||
| query: String, | ||
| ): Flow<List<JointAccountSelectionListItem>> { |
There was a problem hiding this comment.
these functions are not observing flows, they are just getting results as flow. There is no point of returning flow here as well as using combine function. you can simply return the result. This is creating unnecessary flows each time query is updated
| mainActivity?.showAlertSuccess( | ||
| title = getString(R.string.account_has_been_added), | ||
| description = null, | ||
| tag = this::class.simpleName.orEmpty() |
There was a problem hiding this comment.
function's default tag parameter is already set, no need to set the same parameter
| } | ||
| } | ||
|
|
||
| override suspend fun hasSigningCapableLocalAccount(address: String): Boolean { |
| } | ||
| val contact = contactRepository.getContactByAddress(address) | ||
| val localAccount = getLocalAccount(address) | ||
| val isLedger = localAccount is LocalAccount.LedgerBle |
| participantData.localParticipants.isEmpty() || | ||
| !hasUnsigned | ||
|
|
||
| return JointAccountTransactionPreview( |
There was a problem hiding this comment.
ViewState instead of preview
| } | ||
|
|
||
| companion object { | ||
| private const val MIN_PARTICIPANTS_COUNT = 2 |
There was a problem hiding this comment.
We can use existing JointAccount constant for this
Summary
AddAccountIntroFragmentwith create joint account optionNameJointAccountFragmentfor account namingAddJointAccountFragmentfor participant selectionSetThresholdFragmentfor threshold configurationCreateJointAccountFragmentfor final creationCreateJointAccountUseCasewith validationJointAccountInfoDialogfor feature explanationJointAccountSignRequestFragmentfor sign request handlingPendingSignaturesBottomSheetfor signature statusJointAccountLedgerSignHelperfor Ledger device signingTest Plan