Updated on 2026-08-14
This commit is contained in:
parent
e5d135edb4
commit
a0834799ea
15 changed files with 141 additions and 64 deletions
|
|
@ -130,7 +130,7 @@
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="sell-request.tangem.com"
|
android:host="redirect_sell"
|
||||||
android:scheme="tangem" />
|
android:scheme="tangem" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,7 @@ object TradeCryptoMiddleware {
|
||||||
SendRouter.TRANSACTION_ID_KEY to txInfo?.transactionId,
|
SendRouter.TRANSACTION_ID_KEY to txInfo?.transactionId,
|
||||||
SendRouter.DESTINATION_ADDRESS_KEY to txInfo?.destinationAddress,
|
SendRouter.DESTINATION_ADDRESS_KEY to txInfo?.destinationAddress,
|
||||||
SendRouter.AMOUNT_KEY to txInfo?.amount,
|
SendRouter.AMOUNT_KEY to txInfo?.amount,
|
||||||
|
SendRouter.TAG_KEY to txInfo?.tag,
|
||||||
)
|
)
|
||||||
store.dispatchOnMain(NavigationAction.NavigateTo(screen = AppScreen.Send, bundle = bundle))
|
store.dispatchOnMain(NavigationAction.NavigateTo(screen = AppScreen.Send, bundle = bundle))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.tangem.tap.network.exchangeServices.moonpay
|
||||||
|
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.blockchain.common.Blockchain.*
|
||||||
|
import com.tangem.tap.network.exchangeServices.moonpay.models.MoonPaySupportedCurrency
|
||||||
|
|
||||||
|
internal val Blockchain.moonPaySupportedCurrency: MoonPaySupportedCurrency?
|
||||||
|
get() = when (this) {
|
||||||
|
Algorand -> MoonPaySupportedCurrency(networkCode = "algorand", currencyCode = "algo")
|
||||||
|
Aptos -> MoonPaySupportedCurrency(networkCode = "aptos", currencyCode = "apt")
|
||||||
|
Arbitrum -> MoonPaySupportedCurrency(networkCode = "arbitrum", currencyCode = "eth_arbitrum")
|
||||||
|
Avalanche -> MoonPaySupportedCurrency(networkCode = "avalanche_c_chain", currencyCode = "avax_cchain")
|
||||||
|
Binance -> MoonPaySupportedCurrency(networkCode = "bnb_chain", currencyCode = "bnb")
|
||||||
|
Bitcoin -> MoonPaySupportedCurrency(networkCode = "bitcoin", currencyCode = "btc")
|
||||||
|
BitcoinCash -> MoonPaySupportedCurrency(networkCode = "bitcoin_cash", currencyCode = "bch")
|
||||||
|
BSC -> MoonPaySupportedCurrency(networkCode = "binance_smart_chain", currencyCode = "bnb_bsc")
|
||||||
|
Cardano -> MoonPaySupportedCurrency(networkCode = "cardano", currencyCode = "ada")
|
||||||
|
Cosmos -> MoonPaySupportedCurrency(networkCode = "cosmos", currencyCode = "atom")
|
||||||
|
Dogecoin -> MoonPaySupportedCurrency(networkCode = "dogecoin", currencyCode = "doge")
|
||||||
|
Ethereum -> MoonPaySupportedCurrency(networkCode = "ethereum", currencyCode = "eth")
|
||||||
|
EthereumClassic -> MoonPaySupportedCurrency(networkCode = "ethereum_classic", currencyCode = "etc")
|
||||||
|
Hedera -> MoonPaySupportedCurrency(networkCode = "hedera", currencyCode = "hbar")
|
||||||
|
Litecoin -> MoonPaySupportedCurrency(networkCode = "litecoin", currencyCode = "ltc")
|
||||||
|
Near -> MoonPaySupportedCurrency(networkCode = "near", currencyCode = "near")
|
||||||
|
Optimism -> MoonPaySupportedCurrency(networkCode = "optimism", currencyCode = "eth_optimism")
|
||||||
|
Polkadot -> MoonPaySupportedCurrency(networkCode = "polkadot", currencyCode = "dot")
|
||||||
|
Polygon -> MoonPaySupportedCurrency(networkCode = "polygon", currencyCode = "matic_polygon")
|
||||||
|
Ravencoin -> MoonPaySupportedCurrency(networkCode = "ravencoin", currencyCode = "rvn")
|
||||||
|
Solana -> MoonPaySupportedCurrency(networkCode = "solana", currencyCode = "sol")
|
||||||
|
Stellar -> MoonPaySupportedCurrency(networkCode = "stellar", currencyCode = "xlm")
|
||||||
|
Tezos -> MoonPaySupportedCurrency(networkCode = "tezos", currencyCode = "xtz")
|
||||||
|
TON -> MoonPaySupportedCurrency(networkCode = "ton", currencyCode = "ton")
|
||||||
|
Tron -> MoonPaySupportedCurrency(networkCode = "tron", currencyCode = "trx")
|
||||||
|
VeChain -> MoonPaySupportedCurrency(networkCode = "vechain", currencyCode = "vet")
|
||||||
|
XRP -> MoonPaySupportedCurrency(networkCode = "ripple", currencyCode = "xrp")
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import com.tangem.tap.domain.model.Currency
|
||||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||||
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder.Companion.SCHEME
|
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder.Companion.SCHEME
|
||||||
|
import com.tangem.tap.network.exchangeServices.moonpay.models.MoonPayAvailableCurrency
|
||||||
import javax.crypto.Mac
|
import javax.crypto.Mac
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
|
|
@ -35,42 +36,46 @@ class MoonPayService(
|
||||||
override suspend fun update() {
|
override suspend fun update() {
|
||||||
withIOContext {
|
withIOContext {
|
||||||
performRequest {
|
performRequest {
|
||||||
val userStatusResult = performRequest { api.getUserStatus(apiKey) }
|
val userStatus = when (val result = performRequest { api.getUserStatus(apiKey) }) {
|
||||||
if (userStatusResult is Result.Failure) return@performRequest
|
is Result.Failure -> return@performRequest
|
||||||
|
is Result.Success -> result.data
|
||||||
val currenciesResult = performRequest { api.getCurrencies(apiKey) }
|
|
||||||
if (currenciesResult is Result.Failure) return@performRequest
|
|
||||||
|
|
||||||
val userStatus = (userStatusResult as Result.Success).data
|
|
||||||
val currencies = (currenciesResult as Result.Success).data
|
|
||||||
|
|
||||||
// val currenciesToBuy = mutableListOf<String>()
|
|
||||||
val currenciesToSell = mutableListOf<String>()
|
|
||||||
|
|
||||||
currencies.forEach { currencyStatus ->
|
|
||||||
if (currencyStatus.type != "crypto" || currencyStatus.isSuspended ||
|
|
||||||
!currencyStatus.supportsLiveMode
|
|
||||||
) {
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userStatus.countryCode == "USA") {
|
|
||||||
if (!currencyStatus.isSupportedInUS) return@forEach
|
|
||||||
if (currencyStatus.notAllowedUSStates.contains(userStatus.stateCode)) return@forEach
|
|
||||||
}
|
|
||||||
val currencyCode = currencyStatus.code.uppercase()
|
|
||||||
// currenciesToBuy.add(currencyCode)
|
|
||||||
|
|
||||||
if (currencyStatus.isSellSupported) currenciesToSell.add(currencyCode)
|
|
||||||
}
|
}
|
||||||
// currenciesToBuy.sort()
|
|
||||||
currenciesToSell.sort()
|
val currencies = when (val result = performRequest { api.getCurrencies(apiKey) }) {
|
||||||
|
is Result.Failure -> return@performRequest
|
||||||
|
is Result.Success -> result.data
|
||||||
|
}
|
||||||
|
|
||||||
|
val currenciesToSell = currencies
|
||||||
|
.filter { currency ->
|
||||||
|
checkGeneralRequirements(currency) && checkUSARequirements(userStatus, currency)
|
||||||
|
}
|
||||||
|
.mapNotNull { currency ->
|
||||||
|
MoonPayAvailableCurrency(
|
||||||
|
currencyCode = currency.code,
|
||||||
|
networkCode = currency.metadata?.networkCode ?: return@mapNotNull null,
|
||||||
|
contractAddress = currency.metadata.contractAddress,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
status = MoonPayStatus(currenciesToSell, userStatus, currencies)
|
status = MoonPayStatus(currenciesToSell, userStatus, currencies)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkGeneralRequirements(currency: MoonPayCurrencies): Boolean {
|
||||||
|
return currency.type == "crypto" && !currency.isSuspended && currency.supportsLiveMode &&
|
||||||
|
currency.isSellSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkUSARequirements(userStatus: MoonPayUserStatus, currency: MoonPayCurrencies): Boolean {
|
||||||
|
return if (userStatus.countryCode == "USA") {
|
||||||
|
currency.isSupportedInUS && !currency.notAllowedUSStates.contains(userStatus.stateCode)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun isBuyAllowed(): Boolean = false
|
override fun isBuyAllowed(): Boolean = false
|
||||||
|
|
||||||
override fun isSellAllowed(): Boolean {
|
override fun isSellAllowed(): Boolean {
|
||||||
|
|
@ -80,21 +85,21 @@ class MoonPayService(
|
||||||
override fun availableForBuy(currency: Currency): Boolean = false
|
override fun availableForBuy(currency: Currency): Boolean = false
|
||||||
|
|
||||||
override fun availableForSell(currency: Currency): Boolean {
|
override fun availableForSell(currency: Currency): Boolean {
|
||||||
val availableForSell = status?.availableForSell ?: return false
|
|
||||||
val metadata = status?.responseCurrencies?.filter { it.isSellSupported }?.map { it.metadata }
|
|
||||||
if (!isSellAllowed()) return false
|
if (!isSellAllowed()) return false
|
||||||
|
|
||||||
return when (currency) {
|
val availableForSell = status?.availableForSell ?: return false
|
||||||
is Currency.Blockchain -> {
|
|
||||||
val blockchain = currency.blockchain
|
val supportedCurrency = currency.blockchain.moonPaySupportedCurrency ?: return false
|
||||||
when {
|
return availableForSell.any {
|
||||||
blockchain.isTestnet() -> false
|
when (currency) {
|
||||||
blockchain == Blockchain.Unknown || currency.blockchain == Blockchain.BSC -> false
|
is Currency.Blockchain -> {
|
||||||
else -> availableForSell.contains(currency.currencySymbol)
|
it.networkCode.equals(other = supportedCurrency.networkCode, ignoreCase = true) &&
|
||||||
|
it.currencyCode.equals(other = supportedCurrency.currencyCode, ignoreCase = true)
|
||||||
|
}
|
||||||
|
is Currency.Token -> {
|
||||||
|
it.networkCode.equals(other = supportedCurrency.networkCode, ignoreCase = true) &&
|
||||||
|
it.contractAddress.equals(other = currency.token.contractAddress, ignoreCase = true)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is Currency.Token -> {
|
|
||||||
metadata?.any { it?.contractAddress.equals(currency.token.contractAddress, ignoreCase = true) } ?: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +108,7 @@ class MoonPayService(
|
||||||
action: CurrencyExchangeManager.Action,
|
action: CurrencyExchangeManager.Action,
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
cryptoCurrencyName: CryptoCurrencyName,
|
cryptoCurrencyName: CryptoCurrencyName,
|
||||||
fatCurrency: String,
|
fiatCurrencyName: String,
|
||||||
walletAddress: String,
|
walletAddress: String,
|
||||||
isDarkTheme: Boolean,
|
isDarkTheme: Boolean,
|
||||||
): String {
|
): String {
|
||||||
|
|
@ -115,7 +120,8 @@ class MoonPayService(
|
||||||
.appendQueryParameter("apiKey", apiKey)
|
.appendQueryParameter("apiKey", apiKey)
|
||||||
.appendQueryParameter("baseCurrencyCode", cryptoCurrencyName)
|
.appendQueryParameter("baseCurrencyCode", cryptoCurrencyName)
|
||||||
.appendQueryParameter("refundWalletAddress", walletAddress)
|
.appendQueryParameter("refundWalletAddress", walletAddress)
|
||||||
.appendQueryParameter("redirectURL", "tangem://sell-request.tangem.com")
|
.appendQueryParameter("redirectURL", "tangem://redirect_sell")
|
||||||
|
|
||||||
if (isDarkTheme) uri.appendQueryParameter("theme", "dark")
|
if (isDarkTheme) uri.appendQueryParameter("theme", "dark")
|
||||||
|
|
||||||
val originalQuery = uri.build().encodedQuery ?: uri.build().toString()
|
val originalQuery = uri.build().encodedQuery ?: uri.build().toString()
|
||||||
|
|
@ -147,7 +153,7 @@ class MoonPayService(
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class MoonPayStatus(
|
private data class MoonPayStatus(
|
||||||
val availableForSell: List<String>,
|
val availableForSell: List<MoonPayAvailableCurrency>,
|
||||||
val responseUserStatus: MoonPayUserStatus,
|
val responseUserStatus: MoonPayUserStatus,
|
||||||
val responseCurrencies: List<MoonPayCurrencies>,
|
val responseCurrencies: List<MoonPayCurrencies>,
|
||||||
)
|
)
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.tangem.tap.network.exchangeServices.moonpay.models
|
||||||
|
|
||||||
|
internal data class MoonPayAvailableCurrency(
|
||||||
|
val currencyCode: String,
|
||||||
|
val networkCode: String,
|
||||||
|
val contractAddress: String?,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.tangem.tap.network.exchangeServices.moonpay.models
|
||||||
|
|
||||||
|
internal data class MoonPaySupportedCurrency(val networkCode: String, val currencyCode: String?)
|
||||||
|
|
@ -4,13 +4,14 @@ import com.tangem.core.deeplink.DeepLink
|
||||||
|
|
||||||
class SellCurrencyDeepLink(val onReceive: (data: Data) -> Unit) : DeepLink {
|
class SellCurrencyDeepLink(val onReceive: (data: Data) -> Unit) : DeepLink {
|
||||||
|
|
||||||
override val uri: String = "tangem://sell-request.tangem.com"
|
override val uri: String = "tangem://redirect_sell"
|
||||||
|
|
||||||
override fun onReceive(params: Map<String, String>) {
|
override fun onReceive(params: Map<String, String>) {
|
||||||
val data = Data(
|
val data = Data(
|
||||||
transactionId = params["transactionId"] ?: return,
|
transactionId = params["transactionId"] ?: return,
|
||||||
baseCurrencyAmount = params["baseCurrencyAmount"] ?: return,
|
baseCurrencyAmount = params["baseCurrencyAmount"] ?: return,
|
||||||
depositWalletAddress = params["depositWalletAddress"] ?: return,
|
depositWalletAddress = params["depositWalletAddress"] ?: return,
|
||||||
|
depositWalletAddressTag = params["depositWalletAddressTag"],
|
||||||
)
|
)
|
||||||
|
|
||||||
onReceive(data)
|
onReceive(data)
|
||||||
|
|
@ -20,5 +21,6 @@ class SellCurrencyDeepLink(val onReceive: (data: Data) -> Unit) : DeepLink {
|
||||||
val transactionId: String,
|
val transactionId: String,
|
||||||
val baseCurrencyAmount: String,
|
val baseCurrencyAmount: String,
|
||||||
val depositWalletAddress: String,
|
val depositWalletAddress: String,
|
||||||
|
val depositWalletAddressTag: String?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -41,8 +41,9 @@ sealed class TradeCryptoAction : Action {
|
||||||
data class Swap(val cryptoCurrency: CryptoCurrency) : TradeCryptoAction()
|
data class Swap(val cryptoCurrency: CryptoCurrency) : TradeCryptoAction()
|
||||||
|
|
||||||
data class TransactionInfo(
|
data class TransactionInfo(
|
||||||
val amount: String,
|
|
||||||
val destinationAddress: String,
|
|
||||||
val transactionId: String,
|
val transactionId: String,
|
||||||
|
val destinationAddress: String,
|
||||||
|
val amount: String,
|
||||||
|
val tag: String? = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ interface SendRouter {
|
||||||
const val USER_WALLET_ID_KEY = "send_user_wallet_id"
|
const val USER_WALLET_ID_KEY = "send_user_wallet_id"
|
||||||
const val TRANSACTION_ID_KEY = "send_transaction_id"
|
const val TRANSACTION_ID_KEY = "send_transaction_id"
|
||||||
const val AMOUNT_KEY = "send_amount"
|
const val AMOUNT_KEY = "send_amount"
|
||||||
|
const val TAG_KEY = "send_tag"
|
||||||
const val DESTINATION_ADDRESS_KEY = "send_destination_address"
|
const val DESTINATION_ADDRESS_KEY = "send_destination_address"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -87,16 +87,18 @@ internal class SendStateFactory(
|
||||||
val state = currentStateProvider()
|
val state = currentStateProvider()
|
||||||
return state.copy(
|
return state.copy(
|
||||||
amountState = state.amountState ?: amountStateConverter.convert(""),
|
amountState = state.amountState ?: amountStateConverter.convert(""),
|
||||||
recipientState = state.recipientState ?: recipientStateConverter.convert(""),
|
recipientState = state.recipientState
|
||||||
|
?: recipientStateConverter.convert(SendRecipientStateConverter.Data("", null)),
|
||||||
feeState = state.feeState ?: feeStateConverter.convert(Unit),
|
feeState = state.feeState ?: feeStateConverter.convert(Unit),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReadyState(amount: String, destinationAddress: String): SendUiState {
|
fun getReadyState(amount: String, destinationAddress: String, memo: String?): SendUiState {
|
||||||
val state = currentStateProvider()
|
val state = currentStateProvider()
|
||||||
return state.copy(
|
return state.copy(
|
||||||
amountState = state.amountState ?: amountStateConverter.convert(amount),
|
amountState = state.amountState ?: amountStateConverter.convert(amount),
|
||||||
recipientState = state.recipientState ?: recipientStateConverter.convert(destinationAddress),
|
recipientState = state.recipientState
|
||||||
|
?: recipientStateConverter.convert(SendRecipientStateConverter.Data(destinationAddress, memo)),
|
||||||
feeState = state.feeState ?: feeStateConverter.convert(Unit),
|
feeState = state.feeState ?: feeStateConverter.convert(Unit),
|
||||||
isEditingDisabled = true,
|
isEditingDisabled = true,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.features.send.impl.presentation.state.recipient
|
package com.tangem.features.send.impl.presentation.state.recipient
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
|
@ -15,13 +16,18 @@ import com.tangem.utils.converter.Converter
|
||||||
internal class SendRecipientMemoFieldConverter(
|
internal class SendRecipientMemoFieldConverter(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val cryptoCurrencyStatus: Provider<CryptoCurrencyStatus>,
|
private val cryptoCurrencyStatus: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<Int, SendTextField.RecipientMemo> {
|
) : Converter<SendRecipientMemoFieldConverter.Data, SendTextField.RecipientMemo> {
|
||||||
|
|
||||||
fun convertOrNull(): SendTextField.RecipientMemo? {
|
fun convertOrNull(memoValue: String?): SendTextField.RecipientMemo? {
|
||||||
val cryptoCurrency = cryptoCurrencyStatus().currency
|
val cryptoCurrency = cryptoCurrencyStatus().currency
|
||||||
|
val memo = memoValue ?: ""
|
||||||
|
|
||||||
return when (cryptoCurrency.network.id.value) {
|
return when (cryptoCurrency.network.id.value) {
|
||||||
Blockchain.XRP.id -> convert(R.string.send_destination_tag_field)
|
Blockchain.XRP.id -> {
|
||||||
|
convert(
|
||||||
|
value = Data(memo = memo, label = R.string.send_destination_tag_field),
|
||||||
|
)
|
||||||
|
}
|
||||||
Blockchain.Binance.id,
|
Blockchain.Binance.id,
|
||||||
Blockchain.TON.id,
|
Blockchain.TON.id,
|
||||||
Blockchain.Cosmos.id,
|
Blockchain.Cosmos.id,
|
||||||
|
|
@ -30,24 +36,30 @@ internal class SendRecipientMemoFieldConverter(
|
||||||
Blockchain.Stellar.id,
|
Blockchain.Stellar.id,
|
||||||
Blockchain.Hedera.id,
|
Blockchain.Hedera.id,
|
||||||
Blockchain.Algorand.id,
|
Blockchain.Algorand.id,
|
||||||
-> convert(R.string.send_extras_hint_memo)
|
-> {
|
||||||
|
convert(
|
||||||
|
value = Data(memo = memo, label = R.string.send_extras_hint_memo),
|
||||||
|
)
|
||||||
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun convert(value: Int): SendTextField.RecipientMemo {
|
override fun convert(value: Data): SendTextField.RecipientMemo {
|
||||||
return SendTextField.RecipientMemo(
|
return SendTextField.RecipientMemo(
|
||||||
value = "",
|
value = value.memo,
|
||||||
onValueChange = clickIntents::onRecipientMemoValueChange,
|
onValueChange = clickIntents::onRecipientMemoValueChange,
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
imeAction = ImeAction.Done,
|
imeAction = ImeAction.Done,
|
||||||
keyboardType = KeyboardType.Text,
|
keyboardType = KeyboardType.Text,
|
||||||
),
|
),
|
||||||
placeholder = resourceReference(R.string.send_optional_field),
|
placeholder = resourceReference(R.string.send_optional_field),
|
||||||
label = resourceReference(value),
|
label = resourceReference(value.label),
|
||||||
error = resourceReference(R.string.send_memo_destination_tag_error),
|
error = resourceReference(R.string.send_memo_destination_tag_error),
|
||||||
disabledText = resourceReference(R.string.send_additional_field_already_included),
|
disabledText = resourceReference(R.string.send_additional_field_already_included),
|
||||||
isEnabled = true,
|
isEnabled = true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Data(val memo: String, @StringRes val label: Int)
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
internal class SendRecipientStateConverter(
|
internal class SendRecipientStateConverter(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<String, SendStates.RecipientState> {
|
) : Converter<SendRecipientStateConverter.Data, SendStates.RecipientState> {
|
||||||
|
|
||||||
private val addressFieldConverter by lazy { SendRecipientAddressFieldConverter(clickIntents) }
|
private val addressFieldConverter by lazy { SendRecipientAddressFieldConverter(clickIntents) }
|
||||||
private val memoFieldConverter by lazy {
|
private val memoFieldConverter by lazy {
|
||||||
|
|
@ -20,14 +20,16 @@ internal class SendRecipientStateConverter(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun convert(value: String): SendStates.RecipientState {
|
override fun convert(value: Data): SendStates.RecipientState {
|
||||||
return SendStates.RecipientState(
|
return SendStates.RecipientState(
|
||||||
addressTextField = addressFieldConverter.convert(value),
|
addressTextField = addressFieldConverter.convert(value.address),
|
||||||
memoTextField = memoFieldConverter.convertOrNull(),
|
memoTextField = memoFieldConverter.convertOrNull(value.memo),
|
||||||
network = cryptoCurrencyStatusProvider().currency.network.name,
|
network = cryptoCurrencyStatusProvider().currency.network.name,
|
||||||
isPrimaryButtonEnabled = false,
|
isPrimaryButtonEnabled = false,
|
||||||
wallets = persistentListOf(),
|
wallets = persistentListOf(),
|
||||||
recent = persistentListOf(),
|
recent = persistentListOf(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Data(val address: String, val memo: String? = null)
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +99,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
private val transactionId: String? = savedStateHandle[SendRouter.TRANSACTION_ID_KEY]
|
private val transactionId: String? = savedStateHandle[SendRouter.TRANSACTION_ID_KEY]
|
||||||
private val amount: String? = savedStateHandle[SendRouter.AMOUNT_KEY]
|
private val amount: String? = savedStateHandle[SendRouter.AMOUNT_KEY]
|
||||||
private val destinationAddress: String? = savedStateHandle[SendRouter.DESTINATION_ADDRESS_KEY]
|
private val destinationAddress: String? = savedStateHandle[SendRouter.DESTINATION_ADDRESS_KEY]
|
||||||
|
private val memo: String? = savedStateHandle[SendRouter.TAG_KEY]
|
||||||
|
|
||||||
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
||||||
|
|
||||||
|
|
@ -342,7 +343,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
stateRouter.showSend()
|
stateRouter.showSend()
|
||||||
}
|
}
|
||||||
transactionId != null && amount != null && destinationAddress != null -> {
|
transactionId != null && amount != null && destinationAddress != null -> {
|
||||||
uiState = stateFactory.getReadyState(amount, destinationAddress)
|
uiState = stateFactory.getReadyState(amount, destinationAddress, memo)
|
||||||
stateRouter.showFee()
|
stateRouter.showFee()
|
||||||
updateNotifications()
|
updateNotifications()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -175,9 +175,10 @@ internal class TokenDetailsViewModel @Inject constructor(
|
||||||
status = cryptoCurrencyStatus ?: return,
|
status = cryptoCurrencyStatus ?: return,
|
||||||
transactionInfo = data.let {
|
transactionInfo = data.let {
|
||||||
TransactionInfo(
|
TransactionInfo(
|
||||||
amount = it.baseCurrencyAmount,
|
|
||||||
transactionId = it.transactionId,
|
transactionId = it.transactionId,
|
||||||
destinationAddress = it.depositWalletAddress,
|
destinationAddress = it.depositWalletAddress,
|
||||||
|
amount = it.baseCurrencyAmount,
|
||||||
|
tag = it.depositWalletAddressTag,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ internal class WalletDeepLinksHandler @Inject constructor(
|
||||||
amount = it.baseCurrencyAmount,
|
amount = it.baseCurrencyAmount,
|
||||||
destinationAddress = it.depositWalletAddress,
|
destinationAddress = it.depositWalletAddress,
|
||||||
transactionId = it.transactionId,
|
transactionId = it.transactionId,
|
||||||
|
tag = it.depositWalletAddressTag,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue