diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/adapters/SolanaAdapter.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/adapters/SolanaAdapter.kt index d473a27ddde..90a9d217d3b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/adapters/SolanaAdapter.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/adapters/SolanaAdapter.kt @@ -64,22 +64,22 @@ class SolanaAdapter(kitWrapper: SolanaKitWrapper) : BaseSolanaAdapter(kitWrapper is SolanaKit.SyncState.Syncing -> AdapterState.Syncing() } - private fun scaleDown(amount: BigDecimal, decimals: Int = decimal): BigDecimal { - return amount.movePointLeft(decimals).stripTrailingZeros() - } + companion object { + const val decimal = 9 - private fun scaleUp(amount: BigDecimal, decimals: Int = decimal): BigInteger { - return amount.movePointRight(decimals).toBigInteger() - } + private fun scaleDown(amount: BigDecimal, decimals: Int = decimal): BigDecimal { + return amount.movePointLeft(decimals).stripTrailingZeros() + } - private fun balanceInBigDecimal(balance: Long?, decimal: Int): BigDecimal { - balance?.toBigDecimal()?.let { - return scaleDown(it, decimal) - } ?: return BigDecimal.ZERO - } + private fun scaleUp(amount: BigDecimal, decimals: Int = decimal): BigInteger { + return amount.movePointRight(decimals).toBigInteger() + } - companion object { - const val decimal = 9 + fun balanceInBigDecimal(balance: Long?, decimal: Int): BigDecimal { + balance?.toBigDecimal()?.let { + return scaleDown(it, decimal) + } ?: return BigDecimal.ZERO + } fun clear(walletId: String) { SolanaKit.clear(App.instance, walletId) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt index d368417e3b2..5de51de10d2 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt @@ -105,7 +105,7 @@ fun SendConfirmationScreen( } is SendResult.Failed -> { - HudHelper.showErrorMessage(view, sendResult.caution.getString()) + HudHelper.showErrorMessage(view, sendResult.caution.getDescription() ?: sendResult.caution.getString()) } null -> Unit diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaModule.kt index b845157f8e1..a75049eb8bc 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaModule.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.ISendSolanaAdapter +import io.horizontalsystems.bankwallet.core.adapters.SolanaAdapter import io.horizontalsystems.bankwallet.core.isNative import io.horizontalsystems.bankwallet.entities.Wallet import io.horizontalsystems.bankwallet.modules.amount.AmountValidator @@ -12,6 +13,7 @@ import io.horizontalsystems.bankwallet.modules.xrate.XRateService import io.horizontalsystems.marketkit.models.BlockchainType import io.horizontalsystems.marketkit.models.TokenQuery import io.horizontalsystems.marketkit.models.TokenType +import io.horizontalsystems.solanakit.SolanaKit import java.math.RoundingMode object SendSolanaModule { @@ -35,14 +37,17 @@ object SendSolanaModule { adapter.availableBalance.setScale(coinMaxAllowedDecimals, RoundingMode.DOWN), wallet.token.type.isNative, ) + val solToken = App.coinManager.getToken(TokenQuery(BlockchainType.Solana, TokenType.Native)) ?: throw IllegalArgumentException() + val balance = App.solanaKitManager.solanaKitWrapper?.solanaKit?.balance ?: 0L + val solBalance = SolanaAdapter.balanceInBigDecimal(balance, solToken.decimals) - SolanaKit.accountRentAmount val addressService = SendSolanaAddressService(predefinedAddress) val xRateService = XRateService(App.marketKit, App.currencyManager.baseCurrency) - val feeToken = App.coinManager.getToken(TokenQuery(BlockchainType.Solana, TokenType.Native)) ?: throw IllegalArgumentException() SendSolanaViewModel( wallet, wallet.token, - feeToken, + solToken, + solBalance, adapter, xRateService, amountService, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaViewModel.kt index adbb91da43e..df1aeaf11cc 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/solana/SendSolanaViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope import cash.z.ecc.android.sdk.ext.collectWith import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App +import io.horizontalsystems.bankwallet.core.EvmError import io.horizontalsystems.bankwallet.core.HSCaution import io.horizontalsystems.bankwallet.core.ISendSolanaAdapter import io.horizontalsystems.bankwallet.core.LocalizedException @@ -17,11 +18,13 @@ import io.horizontalsystems.bankwallet.entities.Wallet import io.horizontalsystems.bankwallet.modules.amount.SendAmountService import io.horizontalsystems.bankwallet.modules.contacts.ContactsRepository import io.horizontalsystems.bankwallet.modules.send.SendConfirmationData +import io.horizontalsystems.bankwallet.modules.send.SendErrorInsufficientBalance import io.horizontalsystems.bankwallet.modules.send.SendResult import io.horizontalsystems.bankwallet.modules.send.SendUiState import io.horizontalsystems.bankwallet.modules.xrate.XRateService import io.horizontalsystems.bankwallet.ui.compose.TranslatableString import io.horizontalsystems.marketkit.models.Token +import io.horizontalsystems.marketkit.models.TokenType import io.horizontalsystems.solanakit.SolanaKit import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -33,6 +36,7 @@ class SendSolanaViewModel( val wallet: Wallet, val sendToken: Token, val feeToken: Token, + val solBalance: BigDecimal, val adapter: ISendSolanaAdapter, private val xRateService: XRateService, private val amountService: SendAmountService, @@ -117,7 +121,7 @@ class SendSolanaViewModel( } private suspend fun send() = withContext(Dispatchers.IO) { - if (!hasConnection()){ + if (!hasConnection()) { sendResult = SendResult.Failed(createCaution(UnknownHostException())) return@withContext } @@ -125,6 +129,11 @@ class SendSolanaViewModel( try { sendResult = SendResult.Sending + val totalSolAmount = (if (sendToken.type == TokenType.Native) decimalAmount else BigDecimal.ZERO) + SolanaKit.fee + + if (totalSolAmount > solBalance) + throw EvmError.InsufficientBalanceWithFee + adapter.send(decimalAmount, addressState.evmAddress!!) sendResult = SendResult.Sent @@ -136,7 +145,8 @@ class SendSolanaViewModel( private fun createCaution(error: Throwable) = when (error) { is UnknownHostException -> HSCaution(TranslatableString.ResString(R.string.Hud_Text_NoInternet)) is LocalizedException -> HSCaution(TranslatableString.ResString(error.errorTextRes)) - else -> HSCaution(TranslatableString.PlainString(error.message ?: "")) + is EvmError.InsufficientBalanceWithFee -> SendErrorInsufficientBalance(feeToken.coin.code) + else -> HSCaution(TranslatableString.PlainString(error.cause?.message ?: error.message ?: "")) } private fun handleUpdatedAmountState(amountState: SendAmountService.State) { diff --git a/core/src/main/res/layout/view_custom_snackbar.xml b/core/src/main/res/layout/view_custom_snackbar.xml index 43bbcb9edc6..c200217d212 100644 --- a/core/src/main/res/layout/view_custom_snackbar.xml +++ b/core/src/main/res/layout/view_custom_snackbar.xml @@ -29,7 +29,7 @@ android:layout_weight="1" android:fontFamily="sans-serif-medium" android:textSize="14sp" - android:maxLines="2" + android:maxLines="4" tools:text="Snackbar Text" />