Updated on 2026-08-14
This commit is contained in:
parent
12bc959fde
commit
787d354d3d
18 changed files with 102 additions and 262 deletions
|
|
@ -1,40 +0,0 @@
|
|||
package com.tangem.tap.common.compose
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun keyboardObserverAsState(): State<Keyboard> {
|
||||
val keyboardState: MutableState<Keyboard> = remember { mutableStateOf(Keyboard.Closed) }
|
||||
val view = LocalView.current
|
||||
DisposableEffect(view) {
|
||||
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
|
||||
val rect = Rect()
|
||||
view.getWindowVisibleDisplayFrame(rect)
|
||||
val screenHeight = view.rootView.height
|
||||
val keypadHeight = screenHeight - rect.bottom
|
||||
keyboardState.value = if (keypadHeight > screenHeight * 0.15) {
|
||||
Keyboard.Opened(keypadHeight)
|
||||
} else {
|
||||
Keyboard.Closed
|
||||
}
|
||||
}
|
||||
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
|
||||
|
||||
onDispose {
|
||||
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
|
||||
}
|
||||
}
|
||||
|
||||
return keyboardState
|
||||
}
|
||||
|
||||
sealed class Keyboard {
|
||||
data class Opened(val height: Int) : Keyboard()
|
||||
object Closed : Keyboard()
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTangemNote
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
import com.tangem.tap.domain.twins.isTangemTwin
|
||||
import java.util.*
|
||||
|
||||
object TapWorkarounds {
|
||||
|
||||
fun isStart2CoinIssuer(cardIssuer: String?): Boolean {
|
||||
return cardIssuer?.lowercase(Locale.US) == START_2_COIN_ISSUER
|
||||
}
|
||||
|
||||
val Card.isStart2Coin: Boolean
|
||||
get() = isStart2CoinIssuer(issuer.name)
|
||||
|
||||
val Card.isTestCard: Boolean
|
||||
get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH)
|
||||
|
||||
val Card.useOldStyleDerivation: Boolean
|
||||
get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95"
|
||||
|
||||
val Card.derivationStyle: DerivationStyle?
|
||||
get() = if (!settings.isHDWalletAllowed) {
|
||||
null
|
||||
} else if (useOldStyleDerivation) {
|
||||
DerivationStyle.LEGACY
|
||||
} else {
|
||||
DerivationStyle.NEW
|
||||
}
|
||||
|
||||
fun Card.isExcluded(): Boolean {
|
||||
val excludedBatch = excludedBatches.contains(batchId)
|
||||
val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT))
|
||||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
fun Card.isNotSupportedInThatRelease(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
@Deprecated("Use ScanResponse.isTangemNote")
|
||||
fun isTangemNote(card: Card): Boolean = tangemNoteBatches.contains(card.batchId)
|
||||
|
||||
fun isTangemWalletBatch(card: Card): Boolean = tangemWalletBatches.contains(card.batchId)
|
||||
|
||||
fun getTangemNoteBlockchain(card: Card): Blockchain? = tangemNoteBatches[card.batchId]
|
||||
|
||||
private const val START_2_COIN_ISSUER = "start2coin"
|
||||
private const val TEST_CARD_BATCH = "99FF"
|
||||
private const val TEST_CARD_ID_STARTS_WITH = "FF99"
|
||||
|
||||
private val excludedBatches = listOf(
|
||||
"0027",
|
||||
"0030",
|
||||
"0031",
|
||||
"0035"
|
||||
)
|
||||
|
||||
private val excludedIssuers = listOf(
|
||||
"TTM BANK"
|
||||
)
|
||||
|
||||
private val tangemWalletBatches = listOf("AC01")
|
||||
|
||||
private val tangemNoteBatches = mapOf(
|
||||
"AB01" to Blockchain.Bitcoin,
|
||||
"AB02" to Blockchain.Ethereum,
|
||||
"AB03" to Blockchain.CardanoShelley,
|
||||
"AB04" to Blockchain.Dogecoin,
|
||||
"AB05" to Blockchain.BSC,
|
||||
"AB06" to Blockchain.XRP,
|
||||
"AB07" to Blockchain.Bitcoin,
|
||||
"AB08" to Blockchain.Ethereum,
|
||||
)
|
||||
}
|
||||
|
||||
val DELAY_SDK_DIALOG_CLOSE = 1400L
|
||||
|
||||
val Card.isMultiwalletAllowed: Boolean
|
||||
get() {
|
||||
return !isTangemTwin() && !isStart2Coin && !isTangemNote(this)
|
||||
&& (firmwareVersion >= FirmwareVersion.MultiWalletAvailable ||
|
||||
getSingleWallet()?.curve == EllipticCurve.Secp256k1)
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import com.tangem.common.extensions.toMapKey
|
|||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.KeyWalletPublicKey
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.operations.CommandResponse
|
||||
|
|
@ -20,10 +21,6 @@ import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
|||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.domain.tasks.product.CreateWalletsTask
|
||||
import com.tangem.tap.domain.tasks.product.ProductCommandProcessor
|
||||
import com.tangem.tap.domain.tasks.product.getCurvesForNonCreatedWallets
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.card.WalletData
|
||||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.common.core.TangemError
|
||||
|
|
@ -17,8 +15,10 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.*
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.isExcluded
|
||||
import com.tangem.domain.common.TapWorkarounds.isNotSupportedInThatRelease
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.operations.PreflightReadMode
|
||||
import com.tangem.operations.PreflightReadTask
|
||||
import com.tangem.operations.ScanTask
|
||||
|
|
@ -27,57 +27,12 @@ import com.tangem.operations.backup.StartPrimaryCardLinkingTask
|
|||
import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
||||
import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
|
||||
import com.tangem.tap.domain.TapSdkError
|
||||
import com.tangem.domain.common.TapWorkarounds
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain
|
||||
import com.tangem.domain.common.TapWorkarounds.isExcluded
|
||||
import com.tangem.domain.common.TapWorkarounds.isNotSupportedInThatRelease
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.tap.domain.extensions.getPrimaryCurve
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
import com.tangem.tap.domain.tokens.BlockchainNetwork
|
||||
import com.tangem.tap.domain.tokens.CurrenciesRepository
|
||||
import com.tangem.tap.preferencesStorage
|
||||
|
||||
data class 1ScanResponse(
|
||||
val card: Card,
|
||||
val productType: ProductType,
|
||||
val walletData: WalletData?,
|
||||
val secondTwinPublicKey: String? = null,
|
||||
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
||||
val primaryCard: PrimaryCard? = null
|
||||
) : CommandResponse {
|
||||
|
||||
fun getBlockchain(): Blockchain {
|
||||
if (productType == ProductType.Note) return getTangemNoteBlockchain(card)
|
||||
?: return Blockchain.Unknown
|
||||
val blockchainName: String = walletData?.blockchain ?: return Blockchain.Unknown
|
||||
return Blockchain.fromId(blockchainName)
|
||||
}
|
||||
|
||||
fun getPrimaryToken(): Token? {
|
||||
val cardToken = walletData?.token ?: return null
|
||||
return Token(
|
||||
cardToken.name,
|
||||
cardToken.symbol,
|
||||
cardToken.contractAddress,
|
||||
cardToken.decimals,
|
||||
)
|
||||
}
|
||||
|
||||
fun isTangemNote(): Boolean = productType == ProductType.Note
|
||||
fun isTangemWallet(): Boolean = productType == ProductType.Wallet
|
||||
fun isTangemTwins(): Boolean = productType == ProductType.Twins
|
||||
|
||||
fun supportsHdWallet(): Boolean = card.settings.isHDWalletAllowed
|
||||
fun supportsBackup(): Boolean = card.settings.isBackupAllowed
|
||||
|
||||
fun twinsIsTwinned(): Boolean =
|
||||
card.isTangemTwins() && walletData != null && secondTwinPublicKey != null
|
||||
}
|
||||
|
||||
typealias KeyWalletPublicKey = ByteArrayKey
|
||||
|
||||
class ScanProductTask(
|
||||
val card: Card? = null,
|
||||
private val currenciesRepository: CurrenciesRepository?,
|
||||
|
|
@ -296,12 +251,12 @@ private class ScanWalletProcessor(
|
|||
if (!card.useOldStyleDerivation) {
|
||||
blockchainsToDerive.removeAll(
|
||||
listOf(
|
||||
Blockchain.BSC, Blockchain.BSCTestnet,
|
||||
Blockchain.Polygon, Blockchain.PolygonTestnet,
|
||||
Blockchain.RSK,
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet,
|
||||
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
|
||||
).map { BlockchainNetwork(it, card) }
|
||||
Blockchain.BSC, Blockchain.BSCTestnet,
|
||||
Blockchain.Polygon, Blockchain.PolygonTestnet,
|
||||
Blockchain.RSK,
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet,
|
||||
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
|
||||
).map { BlockchainNetwork(it, card) }
|
||||
)
|
||||
}
|
||||
return blockchainsToDerive.distinct()
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ import com.tangem.blockchain.common.Token
|
|||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.tap.common.extensions.appendIf
|
||||
import com.tangem.tap.common.extensions.readJsonFileToString
|
||||
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.domain.extensions.setCustomIconUrl
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import timber.log.Timber
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ import com.tangem.tap.common.redux.navigation.NavigationAction
|
|||
import com.tangem.tap.currenciesRepository
|
||||
import com.tangem.tap.domain.extensions.isMultiwalletAllowed
|
||||
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
|
||||
import com.tangem.tap.domain.isMultiwalletAllowed
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.tokens.BlockchainNetwork
|
||||
import com.tangem.tap.domain.walletconnect.BnbHelper
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectManager
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ fun AddCustomTokenScreen(state: MutableState<AddCustomTokenState>) {
|
|||
HangingOverKeyboardView(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter),
|
||||
keyboardState = keyboardObserverAsState(),
|
||||
keyboardState = keyboardAsState(),
|
||||
defaultBottomPadding = 30.dp,
|
||||
spaceBetweenKeyboard = 20.dp,
|
||||
) {
|
||||
|
|
@ -92,15 +92,16 @@ private fun FormFields(state: MutableState<AddCustomTokenState>) {
|
|||
val context = LocalContext.current
|
||||
val errorConverter = remember { CustomTokenErrorConverter(context) }
|
||||
|
||||
state.value.form.fieldList.forEach { field ->
|
||||
val data = ScreenFieldData.fromState(field, state.value, errorConverter)
|
||||
val stateValue = state.value
|
||||
stateValue.form.fieldList.forEach { field ->
|
||||
val data = ScreenFieldData.fromState(field, stateValue, errorConverter)
|
||||
when (field.id) {
|
||||
ContractAddress -> TokenContractAddressView(data)
|
||||
Network -> TokenNetworkView(data)
|
||||
Network -> TokenNetworkView(data, stateValue)
|
||||
Name -> TokenNameView(data)
|
||||
Symbol -> TokenSymbolView(data)
|
||||
Decimals -> TokenDecimalsView(data)
|
||||
DerivationPath -> TokenDerivationPathView(data)
|
||||
DerivationPath -> TokenDerivationPathView(data, stateValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +146,7 @@ private fun TokenNameView(screenFieldData: ScreenFieldData) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenNetworkView(screenFieldData: ScreenFieldData) {
|
||||
private fun TokenNetworkView(screenFieldData: ScreenFieldData, state: AddCustomTokenState) {
|
||||
if (!screenFieldData.viewState.isVisible) return
|
||||
|
||||
val notSelected = stringResource(id = R.string.custom_token_network_input_not_selected)
|
||||
|
|
@ -156,7 +157,7 @@ private fun TokenNetworkView(screenFieldData: ScreenFieldData) {
|
|||
itemList = networkField.itemList,
|
||||
selectedItem = networkField.data,
|
||||
isEnabled = screenFieldData.viewState.isEnabled,
|
||||
textFieldConverter = { AddCustomTokenState.convertBlockchainName(it, notSelected) },
|
||||
textFieldConverter = { state.convertBlockchainName(it, notSelected) },
|
||||
) { domainStore.dispatch(OnTokenNetworkChanged(Field.Data(it))) }
|
||||
SpacerH8()
|
||||
}
|
||||
|
|
@ -197,7 +198,7 @@ private fun TokenDecimalsView(screenFieldData: ScreenFieldData) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenDerivationPathView(screenFieldData: ScreenFieldData) {
|
||||
private fun TokenDerivationPathView(screenFieldData: ScreenFieldData, state: AddCustomTokenState) {
|
||||
if (!screenFieldData.viewState.isVisible) return
|
||||
|
||||
val notSelected = stringResource(id = R.string.custom_token_derivation_path_default)
|
||||
|
|
@ -208,10 +209,10 @@ private fun TokenDerivationPathView(screenFieldData: ScreenFieldData) {
|
|||
itemList = networkField.itemList,
|
||||
selectedItem = networkField.data,
|
||||
isEnabled = screenFieldData.viewState.isEnabled,
|
||||
textFieldConverter = { AddCustomTokenState.convertBlockchainName(it, notSelected) },
|
||||
textFieldConverter = { state.convertBlockchainName(it, notSelected) },
|
||||
dropdownItemView = { blockchain ->
|
||||
val derivationPathLabel = AddCustomTokenState.convertDerivationPathLabel(blockchain, notSelected)
|
||||
val blockchainName = AddCustomTokenState.convertBlockchainName(blockchain, notSelected)
|
||||
val derivationPathLabel = state.convertDerivationPathLabel(blockchain, notSelected)
|
||||
val blockchainName = state.convertBlockchainName(blockchain, notSelected)
|
||||
TitleSubtitle(derivationPathLabel, blockchainName)
|
||||
}
|
||||
) { domainStore.dispatch(OnTokenDerivationPathChanged(Field.Data(it))) }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.common.extensions.toMapKey
|
|||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.KeyWalletPublicKey
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.tap.*
|
||||
|
|
@ -19,12 +20,7 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
|
||||
import com.tangem.tap.domain.tasks.product.KeyWalletPublicKey
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.tokens.BlockchainNetwork
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ import com.tangem.blockchain.common.*
|
|||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.blockchain.extensions.isAboveZero
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.common.extensions.toQrCode
|
||||
import com.tangem.tap.common.redux.StateDialog
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.common.toggleWidget.WidgetState
|
||||
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
||||
import com.tangem.tap.domain.extensions.buyIsAllowed
|
||||
import com.tangem.tap.domain.extensions.sellIsAllowed
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.squareup.picasso.Picasso
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.common.extensions.getString
|
||||
import com.tangem.tap.common.extensions.loadCurrenciesIcon
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.features.wallet.redux.Currency
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletData
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ package com.tangem.tap.features.wallet.ui.wallet
|
|||
import android.app.Dialog
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.StateDialog
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.currenciesRepository
|
||||
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletDialog
|
||||
|
|
@ -103,9 +103,9 @@ class MultiWalletView : WalletView {
|
|||
val card = store.state.globalState.scanResponse!!.card
|
||||
store.dispatch(TokensAction.LoadCurrencies(
|
||||
supportedBlockchains = currenciesRepository.getBlockchains(
|
||||
card.firmwareVersion,
|
||||
card.isTestCard
|
||||
)))
|
||||
card.firmwareVersion,
|
||||
card.isTestCard
|
||||
)))
|
||||
store.dispatch(TokensAction.AllowToAddTokens(true))
|
||||
store.dispatch(TokensAction.SetAddedCurrencies(
|
||||
wallets = state.walletsData,
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ dependencies {
|
|||
implementation implementation(project(path: ':network'))
|
||||
|
||||
// Tangem sdk's
|
||||
implementation 'com.tangem:blockchain:develop-66'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-140'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-140'
|
||||
implementation 'com.tangem:blockchain:develop-70'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142'
|
||||
|
||||
// Kotlin
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ data class ScanResponse(
|
|||
cardToken.symbol,
|
||||
cardToken.contractAddress,
|
||||
cardToken.decimals,
|
||||
Blockchain.fromId(walletData.blockchain)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.common
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.card.Card
|
||||
import java.util.*
|
||||
|
||||
|
|
@ -9,6 +10,45 @@ import java.util.*
|
|||
*/
|
||||
object TapWorkarounds {
|
||||
|
||||
fun isStart2CoinIssuer(cardIssuer: String?): Boolean {
|
||||
return cardIssuer?.lowercase(Locale.US) == START_2_COIN_ISSUER
|
||||
}
|
||||
|
||||
val Card.isStart2Coin: Boolean
|
||||
get() = isStart2CoinIssuer(issuer.name)
|
||||
|
||||
val Card.isTestCard: Boolean
|
||||
get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH)
|
||||
|
||||
val Card.useOldStyleDerivation: Boolean
|
||||
get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95"
|
||||
|
||||
val Card.derivationStyle: DerivationStyle?
|
||||
get() = if (!settings.isHDWalletAllowed) {
|
||||
null
|
||||
} else if (useOldStyleDerivation) {
|
||||
DerivationStyle.LEGACY
|
||||
} else {
|
||||
DerivationStyle.NEW
|
||||
}
|
||||
|
||||
fun Card.isExcluded(): Boolean {
|
||||
val excludedBatch = excludedBatches.contains(batchId)
|
||||
val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT))
|
||||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
fun Card.isNotSupportedInThatRelease(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
@Deprecated("Use ScanResponse.isTangemNote")
|
||||
fun isTangemNote(card: Card): Boolean = tangemNoteBatches.contains(card.batchId)
|
||||
|
||||
fun isTangemWalletBatch(card: Card): Boolean = tangemWalletBatches.contains(card.batchId)
|
||||
|
||||
fun Card.getTangemNoteBlockchain(): Blockchain? = tangemNoteBatches[batchId]
|
||||
|
||||
private const val START_2_COIN_ISSUER = "start2coin"
|
||||
private const val TEST_CARD_BATCH = "99FF"
|
||||
private const val TEST_CARD_ID_STARTS_WITH = "FF99"
|
||||
|
|
@ -24,6 +64,8 @@ object TapWorkarounds {
|
|||
"TTM BANK"
|
||||
)
|
||||
|
||||
private val tangemWalletBatches = listOf("AC01")
|
||||
|
||||
private val tangemNoteBatches = mapOf(
|
||||
"AB01" to Blockchain.Bitcoin,
|
||||
"AB02" to Blockchain.Ethereum,
|
||||
|
|
@ -38,31 +80,4 @@ object TapWorkarounds {
|
|||
private val tangemWalletBatchesWithStandardDerivationType = listOf(
|
||||
"AC01", "AC02", "CB95"
|
||||
)
|
||||
|
||||
fun Card.getTangemNoteBlockchain(): Blockchain? = tangemNoteBatches[batchId]
|
||||
|
||||
val Card.isStart2Coin: Boolean
|
||||
get() = isStart2CoinIssuer(issuer.name)
|
||||
|
||||
val Card.isTestCard: Boolean
|
||||
get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH)
|
||||
|
||||
|
||||
fun Card.isExcluded(): Boolean {
|
||||
val excludedBatch = excludedBatches.contains(batchId)
|
||||
val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT))
|
||||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
fun Card.isNotSupportedInThatRelease(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
@Deprecated("Use ScanResponse.isTangemNote")
|
||||
fun isTangemNote(card: Card): Boolean = tangemNoteBatches.contains(card.batchId)
|
||||
|
||||
|
||||
fun isStart2CoinIssuer(cardIssuer: String?): Boolean {
|
||||
return cardIssuer?.toLowerCase(Locale.US) == START_2_COIN_ISSUER
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.features.addCustomToken.redux
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.domain.common.form.Field
|
||||
import com.tangem.domain.common.form.FieldId
|
||||
import com.tangem.domain.features.addCustomToken.AddCustomTokenError
|
||||
|
|
@ -13,9 +14,13 @@ import org.rekotlin.Action
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class AddCustomTokenAction : Action {
|
||||
// from user, ui
|
||||
object OnCreate : AddCustomTokenAction()
|
||||
object OnCreate : AddCustomTokenAction() {
|
||||
data class SetDerivationStyle(val derivationStyle: DerivationStyle?) : AddCustomTokenAction()
|
||||
}
|
||||
|
||||
object OnDestroy : AddCustomTokenAction()
|
||||
|
||||
// from user, ui
|
||||
data class OnTokenContractAddressChanged(val contractAddress: Field.Data<String>) : AddCustomTokenAction()
|
||||
data class OnTokenNetworkChanged(val blockchainNetwork: Field.Data<Blockchain>) : AddCustomTokenAction()
|
||||
data class OnTokenNameChanged(val tokenName: Field.Data<String>) : AddCustomTokenAction()
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ package com.tangem.domain.features.addCustomToken.redux
|
|||
import android.webkit.ValueCallback
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.DomainDialog
|
||||
import com.tangem.domain.DomainException
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.form.*
|
||||
import com.tangem.domain.features.addCustomToken.*
|
||||
import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.*
|
||||
|
|
@ -43,12 +45,13 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
cancel: ValueCallback<Action>
|
||||
) {
|
||||
if (action !is AddCustomTokenAction) return
|
||||
// val card = storeState.globalState.scanResponse?.card
|
||||
// ?: throw IllegalStateException("ScanResponse must be set before showing the AddCustomToken screen")
|
||||
val card = storeState.globalState.scanResponse?.card
|
||||
?: throw IllegalStateException("ScanResponse must be set before showing the AddCustomToken screen")
|
||||
|
||||
when (action) {
|
||||
is OnCreate -> {
|
||||
// hubState.addCustomTokenManager.attachAuthKey(card.cardPublicKey.toHexString())
|
||||
hubState.addCustomTokenManager.attachAuthKey(card.cardPublicKey.toHexString())
|
||||
dispatchOnMain(OnCreate.SetDerivationStyle(card.derivationStyle))
|
||||
}
|
||||
is OnDestroy -> hubScope.cancel()
|
||||
is OnTokenContractAddressChanged -> {
|
||||
|
|
@ -201,7 +204,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
if (blockchain == Blockchain.Unknown) {
|
||||
throw DomainException.SelectTokeNetworkException(networkId)
|
||||
}
|
||||
AddCustomTokenState.convertBlockchainName(blockchain, "")
|
||||
hubState.convertBlockchainName(blockchain, "")
|
||||
},
|
||||
onSelect = { selectedContract ->
|
||||
hubScope.launch {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.features.addCustomToken.redux
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.domain.common.form.*
|
||||
import com.tangem.domain.features.addCustomToken.*
|
||||
import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.*
|
||||
|
|
@ -13,7 +14,8 @@ data class AddCustomTokenState(
|
|||
val formErrors: Map<CustomTokenFieldId, AddCustomTokenError> = emptyMap(),
|
||||
val warnings: Set<AddCustomTokenWarning> = emptySet(),
|
||||
val screenState: ScreenState = createInitialScreenState(),
|
||||
val addCustomTokenManager: AddCustomTokenManager = AddCustomTokenManager(TangemTechService())
|
||||
val addCustomTokenManager: AddCustomTokenManager = AddCustomTokenManager(TangemTechService()),
|
||||
val derivationStyle: DerivationStyle? = null
|
||||
) : StateType {
|
||||
|
||||
val completeDataType: CompleteDataType
|
||||
|
|
@ -32,6 +34,15 @@ data class AddCustomTokenState(
|
|||
return formErrors[id]
|
||||
}
|
||||
|
||||
fun convertBlockchainName(blockchain: Blockchain, unknown: String): String = when (blockchain) {
|
||||
Blockchain.Unknown -> unknown
|
||||
else -> blockchain.fullName
|
||||
}
|
||||
|
||||
fun convertDerivationPathLabel(blockchain: Blockchain, unknown: String): String {
|
||||
return blockchain.derivationPath(derivationStyle)?.rawPath ?: unknown
|
||||
}
|
||||
|
||||
private fun calculateDataType(): CompleteDataType {
|
||||
val idsToCheck = listOf(ContractAddress, Name, Symbol, Decimals)
|
||||
val fieldsToCheck = form.fieldList.filter { idsToCheck.contains(it.id) }
|
||||
|
|
@ -47,15 +58,6 @@ data class AddCustomTokenState(
|
|||
}
|
||||
|
||||
companion object {
|
||||
fun convertBlockchainName(blockchain: Blockchain, unknown: String): String = when (blockchain) {
|
||||
Blockchain.Unknown -> unknown
|
||||
else -> blockchain.fullName
|
||||
}
|
||||
|
||||
fun convertDerivationPathLabel(blockchain: Blockchain, unknown: String): String {
|
||||
return blockchain.derivationPath()?.rawPath ?: unknown
|
||||
}
|
||||
|
||||
private fun createFormFields(): List<DataField<*>> {
|
||||
return listOf(
|
||||
TokenField(ContractAddress),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ java {
|
|||
|
||||
dependencies {
|
||||
// Tangem sdk's
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-140'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142'
|
||||
|
||||
// Network
|
||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue