Updated on 2026-08-14
This commit is contained in:
parent
baa5a0cb9c
commit
b1beae4589
18 changed files with 7601 additions and 4938 deletions
|
|
@ -69,7 +69,7 @@ class TapWalletManager {
|
|||
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, wallet: Wallet) {
|
||||
Timber.d(wallet.getTokens().toString())
|
||||
val currencies = wallet.getTokens()
|
||||
.map { Currency.Token(it, wallet.blockchain) }
|
||||
.map { Currency.Token(it) }
|
||||
.plus(Currency.Blockchain(wallet.blockchain))
|
||||
loadFiatRate(fiatCurrency, currencies)
|
||||
}
|
||||
|
|
@ -186,18 +186,18 @@ class TapWalletManager {
|
|||
private fun loadMultiWalletData(
|
||||
card: Card, primaryBlockchain: Blockchain?, primaryWalletManager: WalletManager?
|
||||
) {
|
||||
val presetTokens = primaryWalletManager?.presetTokens ?: emptySet()
|
||||
val primaryTokens = primaryWalletManager?.cardTokens ?: emptySet()
|
||||
val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId)
|
||||
|
||||
if (savedCurrencies == null) {
|
||||
if (primaryBlockchain != null && primaryWalletManager != null) {
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
CardCurrencies(
|
||||
blockchains = setOf(primaryBlockchain), tokens = presetTokens
|
||||
blockchains = setOf(primaryBlockchain), tokens = primaryTokens
|
||||
)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(presetTokens.toList()))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(primaryTokens.toList()))
|
||||
} else {
|
||||
val blockchains = setOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
|
|
@ -213,7 +213,7 @@ class TapWalletManager {
|
|||
} else {
|
||||
val blockchains = savedCurrencies.blockchains.toList()
|
||||
val walletManagers = if (
|
||||
presetTokens.isNotEmpty() &&
|
||||
primaryTokens.isNotEmpty() &&
|
||||
primaryWalletManager != null && primaryBlockchain != null
|
||||
) {
|
||||
val blockchainsWithoutPrimary = blockchains.filterNot { it == primaryBlockchain }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class ConfigValueModel(
|
|||
val coinMarketCapKey: String,
|
||||
val moonPayApiKey: String,
|
||||
val moonPayApiSecretKey: String,
|
||||
val blockchairApiKey: String?,
|
||||
val blockchairAuthorizationToken: String?,
|
||||
val blockcypherTokens: Set<String>?,
|
||||
val infuraProjectId: String?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ fun Card.getToken(): Token? {
|
|||
val symbol = cardData?.tokenSymbol ?: return null
|
||||
val contractAddress = cardData?.tokenContractAddress ?: return null
|
||||
val decimals = cardData?.tokenDecimal ?: return null
|
||||
val blockchain = cardData?.blockchainName?.let { Blockchain.fromId(it) } ?: return null
|
||||
if (symbol.isBlank() || contractAddress.isBlank()) return null
|
||||
return Token(symbol, contractAddress, decimals)
|
||||
return Token(symbol, symbol, contractAddress, decimals, blockchain) // TODO: change to constructor without tokenName
|
||||
}
|
||||
|
||||
fun Card.getBlockchain(): Blockchain? {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.Types
|
||||
|
|
@ -13,11 +14,14 @@ import com.tangem.tap.network.createMoshi
|
|||
|
||||
class CurrenciesRepository(val context: Application) {
|
||||
private val moshi = createMoshi()
|
||||
private val blockchainsAdapter: JsonAdapter<Set<Blockchain>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, Blockchain::class.java)
|
||||
)
|
||||
private val tokensAdapter: JsonAdapter<Set<TokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, TokenDao::class.java)
|
||||
)
|
||||
private val blockchainsAdapter: JsonAdapter<Set<Blockchain>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, Blockchain::class.java)
|
||||
private val obsoleteTokensAdapter: JsonAdapter<Set<ObsoleteTokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, ObsoleteTokenDao::class.java)
|
||||
)
|
||||
|
||||
fun loadCardCurrencies(cardId: String): CardCurrencies? {
|
||||
|
|
@ -57,11 +61,20 @@ class CurrenciesRepository(val context: Application) {
|
|||
}
|
||||
|
||||
private fun loadSavedTokens(cardId: String): Set<Token> {
|
||||
val json = try {
|
||||
context.readFileText(getFileNameForTokens(cardId))
|
||||
} catch (exception: Exception) {
|
||||
return emptySet()
|
||||
}
|
||||
|
||||
return try {
|
||||
val json = context.readFileText(getFileNameForTokens(cardId))
|
||||
tokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet()
|
||||
} catch (exception: Exception) {
|
||||
emptySet()
|
||||
try {
|
||||
obsoleteTokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet()
|
||||
} catch (exception: Exception) {
|
||||
emptySet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,12 +107,20 @@ class CurrenciesRepository(val context: Application) {
|
|||
}
|
||||
|
||||
fun getPopularTokens(isTestNet: Boolean = false): List<Token> {
|
||||
val fileName = if (isTestNet) TESTNET_TOKENS_FILE_NAME else POPULAR_TOKENS_FILE_NAME
|
||||
val json = context.assets.readJsonFileToString(fileName)
|
||||
return tokensAdapter.fromJson(json)!!.map { it.toToken() }
|
||||
val ethereumTokensFileName =
|
||||
if (isTestNet) ETHEREUM_TESTNET_TOKENS_FILE_NAME else ETHEREUM_TOKENS_FILE_NAME
|
||||
val bscTokensFileName =
|
||||
if (isTestNet) BSC_TESTNET_TOKENS_FILE_NAME else BSC_TOKENS_FILE_NAME
|
||||
val ethereumTokensJson = context.assets.readJsonFileToString(ethereumTokensFileName)
|
||||
val bscTokensJson = context.assets.readJsonFileToString(bscTokensFileName)
|
||||
return tokensAdapter.fromJson(ethereumTokensJson)!!.map { it.toToken() } +
|
||||
tokensAdapter.fromJson(bscTokensJson)!!.map { it.toToken() }
|
||||
}
|
||||
|
||||
fun getBlockchains(cardFirmware: FirmwareVersion?, isTestNet: Boolean = false): List<Blockchain> {
|
||||
fun getBlockchains(
|
||||
cardFirmware: FirmwareVersion?,
|
||||
isTestNet: Boolean = false
|
||||
): List<Blockchain> {
|
||||
return if (cardFirmware == null || cardFirmware.major < 4) {
|
||||
Blockchain.secp256k1Blockchains(isTestNet)
|
||||
} else {
|
||||
|
|
@ -108,8 +129,10 @@ class CurrenciesRepository(val context: Application) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val POPULAR_TOKENS_FILE_NAME = "erc20_tokens"
|
||||
private const val TESTNET_TOKENS_FILE_NAME = "ethereum_tokens_testnet"
|
||||
private const val ETHEREUM_TOKENS_FILE_NAME = "ethereum_tokens"
|
||||
private const val ETHEREUM_TESTNET_TOKENS_FILE_NAME = "ethereum_tokens_testnet"
|
||||
private const val BSC_TOKENS_FILE_NAME = "bsc_tokens"
|
||||
private const val BSC_TESTNET_TOKENS_FILE_NAME = "bsc_tokens_testnet"
|
||||
private const val FILE_NAME_PREFIX_TOKENS = "tokens"
|
||||
private const val FILE_NAME_PREFIX_BLOCKCHAINS = "blockchains"
|
||||
|
||||
|
|
@ -119,40 +142,88 @@ class CurrenciesRepository(val context: Application) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TokenDao(
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val contractAddress: String,
|
||||
val decimalCount: Int,
|
||||
@Json(name = "blockchain")
|
||||
val blockchainDao: BlockchainDao
|
||||
) {
|
||||
fun toToken(): Token {
|
||||
return Token(name = name,
|
||||
return Token(
|
||||
name = name,
|
||||
symbol = symbol,
|
||||
contractAddress = contractAddress,
|
||||
decimals = decimalCount)
|
||||
decimals = decimalCount,
|
||||
blockchain = blockchainDao.toBlockchain()
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromToken(token: Token): TokenDao {
|
||||
return TokenDao(name = token.name,
|
||||
return TokenDao(
|
||||
name = token.name,
|
||||
symbol = token.symbol,
|
||||
contractAddress = token.contractAddress,
|
||||
decimalCount = token.decimals)
|
||||
|
||||
decimalCount = token.decimals,
|
||||
blockchainDao = BlockchainDao.fromBlockchain(token.blockchain)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BlockchainDao(
|
||||
@Json(name = "key")
|
||||
val name: String,
|
||||
@Json(name = "testnet")
|
||||
val isTestNet: Boolean
|
||||
) {
|
||||
fun toBlockchain(): Blockchain {
|
||||
val blockchain = Blockchain.values().find { it.name.lowercase() == name.lowercase() }
|
||||
?: throw Exception("Invalid BlockchainDao")
|
||||
return if (!isTestNet) blockchain else blockchain.getTestnetVersion()
|
||||
?: throw Exception("Invalid BlockchainDao")
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromBlockchain(blockchain: Blockchain): BlockchainDao {
|
||||
val name = blockchain.name.removeSuffix("Testnet").lowercase()
|
||||
val isTestnet = blockchain.name.endsWith("Testnet")
|
||||
return BlockchainDao(name, isTestnet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ObsoleteTokenDao(
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val contractAddress: String,
|
||||
val decimalCount: Int,
|
||||
) {
|
||||
fun toToken(): Token {
|
||||
return Token(
|
||||
name = name,
|
||||
symbol = symbol,
|
||||
contractAddress = contractAddress,
|
||||
decimals = decimalCount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CardCurrenciesDao(
|
||||
val tokens: Set<TokenDao>,
|
||||
val blockchains: Set<Blockchain>,
|
||||
) {
|
||||
fun toCardCurrencies(): CardCurrencies {
|
||||
return CardCurrencies(tokens = tokens.map { it.toToken() }.toSet(),
|
||||
blockchains = blockchains)
|
||||
return CardCurrencies(
|
||||
tokens = tokens.map { it.toToken() }.toSet(),
|
||||
blockchains = blockchains
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.squareup.picasso.Picasso
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.domain.tokens.CardCurrencies
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -175,11 +174,17 @@ sealed class CurrencyListItem {
|
|||
tokens: List<Token>
|
||||
): List<CurrencyListItem> {
|
||||
val blockchainsTitle = R.string.add_tokens_subtitle_blockchains
|
||||
val tokensTitle = R.string.add_tokens_subtitle_tokens
|
||||
val ethereumTokensTitle = R.string.add_tokens_subtitle_ethereum_tokens
|
||||
val bscTokensTitle = R.string.add_tokens_subtitle_bsc_tokens
|
||||
|
||||
val ethereumTokens = tokens.filter { it.blockchain == Blockchain.Ethereum }
|
||||
val bscTokens = tokens.filter { it.blockchain == Blockchain.BSC }
|
||||
return listOf(TitleListItem(blockchainsTitle)) +
|
||||
blockchains.map { BlockchainListItem(it) } +
|
||||
listOf(TitleListItem(tokensTitle)) +
|
||||
tokens.map { TokenListItem(it) }
|
||||
listOf(TitleListItem(ethereumTokensTitle)) +
|
||||
ethereumTokens.map { TokenListItem(it) } +
|
||||
listOf(TitleListItem(bscTokensTitle)) +
|
||||
bscTokens.map { TokenListItem(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,19 +50,7 @@ data class WalletState(
|
|||
|
||||
fun getWalletManager(token: Token?): WalletManager? {
|
||||
if (token == null) return null
|
||||
val ethereumWalletManager = walletManagers
|
||||
.find { it.wallet.blockchain == Blockchain.Ethereum ||
|
||||
it.wallet.blockchain == Blockchain.EthereumTestnet }
|
||||
return if (ethereumWalletManager?.presetTokens?.contains(token) == true) {
|
||||
ethereumWalletManager
|
||||
} else {
|
||||
val primaryWalletManager = walletManagers.find { it.wallet.blockchain == primaryBlockchain }
|
||||
if (primaryWalletManager?.presetTokens?.contains(token) == true) {
|
||||
primaryWalletManager
|
||||
} else {
|
||||
ethereumWalletManager
|
||||
}
|
||||
}
|
||||
return walletManagers.find { it.wallet.blockchain == token.blockchain }
|
||||
}
|
||||
|
||||
fun getWalletManager(currency: Currency?) : WalletManager? {
|
||||
|
|
@ -101,7 +89,7 @@ data class WalletState(
|
|||
?: return true
|
||||
|
||||
if (walletData.currency is Currency.Blockchain &&
|
||||
walletManager.presetTokens.isNotEmpty()
|
||||
walletManager.cardTokens.isNotEmpty()
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -233,9 +221,9 @@ sealed interface Currency {
|
|||
val currencySymbol: CryptoCurrencyName
|
||||
|
||||
data class Token(
|
||||
val token: com.tangem.blockchain.common.Token,
|
||||
override val blockchain: com.tangem.blockchain.common.Blockchain
|
||||
val token: com.tangem.blockchain.common.Token
|
||||
) : Currency {
|
||||
override val blockchain = token.blockchain
|
||||
override val currencySymbol: CryptoCurrencyName = token.symbol
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,10 @@ class MultiWalletMiddleware {
|
|||
when (val currency = action.walletData.currency) {
|
||||
is Currency.Blockchain -> {
|
||||
cardId?.let {
|
||||
currenciesRepository.removeBlockchain(it,
|
||||
currency.blockchain)
|
||||
currenciesRepository.removeBlockchain(
|
||||
it,
|
||||
currency.blockchain
|
||||
)
|
||||
}
|
||||
}
|
||||
is Currency.Token -> {
|
||||
|
|
@ -94,11 +96,16 @@ class MultiWalletMiddleware {
|
|||
if (coinAmount != null && !coinAmount.isZero()) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
if (walletState?.getWalletData(wallet.blockchain) == null) {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(
|
||||
listOfNotNull(walletManager)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchain(
|
||||
wallet.blockchain
|
||||
))
|
||||
store.dispatch(
|
||||
WalletAction.MultiWallet.AddWalletManagers(
|
||||
listOfNotNull(walletManager)
|
||||
)
|
||||
)
|
||||
store.dispatch(
|
||||
WalletAction.MultiWallet.AddBlockchain(
|
||||
wallet.blockchain
|
||||
)
|
||||
)
|
||||
store.dispatch(WalletAction.LoadWallet.Success(wallet))
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +143,7 @@ class MultiWalletMiddleware {
|
|||
)
|
||||
store.dispatch(
|
||||
WalletAction.MultiWallet.AddTokens(
|
||||
walletManager.presetTokens.toList()
|
||||
walletManager.cardTokens.toList()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -160,12 +167,7 @@ class MultiWalletMiddleware {
|
|||
}
|
||||
|
||||
store.dispatch(
|
||||
WalletAction.LoadFiatRate(
|
||||
currency = Currency.Token(
|
||||
token = token,
|
||||
blockchain = walletManager?.wallet?.blockchain ?: Blockchain.Ethereum
|
||||
)
|
||||
)
|
||||
WalletAction.LoadFiatRate(currency = Currency.Token(token))
|
||||
)
|
||||
|
||||
scope.launch {
|
||||
|
|
@ -189,15 +191,14 @@ class MultiWalletMiddleware {
|
|||
val walletManager = walletState?.getWalletManager(token)
|
||||
?: globalState.tapWalletManager.walletManagerFactory.makeWalletManagerForApp(
|
||||
card = card,
|
||||
blockchain = if (card.isTestCard) Blockchain.EthereumTestnet else Blockchain.Ethereum
|
||||
blockchain = token.blockchain
|
||||
)?.also { walletManager ->
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchain(walletManager.wallet.blockchain))
|
||||
}
|
||||
store.dispatch(WalletAction.LoadFiatRate(currency = Currency.Token(
|
||||
token = token,
|
||||
blockchain = walletManager?.wallet?.blockchain ?: Blockchain.Ethereum
|
||||
)))
|
||||
store.dispatch(
|
||||
WalletAction.LoadFiatRate(currency = Currency.Token(token))
|
||||
)
|
||||
TokenWithManager(token, walletManager)
|
||||
}
|
||||
scope.launch {
|
||||
|
|
|
|||
|
|
@ -166,9 +166,6 @@ fun Token.toWallet(state: WalletState): WalletData? {
|
|||
walletAddresses = walletAddresses,
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(allowed = false),
|
||||
currency = Currency.Token(
|
||||
token = this,
|
||||
blockchain = walletManager?.blockchain ?: Blockchain.Ethereum
|
||||
)
|
||||
currency = Currency.Token(this)
|
||||
)
|
||||
}
|
||||
|
|
@ -45,35 +45,42 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
newState.twinCardsState?.isCreatingTwinCardsAllowed != true)
|
||||
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
wallets = listOf(WalletData(
|
||||
currencyData = BalanceWidgetData(BalanceStatus.EmptyCard),
|
||||
mainButton = WalletMainButton.CreateWalletButton(creatingWalletAllowed),
|
||||
topUpState = TopUpState(false)
|
||||
)))
|
||||
state = ProgressState.Done,
|
||||
wallets = listOf(
|
||||
WalletData(
|
||||
currencyData = BalanceWidgetData(BalanceStatus.EmptyCard),
|
||||
mainButton = WalletMainButton.CreateWalletButton(creatingWalletAllowed),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletAction.LoadData.Failure -> {
|
||||
when (action.error) {
|
||||
is TapError.NoInternetConnection -> {
|
||||
val wallets = newState.wallets
|
||||
.map {
|
||||
it.copy(currencyData = it.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable
|
||||
))
|
||||
}
|
||||
.map {
|
||||
it.copy(
|
||||
currencyData = it.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable
|
||||
)
|
||||
)
|
||||
}
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Error,
|
||||
error = ErrorType.NoInternetConnection,
|
||||
wallets = wallets
|
||||
state = ProgressState.Error,
|
||||
error = ErrorType.NoInternetConnection,
|
||||
wallets = wallets
|
||||
)
|
||||
}
|
||||
is TapError.UnknownBlockchain -> {
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
wallets = listOf(WalletData(
|
||||
currencyData = BalanceWidgetData(BalanceStatus.UnknownBlockchain),
|
||||
topUpState = TopUpState(false)
|
||||
))
|
||||
state = ProgressState.Done,
|
||||
wallets = listOf(
|
||||
WalletData(
|
||||
currencyData = BalanceWidgetData(BalanceStatus.UnknownBlockchain),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -81,73 +88,76 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
|
||||
is WalletAction.LoadData -> {
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Loading,
|
||||
error = null,
|
||||
state = ProgressState.Loading,
|
||||
error = null,
|
||||
)
|
||||
}
|
||||
is WalletAction.LoadWallet -> {
|
||||
if (action.blockchain == null) {
|
||||
val wallets = newState.wallets.map { wallet ->
|
||||
wallet.copy(
|
||||
currencyData = wallet.currencyData.copy(
|
||||
status = BalanceStatus.Loading,
|
||||
currency = wallet.currencyData.currency,
|
||||
currencySymbol = wallet.currencyData.currencySymbol,
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(allowed = action.allowTopUp
|
||||
?: wallet.topUpState.allowed)
|
||||
currencyData = wallet.currencyData.copy(
|
||||
status = BalanceStatus.Loading,
|
||||
currency = wallet.currencyData.currency,
|
||||
currencySymbol = wallet.currencyData.currencySymbol,
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(
|
||||
allowed = action.allowTopUp
|
||||
?: wallet.topUpState.allowed
|
||||
)
|
||||
)
|
||||
}
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Loading,
|
||||
wallets = wallets
|
||||
state = ProgressState.Loading,
|
||||
wallets = wallets
|
||||
)
|
||||
} else {
|
||||
val walletManager = newState.getWalletManager(action.blockchain) ?: return newState
|
||||
val blockchain = walletManager.wallet.blockchain
|
||||
val currencies = listOf(Currency.Blockchain(blockchain)) + walletManager.presetTokens.map {
|
||||
Currency.Token(token = it, blockchain = blockchain)
|
||||
}
|
||||
val currencies = listOf(Currency.Blockchain(blockchain)) +
|
||||
walletManager.cardTokens.map { Currency.Token(it) }
|
||||
val newWallets = newState.wallets.filter { currencies.contains(it.currency) }
|
||||
.map { wallet ->
|
||||
wallet.copy(
|
||||
currencyData = wallet.currencyData.copy(
|
||||
status = BalanceStatus.Loading,
|
||||
currency = wallet.currencyData.currency,
|
||||
currencySymbol = wallet.currencyData.currencySymbol,
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(
|
||||
allowed = action.allowTopUp ?: wallet.topUpState.allowed
|
||||
)
|
||||
.map { wallet ->
|
||||
wallet.copy(
|
||||
currencyData = wallet.currencyData.copy(
|
||||
status = BalanceStatus.Loading,
|
||||
currency = wallet.currencyData.currency,
|
||||
currencySymbol = wallet.currencyData.currencySymbol,
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(
|
||||
allowed = action.allowTopUp ?: wallet.topUpState.allowed
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
val wallets = newState.replaceSomeWallets(newWallets)
|
||||
newState = newState.copy(wallets = wallets)
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadWallet.Success -> newState = onWalletLoadedReducer.reduce(action.wallet, newState)
|
||||
is WalletAction.LoadWallet.Success -> newState =
|
||||
onWalletLoadedReducer.reduce(action.wallet, newState)
|
||||
is WalletAction.UpdateWallet.Success -> {
|
||||
newState = onWalletLoadedReducer.reduce(action.wallet, newState)
|
||||
}
|
||||
is WalletAction.LoadWallet.NoAccount -> {
|
||||
val walletData = newState.getWalletData(action.wallet.blockchain)?.copy(
|
||||
currencyData = BalanceWidgetData(
|
||||
BalanceStatus.NoAccount, action.wallet.blockchain.fullName,
|
||||
currencySymbol = action.wallet.blockchain.currency,
|
||||
amountToCreateAccount = action.amountToCreateAccount
|
||||
)
|
||||
currencyData = BalanceWidgetData(
|
||||
BalanceStatus.NoAccount, action.wallet.blockchain.fullName,
|
||||
currencySymbol = action.wallet.blockchain.currency,
|
||||
amountToCreateAccount = action.amountToCreateAccount
|
||||
)
|
||||
)
|
||||
val wallets = newState.replaceWalletInWallets(walletData)
|
||||
val progressState = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) {
|
||||
ProgressState.Loading
|
||||
} else {
|
||||
ProgressState.Done
|
||||
}
|
||||
val progressState =
|
||||
if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) {
|
||||
ProgressState.Loading
|
||||
} else {
|
||||
ProgressState.Done
|
||||
}
|
||||
newState = newState.copy(
|
||||
state = progressState,
|
||||
wallets = wallets
|
||||
state = progressState,
|
||||
wallets = wallets
|
||||
)
|
||||
}
|
||||
is WalletAction.LoadWallet.Failure -> {
|
||||
|
|
@ -158,28 +168,31 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
}
|
||||
val walletData = newState.getWalletData(action.wallet.blockchain)
|
||||
val newWalletData = walletData?.copy(
|
||||
currencyData = walletData.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable,
|
||||
errorMessage = message
|
||||
),
|
||||
topUpState = TopUpState(false)
|
||||
currencyData = walletData.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable,
|
||||
errorMessage = message
|
||||
),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
val tokenWallets = action.wallet.getTokens()
|
||||
.mapNotNull { newState.getWalletData(it) }
|
||||
.map {
|
||||
it.copy(currencyData = it.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable, errorMessage = message
|
||||
))
|
||||
}
|
||||
.mapNotNull { newState.getWalletData(it) }
|
||||
.map {
|
||||
it.copy(
|
||||
currencyData = it.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable, errorMessage = message
|
||||
)
|
||||
)
|
||||
}
|
||||
val wallets = newState.replaceSomeWallets(listOfNotNull(newWalletData) + tokenWallets)
|
||||
|
||||
val progressState = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) {
|
||||
ProgressState.Loading
|
||||
} else {
|
||||
ProgressState.Done
|
||||
}
|
||||
val progressState =
|
||||
if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) {
|
||||
ProgressState.Loading
|
||||
} else {
|
||||
ProgressState.Done
|
||||
}
|
||||
newState = newState.copy(
|
||||
state = progressState, wallets = wallets
|
||||
state = progressState, wallets = wallets
|
||||
)
|
||||
}
|
||||
is WalletAction.SetArtworkId -> {
|
||||
|
|
@ -216,11 +229,11 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
is WalletAction.ShowDialog.QrCode -> {
|
||||
val selectedWalletData = newState.getWalletData(newState.selectedWallet)
|
||||
newState = newState.copy(
|
||||
walletDialog = WalletDialog.QrDialog(
|
||||
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl?.toQrCode(),
|
||||
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl,
|
||||
selectedWalletData?.currencyData?.currency
|
||||
)
|
||||
walletDialog = WalletDialog.QrDialog(
|
||||
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl?.toQrCode(),
|
||||
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl,
|
||||
selectedWalletData?.currencyData?.currency
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletAction.ShowDialog.ScanFails -> {
|
||||
|
|
@ -234,7 +247,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
}
|
||||
is WalletAction.Send.ChooseCurrency -> {
|
||||
newState = newState.copy(
|
||||
walletDialog = WalletDialog.SelectAmountToSendDialog(action.amounts)
|
||||
walletDialog = WalletDialog.SelectAmountToSendDialog(action.amounts)
|
||||
)
|
||||
}
|
||||
is WalletAction.Send.Cancel -> newState = newState.copy(walletDialog = null)
|
||||
|
|
@ -242,12 +255,18 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
is WalletAction.ChangeSelectedAddress -> {
|
||||
val selectedWalletData = newState.getWalletData(newState.selectedWallet)
|
||||
|
||||
val walletAddresses = newState.getWalletData(selectedWalletData?.currency)?.walletAddresses
|
||||
val walletAddresses =
|
||||
newState.getWalletData(selectedWalletData?.currency)?.walletAddresses
|
||||
?: return newState
|
||||
val address = walletAddresses.list.firstOrNull { it.type == action.type }
|
||||
?: return newState
|
||||
?: return newState
|
||||
val wallets = newState.replaceWalletInWallets(
|
||||
selectedWalletData?.copy(walletAddresses = WalletAddresses(address, walletAddresses.list))
|
||||
selectedWalletData?.copy(
|
||||
walletAddresses = WalletAddresses(
|
||||
address,
|
||||
walletAddresses.list
|
||||
)
|
||||
)
|
||||
)
|
||||
newState = newState.copy(wallets = wallets)
|
||||
}
|
||||
|
|
@ -261,7 +280,12 @@ fun createAddressList(wallet: Wallet?, walletAddresses: WalletAddresses? = null)
|
|||
val listOfAddressData = mutableListOf<AddressData>()
|
||||
// put a defaultAddress at the first place
|
||||
wallet.addresses.forEach {
|
||||
val addressData = AddressData(it.value, it.type, wallet.getShareUri(it.value), wallet.getExploreUrl(it.value))
|
||||
val addressData = AddressData(
|
||||
it.value,
|
||||
it.type,
|
||||
wallet.getShareUri(it.value),
|
||||
wallet.getExploreUrl(it.value)
|
||||
)
|
||||
if (it.type == wallet.blockchain.defaultAddressType()) {
|
||||
listOfAddressData.add(0, addressData)
|
||||
} else {
|
||||
|
|
@ -272,16 +296,22 @@ fun createAddressList(wallet: Wallet?, walletAddresses: WalletAddresses? = null)
|
|||
// restore a selected wallet address
|
||||
var indexOfSelectedWallet = 0
|
||||
walletAddresses?.let {
|
||||
val index = listOfAddressData.indexOfFirst { it.address == walletAddresses.selectedAddress.address }
|
||||
val index =
|
||||
listOfAddressData.indexOfFirst { it.address == walletAddresses.selectedAddress.address }
|
||||
if (index != -1) indexOfSelectedWallet = index
|
||||
}
|
||||
return WalletAddresses(listOfAddressData[indexOfSelectedWallet], listOfAddressData)
|
||||
}
|
||||
|
||||
private fun handleCheckSignedHashesActions(action: WalletAction.Warnings, state: WalletState): WalletState {
|
||||
private fun handleCheckSignedHashesActions(
|
||||
action: WalletAction.Warnings,
|
||||
state: WalletState
|
||||
): WalletState {
|
||||
return when (action) {
|
||||
WalletAction.Warnings.CheckHashesCount.ConfirmHashesCount -> state.copy(hashesCountVerified = true)
|
||||
WalletAction.Warnings.CheckHashesCount.NeedToCheckHashesCountOnline -> state.copy(hashesCountVerified = false)
|
||||
WalletAction.Warnings.CheckHashesCount.NeedToCheckHashesCountOnline -> state.copy(
|
||||
hashesCountVerified = false
|
||||
)
|
||||
is WalletAction.Warnings.Set -> state.copy(mainWarningsList = action.warningList)
|
||||
else -> state
|
||||
}
|
||||
|
|
@ -289,8 +319,8 @@ private fun handleCheckSignedHashesActions(action: WalletAction.Warnings, state:
|
|||
|
||||
|
||||
private fun setNewFiatRate(
|
||||
fiatRate: Pair<Currency, BigDecimal?>,
|
||||
appCurrency: FiatCurrencyName, state: WalletState
|
||||
fiatRate: Pair<Currency, BigDecimal?>,
|
||||
appCurrency: FiatCurrencyName, state: WalletState
|
||||
): WalletState {
|
||||
val rate = fiatRate.second ?: return state
|
||||
val rateFormatted = rate.toFormattedCurrencyString(2, appCurrency, RoundingMode.HALF_UP)
|
||||
|
|
@ -327,33 +357,34 @@ private fun setMultiWalletFiatRate(
|
|||
}
|
||||
|
||||
private fun setSingeWalletFiatRate(
|
||||
rate: BigDecimal, rateFormatted: String, currency: Currency,
|
||||
appCurrency: FiatCurrencyName, state: WalletState
|
||||
rate: BigDecimal, rateFormatted: String, currency: Currency,
|
||||
appCurrency: FiatCurrencyName, state: WalletState
|
||||
): WalletState {
|
||||
val wallet = state.walletManagers[0].wallet
|
||||
val token = wallet.getFirstToken()
|
||||
|
||||
if (currency == state.primaryWallet?.currency) {
|
||||
val fiatAmount = wallet.amounts[AmountType.Coin]?.value
|
||||
?.toFiatString(rate, appCurrency)
|
||||
?.toFiatString(rate, appCurrency)
|
||||
val walletData = state.primaryWallet.copy(
|
||||
currencyData = state.primaryWallet.currencyData.copy(fiatAmountFormatted = fiatAmount),
|
||||
fiatRate = rate,
|
||||
fiatRateString = rateFormatted
|
||||
currencyData = state.primaryWallet.currencyData.copy(fiatAmountFormatted = fiatAmount),
|
||||
fiatRate = rate,
|
||||
fiatRateString = rateFormatted
|
||||
)
|
||||
return state.copy(wallets = listOf(walletData))
|
||||
} else if (currency is Currency.Token && currency.token == token) {
|
||||
val tokenFiatAmount = wallet.getTokenAmount(token)?.value?.toFiatString(rate, appCurrency)
|
||||
val tokenData = state.primaryWallet?.currencyData?.token?.copy(
|
||||
fiatAmount = tokenFiatAmount,
|
||||
fiatRate = rate,
|
||||
fiatRateString = rateFormatted
|
||||
fiatAmount = tokenFiatAmount,
|
||||
fiatRate = rate,
|
||||
fiatRateString = rateFormatted
|
||||
)
|
||||
|
||||
val walletData = state.primaryWallet?.copy(
|
||||
currencyData = state.primaryWallet.currencyData.copy(
|
||||
token = tokenData
|
||||
))
|
||||
currencyData = state.primaryWallet.currencyData.copy(
|
||||
token = tokenData
|
||||
)
|
||||
)
|
||||
val wallets = walletData?.let { listOf(walletData) } ?: emptyList()
|
||||
return state.copy(wallets = wallets)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue