Updated on 2026-08-14
This commit is contained in:
commit
8a9422304a
19 changed files with 126 additions and 93 deletions
|
|
@ -22,6 +22,7 @@ fun Blockchain.getRoundIconRes(): Int {
|
||||||
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_round
|
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_round
|
||||||
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_round
|
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_round
|
||||||
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_round
|
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_round
|
||||||
|
Blockchain.Dogecoin -> R.drawable.ic_dogecoin_round
|
||||||
else -> R.drawable.ic_tangem_logo
|
else -> R.drawable.ic_tangem_logo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +45,7 @@ fun Blockchain.getGreyedOutIconRes(): Int {
|
||||||
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color
|
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color
|
||||||
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color
|
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color
|
||||||
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_no_color
|
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_no_color
|
||||||
|
Blockchain.Dogecoin -> R.drawable.ic_dogecoin_no_color
|
||||||
else -> R.drawable.ic_tangem_logo
|
else -> R.drawable.ic_tangem_logo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ class TapWalletManager {
|
||||||
val walletManagers = if (
|
val walletManagers = if (
|
||||||
primaryTokens.isNotEmpty() &&
|
primaryTokens.isNotEmpty() &&
|
||||||
primaryWalletManager != null &&
|
primaryWalletManager != null &&
|
||||||
primaryBlockchain != null
|
primaryBlockchain != null && primaryBlockchain != Blockchain.Unknown
|
||||||
) {
|
) {
|
||||||
val blockchainsWithoutPrimary = savedCurrencies.filterNot { it.blockchain == primaryBlockchain }
|
val blockchainsWithoutPrimary = savedCurrencies.filterNot { it.blockchain == primaryBlockchain }
|
||||||
walletManagerFactory.makeWalletManagersForApp(
|
walletManagerFactory.makeWalletManagersForApp(
|
||||||
|
|
@ -288,7 +288,9 @@ class TapWalletManager {
|
||||||
WalletAction.MultiWallet.AddBlockchains(savedCurrencies, walletManagers),
|
WalletAction.MultiWallet.AddBlockchains(savedCurrencies, walletManagers),
|
||||||
)
|
)
|
||||||
savedCurrencies.map {
|
savedCurrencies.map {
|
||||||
dispatchOnMain(WalletAction.MultiWallet.AddTokens(it.tokens, it))
|
if (it.tokens.isNotEmpty()) {
|
||||||
|
dispatchOnMain(WalletAction.MultiWallet.AddTokens(it.tokens, it))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ data class Currency(
|
||||||
val name: String,
|
val name: String,
|
||||||
val symbol: String,
|
val symbol: String,
|
||||||
val iconUrl: String,
|
val iconUrl: String,
|
||||||
val contracts: List<Contract>?
|
val contracts: List<Contract>
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
@ -45,9 +45,19 @@ data class Currency(
|
||||||
name = currency.name,
|
name = currency.name,
|
||||||
symbol = currency.symbol,
|
symbol = currency.symbol,
|
||||||
iconUrl = getIconUrl(currency.id),
|
iconUrl = getIconUrl(currency.id),
|
||||||
contracts = currency.contracts?.toContracts(isTestNet)
|
contracts = prepareListOfContracts(currency.contracts, currency.id, isTestNet)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun prepareListOfContracts(
|
||||||
|
contractsFromJson: List<ContractFromJson>?,
|
||||||
|
currencyId: String,
|
||||||
|
isTestNet: Boolean
|
||||||
|
): List<Contract> {
|
||||||
|
val mainNetwork = Contract.fromCurrencyId(currencyId, isTestNet)
|
||||||
|
val contracts = contractsFromJson?.toContracts(isTestNet) ?: emptyList()
|
||||||
|
return (listOfNotNull(mainNetwork) + contracts).distinct()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,6 +82,18 @@ data class Contract(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fromCurrencyId(currencyId: String, isTestNet: Boolean): Contract? {
|
||||||
|
val networkId = if (isTestNet) currencyId + TESTNET else currencyId
|
||||||
|
val blockchain = Blockchain.fromNetworkId(networkId) ?: return null
|
||||||
|
return Contract(
|
||||||
|
networkId = networkId,
|
||||||
|
blockchain = blockchain,
|
||||||
|
address = blockchain.currency,
|
||||||
|
decimalCount = blockchain.decimals(),
|
||||||
|
iconUrl = getIconUrl(networkId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const val TESTNET = "-testnet"
|
const val TESTNET = "-testnet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.tokens.redux
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.DerivationParams
|
import com.tangem.blockchain.common.DerivationParams
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.DerivationStyle
|
||||||
import com.tangem.common.CompletionResult
|
import com.tangem.common.CompletionResult
|
||||||
import com.tangem.common.card.EllipticCurve
|
import com.tangem.common.card.EllipticCurve
|
||||||
import com.tangem.common.extensions.ByteArrayKey
|
import com.tangem.common.extensions.ByteArrayKey
|
||||||
|
|
@ -68,19 +68,27 @@ class TokensMiddleware {
|
||||||
private fun handleSaveChanges(action: TokensAction.SaveChanges) {
|
private fun handleSaveChanges(action: TokensAction.SaveChanges) {
|
||||||
val scanResponse = store.state.globalState.scanResponse ?: return
|
val scanResponse = store.state.globalState.scanResponse ?: return
|
||||||
|
|
||||||
//TODO: bad things happens.
|
val currentTokens = store.state.tokensState.addedWallets.toNonCustomTokensWithBlockchains(
|
||||||
val currentTokens = store.state.tokensState.addedWallets.toTokens()
|
scanResponse.card.derivationStyle
|
||||||
val currentBlockchains = store.state.tokensState.addedWallets.toBlockchains(
|
)
|
||||||
store.state.tokensState.derivationStyle
|
val currentBlockchains = store.state.tokensState.addedWallets.toNonCustomBlockchains(
|
||||||
|
scanResponse.card.derivationStyle
|
||||||
)
|
)
|
||||||
|
|
||||||
val blockchainsToAdd = action.addedBlockchains.filter { !currentBlockchains.contains(it) }
|
val blockchainsToAdd = action.addedBlockchains.filter { !currentBlockchains.contains(it) }
|
||||||
val blockchainsToRemove = currentBlockchains.filter { !action.addedBlockchains.contains(it) }
|
val blockchainsToRemove = currentBlockchains.filter { !action.addedBlockchains.contains(it) }
|
||||||
|
|
||||||
val tokensToAdd = action.addedTokens.filter { !currentTokens.contains(it.token) }
|
val tokensToAdd = action.addedTokens.filter { !currentTokens.contains(it) }
|
||||||
val tokensToRemove = currentTokens.filter { token -> !action.addedTokens.any { it.token == token } }
|
val tokensToRemove = currentTokens.filter {
|
||||||
|
token -> !action.addedTokens.any { it.token == token.token }
|
||||||
|
}
|
||||||
|
val derivationStyle = scanResponse.card.derivationStyle
|
||||||
|
|
||||||
removeCurrenciesIfNeeded(blockchainsToRemove, tokensToRemove)
|
removeCurrenciesIfNeeded(convertToCurrencies(
|
||||||
|
blockchains = blockchainsToRemove,
|
||||||
|
tokens = tokensToRemove,
|
||||||
|
derivationStyle = derivationStyle
|
||||||
|
))
|
||||||
|
|
||||||
if (tokensToAdd.isEmpty() && blockchainsToAdd.isEmpty()) {
|
if (tokensToAdd.isEmpty() && blockchainsToAdd.isEmpty()) {
|
||||||
store.dispatchDebugErrorNotification("Nothing to save")
|
store.dispatchDebugErrorNotification("Nothing to save")
|
||||||
|
|
@ -88,12 +96,11 @@ class TokensMiddleware {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val derivationStyle = scanResponse.card.derivationStyle
|
val currencyList = convertToCurrencies(
|
||||||
val currencyList = blockchainsToAdd.map {
|
blockchains = blockchainsToAdd,
|
||||||
Currency.Blockchain(it, it.derivationPath(derivationStyle)?.rawPath)
|
tokens = tokensToAdd,
|
||||||
} + tokensToAdd.map {
|
derivationStyle = derivationStyle
|
||||||
Currency.Token(it.token, it.blockchain, it.blockchain.derivationPath(derivationStyle)?.rawPath)
|
)
|
||||||
}
|
|
||||||
if (scanResponse.supportsHdWallet()) {
|
if (scanResponse.supportsHdWallet()) {
|
||||||
deriveMissingBlockchains(scanResponse, currencyList) {
|
deriveMissingBlockchains(scanResponse, currencyList) {
|
||||||
submitAdd(it, currencyList)
|
submitAdd(it, currencyList)
|
||||||
|
|
@ -105,6 +112,22 @@ class TokensMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun convertToCurrencies(
|
||||||
|
blockchains: List<Blockchain>,
|
||||||
|
tokens: List<TokenWithBlockchain>,
|
||||||
|
derivationStyle: DerivationStyle?
|
||||||
|
): List<Currency> {
|
||||||
|
return blockchains.map {
|
||||||
|
Currency.Blockchain(it, it.derivationPath(derivationStyle)?.rawPath)
|
||||||
|
} + tokens.map {
|
||||||
|
Currency.Token(
|
||||||
|
it.token,
|
||||||
|
it.blockchain,
|
||||||
|
it.blockchain.derivationPath(derivationStyle)?.rawPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun deriveMissingBlockchains(
|
private fun deriveMissingBlockchains(
|
||||||
scanResponse: ScanResponse,
|
scanResponse: ScanResponse,
|
||||||
currencyList: List<Currency>,
|
currencyList: List<Currency>,
|
||||||
|
|
@ -233,17 +256,10 @@ class TokensMiddleware {
|
||||||
addActions.forEach { store.dispatchOnMain(it) }
|
addActions.forEach { store.dispatchOnMain(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeCurrenciesIfNeeded(blockchains: List<Blockchain>, tokens: List<Token>) {
|
private fun removeCurrenciesIfNeeded(currencies: List<Currency>) {
|
||||||
if (tokens.isNotEmpty()) {
|
if (currencies.isNotEmpty()) {
|
||||||
tokens.forEach { token ->
|
currencies.forEach { currency ->
|
||||||
store.state.walletState.getWalletData(token)?.let {
|
store.state.walletState.getWalletData(currency)?.let {
|
||||||
store.dispatch(WalletAction.MultiWallet.RemoveWallet(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (blockchains.isNotEmpty()) {
|
|
||||||
blockchains.forEach { blockchain ->
|
|
||||||
store.state.walletState.getWalletData(blockchain)?.let {
|
|
||||||
store.dispatch(WalletAction.MultiWallet.RemoveWallet(it))
|
store.dispatch(WalletAction.MultiWallet.RemoveWallet(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,15 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
|
||||||
is TokensAction.SetAddedCurrencies -> {
|
is TokensAction.SetAddedCurrencies -> {
|
||||||
|
|
||||||
tokensState.copy(
|
tokensState.copy(
|
||||||
addedBlockchains = action.wallets.toBlockchains(action.derivationStyle),
|
addedBlockchains = action.wallets.toNonCustomBlockchains(action.derivationStyle),
|
||||||
addedTokens = action.wallets.toTokensWithBlockchains(action.derivationStyle),
|
addedTokens = action.wallets.toNonCustomTokensWithBlockchains(action.derivationStyle),
|
||||||
addedWallets = action.wallets,
|
addedWallets = action.wallets,
|
||||||
derivationStyle = action.derivationStyle
|
derivationStyle = action.derivationStyle
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is TokensAction.SetNonRemovableCurrencies -> {
|
is TokensAction.SetNonRemovableCurrencies -> {
|
||||||
tokensState.copy(
|
tokensState.copy(
|
||||||
nonRemovableBlockchains = action.wallets.toBlockchains(tokensState.derivationStyle),
|
nonRemovableBlockchains = action.wallets.toNonCustomBlockchains(tokensState.derivationStyle),
|
||||||
nonRemovableTokens = action.wallets.toTokensContractAddresses(),
|
nonRemovableTokens = action.wallets.toTokensContractAddresses(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,13 @@ fun List<WalletData>.toTokensContractAddresses(): List<ContractAddress> {
|
||||||
return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token?.contractAddress }.distinct()
|
return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token?.contractAddress }.distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<WalletData>.toTokens(): List<Token> {
|
fun List<WalletData>.toNonCustomTokens(derivationStyle: DerivationStyle?): List<Token> {
|
||||||
return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token }.distinct()
|
return filter { !it.currency.isCustomCurrency(derivationStyle) }
|
||||||
|
.mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token }
|
||||||
|
.distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<WalletData>.toTokensWithBlockchains(derivationStyle: DerivationStyle?): List<TokenWithBlockchain> {
|
fun List<WalletData>.toNonCustomTokensWithBlockchains(derivationStyle: DerivationStyle?): List<TokenWithBlockchain> {
|
||||||
return mapNotNull {
|
return mapNotNull {
|
||||||
if (it.currency !is com.tangem.tap.features.wallet.redux.Currency.Token) return@mapNotNull null
|
if (it.currency !is com.tangem.tap.features.wallet.redux.Currency.Token) return@mapNotNull null
|
||||||
if (it.currency.isCustomCurrency(derivationStyle)) return@mapNotNull null
|
if (it.currency.isCustomCurrency(derivationStyle)) return@mapNotNull null
|
||||||
|
|
@ -39,7 +41,7 @@ fun List<WalletData>.toTokensWithBlockchains(derivationStyle: DerivationStyle?):
|
||||||
}.distinct()
|
}.distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<WalletData>.toBlockchains(derivationStyle: DerivationStyle?): List<Blockchain> {
|
fun List<WalletData>.toNonCustomBlockchains(derivationStyle: DerivationStyle?): List<Blockchain> {
|
||||||
return mapNotNull {
|
return mapNotNull {
|
||||||
if (it.currency.isCustomCurrency(derivationStyle)) {
|
if (it.currency.isCustomCurrency(derivationStyle)) {
|
||||||
null
|
null
|
||||||
|
|
@ -58,7 +60,7 @@ fun List<Currency>.filter(supportedBlockchains: Set<Blockchain>?): List<Currency
|
||||||
if (supportedBlockchains == null) return this
|
if (supportedBlockchains == null) return this
|
||||||
return map {
|
return map {
|
||||||
it.copy(contracts =
|
it.copy(contracts =
|
||||||
it.contracts?.filter {
|
it.contracts.filter {
|
||||||
supportedBlockchains.contains(it.blockchain) && it.blockchain.canHandleTokens()
|
supportedBlockchains.contains(it.blockchain) && it.blockchain.canHandleTokens()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ fun CollapsedCurrencyItem(
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = currency.name,
|
text = currency.fullName,
|
||||||
fontSize = 17.sp,
|
fontSize = 17.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = Color(0xFF1C1C1E),
|
color = Color(0xFF1C1C1E),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import androidx.compose.ui.unit.sp
|
||||||
import coil.compose.SubcomposeAsyncImage
|
import coil.compose.SubcomposeAsyncImage
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.domain.common.extensions.fromNetworkId
|
|
||||||
import com.tangem.tap.domain.tokens.Currency
|
import com.tangem.tap.domain.tokens.Currency
|
||||||
import com.tangem.tap.features.tokens.redux.ContractAddress
|
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||||
|
|
@ -65,7 +64,7 @@ fun ExpandedCurrencyItem(
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = currency.name,
|
text = currency.fullName,
|
||||||
fontSize = 17.sp,
|
fontSize = 17.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = Color(0xFF1C1C1E),
|
color = Color(0xFF1C1C1E),
|
||||||
|
|
@ -87,9 +86,7 @@ fun ExpandedCurrencyItem(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val blockchains = currency.contracts?.map { it.blockchain } ?: listOfNotNull(
|
val blockchains = currency.contracts.map { it.blockchain }
|
||||||
Blockchain.fromNetworkId(currency.id)
|
|
||||||
)
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -134,7 +131,7 @@ fun ExpandedCurrencyItem(
|
||||||
.padding(top = 6.dp),
|
.padding(top = 6.dp),
|
||||||
) {
|
) {
|
||||||
blockchains.map { blockchain ->
|
blockchains.map { blockchain ->
|
||||||
val contract = currency.contracts?.firstOrNull { it.blockchain == blockchain }
|
val contract = currency.contracts.firstOrNull { it.blockchain == blockchain }
|
||||||
val added = if (contract != null && contract.address != currency.symbol) {
|
val added = if (contract != null && contract.address != currency.symbol) {
|
||||||
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -66,4 +66,7 @@ fun ListOfCurrencies(
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Currency.fullName: String
|
||||||
|
get() = "${this.name} (${this.symbol})"
|
||||||
|
|
@ -46,7 +46,7 @@ fun NetworkItem(
|
||||||
.combinedClickable(
|
.combinedClickable(
|
||||||
enabled = allowToAdd,
|
enabled = allowToAdd,
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
if (contract != null) onNetworkItemClicked(contract.address)
|
if (!isBlockchain) onNetworkItemClicked(contract!!.address)
|
||||||
},
|
},
|
||||||
onClick = {},
|
onClick = {},
|
||||||
indication = null,
|
indication = null,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import com.tangem.blockchain.common.*
|
||||||
import com.tangem.blockchain.common.address.AddressType
|
import com.tangem.blockchain.common.address.AddressType
|
||||||
import com.tangem.blockchain.extensions.isAboveZero
|
import com.tangem.blockchain.extensions.isAboveZero
|
||||||
import com.tangem.common.extensions.isZero
|
import com.tangem.common.extensions.isZero
|
||||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
|
||||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||||
import com.tangem.tap.common.entities.Button
|
import com.tangem.tap.common.entities.Button
|
||||||
import com.tangem.tap.common.extensions.toQrCode
|
import com.tangem.tap.common.extensions.toQrCode
|
||||||
|
|
@ -75,19 +74,9 @@ data class WalletState(
|
||||||
val walletManagers: List<WalletManager>
|
val walletManagers: List<WalletManager>
|
||||||
get() = wallets.mapNotNull { it.walletManager }
|
get() = wallets.mapNotNull { it.walletManager }
|
||||||
|
|
||||||
fun getWalletManager(token: Token?): WalletManager? {
|
|
||||||
if (token == null) return null
|
|
||||||
return wallets
|
|
||||||
.mapNotNull { it.walletManager }
|
|
||||||
.find { walletManager ->
|
|
||||||
walletManager.cardTokens.any { it.contractAddress == token.contractAddress }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getWalletManager(currency: Currency?): WalletManager? {
|
fun getWalletManager(currency: Currency?): WalletManager? {
|
||||||
if (currency?.blockchain == null) return null
|
if (currency?.blockchain == null) return null
|
||||||
return wallets.map { it.walletManager }
|
return getWalletStore(currency)?.walletManager
|
||||||
.find { it?.wallet?.blockchain == currency.blockchain }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWalletManager(blockchain: BlockchainNetwork): WalletManager? {
|
fun getWalletManager(blockchain: BlockchainNetwork): WalletManager? {
|
||||||
|
|
@ -131,22 +120,6 @@ data class WalletState(
|
||||||
return getWalletStore(currency)?.walletsData?.firstOrNull { it.currency == currency }
|
return getWalletStore(currency)?.walletsData?.firstOrNull { it.currency == currency }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWalletData(token: Token?): WalletData? {
|
|
||||||
if (token == null) return null
|
|
||||||
return walletsData.find {
|
|
||||||
(it.currency as? Currency.Token)?.token == token &&
|
|
||||||
!it.currency.isCustomCurrency(store.state.globalState.scanResponse!!.card.derivationStyle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getWalletData(blockchain: Blockchain?): WalletData? {
|
|
||||||
if (blockchain == null) return null
|
|
||||||
return walletsData.find {
|
|
||||||
(it.currency as? Currency.Blockchain)?.blockchain == blockchain &&
|
|
||||||
!it.currency.isCustomCurrency(store.state.globalState.scanResponse!!.card.derivationStyle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSelectedWalletData(): WalletData? {
|
fun getSelectedWalletData(): WalletData? {
|
||||||
return walletsData.find { it.currency == selectedCurrency }
|
return walletsData.find { it.currency == selectedCurrency }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ class MultiWalletMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Currency.Token -> {
|
is Currency.Token -> {
|
||||||
val walletManager = walletState?.getWalletManager(currency.token)
|
val walletManager = walletState?.getWalletManager(currency)
|
||||||
if (walletManager != null) {
|
if (walletManager != null) {
|
||||||
walletManager.removeToken(currency.token)
|
walletManager.removeToken(currency.token)
|
||||||
cardId?.let {
|
cardId?.let {
|
||||||
|
|
@ -223,6 +223,7 @@ class MultiWalletMiddleware {
|
||||||
tokens: List<Token>, blockchainNetwork: BlockchainNetwork,
|
tokens: List<Token>, blockchainNetwork: BlockchainNetwork,
|
||||||
walletState: WalletState?, globalState: GlobalState?
|
walletState: WalletState?, globalState: GlobalState?
|
||||||
) {
|
) {
|
||||||
|
if (tokens.isEmpty()) return
|
||||||
val scanResponse = globalState?.scanResponse ?: return
|
val scanResponse = globalState?.scanResponse ?: return
|
||||||
val wmFactory = globalState.tapWalletManager.walletManagerFactory
|
val wmFactory = globalState.tapWalletManager.walletManagerFactory
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class TradeCryptoMiddleware {
|
||||||
if (exchangeAction == CurrencyExchangeManager.Action.Buy &&
|
if (exchangeAction == CurrencyExchangeManager.Action.Buy &&
|
||||||
currency is Currency.Token && currency.blockchain.isTestnet()
|
currency is Currency.Token && currency.blockchain.isTestnet()
|
||||||
) {
|
) {
|
||||||
val walletManager = store.state.walletState.getWalletManager(currency.token)
|
val walletManager = store.state.walletState.getWalletManager(currency)
|
||||||
if (walletManager !is EthereumWalletManager) return
|
if (walletManager !is EthereumWalletManager) return
|
||||||
|
|
||||||
scope.launch { exchangeManager.buyErc20Tokens(walletManager, currency.token) }
|
scope.launch { exchangeManager.buyErc20Tokens(walletManager, currency.token) }
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,8 @@ class MultiWalletReducer {
|
||||||
addTokens(listOf(action.token), action.blockchain, state)
|
addTokens(listOf(action.token), action.blockchain, state)
|
||||||
}
|
}
|
||||||
is WalletAction.MultiWallet.TokenLoaded -> {
|
is WalletAction.MultiWallet.TokenLoaded -> {
|
||||||
val pendingTransactions = state.getWalletManager(action.token)
|
val currency = Currency.fromBlockchainNetwork(action.blockchain, action.token)
|
||||||
|
val pendingTransactions = state.getWalletManager(currency)
|
||||||
?.wallet?.let { wallet ->
|
?.wallet?.let { wallet ->
|
||||||
wallet.recentTransactions.toPendingTransactions(wallet.address)
|
wallet.recentTransactions.toPendingTransactions(wallet.address)
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
|
|
@ -113,7 +114,7 @@ class MultiWalletReducer {
|
||||||
pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress
|
pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress
|
||||||
else -> BalanceStatus.VerifiedOnline
|
else -> BalanceStatus.VerifiedOnline
|
||||||
}
|
}
|
||||||
val tokenWalletData = state.getWalletData(action.token)
|
val tokenWalletData = state.getWalletData(currency)
|
||||||
val newTokenWalletData = tokenWalletData?.copy(
|
val newTokenWalletData = tokenWalletData?.copy(
|
||||||
currencyData = tokenWalletData.currencyData.copy(
|
currencyData = tokenWalletData.currencyData.copy(
|
||||||
status = tokenBalanceStatus,
|
status = tokenBalanceStatus,
|
||||||
|
|
@ -166,11 +167,10 @@ private fun addTokens(
|
||||||
|
|
||||||
fun Token.toWallet(state: WalletState, blockchain: BlockchainNetwork): WalletData? {
|
fun Token.toWallet(state: WalletState, blockchain: BlockchainNetwork): WalletData? {
|
||||||
if (!state.isMultiwalletAllowed) return null
|
if (!state.isMultiwalletAllowed) return null
|
||||||
if (state.currencies.any { it is Currency.Token && it.token == this }) {
|
val currency = Currency.fromBlockchainNetwork(blockchain, this)
|
||||||
return null
|
if (state.currencies.contains(currency)) return null
|
||||||
}
|
|
||||||
|
|
||||||
val walletManager = state.getWalletManager(this)?.wallet
|
val walletManager = state.getWalletManager(currency)?.wallet
|
||||||
val walletAddresses = createAddressList(walletManager)
|
val walletAddresses = createAddressList(walletManager)
|
||||||
|
|
||||||
return WalletData(
|
return WalletData(
|
||||||
|
|
@ -181,6 +181,6 @@ fun Token.toWallet(state: WalletState, blockchain: BlockchainNetwork): WalletDat
|
||||||
),
|
),
|
||||||
walletAddresses = walletAddresses,
|
walletAddresses = walletAddresses,
|
||||||
mainButton = WalletMainButton.SendButton(false),
|
mainButton = WalletMainButton.SendButton(false),
|
||||||
currency = Currency.fromBlockchainNetwork(blockchain, this)
|
currency = currency
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +74,8 @@ class OnWalletLoadedReducer {
|
||||||
)
|
)
|
||||||
|
|
||||||
val tokens = wallet.getTokens().mapNotNull { token ->
|
val tokens = wallet.getTokens().mapNotNull { token ->
|
||||||
val tokenWalletData = walletState.getWalletData(token)
|
val currency = Currency.fromBlockchainNetwork(blockchainNetwork, token)
|
||||||
|
val tokenWalletData = walletState.getWalletData(currency)
|
||||||
val tokenPendingTransactions =
|
val tokenPendingTransactions =
|
||||||
pendingTransactions.filter { it.currency == token.symbol }
|
pendingTransactions.filter { it.currency == token.symbol }
|
||||||
val tokenBalanceStatus = when {
|
val tokenBalanceStatus = when {
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,10 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
||||||
tradeCryptoState = TradeCryptoState.from(exchangeManager, wallet)
|
tradeCryptoState = TradeCryptoState.from(exchangeManager, wallet)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val wallets = newState.updateTradeCryptoState(exchangeManager, newState.replaceSomeWallets(newWallets))
|
val wallets = newState.updateTradeCryptoState(
|
||||||
|
exchangeManager,
|
||||||
|
newState.replaceSomeWallets(newWallets)
|
||||||
|
)
|
||||||
val walletStore = newState.getWalletStore(action.blockchain)?.updateWallets(wallets)
|
val walletStore = newState.getWalletStore(action.blockchain)?.updateWallets(wallets)
|
||||||
newState = newState.updateWalletStore(walletStore)
|
newState = newState.updateWalletStore(walletStore)
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +220,11 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val tokenWallets = action.wallet.getTokens()
|
val tokenWallets = action.wallet.getTokens()
|
||||||
.mapNotNull { newState.getWalletData(it) }
|
.mapNotNull { token ->
|
||||||
|
walletStore?.blockchainNetwork?.let {
|
||||||
|
newState.getWalletData(Currency.fromBlockchainNetwork(it, token))
|
||||||
|
}
|
||||||
|
}
|
||||||
.map {
|
.map {
|
||||||
it.copy(
|
it.copy(
|
||||||
currencyData = it.currencyData.copy(
|
currencyData = it.currencyData.copy(
|
||||||
|
|
@ -288,12 +295,14 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
||||||
?: return newState
|
?: return newState
|
||||||
val address = walletAddresses.list.firstOrNull { it.type == action.type }
|
val address = walletAddresses.list.firstOrNull { it.type == action.type }
|
||||||
?: return newState
|
?: return newState
|
||||||
newState = newState.updateWalletData(selectedWalletData?.copy(
|
newState = newState.updateWalletData(
|
||||||
walletAddresses = WalletAddresses(
|
selectedWalletData?.copy(
|
||||||
address,
|
walletAddresses = WalletAddresses(
|
||||||
walletAddresses.list
|
address,
|
||||||
|
walletAddresses.list
|
||||||
|
)
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
is WalletAction.SetWalletRent -> {
|
is WalletAction.SetWalletRent -> {
|
||||||
var walletData = newState.getWalletData(action.blockchain)
|
var walletData = newState.getWalletData(action.blockchain)
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ class WalletAdapter
|
||||||
|
|
||||||
private fun toggleWarning(show: Boolean) {
|
private fun toggleWarning(show: Boolean) {
|
||||||
binding.tvExchangeRate.show(!show)
|
binding.tvExchangeRate.show(!show)
|
||||||
|
binding.tvCustomCurrency.show(!show)
|
||||||
binding.tvStatusErrorMessage.show(show)
|
binding.tvStatusErrorMessage.show(show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,12 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
android:paddingStart="4dp"
|
android:paddingStart="4dp"
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
|
android:paddingTop="3dp"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
android:textColor="@color/darkGray2"
|
android:textColor="@color/darkGray2"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:background="@drawable/shape_rectangle_rounded_4"
|
android:background="@drawable/shape_rectangle_rounded_4"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import com.tangem.blockchain.common.Blockchain
|
||||||
|
|
||||||
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
||||||
return when (networkId) {
|
return when (networkId) {
|
||||||
"avalanche" -> Blockchain.Avalanche
|
"avalanche", "avalanche-2" -> Blockchain.Avalanche
|
||||||
"avalanche-testnet" -> Blockchain.AvalancheTestnet
|
"avalanche-testnet", "avalanche-2-testnet" -> Blockchain.AvalancheTestnet
|
||||||
"binancecoin" -> Blockchain.Binance
|
"binancecoin" -> Blockchain.Binance
|
||||||
"binancecoin-testnet" -> Blockchain.BinanceTestnet
|
"binancecoin-testnet" -> Blockchain.BinanceTestnet
|
||||||
"binance-smart-chain" -> Blockchain.BSC
|
"binance-smart-chain" -> Blockchain.BSC
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue