From 633186da8f16d01bf63b7fe7559eccfb69805732 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Mar 2021 10:10:50 +0300 Subject: [PATCH 01/37] Updated on 2026-08-14 --- .../tangem/tap/common/extensions/Blockchain.kt | 10 +++++----- app/src/main/res/drawable/ic_ducatus.png | Bin 0 -> 27573 bytes 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/ic_ducatus.png diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index e03e96133b..dc12172a82 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -7,15 +7,15 @@ import com.tangem.wallet.R @DrawableRes fun Blockchain.getIconRes(): Int { return when (this) { - Blockchain.Unknown, Blockchain.Ducatus, Blockchain.BitcoinTestnet, Blockchain.EthereumTestnet, - Blockchain.BinanceTestnet -> 1 - Blockchain.Bitcoin -> R.drawable.ic_btc + Blockchain.Unknown -> R.drawable.shape_circle + Blockchain.Ducatus -> R.drawable.ic_ducatus + Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_btc Blockchain.BitcoinCash -> R.drawable.ic_btc_cash Blockchain.Litecoin -> R.drawable.ic_ltc - Blockchain.Ethereum -> R.drawable.ic_eth + Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth Blockchain.RSK -> R.drawable.ic_rsk Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano - Blockchain.Binance -> R.drawable.ic_binance + Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_binance Blockchain.Tezos -> R.drawable.ic_tezos Blockchain.XRP -> R.drawable.ic_xrp Blockchain.Stellar -> R.drawable.ic_stellar diff --git a/app/src/main/res/drawable/ic_ducatus.png b/app/src/main/res/drawable/ic_ducatus.png new file mode 100644 index 0000000000000000000000000000000000000000..cfae76f29ff832b062f3310b4fef7bcc76261dcb GIT binary patch literal 27573 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 c!L~2?f5>j=@%UCgmjD0&07*qoM6N<$f Date: Tue, 30 Mar 2021 10:24:22 +0300 Subject: [PATCH 02/37] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TapWalletManager.kt | 2 +- .../redux/middlewares/WalletMiddleware.kt | 24 +++++++------------ .../wallet/ui/wallet/SingleWalletView.kt | 5 ++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 0d6662d4f0..38fe7aec61 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -168,7 +168,7 @@ class TapWalletManager { .mapNotNull { walletManagerFactory.makeWalletManager(data.card, it) } val otherBlockhains = savedCurrencies.blockchains - val activeTokens = walletManagers.first { it.wallet.blockchain == Blockchain.Ethereum} + val activeTokens = walletManagers.first { it.wallet.blockchain == Blockchain.Ethereum } .presetTokens.toList() val tokens = activeTokens + savedCurrencies.tokens diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 54a51ff45e..8570250b54 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -126,22 +126,16 @@ class WalletMiddleware { is WalletAction.Scan -> { scope.launch { val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler) - when (result) { - is CompletionResult.Success -> { - tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) - globalState?.tapWalletManager - ?.onCardScanned(result.data, true) - if (walletState?.twinCardsState != null) { - val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown() - if (showOnboarding) { - store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding)) - } + scope.launch(Dispatchers.Main) { + when (result) { + is CompletionResult.Success -> { + tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) + globalState?.tapWalletManager + ?.onCardScanned(result.data, true) + store.dispatch(WalletAction.ScanCardFinished()) } - store.dispatch(WalletAction.ScanCardFinished()) - } - is CompletionResult.Failure -> { - if (result.error !is TangemSdkError.UserCancelled) { - scope.launch(Dispatchers.Main) { + is CompletionResult.Failure -> { + if (result.error !is TangemSdkError.UserCancelled) { store.dispatch(WalletAction.ScanCardFinished(result.error)) if (store.state.walletState.scanCardFailsCounter >= 2) { store.dispatch(WalletAction.ShowDialog.ScanFails) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index cc14fa932e..c513331351 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -6,6 +6,8 @@ import android.view.ViewGroup import android.widget.Button import androidx.recyclerview.widget.LinearLayoutManager import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.redux.navigation.AppScreen +import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.redux.* @@ -105,6 +107,9 @@ class SingleWalletView : WalletView { this.tv_twin_card_number.hide() this.iv_twin_card.hide() } + if (twinCardsState?.showTwinOnboarding == true) { + store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding)) + } } } From 8ac90772f902bf1fca89c5d2ba9436a916fd7b14 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Mar 2021 15:31:47 +0300 Subject: [PATCH 03/37] Updated on 2026-08-14 --- .../features/send/redux/SendScreenAction.kt | 2 ++ .../send/redux/middlewares/SendMiddleware.kt | 4 ++-- .../send/redux/reducers/SendScreenReducer.kt | 5 +++-- .../redux/middlewares/WalletMiddleware.kt | 18 ++++++++++-------- .../main/res/layout/item_currency_wallet.xml | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 8a87b6108f..36e7ae943b 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -3,6 +3,7 @@ package com.tangem.tap.features.send.redux import com.tangem.Message import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.WalletManager import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.ToastNotificationAction import com.tangem.tap.domain.TapError @@ -25,6 +26,7 @@ object ReleaseSendState : Action data class PrepareSendScreen( val coinAmount: Amount?, val coinRate: BigDecimal?, + val walletManager: WalletManager?, val tokenAmount: Amount? = null, val tokenRate: BigDecimal? = null ) : SendScreenAction diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index 115c1c2033..b24e7916db 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -56,8 +56,8 @@ private fun verifyAndSendTransaction( action: SendActionUi.SendAmountToRecipient, appState: AppState?, dispatch: (Action) -> Unit, ) { val sendState = appState?.sendState ?: return - val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return - val card = appState.globalState.scanNoteResponse.card + val walletManager = sendState.walletManager ?: return + val card = appState.globalState.scanNoteResponse?.card ?: return val destinationAddress = sendState.addressPayIdState.destinationWalletAddress ?: return val typedAmount = sendState.amountState.amountToExtract ?: return val feeAmount = sendState.feeState.currentFee ?: return diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt index 527d3f6545..e6ab87ef01 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt @@ -60,14 +60,15 @@ private class EmptyReducer : SendInternalReducer { private class PrepareSendScreenStatesReducer : SendInternalReducer { override fun handle(action: SendScreenAction, sendState: SendState): SendState { val prepareAction = action as PrepareSendScreen - val walletManager = store.state.globalState.scanNoteResponse!!.walletManager!! + val walletManager = action.walletManager + ?: store.state.globalState.scanNoteResponse!!.walletManager!! val amountToExtract = prepareAction.tokenAmount ?: prepareAction.coinAmount!! val decimals = amountToExtract.decimals return sendState.copy( walletManager = walletManager, coinConverter = action.coinRate?.let { CurrencyConverter(it, decimals) }, - tokenConverter = action.tokenRate?. let { CurrencyConverter(it, decimals) }, + tokenConverter = action.tokenRate?.let { CurrencyConverter(it, decimals) }, amountState = sendState.amountState.copy( amountToExtract = amountToExtract, typeOfAmount = amountToExtract.type, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 8570250b54..af6ceb3d2d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -193,13 +193,14 @@ class WalletMiddleware { private fun prepareSendAction(amount: Amount?, state: WalletState?): Action { val selectedWalletData = state?.getSelectedWalletData() val currency = selectedWalletData?.currencyData?.currencySymbol - val wallet = currency?.let { state.getWalletManager(currency)?.wallet } + val walletManager = state?.getWalletManager(currency) + val wallet = walletManager?.wallet return if (amount != null) { if (amount.type is AmountType.Token) { - prepareSendActionForToken(amount, state, selectedWalletData, wallet) + prepareSendActionForToken(amount, state, selectedWalletData, wallet, walletManager) } else { - PrepareSendScreen(amount, selectedWalletData?.fiatRate) + PrepareSendScreen(amount, selectedWalletData?.fiatRate, walletManager) } } else { val amounts = wallet?.amounts?.toSendableAmounts() @@ -207,23 +208,24 @@ class WalletMiddleware { val amountToSend = amounts?.find { it.currencySymbol == currency } ?: return WalletAction.Send.ChooseCurrency(amounts) if (amountToSend.type is AmountType.Token) { - prepareSendActionForToken(amount, state, selectedWalletData, wallet) + prepareSendActionForToken(amount, state, selectedWalletData, wallet, walletManager) } else { - PrepareSendScreen(amountToSend, selectedWalletData.fiatRate) + PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager) } } else { if (amounts?.size ?: 0 > 1) { WalletAction.Send.ChooseCurrency(amounts) } else { val amountToSend = amounts?.first() - PrepareSendScreen(amountToSend, selectedWalletData?.fiatRate) + PrepareSendScreen(amountToSend, selectedWalletData?.fiatRate, walletManager) } } } } private fun prepareSendActionForToken( - amount: Amount?, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet? + amount: Amount?, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?, + walletManager: WalletManager? ): PrepareSendScreen { val coinRate = state?.getWalletData(wallet?.blockchain?.currency)?.fiatRate val tokenRate = if (state?.isMultiwalletAllowed == true) { @@ -232,7 +234,7 @@ class WalletMiddleware { selectedWalletData?.currencyData?.token?.fiatRate } return PrepareSendScreen( - wallet?.amounts?.get(AmountType.Coin), coinRate, + wallet?.amounts?.get(AmountType.Coin), coinRate, walletManager, amount, tokenRate) } } diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index 09b7dd4cc9..be3b049566 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -124,7 +124,7 @@ android:textColor="@color/darkGray2" android:textSize="14sp" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="@id/tv_exchange_rate" + app:layout_constraintBottom_toBottomOf="@id/iv_currency" tools:text="0.43 USD" /> From 2e70d660f6507d6effddbc1e7fc7e04ff3a6637d Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Mar 2021 15:47:57 +0300 Subject: [PATCH 04/37] Updated on 2026-08-14 --- app/src/main/assets/erc20_tokens.json | 914 ++++++++++++++++++ app/src/main/assets/tangem-android-config | 1 + .../tangem/tap/domain/configurable/Loader.kt | 2 +- 3 files changed, 916 insertions(+), 1 deletion(-) create mode 100644 app/src/main/assets/erc20_tokens.json create mode 160000 app/src/main/assets/tangem-android-config diff --git a/app/src/main/assets/erc20_tokens.json b/app/src/main/assets/erc20_tokens.json new file mode 100644 index 0000000000..9b29c198bb --- /dev/null +++ b/app/src/main/assets/erc20_tokens.json @@ -0,0 +1,914 @@ +[ + { + "decimalCount" : 18, + "symbol" : "ZRX", + "name" : "0x", + "contractAddress" : "0xE41d2489571d322189246DaFA5ebDe1F4699F498" + }, + { + "decimalCount" : 18, + "symbol" : "AAVE", + "name" : "Aave", + "contractAddress" : "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9" + }, + { + "decimalCount" : 18, + "symbol" : "LEND", + "name" : "Aave (OLD)", + "contractAddress" : "0x80fB784B7eD66730e8b1DBd9820aFD29931aab03" + }, + { + "decimalCount" : 18, + "symbol" : "ADX", + "name" : "AdEx", + "contractAddress" : "0xADE00C28244d5CE17D72E40330B1c318cD12B7c3" + }, + { + "decimalCount" : 9, + "symbol" : "ADT", + "name" : "adToken", + "contractAddress" : "0xD0D6D6C5Fe4a677D343cC433536BB717bAe167dD" + }, + { + "decimalCount" : 18, + "symbol" : "ELF", + "name" : "Aelf", + "contractAddress" : "0xbf2179859fc6d5bee9bf9158632dc51678a4100e" + }, + { + "decimalCount" : 8, + "symbol" : "ARN", + "name" : "Aeron", + "contractAddress" : "0xBA5F11b16B155792Cf3B2E6880E8706859A8AEB6" + }, + { + "decimalCount" : 18, + "symbol" : "AE", + "name" : "Aeternity", + "contractAddress" : "0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d" + }, + { + "decimalCount" : 8, + "symbol" : "AION", + "name" : "Aion", + "contractAddress" : "0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466" + }, + { + "decimalCount" : 4, + "symbol" : "AST", + "name" : "Airswap", + "contractAddress" : "0x27054b13b1b798b345b591a4d22e6562d47ea75a" + }, + { + "decimalCount" : 18, + "symbol" : "AMB", + "name" : "Amber", + "contractAddress" : "0x4dc3643dbc642b72c158e7f3d2ff232df61cb6ce" + }, + { + "decimalCount" : 18, + "symbol" : "AMLT", + "name" : "AMLT by Coinfirm", + "contractAddress" : "0xca0e7269600d353f70b14ad118a49575455c0f2f" + }, + { + "decimalCount" : 18, + "symbol" : "APPC", + "name" : "AppCoins", + "contractAddress" : "0x1a7a8bd9106f2b8d977e08582dc7d24c723ab0db" + }, + { + "decimalCount" : 18, + "symbol" : "ANT", + "name" : "Aragon", + "contractAddress" : "0xa117000000f279d81a1d3cc75430faa017fa5a2e" + }, + { + "decimalCount" : 18, + "symbol" : "ABT", + "name" : "ArcBlock", + "contractAddress" : "0xb98d4c97425d9908e66e53a6fdf673acca0be986" + }, + { + "decimalCount" : 18, + "symbol" : "ATMI", + "name" : "Atonomi", + "contractAddress" : "0x97aeb5066e1a590e868b511457beb6fe99d329f5" + }, + { + "decimalCount" : 18, + "symbol" : "REP", + "name" : "Augur", + "contractAddress" : "0x1985365e9f78359a9B6AD760e32412f4a445E862" + }, + { + "decimalCount" : 18, + "symbol" : "AVM", + "name" : "AVM Ecosystem", + "contractAddress" : "0x74004a7227615fb52b82d17ffabfa376907d8a4d" + }, + { + "decimalCount" : 18, + "symbol" : "BNT", + "name" : "Bancor", + "contractAddress" : "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C" + }, + { + "decimalCount" : 18, + "symbol" : "BAT", + "name" : "Basic Attention", + "contractAddress" : "0x0D8775F648430679A709E98d2b0Cb6250d2887EF" + }, + { + "decimalCount" : 18, + "symbol" : "BNB", + "name" : "Binance Coin", + "contractAddress" : "0xb8c77482e45f1f44de1745f52c74426c631bdd52" + }, + { + "decimalCount" : 18, + "symbol" : "BUSD", + "name" : "Binance USD", + "contractAddress" : "0x4fabb145d64652a948d72533023f6e7a623c7c53" + }, + { + "decimalCount" : 18, + "symbol" : "STU", + "name" : "bitJob", + "contractAddress" : "0x0371a82e4a9d0a4312f3ee2ac9c6958512891372" + }, + { + "decimalCount" : 18, + "symbol" : "BIX", + "name" : "BIX Token", + "contractAddress" : "0xb3104b4b9da82025e8b9f8fb28b3553ce2f67069" + }, + { + "decimalCount" : 18, + "symbol" : "VEE", + "name" : "BLOCKv", + "contractAddress" : "0x340d2bde5eb28c1eed91b2f790723e3b160613b7" + }, + { + "decimalCount" : 18, + "symbol" : "BLZ", + "name" : "Bluzelle", + "contractAddress" : "0x5732046a883704404f284ce41ffadd5b007fd668" + }, + { + "decimalCount" : 18, + "symbol" : "BRD", + "name" : "BRD Token", + "contractAddress" : "0x558ec3152e2eb2174905cd19aea4e34a23de9ad6" + }, + { + "decimalCount" : 8, + "symbol" : "BTM", + "name" : "Bytom", + "contractAddress" : "0xcb97e65f07da24d46bcdd078ebebd7c6e6e3d750" + }, + { + "decimalCount" : 18, + "symbol" : "CAS", + "name" : "Cashaa", + "contractAddress" : "0xe8780b48bdb05f928697a5e8155f672ed91462f7" + }, + { + "decimalCount" : 18, + "symbol" : "CSP", + "name" : "Caspian", + "contractAddress" : "0xa6446d655a0c34bc4f05042ee88170d056cbaf45" + }, + { + "decimalCount" : 18, + "symbol" : "LINK", + "name" : "ChainLink", + "contractAddress" : "0x514910771af9ca656af840dff83e8264ecf986ca" + }, + { + "decimalCount" : 8, + "symbol" : "TIME", + "name" : "Chronobank", + "contractAddress" : "0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53" + }, + { + "decimalCount" : 18, + "symbol" : "CND", + "name" : "Cindicator", + "contractAddress" : "0xd4c435f5b09f855c3317c8524cb1f586e42795fa" + }, + { + "decimalCount" : 8, + "symbol" : "CVC", + "name" : "Civic", + "contractAddress" : "0x41e5560054824ea6b0732e656e3ad64e20e94e45" + }, + { + "decimalCount" : 18, + "symbol" : "CNN", + "name" : "CNN Token", + "contractAddress" : "0x8713d26637cf49e1b6b4a7ce57106aabc9325343" + }, + { + "decimalCount" : 18, + "symbol" : "CFI", + "name" : "Cofound.it", + "contractAddress" : "0x12FEF5e57bF45873Cd9B62E9DBd7BFb99e32D73e" + }, + { + "decimalCount" : 18, + "symbol" : "CCC", + "name" : "Container Crypto Coin", + "contractAddress" : "0x9e3359f862b6c7f5c660cfd6d1aa6909b1d9504d" + }, + { + "decimalCount" : 6, + "symbol" : "CS", + "name" : "Credits", + "contractAddress" : "0x46b9ad944d1059450da1163511069c718f699d31" + }, + { + "decimalCount" : 18, + "symbol" : "CRPT", + "name" : "Crypterium", + "contractAddress" : "0x08389495d7456e1951ddf7c3a1314a4bfb646d8b" + }, + { + "decimalCount" : 18, + "symbol" : "AUTO", + "name" : "CUBE", + "contractAddress" : "0x622dFfCc4e83C64ba959530A5a5580687a57581b" + }, + { + "decimalCount" : 18, + "symbol" : "CMT", + "name" : "CyberMiles", + "contractAddress" : "0xf85fEea2FdD81d51177F6b8F35F0e6734Ce45F5F" + }, + { + "decimalCount" : 18, + "symbol" : "DAI", + "name" : "Dai", + "contractAddress" : "0x6b175474e89094c44da98b954eedeac495271d0f" + }, + { + "decimalCount" : 18, + "symbol" : "MANA", + "name" : "Decentraland", + "contractAddress" : "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942" + }, + { + "decimalCount" : 8, + "symbol" : "DENT", + "name" : "DENT", + "contractAddress" : "0x3597bfd533a99c9aa083587b074434e61eb0a258" + }, + { + "decimalCount" : 0, + "symbol" : "XJP", + "name" : "Digital JPY", + "contractAddress" : "0x39689fE671C01fcE173395f6BC45D4C332026666" + }, + { + "decimalCount" : 9, + "symbol" : "DGD", + "name" : "DigixDAO", + "contractAddress" : "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A" + }, + { + "decimalCount" : 18, + "symbol" : "DNT", + "name" : "district0x", + "contractAddress" : "0x0abdace70d3790235af448c88547603b945604ea" + }, + { + "decimalCount" : 18, + "symbol" : "DOV", + "name" : "Dovu", + "contractAddress" : "0xac3211a5025414af2866ff09c23fc18bc97e79b1" + }, + { + "decimalCount" : 18, + "symbol" : "DRGN", + "name" : "Dragon", + "contractAddress" : "0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e" + }, + { + "decimalCount" : 0, + "symbol" : "EDG", + "name" : "Edgeless", + "contractAddress" : "0x08711D3B02C8758F2FB3ab4e80228418a7F8e39c" + }, + { + "decimalCount" : 18, + "symbol" : "EDO", + "name" : "Eidoo", + "contractAddress" : "0xced4e93198734ddaff8492d525bd258d49eb388e" + }, + { + "decimalCount" : 8, + "symbol" : "ENG", + "name" : "Enigma", + "contractAddress" : "0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4" + }, + { + "decimalCount" : 18, + "symbol" : "ENJ", + "name" : "EnjinCoin", + "contractAddress" : "0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c" + }, + { + "decimalCount" : 18, + "symbol" : "EOS", + "name" : "EOS", + "contractAddress" : "0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0" + }, + { + "decimalCount" : 2, + "symbol" : "EUR.AVM", + "name" : "EUR AVM", + "contractAddress" : "0xF01Cd2f1c9E42c509d309aC8C5b29B6dA8E64b1a" + }, + { + "decimalCount" : 18, + "symbol" : "XUC", + "name" : "Exchange Union", + "contractAddress" : "0xc324a2f6b05880503444451b8b27e6f9e63287cb" + }, + { + "decimalCount" : 18, + "symbol" : "1ST", + "name" : "FirstBlood", + "contractAddress" : "0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7" + }, + { + "decimalCount" : 18, + "symbol" : "FXC", + "name" : "Flexacoin", + "contractAddress" : "0x4a57E687b9126435a9B19E4A802113e266AdeBde" + }, + { + "decimalCount" : 8, + "symbol" : "FUN", + "name" : "FunFair", + "contractAddress" : "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b" + }, + { + "decimalCount" : 18, + "symbol" : "FSN", + "name" : "Fusion", + "contractAddress" : "0xd0352a019e9ab9d757776f532377aaebd36fd541" + }, + { + "decimalCount" : 2, + "symbol" : "GUSD", + "name" : "Gemini Dollar", + "contractAddress" : "0x056fd409e1d7a124bd7017459dfea2f387b6d5cd" + }, + { + "decimalCount" : 9, + "symbol" : "GNX", + "name" : "Genaro Network", + "contractAddress" : "0x6ec8a24cabdc339a06a172f8223ea557055adaa5" + }, + { + "decimalCount" : 18, + "symbol" : "GVT", + "name" : "Genesis Vision", + "contractAddress" : "0x103c3A209da59d3E7C4A89307e66521e081CFDF0" + }, + { + "decimalCount" : 5, + "symbol" : "GTO", + "name" : "Gifto", + "contractAddress" : "0xc5bbae50781be1669306b9e001eff57a2957b09d" + }, + { + "decimalCount" : 8, + "symbol" : "GBX", + "name" : "Globitex", + "contractAddress" : "0x12fcd6463e66974cf7bbc24ffc4d40d6be458283" + }, + { + "decimalCount" : 18, + "symbol" : "GNO", + "name" : "Gnosis", + "contractAddress" : "0x6810e776880C02933D47DB1b9fc05908e5386b96" + }, + { + "decimalCount" : 18, + "symbol" : "GNT", + "name" : "Golem", + "contractAddress" : "0xa74476443119A942dE498590Fe1f2454d7D4aC0d" + }, + { + "decimalCount" : 18, + "symbol" : "HPB", + "name" : "HPBCoin", + "contractAddress" : "0x38c6a68304cdefb9bec48bbfaaba5c5b47818bb2" + }, + { + "decimalCount" : 18, + "symbol" : "HYDRO", + "name" : "Hydro", + "contractAddress" : "0xebbdf302c940c6bfd49c6b165f457fdb324649bc" + }, + { + "decimalCount" : 18, + "symbol" : "ICX", + "name" : "ICON", + "contractAddress" : "0xb5a5f22694352c15b00323844ad545abb2b11028" + }, + { + "decimalCount" : 18, + "symbol" : "ICN", + "name" : "ICONOMI", + "contractAddress" : "0x888666CA69E0f178DED6D75b5726Cee99A87D698" + }, + { + "decimalCount" : 9, + "symbol" : "RLC", + "name" : "iExec RLC", + "contractAddress" : "0x607F4C5BB672230e8672085532f7e901544a7375" + }, + { + "decimalCount" : 18, + "symbol" : "IOST", + "name" : "IOStoken", + "contractAddress" : "0xfa1a856cfa3409cfa145fa4e20eb270df3eb21ab" + }, + { + "decimalCount" : 18, + "symbol" : "ITC", + "name" : "IOT Chain", + "contractAddress" : "0x5e6b6d9abad9093fdc861ea1600eba1b355cd940" + }, + { + "decimalCount" : 8, + "symbol" : "IXT", + "name" : "iXledger", + "contractAddress" : "0xfca47962d45adfdfd1ab2d972315db4ce7ccf094" + }, + { + "decimalCount" : 18, + "symbol" : "KIN", + "name" : "Kin", + "contractAddress" : "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5" + }, + { + "decimalCount" : 18, + "symbol" : "KNC", + "name" : "Kyber Network", + "contractAddress" : "0xdd974D5C2e2928deA5F71b9825b8b646686BD200" + }, + { + "decimalCount" : 18, + "symbol" : "LOOM", + "name" : "Loom", + "contractAddress" : "0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0" + }, + { + "decimalCount" : 18, + "symbol" : "LRC", + "name" : "Loopring", + "contractAddress" : "0xbbbbca6a901c926f240b89eacb641d8aec7aeafd" + }, + { + "decimalCount" : 18, + "symbol" : "LUN", + "name" : "Lunyr", + "contractAddress" : "0xfa05A73FfE78ef8f1a739473e462c54bae6567D9" + }, + { + "decimalCount" : 18, + "symbol" : "MKR", + "name" : "Maker", + "contractAddress" : "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2" + }, + { + "decimalCount" : 3, + "symbol" : "GUP", + "name" : "Matchpool", + "contractAddress" : "0xf7B098298f7C69Fc14610bf71d5e02c60792894C" + }, + { + "decimalCount" : 18, + "symbol" : "MAN", + "name" : "MATRIX AI Network", + "contractAddress" : "0xe25bcec5d3801ce3a794079bf94adf1b8ccd802d" + }, + { + "decimalCount" : 8, + "symbol" : "MTL", + "name" : "Metal", + "contractAddress" : "0xF433089366899D83a9f26A773D59ec7eCF30355e" + }, + { + "decimalCount" : 8, + "symbol" : "MCO", + "name" : "Monaco", + "contractAddress" : "0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d" + }, + { + "decimalCount" : 8, + "symbol" : "MYST", + "name" : "Mysterium", + "contractAddress" : "0xa645264C5603E96c3b0B078cdab68733794B0A71" + }, + { + "decimalCount" : 18, + "symbol" : "NAS", + "name" : "Nebulas", + "contractAddress" : "0x5d65D971895Edc438f465c17DB6992698a52318D" + }, + { + "decimalCount" : 18, + "symbol" : "NEXO", + "name" : "Nexo", + "contractAddress" : "0xb62132e35a6c13ee1ee0f84dc5d40bad8d815206" + }, + { + "decimalCount" : 18, + "symbol" : "NCASH", + "name" : "Nucleus Vision", + "contractAddress" : "0x809826cceab68c387726af962713b64cb5cb3cca" + }, + { + "decimalCount" : 18, + "symbol" : "NULS", + "name" : "Nuls", + "contractAddress" : "0xb91318f35bdb262e9423bc7c7c2a3a93dd93c92c" + }, + { + "decimalCount" : 18, + "symbol" : "NMR", + "name" : "Numeraire", + "contractAddress" : "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671" + }, + { + "decimalCount" : 18, + "symbol" : "OMG", + "name" : "OmiseGO", + "contractAddress" : "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07" + }, + { + "decimalCount" : 18, + "symbol" : "OXT", + "name" : "Orchid", + "contractAddress" : "0x4575f41308ec1483f3d399aa9a2826d74da13deb" + }, + { + "decimalCount" : 18, + "symbol" : "OST", + "name" : "OST", + "contractAddress" : "0x2C4e8f2D746113d0696cE89B35F0d8bF88E0AEcA" + }, + { + "decimalCount" : 18, + "symbol" : "PRL", + "name" : "Oyster Pearl", + "contractAddress" : "0x1844b21593262668b7248d0f57a220caaba46ab9" + }, + { + "decimalCount" : 8, + "symbol" : "PTOY", + "name" : "Patientory", + "contractAddress" : "0x8Ae4BF2C33a8e667de34B54938B0ccD03Eb8CC06" + }, + { + "decimalCount" : 18, + "symbol" : "PAX", + "name" : "Paxos Standard", + "contractAddress" : "0x8e870d67f660d95d5be530380d0ec0bd388289e1" + }, + { + "decimalCount" : 18, + "symbol" : "PMTN", + "name" : "Peer Mountain", + "contractAddress" : "0xe91df2bb9bccd18c45f01843cab88768d64f2d32" + }, + { + "decimalCount" : 8, + "symbol" : "POE", + "name" : "Po.et", + "contractAddress" : "0x0e0989b1f9b8a38983c2ba8053269ca62ec9b195" + }, + { + "decimalCount" : 18, + "symbol" : "PAL", + "name" : "PolicyPal Network", + "contractAddress" : "0xfeDAE5642668f8636A11987Ff386bfd215F942EE" + }, + { + "decimalCount" : 18, + "symbol" : "POLY", + "name" : "Polymath", + "contractAddress" : "0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC" + }, + { + "decimalCount" : 8, + "symbol" : "PPT", + "name" : "Populous", + "contractAddress" : "0xd4fa1460F537bb9085d22C7bcCB5DD450Ef28e3a" + }, + { + "decimalCount" : 6, + "symbol" : "POWR", + "name" : "Power Ledger", + "contractAddress" : "0x595832f8fc6bf59c85c527fec3740a1b7a361269" + }, + { + "decimalCount" : 18, + "symbol" : "NPXS", + "name" : "Pundi X Token", + "contractAddress" : "0xa15c7ebe1f07caf6bff097d8a589fb8ac49ae5b3" + }, + { + "decimalCount" : 6, + "symbol" : "QASH", + "name" : "QASH", + "contractAddress" : "0x618e75ac90b12c6049ba3b27f5d5f8651b0037f6" + }, + { + "decimalCount" : 8, + "symbol" : "QRL", + "name" : "QRL", + "contractAddress" : "0x697beac28B09E122C4332D163985e8a73121b97F" + }, + { + "decimalCount" : 18, + "symbol" : "QSP", + "name" : "Quantstamp", + "contractAddress" : "0x99ea4dB9EE77ACD40B119BD1dC4E33e1C070b80d" + }, + { + "decimalCount" : 18, + "symbol" : "RDN", + "name" : "Raiden Network", + "contractAddress" : "0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6" + }, + { + "decimalCount" : 18, + "symbol" : "RCC", + "name" : "Reality Clash", + "contractAddress" : "0x9b6443b0fb9c241a7fdac375595cea13e6b7807a" + }, + { + "decimalCount" : 6, + "symbol" : "RC1U03", + "name" : "RentalCoin 1.0", + "contractAddress" : "0x7384db1aaa06364d1e6e67f5434391d3eea2a038" + }, + { + "decimalCount" : 18, + "symbol" : "REQ", + "name" : "Request", + "contractAddress" : "0x8f8221aFbB33998d8584A2B05749bA73c37a938a" + }, + { + "decimalCount" : 0, + "symbol" : "REV", + "name" : "Revain", + "contractAddress" : "0x48f775efbe4f5ece6e0df2f7b5932df56823b990" + }, + { + "decimalCount" : 18, + "symbol" : "RCN", + "name" : "Ripio Credit", + "contractAddress" : "0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6" + }, + { + "decimalCount" : 18, + "symbol" : "RVT", + "name" : "Rivetz", + "contractAddress" : "0x3d1ba9be9f66b8ee101911bc36d3fb562eac2244" + }, + { + "decimalCount" : 18, + "symbol" : "RUFF", + "name" : "RUFF", + "contractAddress" : "0xf278c1ca969095ffddded020290cf8b5c424ace2" + }, + { + "decimalCount" : 18, + "symbol" : "SAI", + "name" : "Sai", + "contractAddress" : "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359" + }, + { + "decimalCount" : 8, + "symbol" : "SALT", + "name" : "SALT", + "contractAddress" : "0x4156D3342D5c385a87D264F90653733592000581" + }, + { + "decimalCount" : 18, + "symbol" : "SAN", + "name" : "SAN", + "contractAddress" : "0x7C5A0CE9267ED19B22F8cae653F198e3E8daf098" + }, + { + "decimalCount" : 8, + "symbol" : "SENT", + "name" : "SENTinel", + "contractAddress" : "0xa44e5137293e855b1b7bc7e2c6f8cd796ffcb037" + }, + { + "decimalCount" : 0, + "symbol" : "SNGLS", + "name" : "Singular DTV", + "contractAddress" : "0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009" + }, + { + "decimalCount" : 8, + "symbol" : "AGI", + "name" : "SingularityNET", + "contractAddress" : "0x8eB24319393716668D768dCEC29356ae9CfFe285" + }, + { + "decimalCount" : 18, + "symbol" : "SRN", + "name" : "SIRIN", + "contractAddress" : "0x68d57c9a1C35f63E2c83eE8e49A64e9d70528D25" + }, + { + "decimalCount" : 18, + "symbol" : "SNM", + "name" : "SONM", + "contractAddress" : "0x983F6d60db79ea8cA4eB9968C6aFf8cfA04B3c63" + }, + { + "decimalCount" : 18, + "symbol" : "SNT", + "name" : "Status", + "contractAddress" : "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E" + }, + { + "decimalCount" : 18, + "symbol" : "STK", + "name" : "STK", + "contractAddress" : "0xae73b38d1c9a8b274127ec30160a4927c4d71824" + }, + { + "decimalCount" : 18, + "symbol" : "STQ", + "name" : "Storiqa", + "contractAddress" : "0x5c3a228510d246b78a3765c20221cbf3082b44a4" + }, + { + "decimalCount" : 8, + "symbol" : "STORJ", + "name" : "Storj", + "contractAddress" : "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC" + }, + { + "decimalCount" : 18, + "symbol" : "STORM", + "name" : "Storm", + "contractAddress" : "0xD0a4b8946Cb52f0661273bfbC6fD0E0C75Fc6433" + }, + { + "decimalCount" : 18, + "symbol" : "STMX", + "name" : "StormX", + "contractAddress" : "0xbE9375C6a420D2eEB258962efB95551A5b722803" + }, + { + "decimalCount" : 18, + "symbol" : "STX", + "name" : "Stox", + "contractAddress" : "0x006BeA43Baa3f7A6f765F14f10A1a1b08334EF45" + }, + { + "decimalCount" : 18, + "symbol" : "SUB", + "name" : "Substratum", + "contractAddress" : "0x8D75959f1E61EC2571aa72798237101F084DE63a" + }, + { + "decimalCount" : 18, + "symbol" : "SNC", + "name" : "SunContract", + "contractAddress" : "0xF4134146AF2d511Dd5EA8cDB1C4AC88C57D60404" + }, + { + "decimalCount" : 18, + "symbol" : "SUSHI", + "name" : "SushiSwap", + "contractAddress" : "0x6b3595068778dd592e39a122f4f5a5cf09c90fe2" + }, + { + "decimalCount" : 2, + "symbol" : "TEL", + "name" : "Telcoin", + "contractAddress" : "0x467bccd9d29f223bce8043b84e8c8b282827790f" + }, + { + "decimalCount" : 18, + "symbol" : "PAY", + "name" : "TenX", + "contractAddress" : "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280" + }, + { + "decimalCount" : 6, + "symbol" : "USDT", + "name" : "Tether USD", + "contractAddress" : "0xdac17f958d2ee523a2206206994597c13d831ec7" + }, + { + "decimalCount" : 18, + "symbol" : "THETA", + "name" : "Theta Token", + "contractAddress" : "0x3883f5e181fccaf8410fa61e12b59bad963fb645" + }, + { + "decimalCount" : 6, + "symbol" : "TRX", + "name" : "TRON", + "contractAddress" : "0xf230b790e05390fc8295f4d3f60332c93bed42e2" + }, + { + "decimalCount" : 18, + "symbol" : "TUSD", + "name" : "TrueUSD", + "contractAddress" : "0x0000000000085d4780B73119b644AE5ecd22b376" + }, + { + "decimalCount" : 8, + "symbol" : "UCASH", + "name" : "UCASH", + "contractAddress" : "0x92e52a1a235d9a103d970901066ce910aacefd37" + }, + { + "decimalCount" : 18, + "symbol" : "UNI", + "name" : "Uniswap", + "contractAddress" : "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984" + }, + { + "decimalCount" : 6, + "symbol" : "USDC", + "name" : "USD Coin", + "contractAddress" : "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + }, + { + "decimalCount" : 18, + "symbol" : "VIB", + "name" : "Viberate", + "contractAddress" : "0x2C974B2d0BA1716E644c1FC59982a89DDD2fF724" + }, + { + "decimalCount" : 8, + "symbol" : "VGX", + "name" : "Voyager", + "contractAddress" : "0x5af2be193a6abca9c8817001f45744777db30756" + }, + { + "decimalCount" : 18, + "symbol" : "WTC", + "name" : "Waltonchain", + "contractAddress" : "0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74" + }, + { + "decimalCount" : 8, + "symbol" : "WAX", + "name" : "WAX", + "contractAddress" : "0x39Bb259F66E1C59d5ABEF88375979b4D20D98022" + }, + { + "decimalCount" : 18, + "symbol" : "WPR", + "name" : "WePower", + "contractAddress" : "0x4CF488387F035FF08c371515562CBa712f9015d4" + }, + { + "decimalCount" : 18, + "symbol" : "WINGS", + "name" : "Wings", + "contractAddress" : "0x667088b212ce3d06a1b553a7221E1fD19000d9aF" + }, + { + "decimalCount" : 6, + "symbol" : "WRC", + "name" : "Worldcore", + "contractAddress" : "0x72adadb447784dd7ab1f472467750fc485e4cb2d" + }, + { + "decimalCount" : 18, + "symbol" : "ZLA", + "name" : "Zilla", + "contractAddress" : "0xfd8971d5e8e1740ce2d0a84095fca4de729d0c16" + }, + { + "decimalCount" : 0, + "symbol" : "GD", + "name" : "Zilla GD", + "contractAddress" : "0xb4cebdb66b3a5183fd4764a25cad1fc109535016" + }, + { + "decimalCount" : 12, + "symbol" : "ZIL", + "name" : "Zilliqa", + "contractAddress" : "0x05f4a42e251f2d52b8ed15E9FEdAacFcEF1FAD27" + } +] diff --git a/app/src/main/assets/tangem-android-config b/app/src/main/assets/tangem-android-config new file mode 160000 index 0000000000..9a731fcb5a --- /dev/null +++ b/app/src/main/assets/tangem-android-config @@ -0,0 +1 @@ +Subproject commit 9a731fcb5a58d53c90d7db79e5441bdf18e087fc diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/Loader.kt b/app/src/main/java/com/tangem/tap/domain/configurable/Loader.kt index e0d0a6a52c..3471ed78ee 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/Loader.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/Loader.kt @@ -10,7 +10,7 @@ interface Loader { companion object { const val featuresName = "features_${BuildConfig.CONFIG_ENVIRONMENT}" - const val configValuesName = "config_${BuildConfig.CONFIG_ENVIRONMENT}" + const val configValuesName = "tangem-android-config/config_${BuildConfig.CONFIG_ENVIRONMENT}" const val warnings = "warnings_${BuildConfig.CONFIG_ENVIRONMENT}" } } \ No newline at end of file From d56c4d201254457105a254c7e03a2a319b813d13 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Mar 2021 18:02:20 +0300 Subject: [PATCH 05/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c65890f80b..58c711eb31 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.157.0' + implementation 'com.tangem:blockchain:1.158.0' implementation 'com.tangem:core:1.108.0' implementation 'com.tangem:sdk:1.108.0' From 6693041c3be07be210235a7f9ed2e3c292ebeade Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 Mar 2021 10:43:16 +0300 Subject: [PATCH 06/37] Updated on 2026-08-14 --- app/src/main/res/layout/fragment_wallet.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/layout/fragment_wallet.xml b/app/src/main/res/layout/fragment_wallet.xml index 04557df535..af281426f8 100644 --- a/app/src/main/res/layout/fragment_wallet.xml +++ b/app/src/main/res/layout/fragment_wallet.xml @@ -171,6 +171,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" + android:layout_marginTop="30dp" + app:layout_constraintTop_toBottomOf="@id/l_address" + app:layout_constraintVertical_bias="1" app:layout_constraintBottom_toBottomOf="parent" /> Date: Wed, 31 Mar 2021 12:57:45 +0300 Subject: [PATCH 07/37] Updated on 2026-08-14 --- .../redux/middlewares/WalletMiddleware.kt | 8 +++++ .../redux/reducers/OnWalletLoadedReducer.kt | 2 +- .../main/res/layout/item_currency_wallet.xml | 32 +++++++++++-------- .../main/res/layout/layout_wallet_details.xml | 13 ++++++-- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index af6ceb3d2d..6cd4f9da3a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -6,6 +6,7 @@ import androidx.core.content.ContextCompat import com.tangem.TangemSdkError import com.tangem.blockchain.common.* import com.tangem.common.CompletionResult +import com.tangem.common.extensions.isZero import com.tangem.tap.* import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.copyToClipboard @@ -59,6 +60,13 @@ class WalletMiddleware { } } is WalletAction.LoadWallet.Success -> { + val coinAmount = action.wallet.amounts[AmountType.Coin]?.value + if (coinAmount != null && !coinAmount.isZero()) { + if (walletState?.getWalletData(action.wallet.blockchain.currency) == null) { + store.dispatch(WalletAction.MultiWallet.AddBlockchain(action.wallet.blockchain)) + store.dispatch(WalletAction.LoadWallet.Success(action.wallet)) + } + } store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline) warningsMiddleware.tryToShowAppRatingWarning(action.wallet) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 59edbdd896..6941106a0c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -27,7 +27,7 @@ class OnWalletLoadedReducer { } else { val fiatCurrencySymbol = store.state.globalState.appCurrency val amount = wallet.amounts[AmountType.Coin]?.value - if (walletState.getWalletData(wallet.blockchain.currency) == null && amount?.isZero() != false) { + if (walletState.getWalletData(wallet.blockchain.currency) == null) { return walletState } if (wallet.blockchain != Blockchain.Ethereum) { diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index be3b049566..576619305c 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -17,7 +17,7 @@ + android:layout_height="76dp"> diff --git a/app/src/main/res/layout/layout_wallet_details.xml b/app/src/main/res/layout/layout_wallet_details.xml index d276934193..f8ac54763e 100644 --- a/app/src/main/res/layout/layout_wallet_details.xml +++ b/app/src/main/res/layout/layout_wallet_details.xml @@ -83,7 +83,7 @@ app:layout_constraintEnd_toEndOf="@id/guideline" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/chip_group_address_type" - app:layout_constraintBottom_toBottomOf="@id/btn_copy" + app:layout_constraintBottom_toBottomOf="@id/v_qr_lower_end" tools:src="@drawable/ic_qr_code_show" /> + + Date: Wed, 31 Mar 2021 14:24:39 +0300 Subject: [PATCH 08/37] Updated on 2026-08-14 --- .../configurable/config/ConfigManager.kt | 11 ++++++----- .../tangem/tap/domain/tasks/ScanNoteTask.kt | 18 ++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt index b1ccd85929..58096022fd 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt @@ -31,11 +31,12 @@ class ConfigManager( localLoader.load { config -> setupFeature(config.features) setupKey(config.configValues) - } - remoteLoader.load { config -> - setupFeature(config.features) onComplete?.invoke() } + // Uncomment to enable remote config +// remoteLoader.load { config -> +// setupFeature(config.features) +// } } fun turnOff(name: String) { @@ -79,7 +80,7 @@ class ConfigManager( blockchainSdkConfig = BlockchainSdkConfig( blockchairApiKey = values.blockchairApiKey, blockcypherTokens = values.blockcypherTokens, - infuraProjectId = values.infuraProjectId + infuraProjectId = values.infuraProjectId ) ) defaultConfig = defaultConfig.copy( @@ -89,7 +90,7 @@ class ConfigManager( blockchainSdkConfig = BlockchainSdkConfig( blockchairApiKey = values.blockchairApiKey, blockcypherTokens = values.blockcypherTokens, - infuraProjectId = values.infuraProjectId + infuraProjectId = values.infuraProjectId ) ) } diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt index e2ae2aef19..3e24204388 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt @@ -1,9 +1,6 @@ package com.tangem.tap.domain.tasks -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.TangemError -import com.tangem.TangemSdkError +import com.tangem.* import com.tangem.blockchain.common.BlockchainSdkConfig import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory @@ -32,10 +29,6 @@ data class ScanNoteResponse( class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { override val requiresPin2 = false - private val blockchainSdkConfig = store.state.globalState.configManager?.config - ?.blockchainSdkConfig ?: BlockchainSdkConfig() - private val walletManagerFactory = WalletManagerFactory(blockchainSdkConfig) - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { ScanTask().run(session) { result -> when (result) { @@ -59,7 +52,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable Date: Wed, 31 Mar 2021 19:03:46 +0300 Subject: [PATCH 09/37] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 1 + .../java/com/tangem/tap/TapApplication.kt | 3 +- .../tap/features/feedback/FeedbackManager.kt | 51 ++++++++++++++----- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 732ca5892e..0b349f013a 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -55,6 +55,7 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + store.state.globalState.feedbackManager?.updateAcivity(this) requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; store.dispatch(NavigationAction.ActivityCreated(WeakReference(this))) diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 0f609b7328..286c39df5e 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -74,7 +74,6 @@ class TapApplication : Application() { val logWriter = TangemLogCollector() Log.addLogger(logWriter) - val feedbackManager = FeedbackManager(infoHolder, this, logWriter) - store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager)) + store.dispatch(GlobalAction.SetFeedbackManager(FeedbackManager(infoHolder, logWriter))) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index ce94b2602b..3a57a3a211 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -1,11 +1,13 @@ package com.tangem.tap.features.feedback +import android.app.Activity import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Build +import androidx.core.app.ShareCompat import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import com.tangem.Log @@ -22,39 +24,60 @@ import java.io.StringWriter */ class FeedbackManager( val infoHolder: AdditionalEmailInfo, - private val context: Context, private val logCollector: TangemLogCollector, private val email: String = "support@tangem.com", ) { + private lateinit var activity: Activity + + fun updateAcivity(activity: Activity) { + this.activity = activity + } + fun send(emailData: EmailData) { val fileLog = if (emailData is ScanFailsEmail) createLogFile() else null sendTo(email, emailData.subject, emailData.joinTogether(infoHolder), fileLog) } private fun sendTo(email: String, subject: String, message: String, fileLog: File? = null) { - val intent = Intent(Intent.ACTION_SENDTO).apply { - data = Uri.parse("mailto:$email") - putExtra(Intent.EXTRA_SUBJECT, subject) - putExtra(Intent.EXTRA_TEXT, message) - fileLog?.let { - val uri = FileProvider.getUriForFile(context, "${context.packageName}.provider", it) - putExtra(Intent.EXTRA_STREAM, uri) - } - } - + val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")) + val originalIntentResults = activity.packageManager.queryIntentActivities(emailFilterIntent, 0) + val emailFilterIntentResults = activity.packageManager.queryIntentActivities(emailFilterIntent, 0) + val targetedIntents = originalIntentResults + .filter { originalResult -> + emailFilterIntentResults.any { + originalResult.activityInfo.packageName == it.activityInfo.packageName + } + } + .map { + createEmailShareIntent(email, subject, message, fileLog).apply { + setPackage(it.activityInfo.packageName) + } + } + .toMutableList() try { - val chooserIntent = Intent.createChooser(intent, "Send mail...") + val chooserIntent = Intent.createChooser(targetedIntents.removeAt(0), "Send mail...") + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray()) chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ContextCompat.startActivity(context, chooserIntent, null) + ContextCompat.startActivity(activity, chooserIntent, null) } catch (ex: ActivityNotFoundException) { Timber.e(ex) } } + private fun createEmailShareIntent(recipient: String, subject: String, text: String, file: File? = null): Intent { + val builder = ShareCompat.IntentBuilder.from(activity) + .setType("message/rfc822") + .setEmailTo(arrayOf(recipient)) + .setSubject(subject) + .setText(text) + file?.let { builder.setStream(FileProvider.getUriForFile(activity, "${activity.packageName}.provider", it)) } + return builder.intent + } + private fun createLogFile(): File? { return try { - val file = File(context.filesDir, "logs.txt") + val file = File(activity.filesDir, "logs.txt") file.delete() file.createNewFile() From 0fc04f9a3f19de94f99006a02ea75eb4e26e20fb Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 Mar 2021 20:13:41 +0300 Subject: [PATCH 10/37] Updated on 2026-08-14 --- .../tap/common/redux/global/GlobalAction.kt | 12 ++++++++++-- .../common/redux/global/GlobalMidlleware.kt | 19 +++++++++++++++++++ .../tap/common/redux/global/GlobalReducer.kt | 6 ++++++ .../tap/common/redux/global/GlobalState.kt | 5 ++++- .../tangem/tap/features/home/HomeFragment.kt | 19 +++++++++++++++++++ .../tap/features/home/redux/HomeAction.kt | 6 ++++++ .../tap/features/home/redux/HomeMiddleware.kt | 1 + .../tap/features/home/redux/HomeReducer.kt | 6 ++++++ .../tap/features/home/redux/HomeState.kt | 8 +++++++- .../features/send/redux/SendScreenAction.kt | 3 ++- .../features/send/redux/states/SendState.kt | 4 ++-- .../tap/features/wallet/redux/WalletAction.kt | 2 -- .../tap/features/wallet/redux/WalletState.kt | 6 +++--- .../redux/middlewares/WalletMiddleware.kt | 15 +++------------ .../wallet/redux/reducers/WalletReducer.kt | 7 ------- .../wallet/ui/WalletDetailsFragment.kt | 3 ++- .../wallet/ui/dialogs/ScanFailsDialog.kt | 6 +++++- .../wallet/ui/wallet/MultiWalletView.kt | 9 ++++----- .../wallet/ui/wallet/SingleWalletView.kt | 9 ++++----- 19 files changed, 103 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index 45bc0c2707..2a2a612757 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -1,5 +1,6 @@ package com.tangem.tap.common.redux.global +import com.tangem.common.CompletionResult import com.tangem.tap.domain.configurable.config.ConfigManager import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager @@ -11,18 +12,25 @@ import org.rekotlin.Action sealed class GlobalAction : Action { + object ScanFailsCounter { + data class ChooseBehavior(val result: CompletionResult) : GlobalAction() + object Reset : GlobalAction() + object Increment : GlobalAction() + } + data class SaveScanNoteResponse(val scanNoteResponse: ScanNoteResponse) : GlobalAction() data class ChangeAppCurrency(val appCurrency: FiatCurrencyName) : GlobalAction() object RestoreAppCurrency : GlobalAction() { data class Success(val appCurrency: FiatCurrencyName) : GlobalAction() } + data class UpdateWalletSignedHashes(val walletSignedHashes: Int?) : GlobalAction() data class HideWarningMessage(val warning: WarningMessage) : GlobalAction() data class UpdateSecurityOptions(val securityOption: SecurityOption) : GlobalAction() data class SetConfigManager(val configManager: ConfigManager) : GlobalAction() data class SetWarningManager(val warningManager: WarningMessagesManager) : GlobalAction() - data class SetFeedbackManager(val feedbackManager: FeedbackManager): GlobalAction() + data class SetFeedbackManager(val feedbackManager: FeedbackManager) : GlobalAction() - data class SendFeedback(val emailData: EmailData): GlobalAction() + data class SendFeedback(val emailData: EmailData) : GlobalAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt index 0c8de5dc8d..bc4a389355 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt @@ -1,8 +1,11 @@ package com.tangem.tap.common.redux.global +import com.tangem.TangemSdkError +import com.tangem.common.CompletionResult import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager +import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.send.redux.SendAction import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.preferencesStorage @@ -13,6 +16,22 @@ val globalMiddleware: Middleware = { dispatch, appState -> { nextDispatch -> { action -> when (action) { + is GlobalAction.ScanFailsCounter.ChooseBehavior -> { + when (action.result) { + is CompletionResult.Success -> store.dispatch(GlobalAction.ScanFailsCounter.Reset) + is CompletionResult.Failure -> { + if (action.result.error is TangemSdkError.UserCancelled) { + store.dispatch(GlobalAction.ScanFailsCounter.Increment) + if (store.state.globalState.scanCardFailsCounter >= 2) { + store.dispatch(HomeAction.ShowDialog.ScanFails) + store.dispatch(WalletAction.ShowDialog.ScanFails) + } + } else { + store.dispatch(GlobalAction.ScanFailsCounter.Reset) + } + } + } + } is GlobalAction.RestoreAppCurrency -> { store.dispatch(GlobalAction.RestoreAppCurrency.Success( preferencesStorage.getAppCurrency() diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 8df35e1064..eeecf8fb76 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -11,6 +11,12 @@ fun globalReducer(action: Action, state: AppState): GlobalState { val globalState = state.globalState return when (action) { + is GlobalAction.ScanFailsCounter.Increment -> { + globalState.copy(scanCardFailsCounter = globalState.scanCardFailsCounter + 1) + } + is GlobalAction.ScanFailsCounter.Reset -> { + globalState.copy(scanCardFailsCounter = 0) + } is GlobalAction.SaveScanNoteResponse -> globalState.copy(scanNoteResponse = action.scanNoteResponse) is GlobalAction.ChangeAppCurrency -> { diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 52340df26d..a0ac13bc06 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -20,9 +20,12 @@ data class GlobalState( val configManager: ConfigManager? = null, val warningManager: WarningMessagesManager? = null, val feedbackManager: FeedbackManager? = null, - val appCurrency: FiatCurrencyName = DEFAULT_FIAT_CURRENCY + val appCurrency: FiatCurrencyName = DEFAULT_FIAT_CURRENCY, + val scanCardFailsCounter: Int = 0, ) : StateType typealias CryptoCurrencyName = String typealias FiatCurrencyName = String + +interface StateDialog \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index b8b8aa52fc..c93543613e 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -1,11 +1,15 @@ package com.tangem.tap.features.home +import android.app.Dialog import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.features.home.redux.HomeAction +import com.tangem.tap.features.home.redux.HomeDialog import com.tangem.tap.features.home.redux.HomeState +import com.tangem.tap.features.wallet.ui.dialogs.ScanFailsDialog import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_home.* @@ -13,6 +17,8 @@ import org.rekotlin.StoreSubscriber class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber { + private var dialog: Dialog? = null + override fun onStart() { super.onStart() store.subscribe(this) { state -> @@ -39,6 +45,19 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber { + if (dialog == null) dialog = ScanFailsDialog.create(requireContext()).apply { show() } + } + else -> { + dialog?.dismiss() + dialog = null + } + } } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index 5a9edf9fe7..4a575343c7 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -9,4 +9,10 @@ sealed class HomeAction : Action { object CheckIfFirstLaunch : HomeAction() { data class Result(val firstLaunch: Boolean) : HomeAction() } + + object ShowDialog : HomeAction() { + object ScanFails : HomeAction() + } + + object HideDialog : HomeAction() } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index aaf52f3564..b084b208cb 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -32,6 +32,7 @@ class HomeMiddleware { scope.launch { val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler) withContext(Dispatchers.Main) { + store.dispatch(GlobalAction.ScanFailsCounter.ChooseBehavior(result)) when (result) { is CompletionResult.Success -> { tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt index b88da93641..3c031ed7b2 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt @@ -18,6 +18,12 @@ private fun internalReduce(action: Action, state: AppState): HomeState { is HomeAction.CheckIfFirstLaunch.Result -> { homeState = homeState.copy(firstLaunch = action.firstLaunch) } + is HomeAction.ShowDialog.ScanFails -> { + homeState = homeState.copy(dialog = HomeDialog.ScanFailsDialog) + } + is HomeAction.HideDialog -> { + homeState = homeState.copy(dialog = null) + } } return homeState diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt index b167e66785..c9fce9b492 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt @@ -1,7 +1,13 @@ package com.tangem.tap.features.home.redux +import com.tangem.tap.common.redux.global.StateDialog import org.rekotlin.StateType data class HomeState( - val firstLaunch: Boolean = true + val firstLaunch: Boolean = true, + val dialog: StateDialog? = null ) : StateType + +sealed class HomeDialog: StateDialog { + object ScanFailsDialog: HomeDialog() +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 36e7ae943b..0d0d2d8bc7 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.WalletManager import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.ToastNotificationAction +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.domain.TapError import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.features.send.redux.states.FeeType @@ -142,7 +143,7 @@ sealed class SendAction : SendScreenAction { data class SendError(override val error: TapError) : SendAction(), ErrorAction - sealed class Dialog : SendAction() { + sealed class Dialog : SendAction(), StateDialog { data class TezosWarningDialog( val reduceCallback: () -> Unit, val sendAllCallback: () -> Unit, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index c4e57d708a..1e4e8d5072 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -6,10 +6,10 @@ import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.isZero import com.tangem.tap.common.CurrencyConverter import com.tangem.tap.common.entities.TapCurrency +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.common.text.DecimalDigitsInputFilter import com.tangem.tap.domain.TapError import com.tangem.tap.domain.configurable.warningMessage.WarningMessage -import com.tangem.tap.features.send.redux.SendAction import com.tangem.tap.store import org.rekotlin.StateType import java.math.BigDecimal @@ -40,7 +40,7 @@ data class SendState( val receiptState: ReceiptState = ReceiptState(), val sendWarningsList: List = listOf(), val sendButtonState: SendButtonState = SendButtonState.DISABLED, - val dialog: SendAction.Dialog? = null + val dialog: StateDialog? = null ) : SendScreenState { override val stateId: StateId = StateId.SEND_SCREEN diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index b85af64448..f623671395 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.wallet.redux import android.content.Context -import com.tangem.TangemError import com.tangem.blockchain.common.* import com.tangem.blockchain.common.address.AddressType import com.tangem.commands.common.card.Card @@ -99,7 +98,6 @@ sealed class WalletAction : Action { } object Scan : WalletAction() - class ScanCardFinished(val scanError: TangemError? = null) : WalletAction() data class Send(val amount: Amount? = null) : WalletAction() { data class ChooseCurrency(val amounts: List?) : WalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 6bf6a41ffc..a806c477b7 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.address.AddressType import com.tangem.blockchain.extensions.isAboveZero import com.tangem.tap.common.entities.Button import com.tangem.tap.common.redux.global.CryptoCurrencyName +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.domain.twins.TwinCardNumber @@ -22,10 +23,9 @@ data class WalletState( val error: ErrorType? = null, val cardImage: Artwork? = null, val hashesCountVerified: Boolean? = null, - val walletDialog: WalletDialog? = null, + val walletDialog: StateDialog? = null, val twinCardsState: TwinCardsState? = null, val mainWarningsList: List = mutableListOf(), - val scanCardFailsCounter: Int = 0, val wallets: List = emptyList(), val walletManagers: List = emptyList(), val isMultiwalletAllowed: Boolean = false, @@ -96,7 +96,7 @@ data class WalletState( } -sealed class WalletDialog { +sealed class WalletDialog: StateDialog { data class QrDialog( val qrCode: Bitmap?, val shareUrl: String?, val currencyName: CryptoCurrencyName? ) : WalletDialog() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 6cd4f9da3a..6d27122a01 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -3,7 +3,6 @@ package com.tangem.tap.features.wallet.redux.middlewares import android.content.Intent import android.net.Uri import androidx.core.content.ContextCompat -import com.tangem.TangemSdkError import com.tangem.blockchain.common.* import com.tangem.common.CompletionResult import com.tangem.common.extensions.isZero @@ -12,6 +11,7 @@ import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.copyToClipboard import com.tangem.tap.common.extensions.shareText 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.domain.extensions.toSendableAmounts @@ -135,20 +135,11 @@ class WalletMiddleware { scope.launch { val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler) scope.launch(Dispatchers.Main) { + store.dispatch(GlobalAction.ScanFailsCounter.ChooseBehavior(result)) when (result) { is CompletionResult.Success -> { tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) - globalState?.tapWalletManager - ?.onCardScanned(result.data, true) - store.dispatch(WalletAction.ScanCardFinished()) - } - is CompletionResult.Failure -> { - if (result.error !is TangemSdkError.UserCancelled) { - store.dispatch(WalletAction.ScanCardFinished(result.error)) - if (store.state.walletState.scanCardFailsCounter >= 2) { - store.dispatch(WalletAction.ShowDialog.ScanFails) - } - } + globalState?.tapWalletManager?.onCardScanned(result.data, true) } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index f70ba93b11..da5b7d515e 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -246,13 +246,6 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) newState = newState.copy(wallets = wallets) } - is WalletAction.ScanCardFinished -> { - newState = if (action.scanError == null) { - newState.copy(scanCardFailsCounter = 0) - } else { - newState.copy(scanCardFailsCounter = newState.scanCardFailsCounter + 1) - } - } } return newState } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 0cfff7bb46..6517bd7c11 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -11,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater import com.tangem.blockchain.common.Blockchain import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.redux.WalletAction @@ -249,7 +250,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS } } - private fun handleDialogs(walletDialog: WalletDialog?) { + private fun handleDialogs(walletDialog: StateDialog?) { when (walletDialog) { is WalletDialog.SelectAmountToSendDialog -> { if (dialog == null) dialog = AmountToSendDialog(requireContext()).apply { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt index 9a8ff9ace5..b3f63a0236 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.appcompat.app.AlertDialog import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.feedback.ScanFailsEmail +import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store import com.tangem.wallet.R @@ -22,7 +23,10 @@ class ScanFailsDialog { store.dispatch(GlobalAction.SendFeedback(ScanFailsEmail())) } setNegativeButton(R.string.common_cancel) { _, _ -> } - setOnDismissListener { store.dispatch(WalletAction.HideDialog) } + setOnDismissListener { + store.dispatch(HomeAction.HideDialog) + store.dispatch(WalletAction.HideDialog) + } }.create() } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt index 51f47fc82d..9e2320d30c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt @@ -4,6 +4,7 @@ import android.app.Dialog import androidx.recyclerview.widget.LinearLayoutManager import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.tokens.redux.TokensAction @@ -112,7 +113,7 @@ class MultiWalletView : WalletView { } private fun showErrorState( - fragment: WalletFragment, errorTitle: CharSequence, errorDescription: CharSequence + fragment: WalletFragment, errorTitle: CharSequence, errorDescription: CharSequence, ) { fragment.l_card_balance.show() fragment.l_balance.hide() @@ -131,14 +132,12 @@ class MultiWalletView : WalletView { fragment.btn_confirm_long.text = fragment.getText(R.string.wallet_button_create_wallet) } - private fun handleDialogs(walletDialog: WalletDialog?) { + private fun handleDialogs(walletDialog: StateDialog?) { val fragment = fragment ?: return val context = fragment.context ?: return when (walletDialog) { is WalletDialog.ScanFailsDialog -> { - if (dialog == null) dialog = ScanFailsDialog.create(context).apply { - this.show() - } + if (dialog == null) dialog = ScanFailsDialog.create(context).apply { show() } } else -> { dialog?.dismiss() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index c513331351..e7ff1e5db0 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -6,6 +6,7 @@ import android.view.ViewGroup import android.widget.Button import androidx.recyclerview.widget.LinearLayoutManager import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.twins.TwinCardNumber @@ -161,7 +162,7 @@ class SingleWalletView : WalletView { } private fun setupConfirmButton( - state: WalletData, btnConfirm: Button, fragment: WalletFragment, isTwinsWallet: Boolean + state: WalletData, btnConfirm: Button, fragment: WalletFragment, isTwinsWallet: Boolean, ) { val buttonTitle = when (state.mainButton) { is WalletMainButton.SendButton -> R.string.wallet_button_send @@ -215,7 +216,7 @@ class SingleWalletView : WalletView { } } - private fun handleDialogs(walletDialog: WalletDialog?) { + private fun handleDialogs(walletDialog: StateDialog?) { val fragment = fragment ?: return val context = fragment.context ?: return when (walletDialog) { @@ -234,9 +235,7 @@ class SingleWalletView : WalletView { } } is WalletDialog.ScanFailsDialog -> { - if (dialog == null) dialog = ScanFailsDialog.create(context).apply { - this.show() - } + if (dialog == null) dialog = ScanFailsDialog.create(context).apply { show() } } null -> { dialog?.dismiss() From a9d09cd5d534761d837ae97d3a541cd7c4b39b44 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 12:42:36 +0300 Subject: [PATCH 11/37] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/common/extensions/Token.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Token.kt b/app/src/main/java/com/tangem/tap/common/extensions/Token.kt index f9499f8e70..fdfb83ef77 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Token.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Token.kt @@ -3,9 +3,14 @@ package com.tangem.tap.common.extensions import androidx.annotation.ColorInt import androidx.core.graphics.toColorInt import com.tangem.blockchain.common.Token +import com.tangem.wallet.R @ColorInt fun Token.getColor(): Int { - return ("#" + this.contractAddress.subSequence(2..7).toString()) - .toColorInt() + return try { + ("#" + this.contractAddress.subSequence(2..7).toString()) + .toColorInt() + } catch (exception: Exception) { + R.color.lightGray4 + } } \ No newline at end of file From cb4aeda9fa9852c6d682819db1c13cee6338ad73 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 12:43:35 +0300 Subject: [PATCH 12/37] Updated on 2026-08-14 --- app/src/main/res/layout/fragment_details.xml | 42 -------------------- 1 file changed, 42 deletions(-) diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index b45e3e92ce..00c0626cba 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -258,48 +258,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_security_title" /> - - - - - - - - - - From 1b6a250e6101b579532427afa0189ef7ed130707 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 12:44:10 +0300 Subject: [PATCH 13/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 58c711eb31..98ed954d8b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.158.0' + implementation 'com.tangem:blockchain:1.159.0' implementation 'com.tangem:core:1.108.0' implementation 'com.tangem:sdk:1.108.0' From 8bf843bbbae524bfe39618a18dc43789ecc5b25c Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 14:31:47 +0300 Subject: [PATCH 14/37] Updated on 2026-08-14 --- .../wallet/redux/middlewares/MultiWalletMiddleware.kt | 1 + .../features/wallet/redux/middlewares/WalletMiddleware.kt | 4 ++-- .../tap/features/wallet/redux/reducers/WalletReducer.kt | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index 4f28ce1f3f..884616d714 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -41,6 +41,7 @@ class MultiWalletMiddleware { currenciesRepository.saveAddedBlockchain(it, action.blockchain) } store.dispatch(WalletAction.LoadFiatRate(currency = action.blockchain.currency)) + store.dispatch(WalletAction.LoadWallet(currency = action.blockchain.currency)) } is WalletAction.MultiWallet.RemoveWallet -> { val cardId = globalState?.scanNoteResponse?.card?.cardId diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 6d27122a01..05993a08ef 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -207,7 +207,7 @@ class WalletMiddleware { val amountToSend = amounts?.find { it.currencySymbol == currency } ?: return WalletAction.Send.ChooseCurrency(amounts) if (amountToSend.type is AmountType.Token) { - prepareSendActionForToken(amount, state, selectedWalletData, wallet, walletManager) + prepareSendActionForToken(amountToSend, state, selectedWalletData, wallet, walletManager) } else { PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager) } @@ -223,7 +223,7 @@ class WalletMiddleware { } private fun prepareSendActionForToken( - amount: Amount?, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?, + amount: Amount, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?, walletManager: WalletManager? ): PrepareSendScreen { val coinRate = state?.getWalletData(wallet?.blockchain?.currency)?.fiatRate diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index da5b7d515e..59e50c8820 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -135,15 +135,14 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) ) val wallets = newState.replaceWalletInWallets(walletData) - val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { + val progressState = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { ProgressState.Loading } else { ProgressState.Done } newState = newState.copy( - state = state, + state = progressState, wallets = wallets - ) } is WalletAction.LoadWallet.Failure -> { From cb37988cda2acc2413299d0b79ce1f5aada01daa Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 14:39:37 +0300 Subject: [PATCH 15/37] Updated on 2026-08-14 --- .../com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 6517bd7c11..8913acc643 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -179,7 +179,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS state.walletAddresses.selectedAddress.exploreUrl, requireContext())) } - iv_qr_code.setImageBitmap(state.walletAddresses.selectedAddress.address.toQrCode()) + iv_qr_code.setImageBitmap(state.walletAddresses.selectedAddress.shareUrl.toQrCode()) } } From a1d81d9197a1b7dee9dff103b6212d6092fff2c2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 2 Apr 2021 15:41:54 +0300 Subject: [PATCH 16/37] Updated on 2026-08-14 --- .../wallet/ui/adapters/WalletAdapter.kt | 11 ++++---- .../main/res/layout/item_currency_wallet.xml | 25 ++++++++++++++++--- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index f8c337d1f1..73083d0e58 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -8,7 +8,9 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token -import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.extensions.getColor +import com.tangem.tap.common.extensions.getIconRes +import com.tangem.tap.common.extensions.show import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.ui.BalanceStatus @@ -80,11 +82,8 @@ class WalletAdapter fun bind(wallet: WalletData) { view.tv_currency.text = wallet.currencyData.currency - view.tv_amount.text = wallet.currencyData.amount - if (view.tv_amount.isEllipsized()) { - val allowedSize = view.tv_amount.text.length - 4 - view.tv_amount.text = wallet.currencyData.amount?.ellipsizeBeforeSpace(allowedSize) - } + view.tv_amount.text = wallet.currencyData.amount?.takeWhile { !it.isWhitespace() } + view.tv_currency_symbol.text = wallet.currencyData.amount?.takeLastWhile { !it.isWhitespace() } view.tv_amount_fiat.text = wallet.currencyData.fiatAmount view.tv_exchange_rate.text = wallet.fiatRateString view.card_wallet.setOnClickListener { diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index 576619305c..d4a2a6dfd2 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -108,17 +108,34 @@ android:ellipsize="end" android:gravity="end" android:maxLines="1" - android:paddingStart="2dp" - android:paddingEnd="16dp" + android:layout_marginStart="2dp" + android:layout_marginTop="16dp" + android:textColor="@color/darkGray6" + android:textSize="17sp" + android:textStyle="bold" + app:layout_constraintEnd_toStartOf="@id/tv_currency_symbol" + app:layout_constraintHorizontal_weight="1" + app:layout_constraintStart_toEndOf="@id/tv_currency" + app:layout_constraintTop_toTopOf="parent" + tools:text="3 588" /> + + + tools:text="BTC" /> Date: Fri, 2 Apr 2021 16:11:45 +0300 Subject: [PATCH 17/37] Updated on 2026-08-14 --- .../tap/features/send/redux/middlewares/SendMiddleware.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index b24e7916db..997a470724 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -120,6 +120,9 @@ private fun sendTransaction( dispatch(GlobalAction.UpdateWalletSignedHashes(result.data.walletSignedHashes)) dispatch(NavigationAction.PopBackTo()) scope.launch(Dispatchers.IO) { + withContext(Dispatchers.Main) { + dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain.currency)) + } delay(10000) withContext(Dispatchers.Main) { dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain.currency)) From ec3fb18686cbcbc246d7c6dd7228f114a12f4bb5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 4 Apr 2021 23:59:35 +0300 Subject: [PATCH 18/37] Updated on 2026-08-14 --- .../com/tangem/tap/features/feedback/FeedbackManager.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index 3a57a3a211..93ab57812e 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -17,6 +17,8 @@ import timber.log.Timber import java.io.File import java.io.FileWriter import java.io.StringWriter +import java.text.SimpleDateFormat +import java.util.* /** @@ -96,10 +98,12 @@ class FeedbackManager( } class TangemLogCollector : TangemSdkLogger { + private val dateFormatter = SimpleDateFormat("HH:mm:ss.SSS") private val logs = mutableListOf() override fun log(message: () -> String, level: Log.Level) { - logs.add(message()) + val time = dateFormatter.format(Date()) + logs.add("$time: ${message()}\n") } fun getLogs(): List = logs.toList() From 5de5ca1eb29dda501895f6ab824a34aeb720bf6e Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 5 Apr 2021 20:29:19 +0300 Subject: [PATCH 19/37] Updated on 2026-08-14 --- .../java/com/tangem/tap/persistence/PreferencesStorage.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt index 9d45dd8c36..34b0886634 100644 --- a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt @@ -122,7 +122,10 @@ class AppRatingLaunchObserver( if (fundsFoundDate != null) return fundsFoundDate = Calendar.getInstance() - preferences.edit().putLong(K_FUNDS_FOUND_DATE, fundsFoundDate!!.timeInMillis).apply() + preferences.edit(true) { + putLong(K_FUNDS_FOUND_DATE, fundsFoundDate!!.timeInMillis).apply() + putInt(K_SHOW_RATING_AT_LAUNCH_COUNT, launchCounts + firstShowing) + } } fun isReadyToShow(): Boolean { From ca9e033f4f20dbbf56e7c9c3a4ad2e359978add9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 5 Apr 2021 21:22:33 +0300 Subject: [PATCH 20/37] Updated on 2026-08-14 --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 98ed954d8b..0531b05353 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,9 +76,9 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.159.0' - implementation 'com.tangem:core:1.108.0' - implementation 'com.tangem:sdk:1.108.0' + implementation 'com.tangem:blockchain:1.162.0' + implementation 'com.tangem:core:1.109.0' + implementation 'com.tangem:sdk:1.109.0' // WebView implementation "androidx.browser:browser:1.3.0" From 8585e32ce0a3e504c1d09aee2848c68f3c1764f5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 5 Apr 2021 21:33:14 +0300 Subject: [PATCH 21/37] Updated on 2026-08-14 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4dc0d14356..3b07b1a1ac 100644 --- a/build.gradle +++ b/build.gradle @@ -31,14 +31,14 @@ allprojects { username = nexusUser password = nexusPass } - url "https://nexus.tangem.com/repository/maven-releases/" + url "https://nexus.tangem-tech.com/repository/maven-releases/" } maven { credentials { username = nexusUser password = nexusPass } - url "https://nexus.tangem.com/repository/maven-snapshots/" + url "https://nexus.tangem-tech.com/repository/maven-snapshots/" } maven { url 'https://jitpack.io' } } From 7b8f87c255593d5dd53dc4fc1222618ca68d3312 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Apr 2021 12:02:20 +0300 Subject: [PATCH 22/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- .../com/tangem/tap/domain/TapWalletManager.kt | 5 +- .../redux/reducers/OnWalletLoadedReducer.kt | 171 +++++++----------- 3 files changed, 73 insertions(+), 105 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0531b05353..28e3fcaff0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.162.0' + implementation 'com.tangem:blockchain:1.163.0' implementation 'com.tangem:core:1.109.0' implementation 'com.tangem:sdk:1.109.0' diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 38fe7aec61..b471168b8b 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,6 +1,7 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.* +import com.tangem.blockchain.extensions.getBlockchain import com.tangem.commands.common.card.CardStatus import com.tangem.commands.common.network.Result import com.tangem.tap.common.analytics.AnalyticsEvent @@ -168,9 +169,9 @@ class TapWalletManager { .mapNotNull { walletManagerFactory.makeWalletManager(data.card, it) } val otherBlockhains = savedCurrencies.blockchains - val activeTokens = walletManagers.first { it.wallet.blockchain == Blockchain.Ethereum } + val presetTokens = walletManagers.first { it.wallet.blockchain == data.card.getBlockchain() } .presetTokens.toList() - val tokens = activeTokens + savedCurrencies.tokens + val tokens = presetTokens + savedCurrencies.tokens store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers)) store.dispatch(WalletAction.MultiWallet.AddBlockchains(primaryBlockchain + otherBlockhains)) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 6941106a0c..24fb8d843a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.wallet.redux.reducers import com.tangem.blockchain.common.AmountType -import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Wallet import com.tangem.common.extensions.isZero import com.tangem.tap.common.extensions.toFiatString @@ -21,112 +20,80 @@ import com.tangem.tap.store import java.math.RoundingMode class OnWalletLoadedReducer { + fun reduce(wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null): WalletState { - if (!walletState.isMultiwalletAllowed) { - return onSingleWalletLoaded(wallet, walletState, topUpAllowed) + return if (!walletState.isMultiwalletAllowed) { + onSingleWalletLoaded(wallet, walletState, topUpAllowed) } else { - val fiatCurrencySymbol = store.state.globalState.appCurrency - val amount = wallet.amounts[AmountType.Coin]?.value - if (walletState.getWalletData(wallet.blockchain.currency) == null) { - return walletState - } - if (wallet.blockchain != Blockchain.Ethereum) { - val formattedAmount = amount?.toFormattedCurrencyString( - wallet.blockchain.decimals(), - wallet.blockchain.currency) - - val pendingTransactions = wallet.recentTransactions - .toPendingTransactions(wallet.address) - - val sendButtonEnabled = amount?.isZero() == false && pendingTransactions.isEmpty() - val balanceStatus = if (pendingTransactions.isNotEmpty()) { - BalanceStatus.TransactionInProgress - } else { - BalanceStatus.VerifiedOnline - } - val walletData = walletState.getWalletData(wallet.blockchain.currency) - ?: WalletData() - val newWalletData = walletData.copy( - currencyData = walletData.currencyData.copy( - status = balanceStatus, currency = wallet.blockchain.fullName, - currencySymbol = wallet.blockchain.currency, - amount = formattedAmount, - fiatAmount = walletData.fiatRate?.let { amount?.toFiatString(it, fiatCurrencySymbol) } - ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(sendButtonEnabled) - ) - val wallets = walletState.replaceWalletInWallets(newWalletData) - val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { - ProgressState.Loading - } else { - ProgressState.Done - } - return walletState.copy( - state = state, wallets = wallets - ) - } else { - val formattedAmount = amount?.toFormattedCurrencyString( - wallet.blockchain.decimals(), - wallet.blockchain.currency) - - val pendingTransactions = wallet.recentTransactions - .toPendingTransactions(wallet.address) - - val sendButtonEnabled = amount?.isZero() == false && pendingTransactions.isEmpty() - val balanceStatus = if (pendingTransactions.isNotEmpty()) { - BalanceStatus.TransactionInProgress - } else { - BalanceStatus.VerifiedOnline - } - - val ethereumWalletData = walletState.getWalletData(wallet.blockchain.currency) - ?: WalletData() - val newEthereumWalletData = ethereumWalletData.copy( - currencyData = ethereumWalletData.currencyData.copy( - status = balanceStatus, - amount = formattedAmount, - currency = wallet.blockchain.fullName, - currencySymbol = wallet.blockchain.currency, - fiatAmount = ethereumWalletData.fiatRate?.let { - amount?.toFiatString(it, fiatCurrencySymbol) - } - ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(sendButtonEnabled) - ) - - val tokens = wallet.getTokens().mapNotNull { token -> - val tokenWalletData = walletState.getWalletData(token.symbol) - tokenWalletData?.copy( - currencyData = tokenWalletData.currencyData.copy( - status = balanceStatus, - amount = wallet.getTokenAmount(token)?.value?.toFormattedCurrencyString( - token.decimals, token.symbol - ), - fiatAmount = tokenWalletData.fiatRate?.let { - wallet.getTokenAmount(token)?.value - ?.toFiatString(it, fiatCurrencySymbol) - } - ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(sendButtonEnabled) - ) - } - val wallets = walletState.replaceSomeWallets((tokens + newEthereumWalletData).filterNotNull()) - val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { - ProgressState.Loading - } else { - ProgressState.Done - } - return walletState.copy( - state = state, wallets = wallets - ) - } + onMultiWalletLoaded(wallet, walletState, topUpAllowed) } } - private fun onSingleWalletLoaded(wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null + private fun onMultiWalletLoaded( + wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null + ): WalletState { + val fiatCurrencySymbol = store.state.globalState.appCurrency + val amount = wallet.amounts[AmountType.Coin]?.value + if (walletState.getWalletData(wallet.blockchain.currency) == null) { + return walletState + } + val formattedAmount = amount?.toFormattedCurrencyString( + wallet.blockchain.decimals(), + wallet.blockchain.currency) + + val pendingTransactions = wallet.recentTransactions + .toPendingTransactions(wallet.address) + + val sendButtonEnabled = amount?.isZero() == false && pendingTransactions.isEmpty() + val balanceStatus = if (pendingTransactions.isNotEmpty()) { + BalanceStatus.TransactionInProgress + } else { + BalanceStatus.VerifiedOnline + } + val walletData = walletState.getWalletData(wallet.blockchain.currency) + ?: WalletData() + val newWalletData = walletData.copy( + currencyData = walletData.currencyData.copy( + status = balanceStatus, currency = wallet.blockchain.fullName, + currencySymbol = wallet.blockchain.currency, + amount = formattedAmount, + fiatAmount = walletData.fiatRate?.let { amount?.toFiatString(it, fiatCurrencySymbol) } + ), + pendingTransactions = pendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(sendButtonEnabled) + ) + + val tokens = wallet.getTokens().mapNotNull { token -> + val tokenWalletData = walletState.getWalletData(token.symbol) + tokenWalletData?.copy( + currencyData = tokenWalletData.currencyData.copy( + status = balanceStatus, + amount = wallet.getTokenAmount(token)?.value?.toFormattedCurrencyString( + token.decimals, token.symbol + ), + fiatAmount = tokenWalletData.fiatRate?.let { + wallet.getTokenAmount(token)?.value + ?.toFiatString(it, fiatCurrencySymbol) + } + ), + pendingTransactions = pendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(sendButtonEnabled) + ) + } + val wallets = walletState.replaceSomeWallets((tokens + newWalletData)) + + val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { + ProgressState.Loading + } else { + ProgressState.Done + } + return walletState.copy( + state = state, wallets = wallets + ) + } + + private fun onSingleWalletLoaded( + wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null ): WalletState { if (wallet.blockchain != walletState.primaryBlockchain) return walletState From 8de37a6cd5e9a14b8c268918ad1ec72e2fdc90d4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Apr 2021 13:47:56 +0300 Subject: [PATCH 23/37] Updated on 2026-08-14 --- .../features/wallet/redux/middlewares/WarningsMiddleware.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index 347dce4c7f..a64f722056 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -32,8 +32,9 @@ class WarningsMiddleware { val validator = globalState?.scanNoteResponse?.walletManager as? SignatureCountValidator globalState?.scanNoteResponse?.card?.let { card -> globalState.warningManager?.removeWarnings(WarningMessage.Origin.Local) - if (card.getType() != CardType.Release) addWarningMessage(WarningMessagesManager.devCardWarning()) - if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { + if (card.getType() != CardType.Release) { + addWarningMessage(WarningMessagesManager.devCardWarning()) + } else if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { checkIfWarningNeeded(card, validator)?.let { addWarningMessage(it) } } updateWarningMessages() From 2b354a9a4e4d0b4b5e9030d4a2670af10d15b160 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Apr 2021 17:51:56 +0300 Subject: [PATCH 24/37] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/persistence/PreferencesStorage.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt index 34b0886634..1f85e4d251 100644 --- a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt @@ -134,7 +134,7 @@ class AppRatingLaunchObserver( if (!userWasInteractWithRating()) { val diff = Calendar.getInstance().timeInMillis - fundsDate.timeInMillis val diffInDays = diff / (100 * 60 * 60 * 24) - if (diffInDays >= firstShowing) return true + return launchCounts >= firstShowing && diffInDays >= firstShowing } val nextShowing = getCounterOfNextShowing() From a28c0c925f50224af9855fdb5765053c264291a8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Apr 2021 18:01:05 +0300 Subject: [PATCH 25/37] Updated on 2026-08-14 --- .../warningMessage/WarningMessagesManager.kt | 12 +++++++ .../redux/middlewares/WarningsMiddleware.kt | 31 +++++++++++++------ .../main/res/values/strings_untranslated.xml | 2 ++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt index 1ee151033f..391bbc9b13 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt @@ -117,5 +117,17 @@ class WarningMessagesManager( fun isAlreadySignedHashesWarning(warning: WarningMessage): Boolean { return warning.messageResId == R.string.alert_card_signed_transactions } + + fun onlineVerificationFailed(): WarningMessage = WarningMessage( + "", + "", + type = WarningMessage.Type.Permanent, + priority = WarningMessage.Priority.Critical, + listOf(WarningMessage.Location.MainScreen), + null, + R.string.warning_failed_to_verify_card_title, + R.string.warning_failed_to_verify_card_message, + WarningMessage.Origin.Local + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index a64f722056..ad2c009c9c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.extensions.SimpleResult import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.CardType +import com.tangem.commands.verifycard.VerifyCardState import com.tangem.common.extensions.getType import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler @@ -29,16 +30,7 @@ class WarningsMiddleware { fun handle(action: WalletAction.Warnings, globalState: GlobalState?) { when (action) { is WalletAction.Warnings.CheckIfNeeded -> { - val validator = globalState?.scanNoteResponse?.walletManager as? SignatureCountValidator - globalState?.scanNoteResponse?.card?.let { card -> - globalState.warningManager?.removeWarnings(WarningMessage.Origin.Local) - if (card.getType() != CardType.Release) { - addWarningMessage(WarningMessagesManager.devCardWarning()) - } else if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { - checkIfWarningNeeded(card, validator)?.let { addWarningMessage(it) } - } - updateWarningMessages() - } + showCardWarningsIfNeeded(globalState) val readyToShow = preferencesStorage.appRatingLaunchObserver.isReadyToShow() if (readyToShow) addWarningMessage(WarningMessagesManager.appRatingWarning(), true) } @@ -69,6 +61,25 @@ class WarningsMiddleware { } } + private fun showCardWarningsIfNeeded(globalState: GlobalState?) { + val validator = globalState?.scanNoteResponse?.walletManager as? SignatureCountValidator + globalState?.scanNoteResponse?.card?.let { card -> + globalState.warningManager?.removeWarnings(WarningMessage.Origin.Local) + if (card.getType() != CardType.Release) { + addWarningMessage(WarningMessagesManager.devCardWarning()) + } else if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { + checkIfWarningNeeded(card, validator)?.let { addWarningMessage(it) } + } + if (card.getType() == CardType.Release) { + if (globalState.scanNoteResponse.verifyResponse?.verificationState == + VerifyCardState.VerifiedOffline) { + addWarningMessage(WarningMessagesManager.onlineVerificationFailed()) + } + } + updateWarningMessages() + } + } + private fun checkIfWarningNeeded( card: Card, signatureCountValidator: SignatureCountValidator? = null, ): WarningMessage? { diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 3e6b22d9c1..860b985336 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -99,6 +99,8 @@ this wallet. + Add tokens + Authenticity check failed + This card might be a production sample or counterfeit From 97d75a71a5b83b4d09728014a8b32421d76e9c10 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 7 Apr 2021 11:28:21 +0300 Subject: [PATCH 26/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 28e3fcaff0..75ca19087f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.163.0' + implementation 'com.tangem:blockchain:1.164.0' implementation 'com.tangem:core:1.109.0' implementation 'com.tangem:sdk:1.109.0' From 9abf64d69ae27f2d431259d5c7edc67efb4fa420 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 7 Apr 2021 15:46:24 +0300 Subject: [PATCH 27/37] Updated on 2026-08-14 --- .../java/com/tangem/tap/persistence/PreferencesStorage.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt index 1f85e4d251..871e3eb3d5 100644 --- a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt @@ -133,8 +133,8 @@ class AppRatingLaunchObserver( if (!userWasInteractWithRating()) { val diff = Calendar.getInstance().timeInMillis - fundsDate.timeInMillis - val diffInDays = diff / (100 * 60 * 60 * 24) - return launchCounts >= firstShowing && diffInDays >= firstShowing + val diffInDays = diff / (1000 * 60 * 60 * 24) + return launchCounts >= getCounterOfNextShowing() && diffInDays >= firstShowing } val nextShowing = getCounterOfNextShowing() From b578df9cc726c1a9dfefdd2b04c3340c5f35117d Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 7 Apr 2021 17:05:08 +0300 Subject: [PATCH 28/37] Updated on 2026-08-14 --- .../wallet/redux/middlewares/MultiWalletMiddleware.kt | 5 +---- .../tap/features/wallet/redux/reducers/MultiWalletReducer.kt | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index 884616d714..cb0d307ac5 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -54,7 +54,6 @@ class MultiWalletMiddleware { is WalletAction.MultiWallet.FindTokensInUse -> { val walletManager = walletState?.getWalletManager(Blockchain.Ethereum.currency) ?: return - val alreadyAddedTokens = walletManager.presetTokens val tokenFinder = walletManager as TokenFinder scope.launch { val result = tokenFinder.findTokens() @@ -63,9 +62,7 @@ class MultiWalletMiddleware { is Result.Success -> { if (result.data.isNotEmpty()) { store.dispatch(WalletAction.MultiWallet.AddTokens( - walletManager.presetTokens - .filterNot { presetToken -> alreadyAddedTokens.any { it.symbol == presetToken.symbol } } - .toList() + walletManager.presetTokens.toList() )) } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index 0ce62a948d..490ac752d7 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -90,7 +90,7 @@ class MultiWalletReducer { token = token ) } - state.copy(wallets = state.wallets + wallets) + state.copy(wallets = state.replaceSomeWallets(wallets)) } is WalletAction.MultiWallet.AddToken -> { if (!state.isMultiwalletAllowed) return state From a6618b4d35806d432c13b11e4c7cbdd384fefb99 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 7 Apr 2021 19:30:14 +0300 Subject: [PATCH 29/37] Updated on 2026-08-14 --- .../java/com/tangem/tap/TapApplication.kt | 2 +- .../com/tangem/tap/domain/TapWalletManager.kt | 15 +-- .../tap/features/feedback/FeedbackManager.kt | 118 ++++++++++++++---- .../send/redux/middlewares/SendMiddleware.kt | 28 +---- .../middlewares/MultiWalletMiddleware.kt | 6 +- 5 files changed, 102 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 286c39df5e..e458fd4e04 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -69,7 +69,7 @@ class TapApplication : Application() { private fun initFeedbackManager() { val infoHolder = AdditionalEmailInfo() - infoHolder.updateAppVersion(this) + infoHolder.setAppVersion(this) val logWriter = TangemLogCollector() Log.addLogger(logWriter) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index b471168b8b..adee9c07c7 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -85,9 +85,9 @@ class TapWalletManager { FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) } TapWorkarounds.updateCard(data.card) + store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card) store.state.globalState.warningManager?.setBlockchain(data.walletManager?.wallet?.blockchain) updateConfigManager(data) - updateFeedbackManager(data) withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) @@ -125,19 +125,6 @@ class TapWalletManager { } } - private fun updateFeedbackManager(data: ScanNoteResponse) { - val card = data.card - val wallet = data.walletManager?.wallet ?: return - val infoHolder = store.state.globalState.feedbackManager?.infoHolder ?: return - - infoHolder.cardId = card.cardId - infoHolder.cardFirmwareVersion = card.firmwareVersion.version - infoHolder.signedHashesCount = card.walletSignedHashes?.toString() ?: "0" - infoHolder.sourceAddress = wallet.address - infoHolder.explorerLink = wallet.getExploreUrl(wallet.address) - infoHolder.blockchain = wallet.blockchain - } - suspend fun loadData(data: ScanNoteResponse) { withContext(Dispatchers.Main) { store.dispatch(WalletAction.Warnings.CheckIfNeeded) diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index 93ab57812e..cbd536c464 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -12,7 +12,13 @@ import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import com.tangem.Log import com.tangem.TangemSdkLogger +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.Wallet +import com.tangem.commands.common.card.Card +import com.tangem.tap.common.extensions.stripZeroPlainString +import com.tangem.tap.store import timber.log.Timber import java.io.File import java.io.FileWriter @@ -114,26 +120,36 @@ class TangemLogCollector : TangemSdkLogger { } class AdditionalEmailInfo { - var cardId: String = "" - var cardFirmwareVersion: String = "" - var blockchain: Blockchain = Blockchain.Unknown + class EmailWalletInfo( + var blockchain: Blockchain = Blockchain.Unknown, + var address: String = "", + var explorerLink: String = "", + // var outputsCount: String = "" + // var transactionHex: String = "" + ) - var phoneModel: String = Build.MODEL - var osVersion: String = Build.VERSION.SDK_INT.toString() var appVersion: String = "" - var token: String = "" - var sourceAddress: String = "" + // card + var cardId: String = "" + var cardFirmwareVersion: String = "" + + // wallets + internal val walletsInfo = mutableListOf() + internal var onSendErrorWalletInfo: EmailWalletInfo? = null + var signedHashesCount: String = "" + + // device + var phoneModel: String = Build.MODEL + var osVersion: String = Build.VERSION.SDK_INT.toString() + + // send error var destinationAddress: String = "" var amount: String = "" var fee: String = "" + var token: String = "" - // var transactionHex: String = "" - var signedHashesCount: String = "" - var explorerLink: String = "" -// var outputsCount: String = "" - - fun updateAppVersion(context: Context) { + fun setAppVersion(context: Context) { try { val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) appVersion = pInfo.versionName @@ -141,6 +157,51 @@ class AdditionalEmailInfo { e.printStackTrace() } } + + fun setCardInfo(card: Card) { + cardId = card.cardId + cardFirmwareVersion = card.firmwareVersion.version + signedHashesCount = card.walletSignedHashes?.toString() ?: "0" + } + + fun setWalletsInfo(wallets: List) { + walletsInfo.clear() + wallets.forEach { walletsInfo.add(EmailWalletInfo(it.blockchain, getAddress(it), getExploreUri(it))) } + } + + fun updateOnSendError(wallet: Wallet, amountToSend: Amount, feeAmount: Amount, destinationAddress: String) { + val amountState = store.state.sendState.amountState + onSendErrorWalletInfo = EmailWalletInfo(wallet.blockchain, getAddress(wallet), getExploreUri(wallet)) + + this.destinationAddress = destinationAddress + amount = amountToSend.value?.stripZeroPlainString() ?: "0" + fee = feeAmount.value?.stripZeroPlainString() ?: "0" + if (amountState.typeOfAmount is AmountType.Token) { + token = amountState.amountToExtract?.currencySymbol ?: "" + } + } + + private fun getAddress(wallet: Wallet): String { + return if (wallet.addresses.size == 1) { + wallet.address + } else { + val addresses = wallet.addresses.joinToString(", ") { + "${it.type.javaClass.simpleName} - ${it.value}" + } + "Multiple address: $addresses" + } + } + + private fun getExploreUri(wallet: Wallet): String { + return if (wallet.addresses.size == 1) { + wallet.getExploreUrl(wallet.address) + } else { + val links = wallet.addresses.joinToString(", ") { + "${it.type.javaClass.simpleName} - ${wallet.getExploreUrl(it.value)}" + } + "Multiple explorers links: $links" + } + } } interface EmailData { @@ -160,9 +221,10 @@ class RateCanBeBetterEmail : EmailData { override val mainMessage: String = "Tell us what functions you are missing, and we will try to help you." override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String { + val walletInfo = infoHolder.walletsInfo[0] return StringBuilder().apply { appendKeyValue("Card ID", infoHolder.cardId) - appendKeyValue("Blockchain", infoHolder.blockchain.fullName) + appendKeyValue("Blockchain", walletInfo.blockchain.fullName) appendKeyValue("Phone model", infoHolder.phoneModel) appendKeyValue("OS version", infoHolder.osVersion) appendKeyValue("App version", infoHolder.appVersion) @@ -186,12 +248,13 @@ class SendTransactionFailedEmail(private val error: String) : EmailData { override val subject: String = "Can’t send a transaction" override val mainMessage: String = "Please tell us more about your issue. Every small detail can help." override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String { + val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalEmailInfo.EmailWalletInfo() return StringBuilder().apply { appendKeyValue("Error", error) appendKeyValue("Card ID", infoHolder.cardId) - appendKeyValue("Blockchain", infoHolder.blockchain.fullName) + appendKeyValue("Blockchain", walletInfo.blockchain.fullName) appendKeyValue("Token", infoHolder.token) - appendKeyValue("Source address", infoHolder.sourceAddress) + appendKeyValue("Source address", walletInfo.address) appendKeyValue("Destination address", infoHolder.destinationAddress) appendKeyValue("Amount", infoHolder.amount) appendKeyValue("Fee", infoHolder.fee) @@ -208,17 +271,20 @@ class FeedbackEmail : EmailData { override val subject: String = "Tangem Tap feedback" override val mainMessage: String = "Hi Tangem," override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String { - return StringBuilder().apply { - appendKeyValue("Card ID", infoHolder.cardId) - appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion) - appendKeyValue("Signed hashes", infoHolder.signedHashesCount) - appendKeyValue("Blockchain", infoHolder.blockchain.fullName) - appendKeyValue("Wallet address", infoHolder.sourceAddress) - appendKeyValue("Explorer link", infoHolder.explorerLink) + val builder = StringBuilder() + builder.appendKeyValue("Card ID", infoHolder.cardId) + builder.appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion) + builder.appendKeyValue("Signed hashes", infoHolder.signedHashesCount) + + infoHolder.walletsInfo.forEach { + builder.appendKeyValue("Blockchain", it.blockchain.fullName) + builder.appendKeyValue("Wallet address", it.address) + builder.appendKeyValue("Explorer link", it.explorerLink) + } // appendKeyValue("Outputs count", infoHolder.outputsCount) - appendKeyValue("Phone model", infoHolder.phoneModel) - appendKeyValue("OS version", infoHolder.osVersion) - }.toString() + builder.appendKeyValue("Phone model", infoHolder.phoneModel) + builder.appendKeyValue("OS version", infoHolder.osVersion) + return builder.toString() } } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index 997a470724..d1b7246ef2 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -145,10 +145,11 @@ private fun sendTransaction( is Throwable -> { val throwable = result.error as Throwable val message = throwable.message + val infoHolder = store.state.globalState.feedbackManager?.infoHolder when { message == null -> { dispatch(SendAction.SendError(TapError.UnknownError)) - updateFeedbackManager(walletManager, amountToSend, feeAmount, destinationAddress, card) + infoHolder?.updateOnSendError(walletManager.wallet, amountToSend, feeAmount, destinationAddress) dispatch(SendAction.Dialog.SendTransactionFails("unknown error")) } message.contains("50002") -> { @@ -163,7 +164,7 @@ private fun sendTransaction( Timber.e(throwable) FirebaseCrashlytics.getInstance().recordException(throwable) dispatch(SendAction.SendError(TapError.CustomError(message))) - updateFeedbackManager(walletManager, amountToSend, feeAmount, destinationAddress, card) + infoHolder?.updateOnSendError(walletManager.wallet, amountToSend, feeAmount, destinationAddress) dispatch(SendAction.Dialog.SendTransactionFails(message)) } } @@ -176,29 +177,6 @@ private fun sendTransaction( } } -private fun updateFeedbackManager( - walletManager: WalletManager, - amountToSend: Amount, - feeAmount: Amount, - destinationAddress: String, - card: Card, -) { - val infoHolder = store.state.globalState.feedbackManager?.infoHolder ?: return - val amountState = store.state.sendState.amountState - - infoHolder.cardId = card.cardId - infoHolder.blockchain = walletManager.wallet.blockchain - infoHolder.sourceAddress = walletManager.wallet.address - infoHolder.destinationAddress = destinationAddress - infoHolder.amount = amountToSend.value?.stripZeroPlainString() ?: "0" - infoHolder.fee = feeAmount.value?.stripZeroPlainString() ?: "0" - infoHolder.cardFirmwareVersion = card.firmwareVersion.version - if (amountState.typeOfAmount is AmountType.Token) { - infoHolder.token = amountState.amountToExtract?.currencySymbol ?: "" - } -// infoHolder.transactionHex = "" -} - fun extractErrorsForAmountField(errors: EnumSet): EnumSet { val showIntoAmountField = EnumSet.noneOf(TransactionError::class.java) errors.forEach { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index cb0d307ac5..69ff70c7bf 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -19,9 +19,13 @@ import kotlinx.coroutines.withContext class MultiWalletMiddleware { fun handle( - action: WalletAction.MultiWallet, walletState: WalletState?, globalState: GlobalState? + action: WalletAction.MultiWallet, walletState: WalletState?, globalState: GlobalState?, ) { when (action) { + is WalletAction.MultiWallet.AddWalletManagers -> { + val wallets = action.walletManagers.map { it.wallet } + store.state.globalState.feedbackManager?.infoHolder?.setWalletsInfo(wallets) + } is WalletAction.MultiWallet.SelectWallet -> { if (action.walletData != null) { store.dispatch(NavigationAction.NavigateTo(AppScreen.WalletDetails)) From 0331ab04cea47fa76a5bfcf413e0597efe2e0a67 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 8 Apr 2021 10:58:16 +0300 Subject: [PATCH 30/37] Updated on 2026-08-14 --- .../tap/features/wallet/redux/WalletState.kt | 11 +++++++++-- .../redux/middlewares/MultiWalletMiddleware.kt | 4 +--- .../wallet/redux/reducers/MultiWalletReducer.kt | 14 +++++++++----- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index a806c477b7..4bf58caa8c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -45,13 +45,20 @@ data class WalletState( fun getWalletManager(currencyName: CryptoCurrencyName?): WalletManager? { if (currencyName == null) return null val walletManager = walletManagers.find { it.wallet.blockchain.currency == currencyName } - if (walletManager != null) return walletManager + return walletManager ?: getWalletManagerForToken(currencyName) + } + fun getWalletManagerForToken(currencyName: CryptoCurrencyName?): WalletManager? { val ethereumWalletManager = walletManagers.find { it.wallet.blockchain == Blockchain.Ethereum } return if (ethereumWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) { ethereumWalletManager } else { - null + val primaryWalletManager = walletManagers.find { it.wallet.blockchain == primaryBlockchain } + if (primaryWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) { + primaryWalletManager + } else { + null + } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index cb0d307ac5..79c18e9c53 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -1,6 +1,5 @@ package com.tangem.tap.features.wallet.redux.middlewares -import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.TokenFinder @@ -74,8 +73,7 @@ class MultiWalletMiddleware { } private fun addToken(token: Token, walletState: WalletState?) { - val walletManager = - (walletState?.getWalletManager(Blockchain.Ethereum.currency) as? EthereumWalletManager) + val walletManager = walletState?.getWalletManager(token.symbol) scope.launch { val result = walletManager?.addToken(token) withContext(Dispatchers.Main) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index 490ac752d7..cb44136adf 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.wallet.redux.reducers import com.tangem.blockchain.common.AmountType -import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.isZero import com.tangem.tap.common.extensions.toFiatString import com.tangem.tap.common.extensions.toFormattedCurrencyString @@ -76,7 +75,6 @@ class MultiWalletReducer { } is WalletAction.MultiWallet.AddTokens -> { if (!state.isMultiwalletAllowed) return state - val walletAddresses = createAddressList(state.getWalletManager(Blockchain.Ethereum.currency)?.wallet) val wallets = action.tokens.map { token -> WalletData( currencyData = BalanceWidgetData( @@ -84,7 +82,9 @@ class MultiWalletReducer { currency = token.name, currencySymbol = token.symbol ), - walletAddresses = walletAddresses, + walletAddresses = createAddressList( + state.getWalletManagerForToken(token.symbol)?.wallet + ), mainButton = WalletMainButton.SendButton(false), topUpState = TopUpState(allowed = false), token = token @@ -94,7 +94,11 @@ class MultiWalletReducer { } is WalletAction.MultiWallet.AddToken -> { if (!state.isMultiwalletAllowed) return state - val walletAddresses = createAddressList(state.getWalletManager(Blockchain.Ethereum.currency)?.wallet) + + val walletAddresses = createAddressList( + state.getWalletManagerForToken(action.token.symbol)?.wallet + + ) val wallet = WalletData( currencyData = BalanceWidgetData( BalanceStatus.Loading, @@ -110,7 +114,7 @@ class MultiWalletReducer { state.copy(wallets = wallets) } is WalletAction.MultiWallet.TokenLoaded -> { - val pendingTransactions = state.getWalletManager(Blockchain.Ethereum.currency) + val pendingTransactions = state.getWalletManagerForToken(action.amount.currencySymbol) ?.wallet?.let { wallet -> wallet.recentTransactions.toPendingTransactions(wallet.address) } ?: emptyList() From 094064b92de66af38aed3dbe2c39d8e5c0a65921 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 8 Apr 2021 13:53:54 +0300 Subject: [PATCH 31/37] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 22 ++++++++++++++ .../com/tangem/tap/domain/TapWalletManager.kt | 8 ++--- .../redux/reducers/OnWalletLoadedReducer.kt | 4 +-- .../wallet/redux/reducers/WalletReducer.kt | 30 +++++++++++++++---- .../wallet/ui/WalletDetailsFragment.kt | 23 ++++++++++---- .../tap/features/wallet/ui/WalletFragment.kt | 19 ++++++------ 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 0b349f013a..78c6c7dbd6 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -6,7 +6,9 @@ import android.nfc.NfcAdapter import android.nfc.Tag import android.os.Bundle import android.util.Log +import android.view.View import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.snackbar.Snackbar import com.tangem.CardFilter import com.tangem.Config import com.tangem.TangemSdk @@ -52,6 +54,9 @@ private fun initCoroutineExceptionHandler(): CoroutineExceptionHandler { } class MainActivity : AppCompatActivity() { + + private var snackbar: Snackbar? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) @@ -104,4 +109,21 @@ class MainActivity : AppCompatActivity() { store.dispatch(NavigationAction.ActivityDestroyed) super.onDestroy() } + + fun showSnackbar(text: Int, buttonTitle: Int? = null, action: View.OnClickListener? = null) { + if (snackbar != null) return + + snackbar = Snackbar.make( + fragment_container, getString(text), Snackbar.LENGTH_INDEFINITE + ) + if (buttonTitle != null && action != null) { + snackbar?.setAction(getString(buttonTitle), action) + } + snackbar?.show() + } + + fun dismissSnackbar() { + snackbar?.dismiss() + snackbar = null + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index b471168b8b..3782d4a7fb 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -143,10 +143,6 @@ class TapWalletManager { store.dispatch(WalletAction.Warnings.CheckIfNeeded) val artworkId = data.verifyResponse?.artworkInfo?.id if (data.walletManager != null) { - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { - store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection)) - return@withContext - } val config = store.state.globalState.configManager?.config ?: return@withContext val primaryWalletManager = data.walletManager @@ -218,6 +214,10 @@ class TapWalletManager { when (result) { is Result.Success -> store.dispatch(WalletAction.LoadWallet.Success(result.data)) is Result.Failure -> { + if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection)) + return@withContext + } val error = result.error val blockchain = walletManager.wallet.blockchain if (error != null && blockchain.isNoAccountError(error)) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 24fb8d843a..1b3442c812 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -88,7 +88,7 @@ class OnWalletLoadedReducer { ProgressState.Done } return walletState.copy( - state = state, wallets = wallets + state = state, wallets = wallets, error = null ) } @@ -143,7 +143,7 @@ class OnWalletLoadedReducer { ) val wallets = walletData?.let { listOf(walletData) } ?: emptyList() return walletState.copy( - state = ProgressState.Done, wallets = wallets + state = ProgressState.Done, wallets = wallets, error = null ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index 59e50c8820..051594b368 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -57,9 +57,16 @@ private fun internalReduce(action: Action, state: AppState): WalletState { is WalletAction.LoadData.Failure -> { when (action.error) { is TapError.NoInternetConnection -> { + val wallets = newState.wallets + .map { + it.copy(currencyData = it.currencyData.copy( + status = BalanceStatus.Unreachable + )) + } newState = newState.copy( state = ProgressState.Error, error = ErrorType.NoInternetConnection, + wallets = wallets ) } is TapError.UnknownBlockchain -> { @@ -100,7 +107,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) } else { val walletManager = newState.getWalletManager(action.currency) ?: return newState - val currencies = listOf(walletManager.wallet.blockchain.currency + walletManager.presetTokens.map { it.symbol }) + val currencies = listOf(walletManager.wallet.blockchain.currency) + walletManager.presetTokens.map { it.symbol } val newWallets = newState.wallets.filter { currencies.contains(it.currencyData.currencySymbol) } .map { wallet -> wallet.copy( @@ -146,22 +153,35 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) } is WalletAction.LoadWallet.Failure -> { + val message = if (newState.error == ErrorType.NoInternetConnection) { + null + } else { + action.errorMessage + } val walletData = newState.getWalletData(action.wallet.blockchain.currency) val newWalletData = walletData?.copy( currencyData = walletData.currencyData.copy( status = BalanceStatus.Unreachable, - errorMessage = action.errorMessage + errorMessage = message ), topUpState = TopUpState(false) ) - val wallets = newState.replaceWalletInWallets(newWalletData) - val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { + val tokenWallets = action.wallet.getTokens() + .mapNotNull { newState.getWalletData(it.symbol) } + .map { + it.copy(currencyData = it.currencyData.copy( + status = BalanceStatus.Unreachable, errorMessage = message + )) + } + val wallets = newState.replaceSomeWallets(listOfNotNull(newWalletData) + tokenWallets) + + val progressState = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { ProgressState.Loading } else { ProgressState.Done } newState = newState.copy( - state = state, wallets = wallets + state = progressState, wallets = wallets ) } is WalletAction.SetArtworkId -> { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 8913acc643..3998eee99b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -10,22 +10,18 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater import com.tangem.blockchain.common.Blockchain +import com.tangem.tap.MainActivity import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.global.StateDialog import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.wallet.models.PendingTransaction -import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.WalletData -import com.tangem.tap.features.wallet.redux.WalletDialog -import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_details_twin_cards.* -import kotlinx.android.synthetic.main.fragment_wallet.* import kotlinx.android.synthetic.main.fragment_wallet_details.* -import kotlinx.android.synthetic.main.fragment_wallet_details.rv_pending_transaction import kotlinx.android.synthetic.main.fragment_wallet_details.toolbar import kotlinx.android.synthetic.main.item_currency_wallet.view.* import kotlinx.android.synthetic.main.layout_balance_error.* @@ -105,6 +101,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS showPendingTransactionsIfPresent(selectedWallet.pendingTransactions) setupAddressCard(selectedWallet) + setupNoInternetHandling(state) setupBalanceData(selectedWallet.currencyData) btn_confirm.isEnabled = selectedWallet.mainButton.enabled @@ -183,6 +180,20 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS } } + private fun setupNoInternetHandling(state: WalletState) { + if (state.state == ProgressState.Error) { + if (state.error == ErrorType.NoInternetConnection) { + srl_wallet_details?.isRefreshing = false + (activity as? MainActivity)?.showSnackbar( + text = R.string.wallet_notification_no_internet, + buttonTitle = R.string.common_retry + ) { store.dispatch(WalletAction.LoadData) } + } + } else { + (activity as? MainActivity)?.dismissSnackbar() + } + } + private fun setupBalanceData(data: BalanceWidgetData) { when (data.status) { BalanceStatus.Loading -> { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index ec1c7cdf74..580bb34141 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -12,9 +12,9 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionInflater -import com.google.android.material.snackbar.Snackbar import com.squareup.picasso.Picasso import com.tangem.tangem_sdk_new.extensions.dpToPx +import com.tangem.tap.MainActivity import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction @@ -30,13 +30,13 @@ import com.tangem.tap.features.wallet.ui.wallet.WalletView import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_wallet.* +import kotlinx.android.synthetic.main.fragment_wallet.toolbar +import kotlinx.android.synthetic.main.fragment_wallet_details.* import org.rekotlin.StoreSubscriber class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { - private var snackbar: Snackbar? = null - private lateinit var warningsAdapter: WarningMessagesAdapter private var walletView: WalletView = SingleWalletView() @@ -133,15 +133,14 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber Date: Thu, 8 Apr 2021 14:33:59 +0300 Subject: [PATCH 32/37] Updated on 2026-08-14 --- .../tap/features/wallet/ui/MultipleAddressUiHelper.kt | 8 -------- .../tap/features/wallet/ui/WalletDetailsFragment.kt | 4 ++-- .../tap/features/wallet/ui/wallet/SingleWalletView.kt | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt index f7b06a5b5e..66425c74a7 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt @@ -5,7 +5,6 @@ import com.tangem.blockchain.blockchains.bitcoin.BitcoinAddressType import com.tangem.blockchain.blockchains.cardano.CardanoAddressType import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.address.AddressType -import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.wallet.R class MultipleAddressUiHelper { @@ -20,13 +19,6 @@ class MultipleAddressUiHelper { } } - fun idToType(id: Int, currencyName: CryptoCurrencyName?): AddressType? { - val blockchain = currencyName?.let { currency -> - Blockchain.fromCurrency(currency) - } - return idToType(id, blockchain) - } - fun idToType(id: Int, blockchain: Blockchain?): AddressType? { return when (id) { R.id.chip_default -> { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 8913acc643..94106ba2f9 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -157,7 +157,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS private fun setupAddressCard(state: WalletData) { if (state.walletAddresses != null) { - if (state.shouldShowMultipleAddress()) { + if (state.shouldShowMultipleAddress() && state.blockchain != null) { (card_balance as? ViewGroup)?.beginDelayedTransition() chip_group_address_type.show() chip_group_address_type.fitChipsByGroupWidth() @@ -167,7 +167,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS chip_group_address_type.setOnCheckedChangeListener { group, checkedId -> if (checkedId == -1) return@setOnCheckedChangeListener - val type = MultipleAddressUiHelper.idToType(checkedId, state.currencyData.currencySymbol) + val type = MultipleAddressUiHelper.idToType(checkedId, state.blockchain) type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) } } } else { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index e7ff1e5db0..d6762f815b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -187,7 +187,7 @@ class SingleWalletView : WalletView { private fun setupAddressCard(state: WalletData) { val fragment = fragment ?: return - if (state.walletAddresses != null) { + if (state.walletAddresses != null && state.blockchain != null) { fragment.l_address?.show() if (state.shouldShowMultipleAddress()) { (fragment.l_address as? ViewGroup)?.beginDelayedTransition() @@ -199,7 +199,7 @@ class SingleWalletView : WalletView { fragment.chip_group_address_type.setOnCheckedChangeListener { group, checkedId -> if (checkedId == -1) return@setOnCheckedChangeListener - val type = MultipleAddressUiHelper.idToType(checkedId, state.currencyData.currencySymbol) + val type = MultipleAddressUiHelper.idToType(checkedId, state.blockchain) type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) } } } else { From f4ee8b7b88923f0445f2dcc1fcd8ff01e229ae87 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 8 Apr 2021 18:23:36 +0300 Subject: [PATCH 33/37] Updated on 2026-08-14 --- .../tangem/tap/common/extensions/Collections.kt | 11 +++++++++++ .../tap/common/redux/global/GlobalMidlleware.kt | 7 ++----- .../tap/common/redux/global/GlobalReducer.kt | 1 - .../com/tangem/tap/domain/TapWalletManager.kt | 3 +-- .../warningMessage/WarningMessagesManager.kt | 14 +++++--------- .../tap/features/send/redux/SendScreenAction.kt | 9 +++++++-- .../send/redux/middlewares/SendMiddleware.kt | 10 ++++++++++ .../send/redux/reducers/SendScreenReducer.kt | 2 +- .../tangem/tap/features/send/ui/SendFragment.kt | 4 +--- .../tap/features/wallet/redux/WalletAction.kt | 3 ++- .../tap/features/wallet/redux/WalletState.kt | 3 +++ .../redux/middlewares/WarningsMiddleware.kt | 15 ++++++++++----- .../wallet/redux/reducers/WalletReducer.kt | 10 ++-------- 13 files changed, 55 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/common/extensions/Collections.kt diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt b/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt new file mode 100644 index 0000000000..a280071a02 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt @@ -0,0 +1,11 @@ +package com.tangem.tap.common.extensions + +/** +[REDACTED_AUTHOR] + */ +fun List.containsAny(list: List): Boolean { + this.forEach { mainItem -> + list.forEach { if (it == mainItem) return true } + } + return false +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt index bc4a389355..dce356f1be 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt @@ -3,7 +3,6 @@ package com.tangem.tap.common.redux.global import com.tangem.TangemSdkError import com.tangem.common.CompletionResult import com.tangem.tap.common.redux.AppState -import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.send.redux.SendAction @@ -45,10 +44,8 @@ val globalMiddleware: Middleware = { dispatch, appState -> store.dispatch(WalletAction.Warnings.CheckHashesCount.SaveCardId) } - store.dispatch(WalletAction.Warnings.SetWarnings( - it.getWarnings(WarningMessage.Location.MainScreen))) - store.dispatch(SendAction.SetWarnings( - it.getWarnings(WarningMessage.Location.SendScreen))) + store.dispatch(WalletAction.Warnings.Update) + store.dispatch(SendAction.Warnings.Update) } } } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index eeecf8fb76..bfc866a06c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -39,7 +39,6 @@ fun globalReducer(action: Action, state: AppState): GlobalState { globalState.copy(configManager = action.configManager) } is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager) - is GlobalAction.HideWarningMessage -> globalState is GlobalAction.UpdateSecurityOptions -> { val card = when (action.securityOption) { SecurityOption.LongTap -> globalState.scanNoteResponse?.card?.copy( diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 48d387adc3..4dc3906281 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -86,7 +86,6 @@ class TapWalletManager { } TapWorkarounds.updateCard(data.card) store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card) - store.state.globalState.warningManager?.setBlockchain(data.walletManager?.wallet?.blockchain) updateConfigManager(data) withContext(Dispatchers.Main) { @@ -127,7 +126,6 @@ class TapWalletManager { suspend fun loadData(data: ScanNoteResponse) { withContext(Dispatchers.Main) { - store.dispatch(WalletAction.Warnings.CheckIfNeeded) val artworkId = data.verifyResponse?.artworkInfo?.id if (data.walletManager != null) { val config = store.state.globalState.configManager?.config ?: return@withContext @@ -175,6 +173,7 @@ class TapWalletManager { store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain)) store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) } + store.dispatch(WalletAction.Warnings.CheckIfNeeded) } } diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt index 391bbc9b13..81739ee7b5 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt @@ -2,6 +2,7 @@ package com.tangem.tap.domain.configurable.warningMessage import com.tangem.blockchain.common.Blockchain import com.tangem.tangem_sdk_new.ui.animation.VoidCallback +import com.tangem.tap.common.extensions.containsAny import com.tangem.wallet.R /** @@ -11,7 +12,6 @@ class WarningMessagesManager( private val warningLoader: RemoteWarningLoader, ) { - private var blockchain: Blockchain? = null private val warningsList: MutableList = mutableListOf() fun load(onComplete: VoidCallback? = null) { @@ -23,10 +23,6 @@ class WarningMessagesManager( } } - fun setBlockchain(blockchain: Blockchain?) { - this.blockchain = blockchain - } - fun addWarning(warning: WarningMessage) { if (findWarning(warning) == null) { warningsList.add(warning) @@ -34,14 +30,14 @@ class WarningMessagesManager( } } - fun getWarnings(location: WarningMessage.Location): List { + fun getWarnings(location: WarningMessage.Location, forBlockchains: List = emptyList()): List { return warningsList .filter { !it.isHidden && it.location.contains(location) } .filter { - val blockchainList = it.blockchainList + val list = it.blockchainList when { - blockchainList == null -> true - blockchainList.contains(blockchain) -> true + list == null -> true + list.containsAny(forBlockchains) -> true else -> false } } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 0d0d2d8bc7..08c3b35a09 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -149,8 +149,13 @@ sealed class SendAction : SendScreenAction { val sendAllCallback: () -> Unit, val reduceAmount: BigDecimal, ) : Dialog() - data class SendTransactionFails(val errorMessage: String): Dialog() + + data class SendTransactionFails(val errorMessage: String) : Dialog() object Hide : Dialog() } - data class SetWarnings(val warningList: List) : SendAction() + + sealed class Warnings : SendAction() { + object Update : SendAction() + data class Set(val warningList: List) : SendAction() + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index d1b7246ef2..5a5f927b30 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -15,6 +15,7 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.TapWorkarounds +import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.extensions.minimalAmount import com.tangem.tap.features.send.redux.* import com.tangem.tap.features.send.redux.FeeAction.RequestFee @@ -46,6 +47,7 @@ val sendMiddleware: Middleware = { dispatch, appState -> is SendActionUi.SendAmountToRecipient -> verifyAndSendTransaction(action, appState(), dispatch) is PrepareSendScreen -> setIfSendingToPayIdEnabled(appState(), dispatch) + is SendAction.Warnings.Update -> updateWarnings(dispatch) } nextDispatch(action) } @@ -224,3 +226,11 @@ private fun setIfSendingToPayIdEnabled(appState: AppState?, dispatch: (Action) - dispatch(AddressPayIdActionUi.ChangePayIdState(isSendingToPayIdEnabled)) } +private fun updateWarnings(dispatch: (Action) -> Unit) { + val warningsManager = store.state.globalState.warningManager ?: return + val blockchain = store.state.sendState.walletManager?.wallet?.blockchain ?: return + + val warnings = warningsManager.getWarnings(WarningMessage.Location.SendScreen, listOf(blockchain)) + dispatch(SendAction.Warnings.Set(warnings)) +} + diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt index e6ab87ef01..9db3d6e7ca 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt @@ -45,7 +45,7 @@ private class SendReducer : SendInternalReducer { is SendAction.Dialog.TezosWarningDialog -> sendState.copy(dialog = action) is SendAction.Dialog.SendTransactionFails -> sendState.copy(dialog = action) is SendAction.Dialog.Hide -> sendState.copy(dialog = null) - is SendAction.SetWarnings -> sendState.copy(sendWarningsList = action.warningList) + is SendAction.Warnings.Set -> sendState.copy(sendWarningsList = action.warningList) else -> return sendState } diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index 6ee78a5baf..080114705d 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -25,7 +25,6 @@ import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity import com.tangem.tap.common.snackBar.MaxAmountSnackbar import com.tangem.tap.common.text.truncateMiddleWith import com.tangem.tap.common.toggleWidget.* -import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.features.send.BaseStoreFragment import com.tangem.tap.features.send.redux.* import com.tangem.tap.features.send.redux.AddressPayIdActionUi.* @@ -249,8 +248,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { rv_warning_messages.addItemDecoration(SpacesItemDecoration(rv_warning_messages.dpToPx(16f).toInt())) rv_warning_messages.adapter = warningsAdapter - val warnings = store.state.globalState.warningManager?.getWarnings(WarningMessage.Location.SendScreen) ?: listOf() - store.dispatch(SendAction.SetWarnings(warnings)) + store.dispatch(SendAction.Warnings.Update) } override fun subscribeToStore() { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index f623671395..682b4dc0d2 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -71,7 +71,8 @@ sealed class WalletAction : Action { } object CheckIfNeeded : Warnings() - data class SetWarnings(val warningList: List) : Warnings() + object Update : Warnings() + data class Set(val warningList: List) : Warnings() object AppRating : Warnings() { object SetNeverToShow : Warnings() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 4bf58caa8c..f8e47d81bb 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -42,6 +42,9 @@ data class WalletState( primaryWallet?.currencyData?.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard && primaryWallet?.currencyData?.status != com.tangem.tap.features.wallet.ui.BalanceStatus.UnknownBlockchain + val blockchains: List + get() = walletManagers.map { it.wallet.blockchain } + fun getWalletManager(currencyName: CryptoCurrencyName?): WalletManager? { if (currencyName == null) return null val walletManager = walletManagers.find { it.wallet.blockchain.currency == currencyName } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index ad2c009c9c..d158d3d323 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -29,6 +29,7 @@ import java.math.BigDecimal class WarningsMiddleware { fun handle(action: WalletAction.Warnings, globalState: GlobalState?) { when (action) { + WalletAction.Warnings.Update -> setWarningMessages() is WalletAction.Warnings.CheckIfNeeded -> { showCardWarningsIfNeeded(globalState) val readyToShow = preferencesStorage.appRatingLaunchObserver.isReadyToShow() @@ -76,7 +77,7 @@ class WarningsMiddleware { addWarningMessage(WarningMessagesManager.onlineVerificationFailed()) } } - updateWarningMessages() + setWarningMessages() } } @@ -130,11 +131,15 @@ class WarningsMiddleware { private fun addWarningMessage(warning: WarningMessage, autoUpdate: Boolean = false) { store.state.globalState.warningManager?.addWarning(warning) - if (autoUpdate) updateWarningMessages() + if (autoUpdate) setWarningMessages() } - private fun updateWarningMessages() { - val warningManager = store.state.globalState.warningManager ?: return - store.dispatch(WalletAction.Warnings.SetWarnings(warningManager.getWarnings(WarningMessage.Location.MainScreen))) + private fun setWarningMessages() { + store.dispatch(WalletAction.Warnings.Set(getWarnings())) + } + + private fun getWarnings(): List { + val warningManager = store.state.globalState.warningManager ?: return emptyList() + return warningManager.getWarnings(WarningMessage.Location.MainScreen, store.state.walletState.blockchains) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index 051594b368..e9241531cc 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -294,16 +294,10 @@ fun createAddressList(wallet: Wallet?, walletAddresses: WalletAddresses? = null) private fun handleCheckSignedHashesActions(action: WalletAction.Warnings, state: WalletState): WalletState { return when (action) { - WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline -> state WalletAction.Warnings.CheckHashesCount.ConfirmHashesCount -> state.copy(hashesCountVerified = true) WalletAction.Warnings.CheckHashesCount.NeedToCheckHashesCountOnline -> state.copy(hashesCountVerified = false) - WalletAction.Warnings.CheckHashesCount.SaveCardId -> state - is WalletAction.Warnings.SetWarnings -> state.copy(mainWarningsList = action.warningList) - WalletAction.Warnings.CheckIfNeeded -> state - WalletAction.Warnings.AppRating -> state - WalletAction.Warnings.CheckHashesCount -> state - WalletAction.Warnings.AppRating.RemindLater -> state - WalletAction.Warnings.AppRating.SetNeverToShow -> state + is WalletAction.Warnings.Set -> state.copy(mainWarningsList = action.warningList) + else -> state } } From 7ee85f9464c7733ed8043a552b3fa0315c0517f8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 9 Apr 2021 16:33:12 +0300 Subject: [PATCH 34/37] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TapWalletManager.kt | 59 +++++++++++-------- .../tap/domain/tokens/CurrenciesRepository.kt | 7 ++- .../tap/features/wallet/redux/WalletAction.kt | 22 ++----- .../tap/features/wallet/redux/WalletState.kt | 2 +- .../middlewares/MultiWalletMiddleware.kt | 45 +++++++++++++- .../redux/reducers/MultiWalletReducer.kt | 4 +- .../wallet/redux/reducers/WalletReducer.kt | 18 ------ 7 files changed, 94 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 4dc3906281..497c7dde68 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,7 +1,7 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.* -import com.tangem.blockchain.extensions.getBlockchain +import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.CardStatus import com.tangem.commands.common.network.Result import com.tangem.tap.common.analytics.AnalyticsEvent @@ -14,6 +14,7 @@ import com.tangem.tap.domain.configurable.config.ConfigManager import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.domain.tokens.CardCurrencies import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.features.tokens.redux.TokensAction @@ -32,7 +33,7 @@ class TapWalletManager { private val blockchainSdkConfig by lazy { store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig() } - private val walletManagerFactory: WalletManagerFactory + val walletManagerFactory: WalletManagerFactory by lazy { WalletManagerFactory(blockchainSdkConfig) } suspend fun loadWalletData(walletManager: WalletManager) { @@ -131,36 +132,20 @@ class TapWalletManager { val config = store.state.globalState.configManager?.config ?: return@withContext val primaryWalletManager = data.walletManager - val primaryBlockchain = listOf(data.walletManager.wallet.blockchain) + val primaryBlockchain = data.walletManager.wallet.blockchain val primaryTokenSymbol = data.card.cardData?.tokenSymbol val primaryToken = primaryWalletManager.presetTokens.toList() .firstOrNull { it.symbol == primaryTokenSymbol } - store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(primaryBlockchain[0])) + store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(primaryBlockchain)) if (primaryToken != null) { store.dispatch(WalletAction.MultiWallet.SetPrimaryToken(primaryToken)) } - if (data.card.isMultiwalletAllowed) { - val savedCurrencies = currenciesRepository.loadCardCurrencies(data.card.cardId) - - val walletManagers = listOf(primaryWalletManager) + - currenciesRepository.getBlockchains() - .filterNot { it == primaryWalletManager.wallet.blockchain } - .mapNotNull { walletManagerFactory.makeWalletManager(data.card, it) } - val otherBlockhains = savedCurrencies.blockchains - - val presetTokens = walletManagers.first { it.wallet.blockchain == data.card.getBlockchain() } - .presetTokens.toList() - val tokens = presetTokens + savedCurrencies.tokens - - store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers)) - store.dispatch(WalletAction.MultiWallet.AddBlockchains(primaryBlockchain + otherBlockhains)) - store.dispatch(WalletAction.MultiWallet.AddTokens(tokens)) - store.dispatch(WalletAction.MultiWallet.FindTokensInUse) + loadMultiWalletData(data.card, primaryBlockchain, primaryWalletManager) } else { - store.dispatch(WalletAction.MultiWallet.AddWalletManagers(listOf(primaryWalletManager))) - store.dispatch(WalletAction.MultiWallet.AddBlockchains(primaryBlockchain)) + store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager)) + store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain))) } store.dispatch(WalletAction.SetArtworkId(data.verifyResponse?.artworkInfo?.id)) store.dispatch(WalletAction.LoadWallet(config.isTopUpEnabled)) @@ -177,6 +162,34 @@ class TapWalletManager { } } + private fun loadMultiWalletData( + card: Card, primaryBlockchain: Blockchain, primaryWalletManager: WalletManager + ) { + val presetTokens = primaryWalletManager.presetTokens.toList() + val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId) + + if (savedCurrencies == null) { + store.dispatch(WalletAction.MultiWallet.SaveCurrencies( + CardCurrencies( + blockchains = listOf(primaryBlockchain), tokens = presetTokens + ))) + store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager)) + store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain))) + store.dispatch(WalletAction.MultiWallet.AddTokens(presetTokens)) + store.dispatch(WalletAction.MultiWallet.FindBlockchainsInUse(card, walletManagerFactory)) + store.dispatch(WalletAction.MultiWallet.FindTokensInUse) + } else { + val blockchains = listOf(primaryBlockchain) + savedCurrencies.blockchains + val walletManagers = walletManagerFactory.makeWalletManagers(card, blockchains) + val tokens = presetTokens + savedCurrencies.tokens + + store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers)) + store.dispatch(WalletAction.MultiWallet.AddBlockchains(blockchains)) + store.dispatch(WalletAction.MultiWallet.AddTokens(tokens)) + store.dispatch(WalletAction.MultiWallet.FindTokensInUse) + } + } + suspend fun reloadData(data: ScanNoteResponse) { withContext(Dispatchers.Main) { if (data.walletManager != null) { diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt index 3c4cf0e981..42c7aeefe4 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt @@ -19,8 +19,11 @@ class CurrenciesRepository(val context: Application) { Types.newParameterizedType(List::class.java, Blockchain::class.java) ) - fun loadCardCurrencies(cardId: String): CardCurrencies { - return CardCurrencies(loadSavedTokens(cardId), loadSavedBlockchains(cardId)) + fun loadCardCurrencies(cardId: String): CardCurrencies? { + val blockchains = loadSavedBlockchains(cardId) + if (blockchains.isEmpty()) return null + + return CardCurrencies(loadSavedTokens(cardId), blockchains) } fun saveCardCurrencies(cardId: String, currencies: CardCurrencies) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 682b4dc0d2..5b3877338d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -9,6 +9,7 @@ import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.domain.TapError import com.tangem.tap.domain.configurable.warningMessage.WarningMessage +import com.tangem.tap.domain.tokens.CardCurrencies import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.wallet.R import org.rekotlin.Action @@ -32,29 +33,18 @@ sealed class WalletAction : Action { data class SetArtworkId(val artworkId: String?) : WalletAction() - // sealed class ProcessWallet : WalletAction() { -// data class LoadWallet(val artworkId: String?, val allowTopUp: Boolean -// ) : ProcessWallet() { -// data class Success(val wallet: Wallet) : ProcessWallet() -// data class NoAccount(val wallet: Wallet, val amountToCreateAccount: String) : ProcessWallet() -// data class Failure(val wallet: Wallet, val errorMessage: String? = null) : ProcessWallet() -// } -// -// data class UpdateWallet(val currency: CryptoCurrencyName? = null) : ProcessWallet() { -// object ScheduleUpdatingWallet : ProcessWallet() -// data class Success(val wallet: Wallet) : ProcessWallet() -// data class Failure(val errorMessage: String? = null) : ProcessWallet() -// } -// } - sealed class MultiWallet : WalletAction() { data class SetIsMultiwalletAllowed(val isMultiwalletAllowed: Boolean) : MultiWallet() - data class AddWalletManagers(val walletManagers: List) : MultiWallet() + data class AddWalletManagers(val walletManagers: List) : MultiWallet() { + constructor(walletManager: WalletManager) : this(listOf(walletManager)) + } data class AddBlockchain(val blockchain: Blockchain) : MultiWallet() data class AddBlockchains(val blockchains: List) : MultiWallet() data class AddTokens(val tokens: List) : MultiWallet() data class AddToken(val token: Token) : MultiWallet() + data class SaveCurrencies(val cardCurrencies: CardCurrencies) : MultiWallet() object FindTokensInUse : MultiWallet() + data class FindBlockchainsInUse(val card: Card, val factory: WalletManagerFactory) : MultiWallet() data class TokenLoaded(val amount: Amount) : MultiWallet() data class SelectWallet(val walletData: WalletData?) : MultiWallet() data class RemoveWallet(val walletData: WalletData) : MultiWallet() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index f8e47d81bb..244f7f026d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -60,7 +60,7 @@ data class WalletState( if (primaryWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) { primaryWalletManager } else { - null + ethereumWalletManager } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index 099387721d..6daa182e35 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -1,9 +1,11 @@ package com.tangem.tap.features.wallet.redux.middlewares +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.TokenFinder import com.tangem.blockchain.extensions.Result +import com.tangem.common.extensions.isZero import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction @@ -13,6 +15,7 @@ import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.scope import com.tangem.tap.store import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -40,12 +43,20 @@ class MultiWalletMiddleware { action.tokens.map { addToken(it, walletState) } } is WalletAction.MultiWallet.AddBlockchain -> { - globalState?.scanNoteResponse?.card?.cardId?.let { - currenciesRepository.saveAddedBlockchain(it, action.blockchain) + globalState?.scanNoteResponse?.card?.let { card -> + currenciesRepository.saveAddedBlockchain(card.cardId, action.blockchain) + globalState.tapWalletManager.walletManagerFactory + .makeWalletManager(card, action.blockchain)?.let { + store.dispatch(WalletAction.MultiWallet.AddWalletManagers(it)) + } } store.dispatch(WalletAction.LoadFiatRate(currency = action.blockchain.currency)) store.dispatch(WalletAction.LoadWallet(currency = action.blockchain.currency)) } + is WalletAction.MultiWallet.SaveCurrencies -> { + val cardId = globalState?.scanNoteResponse?.card?.cardId + cardId?.let { currenciesRepository.saveCardCurrencies(it, action.cardCurrencies) } + } is WalletAction.MultiWallet.RemoveWallet -> { val cardId = globalState?.scanNoteResponse?.card?.cardId if (action.walletData.token != null) { @@ -54,6 +65,36 @@ class MultiWalletMiddleware { cardId?.let { currenciesRepository.removeBlockchain(it, action.walletData.blockchain) } } } + is WalletAction.MultiWallet.FindBlockchainsInUse -> { + val blockchains = currenciesRepository.getBlockchains() + .filterNot { walletState?.blockchains?.contains(it) == true } + val walletManagers = action.factory.makeWalletManagers(action.card, blockchains) + + scope.launch { + walletManagers.map { walletManager -> + async(Dispatchers.IO) { + try { + walletManager.update() + val wallet = walletManager.wallet + val coinAmount = wallet.amounts[AmountType.Coin]?.value + if (coinAmount != null && !coinAmount.isZero()) { + if (walletState?.getWalletData(wallet.blockchain.currency) == null) { + scope.launch(Dispatchers.Main) { + store.dispatch(WalletAction.MultiWallet.AddWalletManagers( + listOfNotNull(walletManager))) + store.dispatch(WalletAction.MultiWallet.AddBlockchain( + wallet.blockchain + )) + store.dispatch(WalletAction.LoadWallet.Success(wallet)) + } + } + } + } catch (exception: Exception) { + } + } + } + } + } is WalletAction.MultiWallet.FindTokensInUse -> { val walletManager = walletState?.getWalletManager(Blockchain.Ethereum.currency) ?: return diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index cb44136adf..2c19ca8e8b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -18,7 +18,7 @@ class MultiWalletReducer { return when (action) { is WalletAction.MultiWallet.AddWalletManagers -> { state.copy( - walletManagers = action.walletManagers + walletManagers = state.walletManagers + action.walletManagers ) } is WalletAction.MultiWallet.AddBlockchains -> { @@ -160,6 +160,8 @@ class MultiWalletReducer { is WalletAction.MultiWallet.SetPrimaryToken -> state.copy(primaryToken = action.token) is WalletAction.MultiWallet.FindTokensInUse -> state + is WalletAction.MultiWallet.FindBlockchainsInUse -> state + is WalletAction.MultiWallet.SaveCurrencies -> state } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index e9241531cc..957e9a32d3 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -125,14 +125,11 @@ private fun internalReduce(action: Action, state: AppState): WalletState { val wallets = newState.replaceSomeWallets(newWallets) newState = newState.copy(wallets = wallets) } - } is WalletAction.LoadWallet.Success -> newState = onWalletLoadedReducer.reduce(action.wallet, newState) is WalletAction.UpdateWallet.Success -> { newState = onWalletLoadedReducer.reduce(action.wallet, newState) -// newState = newState.copy(updatingWallet = newState.pendingTransactions.isNotEmpty()) } - is WalletAction.LoadWallet.NoAccount -> { val walletData = newState.getWalletData(action.wallet.blockchain.currency)?.copy( currencyData = BalanceWidgetData( @@ -193,21 +190,6 @@ private fun internalReduce(action: Action, state: AppState): WalletState { newState = newState.copy(cardImage = cardImage) } -// is WalletAction.UpdateWallet -> { -// if (store.state.walletState.state == ProgressState.Done) { -// newState = newState.copy(updatingWallet = true) -// } -// } -// is WalletAction.UpdateWallet.ScheduleUpdatingWallet -> -// newState = newState.copy(updatingWallet = true) - -// is WalletAction.UpdateWallet.Failure -> newState = newState.copy(updatingWallet = false) -// is WalletAction.LoadFiatRate -> { -// newState.copy(currencyData = newState.currencyData.copy( -// fiatAmount = null, -// token = newState.currencyData.token?.copy(fiatAmount = null)) -// ) -// } is WalletAction.LoadFiatRate.Success -> newState = setNewFiatRate(action.fiatRate, state.globalState.appCurrency, newState) is WalletAction.LoadArtwork -> { From 382bf23553917de2a5b0148aa3e7e50130c76585 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 9 Apr 2021 17:42:41 +0300 Subject: [PATCH 35/37] Updated on 2026-08-14 --- .../redux/reducers/MultiWalletReducer.kt | 12 ++++--- .../redux/reducers/OnWalletLoadedReducer.kt | 10 ++++-- .../tap/features/wallet/ui/BalanceWidget.kt | 1 + .../wallet/ui/WalletDetailsFragment.kt | 7 ++-- .../wallet/ui/adapters/WalletAdapter.kt | 2 +- .../res/layout/fragment_wallet_details.xml | 36 +++++++++++++++++-- .../main/res/values/strings_untranslated.xml | 2 +- 7 files changed, 57 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index 2c19ca8e8b..158d7e61ff 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -120,15 +120,17 @@ class MultiWalletReducer { } ?: emptyList() val sendButtonEnabled = action.amount.value?.isZero() == false && pendingTransactions.isEmpty() - val balanceStatus = if (pendingTransactions.isNotEmpty()) { - BalanceStatus.TransactionInProgress - } else { - BalanceStatus.VerifiedOnline + val tokenPendingTransactions = pendingTransactions + .filter { it.currency == action.amount.currencySymbol } + val tokenBalanceStatus = when { + tokenPendingTransactions.isNotEmpty() -> BalanceStatus.TransactionInProgress + pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress + else -> BalanceStatus.VerifiedOnline } val tokenWalletData = state.getWalletData(action.amount.currencySymbol) val newTokenWalletData = tokenWalletData?.copy( currencyData = tokenWalletData.currencyData.copy( - status = balanceStatus, + status = tokenBalanceStatus, amount = action.amount.value?.toFormattedCurrencyString( action.amount.decimals, action.amount.currencySymbol ), diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 1b3442c812..2b3ad57454 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -65,9 +65,15 @@ class OnWalletLoadedReducer { val tokens = wallet.getTokens().mapNotNull { token -> val tokenWalletData = walletState.getWalletData(token.symbol) + val tokenPendingTransactions = pendingTransactions.filter { it.currency == token.symbol } + val tokenBalanceStatus = when { + tokenPendingTransactions.isNotEmpty() -> BalanceStatus.TransactionInProgress + pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress + else -> BalanceStatus.VerifiedOnline + } tokenWalletData?.copy( currencyData = tokenWalletData.currencyData.copy( - status = balanceStatus, + status = tokenBalanceStatus, amount = wallet.getTokenAmount(token)?.value?.toFormattedCurrencyString( token.decimals, token.symbol ), @@ -76,7 +82,7 @@ class OnWalletLoadedReducer { ?.toFiatString(it, fiatCurrencySymbol) } ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), + pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(sendButtonEnabled) ) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index ed446c3ee5..508a62b08c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -13,6 +13,7 @@ import java.math.BigDecimal enum class BalanceStatus { VerifiedOnline, TransactionInProgress, + SameCurrencyTransactionInProgress, Unreachable, Loading, NoAccount, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index bd13ada0c9..5b59b03015 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -205,10 +205,12 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS showStatus(R.id.tv_status_loading) showBalanceWithoutToken(data, false) } - BalanceStatus.VerifiedOnline, BalanceStatus.TransactionInProgress -> { + BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, + BalanceStatus.TransactionInProgress -> { l_balance.show() l_balance_error.hide() - val statusView = if (data.status == BalanceStatus.VerifiedOnline) { + val statusView = if (data.status == BalanceStatus.VerifiedOnline || + data.status == BalanceStatus.SameCurrencyTransactionInProgress) { R.id.tv_status_verified } else { tv_status_error.text = @@ -245,6 +247,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS ) } } + card_pending_transaction_warning.show(data.status == BalanceStatus.SameCurrencyTransactionInProgress) } private fun showStatus(@IdRes viewRes: Int) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index 73083d0e58..c14d364abf 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -100,7 +100,7 @@ class WalletAdapter view.iv_currency.setImageResource(R.drawable.shape_circle) } when (wallet.currencyData.status) { - BalanceStatus.VerifiedOnline -> hideWarning() + BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress -> hideWarning() BalanceStatus.Loading -> { hideWarning() if (wallet.currencyData.amount == null) { diff --git a/app/src/main/res/layout/fragment_wallet_details.xml b/app/src/main/res/layout/fragment_wallet_details.xml index a848f0df9d..757eeab445 100644 --- a/app/src/main/res/layout/fragment_wallet_details.xml +++ b/app/src/main/res/layout/fragment_wallet_details.xml @@ -79,6 +79,36 @@ app:layout_constraintTop_toBottomOf="@id/rv_pending_transaction" /> + + + + + + + @@ -107,12 +138,13 @@ android:id="@+id/btn_confirm" style="@style/TapButtonWithIcon" android:layout_width="0dp" - android:layout_marginStart="8dp" + android:layout_marginStart="4dp" android:layout_marginTop="30dp" android:layout_marginEnd="16dp" android:layout_marginBottom="33dp" android:text="@string/wallet_button_send" app:icon="@drawable/ic_send" + app:layout_constraintTop_toBottomOf="@id/barrier" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/guideline" diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 860b985336..238bc7a845 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -97,7 +97,7 @@ this wallet. Copy Share + Add tokens - + Please wait for the transaction to complete to be able to send funds Authenticity check failed This card might be a production sample or counterfeit From b8210ae96ffe1a34b122e086ea98c8c43413f3dd Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 13 Apr 2021 10:08:00 +0000 Subject: [PATCH 36/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 75ca19087f..9a344dafb7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.164.0' + implementation 'com.tangem:blockchain:1.165.0' implementation 'com.tangem:core:1.109.0' implementation 'com.tangem:sdk:1.109.0' From 349b0aaab6439b5d2979bf59a7ec290c259a8260 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Apr 2021 08:00:58 +0000 Subject: [PATCH 37/37] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 9a344dafb7..76faa09bc5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:1.165.0' + implementation 'com.tangem:blockchain:1.166.0' implementation 'com.tangem:core:1.109.0' implementation 'com.tangem:sdk:1.109.0'