diff --git a/app/build.gradle b/app/build.gradle index 56fa51dc9b..f5ebeb41d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.35.0' + implementation 'com.tangem:blockchain:1.37.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index 774c582c4e..44a08cd1d5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.TransactionError import com.tangem.common.extensions.isZero import com.tangem.tap.common.redux.AppState @@ -41,11 +40,7 @@ class AmountMiddleware { if (inputValue.isZero() && amountState.amountToSendCrypto.isZero()) return val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) inputValue - else when (amountState.typeOfAmount) { - AmountType.Coin -> sendState.convertFiatToCoin(inputValue) - AmountType.Token -> sendState.convertFiatToToken(inputValue) - else -> inputValue - } + else sendState.convertFiatToExtractCrypto(inputValue) dispatch(AmountAction.SetAmount(inputValueCrypto, true)) dispatch(AmountActionUi.CheckAmountToSend) @@ -54,6 +49,7 @@ class AmountMiddleware { private fun checkAmountToSend(appState: AppState?, dispatch: (Action) -> Unit) { val sendState = appState?.sendState ?: return val walletManager = sendState.walletManager ?: return + val typedAmount = sendState.amountState.amountToExtract ?: return val inputCrypto = sendState.amountState.amountToSendCrypto if (sendState.amountState.viewAmountValue.value == "0" && inputCrypto.isZero()) { @@ -62,12 +58,8 @@ class AmountMiddleware { return } - val feeCrypto = sendState.feeState.getCurrentFee() - - val feeAmount = Amount(feeCrypto, walletManager.wallet.blockchain) - val totalAmount = Amount(sendState.getTotalAmountToSend(inputCrypto), walletManager.wallet.blockchain) - - val transactionErrors = walletManager.validateTransaction(totalAmount, feeAmount) + val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend(inputCrypto)) + val transactionErrors = walletManager.validateTransaction(amountToSend, sendState.feeState.currentFee) if (transactionErrors.isEmpty()) { dispatch(AmountAction.SetAmountError(null)) } else { 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 c89c0a6bad..ed70149d38 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 @@ -20,6 +20,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.rekotlin.Action import org.rekotlin.Middleware +import timber.log.Timber /** [REDACTED_AUTHOR] @@ -43,10 +44,9 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return val recipientAddress = sendState.addressPayIdState.recipientWalletAddress ?: return val typedAmount = sendState.amountState.amountToExtract ?: return + val feeAmount = sendState.feeState.currentFee ?: return - val feeAmount = Amount(sendState.feeState.getCurrentFee(), walletManager.wallet.blockchain) - val totalToSend = sendState.getTotalAmountToSend() - val amountToSend = Amount(typedAmount.currencySymbol, totalToSend, recipientAddress, typedAmount.decimals, typedAmount.type) + val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend()) val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount) if (verifyResult.isNotEmpty()) { @@ -57,6 +57,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS)) val txData = walletManager.createTransaction(amountToSend, feeAmount, recipientAddress) scope.launch { + walletManager.update() val result = (walletManager as TransactionSender).send(txData, Signer(tangemSdk)) withContext(Dispatchers.Main) { when (result) { @@ -76,6 +77,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> // user was cancelled the operation by closing the Sdk bottom sheet } else -> { + Timber.e(result.error) dispatch(SendAction.SendError(TapError.BlockchainInternalError)) } } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt index ebe5c2b7b9..01acbe1feb 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt @@ -30,8 +30,8 @@ class AmountReducer : SendInternalReducer { when (val currency = if (currencyCanBeSwitched) action.mainCurrency else MainCurrencyType.CRYPTO) { MainCurrencyType.FIAT -> { val fiatToSend = if (state.amountToSendCrypto.isZero()) BigDecimal.ZERO - else sendState.convertCoinToFiat(state.amountToSendCrypto) - val rescaledBalance = sendState.convertCoinToFiat(state.balanceCrypto, true) + else sendState.convertExtractCryptoToFiat(state.amountToSendCrypto) + val rescaledBalance = sendState.convertExtractCryptoToFiat(state.balanceCrypto, true) state.copy( viewAmountValue = InputViewValue(fiatToSend.stripZeroPlainString()), viewBalanceValue = rescaledBalance.stripZeroPlainString(), @@ -61,7 +61,7 @@ class AmountReducer : SendInternalReducer { val result = when (action) { is AmountAction.SetAmount -> { val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) action.amountCrypto - else sendState.convertCoinToFiat(action.amountCrypto, true) + else sendState.convertExtractCryptoToFiat(action.amountCrypto, true) state.copy( viewAmountValue = InputViewValue(amount.stripZeroPlainString(), action.isUserInput), amountToSendCrypto = action.amountCrypto, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt index 323a34cf74..c6f6511773 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt @@ -15,10 +15,13 @@ import java.math.BigDecimal */ class ReceiptReducer : SendInternalReducer { + companion object { + const val EMPTY = "-" + } + private lateinit var sendState: SendState private lateinit var amountState: AmountState private lateinit var feeState: FeeState - private val EMPTY = "-" override fun handle(action: SendScreenAction, sendState: SendState): SendState { this.sendState = sendState @@ -50,7 +53,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptFiat { - val feeCrypto = feeState.getCurrentFee() + val feeCrypto = feeState.getCurrentFeeValue() val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { @@ -82,7 +85,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptCrypto { - val feeCrypto = feeState.getCurrentFee() + val feeCrypto = feeState.getCurrentFeeValue() val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { return ReceiptCrypto("0", feeCrypto.stripZeroPlainString(), "0", "0", "0", symbols) @@ -111,7 +114,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createTokenFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenFiat { - val feeCoin = feeState.getCurrentFee() + val feeCoin = feeState.getCurrentFeeValue() if (showBlank) { val feeFiat = convertToFiatPrecision(feeCoin) return ReceiptTokenFiat("0", feeFiat, "0", "0", "0", symbols) @@ -124,9 +127,9 @@ class ReceiptReducer : SendInternalReducer { val amountFiat = sendState.tokenConverter!!.toFiatUnscaled(tokensToSend) val totalFiat = amountFiat.plus(feeFiat) ReceiptTokenFiat( - amountFiat = amountFiat.scaleToFiat().stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + amountFiat = amountFiat.scaleToFiat(true).stripZeroPlainString(), + feeFiat = feeFiat.scaleToFiat(true).stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(), willSentToken = tokensToSend.stripZeroPlainString(), willSentFeeCoin = feeCoin.stripZeroPlainString(), symbols = symbols @@ -144,7 +147,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createTokenCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenCrypto { - val feeCoin = feeState.getCurrentFee() + val feeCoin = feeState.getCurrentFeeValue() if (showBlank) { return ReceiptTokenCrypto("0", feeCoin.stripZeroPlainString(), "0", symbols) } @@ -158,7 +161,7 @@ class ReceiptReducer : SendInternalReducer { ReceiptTokenCrypto( amountToken = tokensToSend.stripZeroPlainString(), feeCoin = feeCoin.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(), symbols = symbols ) } else { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt index 72575e6a6b..532031bbb4 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt @@ -27,5 +27,5 @@ data class FeeState( fun isReady(): Boolean = error == null && currentFee != null - fun getCurrentFee(): BigDecimal = currentFee?.value ?: BigDecimal.ZERO + fun getCurrentFeeValue(): BigDecimal = currentFee?.value ?: BigDecimal.ZERO } \ No newline at end of file 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 975c89a673..5441e0ac02 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 @@ -56,6 +56,11 @@ data class SendState( else coinConverter!!.toCrypto(value) } + fun convertFiatToToken(value: BigDecimal): BigDecimal { + return if (!this.tokenIsConvertible()) value + else tokenConverter!!.toCrypto(value) + } + fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { if (!this.coinIsConvertible()) return value @@ -63,11 +68,6 @@ data class SendState( return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } - fun convertFiatToToken(value: BigDecimal): BigDecimal { - return if (!this.tokenIsConvertible()) value - else tokenConverter!!.toCrypto(value) - } - fun convertTokenToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { if (!this.tokenIsConvertible()) return value @@ -75,11 +75,25 @@ data class SendState( return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } + fun convertFiatToExtractCrypto(fiatValue: BigDecimal): BigDecimal = when (amountState.typeOfAmount) { + AmountType.Coin -> convertFiatToCoin(fiatValue) + AmountType.Token -> convertFiatToToken(fiatValue) + AmountType.Reserve -> fiatValue + } + + fun convertExtractCryptoToFiat(cryptoValue: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { + return when (amountState.typeOfAmount) { + AmountType.Coin -> convertCoinToFiat(cryptoValue, scaleWithPrecision) + AmountType.Token -> convertTokenToFiat(cryptoValue, scaleWithPrecision) + AmountType.Reserve -> cryptoValue + } + } + fun getButtonState(): SendButtonState = if (isReadyToSend()) SendButtonState.ENABLED else SendButtonState.DISABLED fun getTotalAmountToSend(value: BigDecimal = amountState.amountToSendCrypto): BigDecimal { val needToExtractFee = amountState.isCoinAmount() && feeState.feeIsIncluded - return if (needToExtractFee) value.minus(feeState.getCurrentFee()) else value + return if (needToExtractFee) value.minus(feeState.getCurrentFeeValue()) else value } fun coinIsConvertible(): Boolean = coinConverter != null diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 278b8d62b4..476c1dee45 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -15,6 +15,7 @@ import com.tangem.tap.domain.assembleErrorIds import com.tangem.tap.features.send.BaseStoreFragment import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error import com.tangem.tap.features.send.redux.FeeAction +import com.tangem.tap.features.send.redux.reducers.ReceiptReducer import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.features.send.ui.FeeUiHelper import com.tangem.tap.features.send.ui.SendFragment @@ -183,6 +184,8 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber fun getString(id: Int): String = mainLayout.context.getString(id) val rough = getString(R.string.sign_rough) + fun roughOrEmpty(value: String): String = if (value == ReceiptReducer.EMPTY) value else "$rough $value" + when (state.visibleTypeOfReceipt) { ReceiptLayoutType.FIAT -> { val receipt = state.fiat ?: return @@ -191,7 +194,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalTokenLayout.show(false) fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("$rough ${receipt.totalFiat} ${receipt.symbols.fiat}") + totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") val willSent = SpannableStringBuilder() .bold { append(receipt.willSentCrypto) }.append(" ") @@ -211,8 +214,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val willSent = SpannableStringBuilder() .bold { - append(rough).append(" ") - append(receipt.willSentFiat).append(" ") + append(roughOrEmpty(receipt.willSentFiat)).append(" ") append(receipt.symbols.fiat) append(" (fee: ${receipt.feeFiat} ") append(receipt.symbols.fiat).append(")") @@ -226,7 +228,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalTokenLayout.show(false) fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("${receipt.totalFiat} ${receipt.symbols.fiat}") + totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") val willSent = SpannableStringBuilder() .bold { @@ -252,8 +254,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val willSent = SpannableStringBuilder() .bold { - append(getString(R.string.sign_rough)).append(" ") - append(receipt.totalFiat).append(" ") + append(roughOrEmpty(receipt.totalFiat)).append(" ") append(receipt.symbols.fiat) } totalTokenLayout.tvTotalTokenCryptoValue.update(willSent.toString())