Updated on 2026-08-14

This commit is contained in:
Tangem 2020-12-02 16:38:44 +03:00
parent ec392c2cc8
commit db314577a0
10 changed files with 477 additions and 16 deletions

View file

@ -1,9 +1,13 @@
package com.tangem.tap.features.details.redux
import com.tangem.Message
import com.tangem.blockchain.common.Wallet
import com.tangem.commands.Card
import com.tangem.commands.common.card.Card
import com.tangem.tap.common.redux.NotificationAction
import com.tangem.tap.common.redux.global.FiatCurrencyName
import com.tangem.tap.domain.TwinCardNumber
import com.tangem.tap.domain.tasks.ScanNoteResponse
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
import com.tangem.tap.network.coinmarketcap.FiatCurrency
import com.tangem.wallet.R
import org.rekotlin.Action
@ -12,10 +16,11 @@ sealed class DetailsAction : Action {
data class PrepareScreen(
val card: Card,
val scanNoteResponse: ScanNoteResponse,
val wallet: Wallet?,
val fiatCurrencyName: FiatCurrencyName,
val fiatCurrencies: List<FiatCurrencyName>? = null,
): DetailsAction()
) : DetailsAction()
object ShowDisclaimer : DetailsAction()
@ -23,24 +28,54 @@ sealed class DetailsAction : Action {
sealed class EraseWallet : DetailsAction() {
object Check : EraseWallet()
object Proceed : EraseWallet() {
object NotAllowedByCard: EraseWallet(), NotificationAction {
object NotAllowedByCard : EraseWallet(), NotificationAction {
override val messageResource = R.string.error_purge_prohibited
}
object NotEmpty: EraseWallet(), NotificationAction {
object NotEmpty : EraseWallet(), NotificationAction {
override val messageResource = R.string.details_notification_erase_wallet_not_possible
}
}
object Confirm : EraseWallet()
object Cancel : EraseWallet()
object Failure : EraseWallet()
object Success : EraseWallet()
}
sealed class CreateTwinWalletAction : DetailsAction() {
object ShowWarning : CreateTwinWalletAction()
object ShowAlert : CreateTwinWalletAction()
object HideAlert : CreateTwinWalletAction()
data class Proceed(
val twinCardNumber: TwinCardNumber?, val createTwinWallet: CreateTwinWallet
) : CreateTwinWalletAction()
object Cancel : CreateTwinWalletAction() {
object Confirm : CreateTwinWalletAction()
}
data class LaunchFirstStep(val message: Message) : CreateTwinWalletAction() {
object Success : CreateTwinWalletAction()
object Failure : CreateTwinWalletAction()
}
data class LaunchSecondStep(val message: Message) : CreateTwinWalletAction() {
object Success : CreateTwinWalletAction()
object Failure : CreateTwinWalletAction()
}
data class LaunchThirdStep(val message: Message) : CreateTwinWalletAction() {
data class Success(val scanNoteResponse: ScanNoteResponse) : CreateTwinWalletAction()
object Failure : CreateTwinWalletAction()
}
}
sealed class AppCurrencyAction : DetailsAction() {
data class SetCurrencies(val currencies: List<FiatCurrency>) : AppCurrencyAction()
object ChooseAppCurrency : AppCurrencyAction()
object Cancel: AppCurrencyAction()
data class SelectAppCurrency(val fiatCurrencyName: FiatCurrencyName): AppCurrencyAction()
object Cancel : AppCurrencyAction()
data class SelectAppCurrency(val fiatCurrencyName: FiatCurrencyName) : AppCurrencyAction()
}
sealed class ManageSecurity : DetailsAction() {
@ -50,8 +85,9 @@ sealed class DetailsAction : Action {
object Success : ManageSecurity()
object Failure : ManageSecurity()
}
data class ConfirmSelection(val option: SecurityOption) : ManageSecurity() {
object AlreadySet: ManageSecurity(), NotificationAction {
object AlreadySet : ManageSecurity(), NotificationAction {
override val messageResource = R.string.details_notification_security_option_already_active
}
}

View file

@ -6,6 +6,7 @@ import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletMiddleware
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.network.coinmarketcap.CoinMarketCapService
@ -22,6 +23,7 @@ class DetailsMiddleware {
private val eraseWalletMiddleware = EraseWalletMiddleware()
private val appCurrencyMiddleware = AppCurrencyMiddleware()
private val manageSecurityMiddleware = ManageSecurityMiddleware()
private val twinWalletMiddleware = CreateTwinWalletMiddleware()
val detailsMiddleware: Middleware<AppState> = { dispatch, state ->
{ next ->
{ action ->
@ -30,7 +32,8 @@ class DetailsMiddleware {
is DetailsAction.EraseWallet -> eraseWalletMiddleware.handle(action)
is DetailsAction.AppCurrencyAction -> appCurrencyMiddleware.handle(action)
is DetailsAction.ManageSecurity -> manageSecurityMiddleware.handle(action)
is DetailsAction.ShowDisclaimer -> {
is DetailsAction.CreateTwinWalletAction -> twinWalletMiddleware.handle(action)
is DetailsAction.ShowDisclaimer -> {
store.dispatch(DisclaimerAction.ShowAcceptedDisclaimer)
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
}

View file

@ -1,10 +1,16 @@
package com.tangem.tap.features.details.redux
import com.tangem.commands.Card
import com.tangem.commands.Settings
import com.tangem.commands.common.card.Card
import com.tangem.commands.common.card.masks.Product
import com.tangem.commands.common.card.masks.Settings
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.TapWorkarounds
import com.tangem.tap.domain.TwinsHelper
import com.tangem.tap.domain.extensions.toSendableAmounts
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletReducer
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletState
import com.tangem.wallet.BuildConfig
import org.rekotlin.Action
import java.util.*
@ -31,6 +37,9 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
is DetailsAction.ManageSecurity -> {
handleSecurityAction(action, detailsState)
}
is DetailsAction.CreateTwinWalletAction -> {
CreateTwinWalletReducer.handle(action, detailsState)
}
else -> detailsState
}
}
@ -47,13 +56,25 @@ private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: Deta
SecurityOption.LongTap
}
}
val twinsState = if (action.card.cardData?.productMask?.contains(Product.TwinCard) == true) {
CreateTwinWalletState(
scanResponse = action.scanNoteResponse,
twinCardNumber = TwinsHelper.getTwinCardNumber(action.card.cardId),
createTwinWallet = null,
showAlert = false,
allowRecreatingWallet = BuildConfig.DEBUG
)
} else {
null
}
return DetailsState(
card = action.card, wallet = action.wallet,
cardInfo = action.card.toCardInfo(),
appCurrencyState = AppCurrencyState(
action.fiatCurrencyName
),
securityScreenState = SecurityScreenState(currentOption = securityOption)
securityScreenState = SecurityScreenState(currentOption = securityOption),
createTwinWalletState = twinsState
)
}
@ -169,6 +190,7 @@ private fun handleSecurityAction(
}
}
private fun Card.toCardInfo(): CardInfo? {
val cardId = this.cardId.chunked(4).joinToString(separator = " ")
val issuer = this.cardData?.issuerName ?: return null

View file

@ -1,10 +1,11 @@
package com.tangem.tap.features.details.redux
import com.tangem.blockchain.common.Wallet
import com.tangem.commands.Card
import com.tangem.commands.common.card.Card
import com.tangem.tap.common.entities.Button
import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY
import com.tangem.tap.common.redux.global.FiatCurrencyName
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletState
import com.tangem.tap.network.coinmarketcap.FiatCurrency
import org.rekotlin.StateType
import java.util.*
@ -17,6 +18,7 @@ data class DetailsState(
val eraseWalletState: EraseWalletState? = null,
val confirmScreenState: ConfirmScreenState? = null,
val securityScreenState: SecurityScreenState? = null,
val createTwinWalletState: CreateTwinWalletState? = null
) : StateType
data class CardInfo(
@ -39,4 +41,4 @@ data class AppCurrencyState(
val fiatCurrencyName: FiatCurrencyName = DEFAULT_FIAT_CURRENCY,
val showAppCurrencyDialog: Boolean = false,
val fiatCurrencies: List<FiatCurrency>? = null,
)
)

View file

@ -0,0 +1,104 @@
package com.tangem.tap.features.details.redux.twins
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.twins.TwinCardsManager
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class CreateTwinWalletMiddleware {
var twinsManager: TwinCardsManager? = null
fun handle(action: DetailsAction.CreateTwinWalletAction) {
when (action) {
DetailsAction.CreateTwinWalletAction.ShowWarning ->
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
is DetailsAction.CreateTwinWalletAction.Proceed ->
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWallet))
is DetailsAction.CreateTwinWalletAction.Cancel -> {
val step = store.state.detailsState.createTwinWalletState?.step
if (step != null && step != CreateTwinWalletStep.FirstStep
) {
store.dispatch(DetailsAction.CreateTwinWalletAction.ShowAlert)
} else {
twinsManager = null
store.dispatch(NavigationAction.PopBackTo())
}
}
is DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> {
twinsManager = null
store.dispatch(NavigationAction.PopBackTo())
}
is DetailsAction.CreateTwinWalletAction.LaunchFirstStep -> {
store.state.globalState.scanNoteResponse?.let {
twinsManager = TwinCardsManager(it)
}
scope.launch {
val result = twinsManager?.createFirstWallet(action.message)
withContext(Dispatchers.Main) {
when (result) {
SimpleResult.Success ->
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success)
is SimpleResult.Failure ->
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure)
}
}
}
}
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success -> {
}
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure -> {
}
is DetailsAction.CreateTwinWalletAction.LaunchSecondStep ->
scope.launch {
val result = twinsManager?.createSecondWallet(action.message)
withContext(Dispatchers.Main) {
when (result) {
SimpleResult.Success ->
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success)
is SimpleResult.Failure ->
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure)
}
}
}
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success -> {
}
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure -> {
}
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep -> {
scope.launch {
val result = twinsManager?.complete(action.message)
withContext(Dispatchers.Main) {
when (result) {
is Result.Success ->
store.dispatch(
DetailsAction.CreateTwinWalletAction
.LaunchThirdStep.Success(result.data)
)
is Result.Failure ->
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure)
}
}
}
}
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Success -> {
store.dispatch(GlobalAction.SaveScanNoteResponse(action.scanNoteResponse))
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
}
DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure -> {
}
}
}
}

View file

@ -0,0 +1,67 @@
package com.tangem.tap.features.details.redux.twins
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
class CreateTwinWalletReducer {
companion object {
fun handle(
action: DetailsAction.CreateTwinWalletAction, state: DetailsState
): DetailsState {
return when (action) {
DetailsAction.CreateTwinWalletAction.ShowWarning -> {
state
}
DetailsAction.CreateTwinWalletAction.ShowAlert -> {
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
showAlert = true
))
}
DetailsAction.CreateTwinWalletAction.HideAlert -> {
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
showAlert = false
))
}
is DetailsAction.CreateTwinWalletAction.Proceed -> {
state.copy(createTwinWalletState = CreateTwinWalletState(
scanResponse = null,
twinCardNumber = action.twinCardNumber
?: state.createTwinWalletState?.twinCardNumber,
createTwinWallet = action.createTwinWallet,
showAlert = false,
step = CreateTwinWalletStep.FirstStep,
))
}
DetailsAction.CreateTwinWalletAction.Cancel -> state
DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> state
is DetailsAction.CreateTwinWalletAction.LaunchFirstStep -> state
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success -> {
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
step = CreateTwinWalletStep.SecondStep
))
}
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure -> state
is DetailsAction.CreateTwinWalletAction.LaunchSecondStep -> state
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success ->
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
step = CreateTwinWalletStep.ThirdStep
))
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure -> {
state
}
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep -> {
state
}
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Success -> {
state
}
DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure -> {
state
}
}
}
}
}

View file

@ -0,0 +1,17 @@
package com.tangem.tap.features.details.redux.twins
import com.tangem.tap.domain.TwinCardNumber
import com.tangem.tap.domain.tasks.ScanNoteResponse
data class CreateTwinWalletState(
val scanResponse: ScanNoteResponse?,
val step: CreateTwinWalletStep = CreateTwinWalletStep.FirstStep,
val twinCardNumber: TwinCardNumber?,
val createTwinWallet: CreateTwinWallet?,
val showAlert: Boolean,
val allowRecreatingWallet: Boolean? = null
)
enum class CreateTwinWalletStep { FirstStep, SecondStep, ThirdStep }
enum class CreateTwinWallet { CreateWallet, RecreateWallet }

View file

@ -5,6 +5,8 @@ import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
@ -66,11 +68,26 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
tv_disclaimer.setOnClickListener { store.dispatch(DetailsAction.ShowDisclaimer) }
tv_erase_wallet.setOnClickListener {
store.dispatch(DetailsAction.EraseWallet.Check)
store.dispatch(DetailsAction.EraseWallet.Proceed)
if (state.createTwinWalletState != null) {
if (state.createTwinWalletState.allowRecreatingWallet == true) {
tv_erase_wallet.show()
tv_erase_wallet.text = getText(R.string.details_row_title_twins_recreate)
tv_erase_wallet.setOnClickListener {
store.dispatch(DetailsAction.CreateTwinWalletAction.ShowWarning)
}
} else {
tv_erase_wallet.hide()
}
} else {
tv_erase_wallet.show()
tv_erase_wallet.text = getText(R.string.details_row_title_erase_wallet)
tv_erase_wallet.setOnClickListener {
store.dispatch(DetailsAction.EraseWallet.Check)
store.dispatch(DetailsAction.EraseWallet.Proceed)
}
}
tv_app_currency.text = state.appCurrencyState.fiatCurrencyName
tv_app_currency_title.setOnClickListener {

View file

@ -0,0 +1,152 @@
package com.tangem.tap.features.details.ui.twins
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.core.content.ContextCompat.getColor
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.Message
import com.tangem.tap.domain.TwinCardNumber
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletStep
import com.tangem.tap.store
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.fragment_details_twin_cards.*
import org.rekotlin.StoreSubscriber
class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
StoreSubscriber<DetailsState> {
private var dialog: Dialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel)
}
})
val inflater = TransitionInflater.from(requireContext())
enterTransition = inflater.inflateTransition(R.transition.slide_right)
exitTransition = inflater.inflateTransition(R.transition.fade)
}
override fun onStart() {
super.onStart()
store.subscribe(this) { state ->
state.skipRepeats { oldState, newState ->
oldState.detailsState == newState.detailsState
}.select { it.detailsState }
}
}
override fun onStop() {
super.onStop()
store.unsubscribe(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar.setNavigationOnClickListener {
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel)
}
}
override fun newState(state: DetailsState) {
if (activity == null) return
toolbar.title = when (state.createTwinWalletState?.createTwinWallet) {
CreateTwinWallet.CreateWallet -> getText(R.string.wallet_button_create_wallet)
CreateTwinWallet.RecreateWallet, null -> getText(R.string.details_twins_recreate_toolbar)
}
val selectedColor = getColor(requireContext(), R.color.colorSecondary)
val defaultColor = getColor(requireContext(), R.color.blue_pale)
val twinCardNumber = state.createTwinWalletState?.twinCardNumber ?: TwinCardNumber.First
val cardNumber = when (state.createTwinWalletState?.step) {
CreateTwinWalletStep.FirstStep -> {
val twinCardNumberString = twinCardNumber.number.toString()
tv_step_number.text =
getString(R.string.details_twins_recreate_step_format, "1")
v_step_1.setBackgroundColor(selectedColor)
v_step_2.setBackgroundColor(defaultColor)
v_step_3.setBackgroundColor(defaultColor)
btn_tap.setOnClickListener {
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep(
Message(getString(
R.string.details_twins_recreate_title_format, twinCardNumber)
)))
}
btn_tap.text = getString(R.string.details_twins_recreate_button_format,
twinCardNumber.number.toString())
twinCardNumberString
}
CreateTwinWalletStep.SecondStep -> {
val twinCardNumberString = twinCardNumber.pairNumber().number.toString()
tv_step_number.text =
getString(R.string.details_twins_recreate_step_format, "2")
v_step_1.setBackgroundColor(defaultColor)
v_step_2.setBackgroundColor(selectedColor)
v_step_3.setBackgroundColor(defaultColor)
btn_tap.setOnClickListener {
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep(
Message(getString(
R.string.details_twins_recreate_title_format, twinCardNumberString)
)
))
}
btn_tap.text = getString(R.string.details_twins_recreate_button_format, "2")
twinCardNumberString
}
CreateTwinWalletStep.ThirdStep -> {
val twinCardNumberString = twinCardNumber.number.toString()
tv_step_number.text =
getString(R.string.details_twins_recreate_step_format, "3")
v_step_1.setBackgroundColor(defaultColor)
v_step_2.setBackgroundColor(defaultColor)
v_step_3.setBackgroundColor(selectedColor)
btn_tap.setOnClickListener {
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchThirdStep(
Message(getString(
R.string.details_twins_recreate_title_format, twinCardNumberString)
)
))
}
btn_tap.text = getString(R.string.details_twins_recreate_button_format, twinCardNumberString)
twinCardNumberString
}
else -> null
}
btn_tap.text = getString(R.string.details_twins_recreate_button_format, cardNumber)
tv_twin_title.text = getString(R.string.details_twins_recreate_title_format, cardNumber)
if (state.createTwinWalletState?.showAlert == true) {
dialog = MaterialAlertDialogBuilder(requireContext())
.setMessage(R.string.details_twins_recreate_alert)
.setPositiveButton(R.string.common_ok) { _, _ ->
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel.Confirm)
}
.setNegativeButton(R.string.common_cancel) { _, _ ->
store.dispatch(DetailsAction.CreateTwinWalletAction.HideAlert)
}
.create()
dialog?.show()
} else {
dialog?.cancel()
dialog = null
}
}
}

View file

@ -0,0 +1,41 @@
package com.tangem.tap.features.details.ui.twins
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
import com.tangem.tap.store
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.fragment_details_twin_cards_warning.*
class TwinWalletWarningFragment : Fragment(R.layout.fragment_details_twin_cards_warning) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
store.dispatch(NavigationAction.PopBackTo())
}
})
val inflater = TransitionInflater.from(requireContext())
enterTransition = inflater.inflateTransition(R.transition.slide_right)
exitTransition = inflater.inflateTransition(R.transition.fade)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_cancel.setOnClickListener { store.dispatch(NavigationAction.PopBackTo()) }
btn_start.setOnClickListener {
store.dispatch(
DetailsAction.CreateTwinWalletAction.Proceed(
null, createTwinWallet = CreateTwinWallet.RecreateWallet
))
}
}
}