Updated on 2026-08-14

This commit is contained in:
Tangem 2023-03-29 14:12:34 +03:00
commit d2baa177a4
21 changed files with 107 additions and 9 deletions

View file

@ -36,6 +36,7 @@ fun Blockchain.getGreyedOutIconRes(): Int {
Blockchain.Kusama -> R.drawable.ic_kusama_no_color
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism_no_color
Blockchain.Dash -> R.drawable.ic_dash_no_color
Blockchain.Kaspa -> R.drawable.ic_kaspa_no_color
else -> R.drawable.ic_tangem_logo
}
}

View file

@ -60,7 +60,7 @@ class LoadAvailableCoinsService(
return withContext(dispatchers.io) {
runCatching {
tangemTechApi.getCoins(
networkIds = supportedBlockchains.toSet().map(Blockchain::toNetworkId).joinToString(","),
networkIds = supportedBlockchains.toSet().joinToString(",", transform = Blockchain::toNetworkId),
active = true,
searchText = searchInput,
offset = offset,

View file

@ -155,6 +155,12 @@ sealed class SendAction : SendScreenAction {
val reduceAmount: BigDecimal,
) : Dialog()
data class KaspaWarningDialog(
val maxOutputs: Int,
val maxAmount: BigDecimal,
val onOk: () -> Unit,
) : Dialog()
sealed class SendTransactionFails : Dialog() {
data class CardSdkError(val error: TangemSdkError) : Dialog()
data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError) : Dialog()

View file

@ -52,7 +52,7 @@ internal class AddressPayIdMiddleware {
}
private fun setAddressAndCheck(data: String, isUserInput: Boolean, dispatch: (Action) -> Unit) {
val potentialPayId = data.toLowerCase()
val potentialPayId = data.lowercase()
if (isPayIdEnabled() && PayIdManager.isPayId(potentialPayId)) {
dispatch(SetPayIdWalletAddress(potentialPayId, "", isUserInput))
} else {
@ -113,10 +113,11 @@ internal class AddressPayIdMiddleware {
}
private fun verifyAddress(address: String, wallet: Wallet, isUserInput: Boolean, dispatch: (Action) -> Unit) {
val addressSchemeSplit = if (wallet.blockchain == Blockchain.BitcoinCash) {
listOf(address)
} else {
address.split(":")
val addressSchemeSplit = when (wallet.blockchain) {
Blockchain.BitcoinCash,
Blockchain.Kaspa,
-> listOf(address)
else -> address.split(":")
}
val noSchemeAddress = when (addressSchemeSplit.size) {
1 -> address // no scheme

View file

@ -269,6 +269,18 @@ private fun sendTransaction(
// from XLM, XRP, Polkadot
dispatch(SendAction.Dialog.SendTransactionFails.BlockchainSdkError(error))
}
is BlockchainSdkError.Kaspa.UtxoAmountError -> {
dispatch(
SendAction.Dialog.KaspaWarningDialog(
maxOutputs = error.maxOutputs,
maxAmount = error.maxAmount,
onOk = {
dispatch(AmountAction.SetAmount(error.maxAmount, isUserInput = false))
dispatch(AmountActionUi.CheckAmountToSend)
},
),
)
}
else -> {
when {
error.customMessage.contains(DemoTransactionSender.ID) -> {

View file

@ -55,6 +55,7 @@ private class SendReducer : SendInternalReducer {
sendState.copy(sendButtonState = IndeterminateProgressButton(action.state))
}
is SendAction.Dialog.TezosWarningDialog -> sendState.copy(dialog = action)
is SendAction.Dialog.KaspaWarningDialog -> sendState.copy(dialog = action)
is SendAction.Dialog.SendTransactionFails.CardSdkError -> sendState.copy(dialog = action)
is SendAction.Dialog.SendTransactionFails.BlockchainSdkError -> sendState.copy(dialog = action)
is SendAction.Dialog.RequestFeeError -> sendState.copy(dialog = action)

View file

@ -0,0 +1,27 @@
package com.tangem.tap.features.send.ui.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.tangem.tap.features.send.redux.SendAction
import com.tangem.tap.store
import com.tangem.wallet.R
object KaspaWarningDialog {
fun create(context: Context, dialog: SendAction.Dialog.KaspaWarningDialog): AlertDialog {
return AlertDialog.Builder(context).apply {
setTitle(R.string.common_warning)
setMessage(
context.getString(
R.string.kaspa_withdrawal_message_warning,
dialog.maxOutputs,
dialog.maxAmount.toPlainString(),
),
)
setPositiveButton(R.string.common_ok) { _, _ ->
store.dispatch(SendAction.Dialog.Hide)
dialog.onOk()
}
}
.create()
}
}

View file

@ -33,6 +33,7 @@ import com.tangem.tap.features.send.redux.states.TransactionExtraError
import com.tangem.tap.features.send.redux.states.TransactionExtrasState
import com.tangem.tap.features.send.ui.FeeUiHelper
import com.tangem.tap.features.send.ui.SendFragment
import com.tangem.tap.features.send.ui.dialogs.KaspaWarningDialog
import com.tangem.tap.features.send.ui.dialogs.RequestFeeErrorDialog
import com.tangem.tap.features.send.ui.dialogs.SendTransactionFailsDialog
import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog
@ -124,6 +125,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
dialog?.show()
}
}
is SendAction.Dialog.KaspaWarningDialog -> {
if (dialog == null) {
dialog = KaspaWarningDialog.create(fg.requireContext(), state.dialog)
dialog?.show()
}
}
is SendAction.Dialog.SendTransactionFails.CardSdkError -> {
if (dialog == null) {
dialog = SendTransactionFailsDialog.create(fg.requireContext(), state.dialog)

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:fillColor="#EBEBEB"
android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z" />
<path
android:fillColor="#C9C9C9"
android:pathData="M13.659,5.35L11.564,5.663L12.174,9.721L7.787,6.34L6.5,8.022L10.343,10.975L6.5,13.944L7.787,15.626L12.174,12.245L11.564,16.303L13.659,16.616L14.5,10.975L13.659,5.35Z" />
</vector>

View file

@ -102,6 +102,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
saltPayAuthToken = configValues.saltPay.credentials.basicAuthToken,
nowNodeCredentials = NowNodeCredentials(configValues.nowNodesApiKey),
getBlockCredentials = GetBlockCredentials(configValues.getBlockApiKey),
kaspaSecondaryApiUrl = configValues.kaspaSecondaryApiUrl,
),
appsFlyerDevKey = configValues.appsFlyer.appsFlyerDevKey,
amplitudeApiKey = configValues.amplitudeApiKey,

View file

@ -35,6 +35,7 @@ class ConfigValueModel(
val tronGridApiKey: String,
val amplitudeApiKey: String,
val swapReferrerAccount: SwapReferrerAccount?,
val kaspaSecondaryApiUrl: String,
)
data class AppsFlyer(

View file

@ -3,6 +3,8 @@
<string name="address_type_default">Default</string>
<string name="address_type_legacy">Legacy</string>
<string name="common_fee_error">Erhalt der Gebühr fehlgeschlagen</string>
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">Laden Sie %1$s+ %2$s auf um ein Konto zu erstellen</string>
<string name="no_account_polkadot">Destination account is not active. Send %s or more to activate the account.</string>
<string name="send_error_blockchain_internal">Interner Fehler der Blockchain</string>

View file

@ -3,6 +3,8 @@
<string name="address_type_default">Default</string>
<string name="address_type_legacy">Legacy</string>
<string name="common_fee_error">Échec de réception des commissions</string>
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">Pour créer un compte, téléchargez %1$s+ %2$s</string>
<string name="no_account_polkadot">Destination account is not active. Send %s or more to activate the account.</string>
<string name="send_error_blockchain_internal">Erreur interne de la blockchain</string>

View file

@ -3,6 +3,8 @@
<string name="address_type_default">Default</string>
<string name="address_type_legacy">Legacy</string>
<string name="common_fee_error">Impossibile ottenere la commissione</string>
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">Scarica %1$s+ %2$s per creare un account</string>
<string name="no_account_polkadot">Destination account is not active. Send %s or more to activate the account.</string>
<string name="send_error_blockchain_internal">Errore interno della blockchain</string>

View file

@ -3,6 +3,8 @@
<string name="address_type_default">По умолчанию</string>
<string name="address_type_legacy">Устаревший</string>
<string name="common_fee_error">Не удалось получить комиссию</string>
<string name="eth_gas_required_exceeds_allowance">Недостаточно средств для совершения транзакции. Пожалуйста, пополните свой аккаунт.</string>
<string name="kaspa_withdrawal_message_warning">Из-за ограничений Kaspa в одну транзакцию может поместиться только %1$d UTXO. Это означает, что вы можете отправить только %2$s или меньше. Вам нужно уменьшить сумму.</string>
<string name="no_account_generic">Пополните счет на %1$s+ %2$s, чтобы создать аккаунт</string>
<string name="no_account_polkadot">Аккаунт получателя не активирован. Отправьте %s или более для активации аккаунта.</string>
<string name="send_error_blockchain_internal">Внутренняя ошибка блокчейна</string>

View file

@ -3,8 +3,10 @@
<string name="address_type_default">默認</string>
<string name="address_type_legacy">遺留資產</string>
<string name="common_fee_error">獲取費用失敗</string>
<string name="eth_gas_required_exceeds_allowance">沒有足夠的資金進行交易。請先入金</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">加載 %1$s+ %2$s 以創建帳戶</string>
<string name="no_account_polkadot">目標帳戶未激活。發送 %s 或更多以激活帳戶。</string>
<string name="no_account_polkadot">目標帳戶未激活。發送 %s 或更多以激活帳戶</string>
<string name="send_error_blockchain_internal">區塊鏈內部錯誤</string>
<string name="send_error_dust_amount_format">最小數量是 %s</string>
<string name="send_error_dust_change">更動太小</string>

View file

@ -3,6 +3,8 @@
<string name="address_type_default">Default</string>
<string name="address_type_legacy">Legacy</string>
<string name="common_fee_error">Failed to get fee</string>
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">Load %1$s+ %2$s to create account</string>
<string name="no_account_polkadot">Destination account is not active. Send %s or more to activate the account.</string>
<string name="send_error_blockchain_internal">Blockchain internal error</string>

View file

@ -32,6 +32,7 @@ fun getActiveIconRes(blockchainId: String): Int {
"Kusama" -> R.drawable.img_kusama_22
"OPTIMISM", "OPTIMISM/test" -> R.drawable.img_optimism_22
"DASH" -> R.drawable.img_dash_22
"KAS" -> R.drawable.img_kaspa_22
else -> R.drawable.ic_alert_24
}
}
@ -70,6 +71,7 @@ fun getActiveIconResByCoinId(coinId: String, networkId: String): Int {
"ethereumfair" -> R.drawable.img_eth_fair_22
"kusama" -> R.drawable.img_kusama_22
"dash" -> R.drawable.img_dash_22
"kaspa" -> R.drawable.img_kaspa_22
else -> R.drawable.ic_alert_24
}
}

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:fillColor="#71C9BB"
android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z" />
<path
android:fillColor="#ffffff"
android:pathData="M13.659,5.35L11.564,5.663L12.174,9.721L7.787,6.34L6.5,8.022L10.343,10.975L6.5,13.944L7.787,15.626L12.174,12.245L11.564,16.303L13.659,16.616L14.5,10.975L13.659,5.35Z" />
</vector>

View file

@ -49,6 +49,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
"optimistic-ethereum/test" -> Blockchain.OptimismTestnet
"dash" -> Blockchain.Dash
"sxdai" -> Blockchain.SaltPay
"kaspa" -> Blockchain.Kaspa
else -> null
}
}
@ -102,6 +103,7 @@ fun Blockchain.toNetworkId(): String {
Blockchain.OptimismTestnet -> "optimistic-ethereum/test"
Blockchain.Dash -> "dash"
Blockchain.SaltPay -> "sxdai"
Blockchain.Kaspa -> "kaspa"
}
}
@ -135,6 +137,7 @@ fun Blockchain.toCoinId(): String {
Blockchain.Optimism, Blockchain.OptimismTestnet -> "ethereum"
Blockchain.Dash -> "dash"
Blockchain.SaltPay -> "xdai"
Blockchain.Kaspa -> "kaspa"
Blockchain.Unknown -> "unknown"
}
}

View file

@ -68,8 +68,8 @@ kotlinSerialization = "1.4.1"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-177"
# tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemBlockchainSdk = "develop-179"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-204"
# tangemCardSdk = "0.0.1" # Keep it! - used for local builds
# endregion Tangem