Updated on 2026-08-14

This commit is contained in:
Tangem 2022-08-02 10:26:14 +03:00
commit f77fa1fe70
15 changed files with 317 additions and 77 deletions

@ -1 +1 @@
Subproject commit 59ee0bff06ee54f3202421c28f7fb6e3d421dad8
Subproject commit bf673f7f88ed561cd8827447c4886f80f30b7e23

View file

@ -148,14 +148,14 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di
val techService = store.state.domainNetworks.tangemTechService
when (val result = techService.userCountry()) {
is Result.Success -> {
store.dispatch(
store.dispatchOnMain(
GlobalAction.FetchUserCountry.Success(
countryCode = result.data.code.lowercase()
)
)
}
is Result.Failure -> {
store.dispatch(
store.dispatchOnMain(
GlobalAction.FetchUserCountry.Success(
countryCode = Locale.getDefault().country.lowercase()
)

View file

@ -91,7 +91,8 @@ class ConfigManager(
blockchairApiKey = values.blockchairApiKey,
blockchairAuthorizationToken = values.blockchairAuthorizationToken,
blockcypherTokens = values.blockcypherTokens,
infuraProjectId = values.infuraProjectId
infuraProjectId = values.infuraProjectId,
tronGridApiKey = values.tronGridApiKey
),
appsFlyerDevKey = values.appsFlyerDevKey,
shopify = values.shopifyShop,

View file

@ -27,6 +27,7 @@ class ConfigValueModel(
val appsFlyerDevKey: String,
val shopifyShop: ShopifyShop?,
val zendesk: ZendeskConfig?,
val tronGridApiKey: String,
)
class ConfigModel(val features: FeatureModel?, val configValues: ConfigValueModel?) {

View file

@ -104,56 +104,25 @@ class DemoConfig {
?: Amount(BigDecimal.ZERO, blockchain).copy()
private fun getReleaseIds(): List<String> {
return (releaseDemoCardIds +
releaseDemoCardIds_19042022 +
testDemoCardIds).distinct()
return (releaseDemoCardIds + testDemoCardIds).distinct()
}
private val releaseDemoCardIds = mutableListOf(
// Tangem Wallet:
"AC01000000041100",
"AC01000000042462",
"AC01000000041647",
"AC01000000041621",
"AC01000000041217",
// === Not from the Google Sheet table ===
"FB10000000000196", // Note BTC
"FB20000000000186", // Note ETH
"FB30000000000176", // Wallet
"AC01000000041225",
"AC01000000041209",
"AC01000000041092",
"AC01000000041472",
"AC01000000041662",
"AC01000000045754",
"AC01000000045960",
// Tangem Note BTC:
"AB01000000046530",
"AB01000000046720",
"AB01000000046746",
"AB01000000046498",
"AB01000000046753",
"AB01000000049608",
"AB01000000046761",
"AB01000000049574",
"AB01000000046605",
"AB01000000046571",
"AB01000000046704",
"AB01000000046647",
// Tangem Note Ethereum:
"AB02000000051000",
"AB02000000050986",
"AB02000000051026",
"AB02000000051042",
"AB02000000051091",
"AB02000000051083",
"AB02000000050960",
"AB02000000051034",
"AB02000000050911",
"AB02000000051133",
"AB02000000051158",
"AB02000000051059",
)
// https://tangem.slack.com/archives/GMXC6PP71/p1650360610759269
private val releaseDemoCardIds_19042022 = listOf(
// Wallet
// === Mvideo ===
// Wallet
"AC01000000045754",
"AC01000000041662",
"AC01000000041647",
@ -186,7 +155,58 @@ class DemoConfig {
"AC01000000013497",
"AC01000000013836",
"AC01000000013505",
// Note BTC
"AC03000000046693",
"AC03000000046685",
"AC03000000046677",
"AC03000000046669",
"AC03000000046651",
"AC03000000046644",
"AC03000000046636",
"AC03000000046628",
"AC03000000046610",
"AC03000000046602",
"AC03000000046594",
"AC03000000046586",
"AC03000000046578",
"AC03000000046560",
"AC03000000046552",
"AC03000000046545",
"AC03000000046537",
"AC03000000046529",
"AC03000000046511",
"AC03000000046800",
"AC03000000046792",
"AC03000000046784",
"AC03000000046776",
"AC03000000046768",
"AC03000000046750",
"AC03000000046743",
"AC03000000046735",
"AC03000000046727",
"AC03000000046446",
"AC03000000046438",
"AC03000000046412",
"AC03000000046388",
"AC03000000046370",
"AC03000000046354",
"AC03000000046347",
"AC03000000046339",
"AC03000000046321",
"AC03000000046172",
"AC03000000046396",
"AC03000000046404",
"AC03000000046701",
"AC03000000046420",
"AC03000000046719",
"AC03000000046503",
"AC03000000046495",
"AC03000000046487",
"AC03000000046362",
"AC03000000046479",
"AC03000000046461",
"AC03000000046453",
// Note BTC
"AB01000000059608",
"AB01000000046647",
"AB01000000046571",
@ -219,7 +239,58 @@ class DemoConfig {
"AB01000000015782",
"AB01000000022598",
"AB01000000022580",
// Note ETH
"AB01000000005688",
"AB07000000005696",
"AB07000000005902",
"AB07000000005910",
"AB07000000005928",
"AB07000000005936",
"AB07000000005944",
"AB07000000005993",
"AB07000000005985",
"AB07000000005977",
"AB07000000005969",
"AB07000000005951",
"AB07000000005605",
"AB07000000005803",
"AB07000000005811",
"AB07000000005829",
"AB07000000005837",
"AB07000000005845",
"AB07000000005852",
"AB07000000005860",
"AB07000000005878",
"AB07000000005886",
"AB07000000005894",
"AB07000000005704",
"AB07000000005712",
"AB07000000005720",
"AB07000000005738",
"AB07000000005746",
"AB07000000005514",
"AB07000000005522",
"AB07000000005563",
"AB07000000005571",
"AB07000000005589",
"AB07000000005597",
"AB07000000005613",
"AB07000000005621",
"AB07000000005639",
"AB07000000005647",
"AB07000000005654",
"AB07000000005662",
"AB07000000005670",
"AB07000000005530",
"AB07000000005548",
"AB07000000005555",
"AB07000000005753",
"AB07000000005761",
"AB07000000005779",
"AB07000000005787",
"AB07000000005795",
"AB07000000005506",
// Note ETH
"AB02000000051083",
"AB02000000051059",
"AB02000000051158",
@ -252,6 +323,123 @@ class DemoConfig {
"AB02000000020252",
"AB02000000018652",
"AB02000000018561",
"AB08000000009481",
"AB08000000009473",
"AB08000000009705",
"AB08000000009897",
"AB08000000009689",
"AB08000000009671",
"AB08000000009465",
"AB08000000009457",
"AB08000000009440",
"AB08000000009432",
"AB08000000009424",
"AB08000000009416",
"AB08000000009408",
"AB08000000009390",
"AB08000000009374",
"AB08000000009382",
"AB08000000009267",
"AB08000000009275",
"AB08000000009283",
"AB08000000009291",
"AB08000000009309",
"AB08000000009317",
"AB08000000009325",
"AB08000000009333",
"AB08000000009341",
"AB08000000009358",
"AB08000000009366",
"AB08000000009077",
"AB08000000009143",
"AB08000000009168",
"AB08000000009184",
"AB08000000009192",
"AB08000000009200",
"AB08000000009226",
"AB08000000009218",
"AB08000000009234",
"AB08000000009242",
"AB08000000008574",
"AB08000000009069",
"AB08000000008525",
"AB08000000009051",
"AB08000000009135",
"AB08000000009150",
"AB08000000009176",
"AB08000000009085",
"AB08000000009093",
"AB08000000009101",
"AB08000000009119",
"AB08000000009127",
"AB08000000009259",
// === Technopark ===
// Wallet
"AC01000000044120",
"AC01000000044997",
"AC01000000044989",
"AC01000000043494",
"AC01000000043486",
"AC01000000044187",
"AC01000000043148",
"AC01000000044013",
"AC01000000043973",
"AC01000000044815",
"AC01000000044807",
"AC01000000043809",
"AC01000000043833",
"AC01000000043460",
"AC01000000043064",
"AC01000000044138",
"AC01000000044500",
"AC01000000044492",
"AC01000000044260",
"AC01000000044278",
// Note BTC
"AB01000000049864",
"AB01000000053239",
"AB01000000053056",
"AB01000000054237",
"AB01000000054245",
"AB01000000054211",
"AB01000000054229",
"AB01000000053189",
"AB01000000054195",
"AB01000000050797",
"AB01000000053833",
"AB01000000052124",
"AB01000000051605",
"AB01000000052223",
"AB01000000052207",
"AB01000000052199",
"AB01000000047785",
"AB01000000047850",
"AB01000000047868",
"AB01000000048288",
// Note ETH
"AB02000000049715",
"AB02000000049848",
"AB02000000049814",
"AB02000000049863",
"AB02000000049871",
"AB02000000049855",
"AB02000000049285",
"AB02000000049277",
"AB02000000049558",
"AB02000000049889",
"AB02000000049988",
"AB02000000049707",
"AB02000000049699",
"AB02000000049897",
"AB02000000049905",
"AB02000000049913",
"AB02000000049251",
"AB02000000049533",
"AB02000000049541",
"AB02000000049830",
)
private val testDemoCardIds = listOf(
@ -281,7 +469,6 @@ class DemoTransactionSender(
}
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
val dataToSign = randomString(32).toByteArray()
val signerResponse = signer.sign(

View file

@ -10,8 +10,8 @@ data class PendingTransaction(
val type: PendingTransactionType,
) {
val address: String? = when (type) {
PendingTransactionType.Incoming -> transactionData.destinationAddress
PendingTransactionType.Outgoing -> transactionData.sourceAddress
PendingTransactionType.Incoming -> transactionData.sourceAddress
PendingTransactionType.Outgoing -> transactionData.destinationAddress
PendingTransactionType.Unknown -> null
}

View file

@ -4,7 +4,6 @@ sealed class WalletWarning(
val showingPosition: Int,
) {
object TransactionInProgress : WalletWarning(10)
object SolanaTokensUnsupported : WalletWarning(20)
data class BalanceNotEnoughForFee(val blockchainFullName: String) : WalletWarning(30)
data class Rent(val walletRent: WalletRent) : WalletWarning(40)
}

View file

@ -8,6 +8,8 @@ import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.extensions.isZero
import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.features.addCustomToken.CustomCurrency
import com.tangem.tap.common.entities.Button
import com.tangem.tap.common.extensions.toQrCode
import com.tangem.tap.common.redux.global.CryptoCurrencyName
@ -395,19 +397,10 @@ data class WalletData(
}
fun assembleWarnings(): List<WalletWarning> {
val blockchain = currency.blockchain
val walletWarnings = mutableListOf<WalletWarning>()
if (currencyData.status == BalanceStatus.SameCurrencyTransactionInProgress) {
walletWarnings.add(WalletWarning.TransactionInProgress)
}
if (currency.isBlockchain()) {
if (blockchain == Blockchain.Solana || blockchain == Blockchain.SolanaTestnet) {
val card = store.state.globalState.scanResponse?.card
if (card?.canHandleToken(blockchain) == false) {
walletWarnings.add(WalletWarning.SolanaTokensUnsupported)
}
}
}
if (walletRent != null) {
walletWarnings.add(WalletWarning.Rent(walletRent))
}

View file

@ -21,9 +21,6 @@ class WalletWarningConverter(
message.blockchainFullName, message.blockchainFullName
)
}
WalletWarning.SolanaTokensUnsupported -> {
context.getString(R.string.warning_token_send_unsupported_message)
}
WalletWarning.TransactionInProgress -> {
context.getString(R.string.wallet_pending_transaction_warning)
}

View file

@ -0,0 +1,58 @@
package com.tangem.tap.features.wallet.ui.images
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader
import androidx.annotation.Px
import androidx.core.graphics.applyCanvas
import coil.size.Size
import coil.size.pxOrElse
import coil.transform.Transformation
class RoundedCornersCropTransformation(
@Px val radiusPx: Float,
) : Transformation {
override val cacheKey: String = "${javaClass.name}-$radiusPx"
override suspend fun transform(input: Bitmap, size: Size): Bitmap {
val outputWidth = size.width.pxOrElse { Int.MAX_VALUE }
val outputHeight = size.height.pxOrElse { Int.MAX_VALUE }
val outputSize = minOf(outputWidth, outputHeight)
val output = Bitmap.createBitmap(outputSize, outputSize, Bitmap.Config.ARGB_8888)
val rect = RectF(
/* left = */ 0f,
/* top = */ 0f,
/* right = */ outputWidth.toFloat(),
/* bottom = */ outputHeight.toFloat()
)
val matrix = Matrix().apply {
setTranslate(
/* dx = */ (outputWidth - input.width) * .5f,
/* dy = */ (outputHeight - input.height) * .5f
)
}
val bitmapShader = BitmapShader(
/* bitmap = */ input,
/* tileX = */ Shader.TileMode.DECAL,
/* tileY = */ Shader.TileMode.DECAL
).apply {
setLocalMatrix(matrix)
}
val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply {
shader = bitmapShader
}
return output.applyCanvas {
drawRoundRect(
/* rect = */ rect,
/* rx = */ radiusPx,
/* ry = */ radiusPx,
/* paint = */ paint
)
}
}
}

View file

@ -244,8 +244,8 @@
<string name="onboarding_done_body">Ваша криптокарта активирована и готова к использованию</string>
<string name="onboarding_done_button_continue">Продолжить</string>
<string name="onboarding_balance_title">Баланс</string>
<string name="address_qr_code_message_format">Отправляйте только %s (%s) на этот адрес. Отправка любой другой валюты приведет к ее безвозвратной потере.</string>
<string name="address_qr_code_message_token_format">Отправляйте только %s (%s) из сети %s на этот адрес. Отправка любой другой валюты приведет к ее безвозвратной потере.</string>
<string name="address_qr_code_message_format">Отправляйте только %s (%s) на этот адрес. Иначе это может привести к утрате средств.</string>
<string name="address_qr_code_message_token_format">Отправляйте только %s (%s) из сети %s на этот адрес. Иначе это может привести к утрате средств.</string>
<string name="onboarding_twins_interrupt_warning">Если процесс повторного создания кошелька каким-либо образом прервется, вам придется начать все сначала.</string>
<string name="onboarding_twin_exit_warning">Процесс связывания карт частично завершен. Вы не можете выйти из него сейчас.</string>
<string name="onboarding_error_create_primary_wallet">Внутренняя ошибка: не удается создать менеджер кошельков</string>

View file

@ -205,8 +205,8 @@
<string name="onboarding_done_body" translatable="false">Your crypto card is activated and ready to be used</string>
<string name="onboarding_done_button_continue" translatable="false">Continue</string>
<string name="onboarding_balance_title" translatable="false">Balance</string>
<string name="address_qr_code_message_format" translatable="false">Send only %s (%s) to this address. Sending any other currency will result in its irreversible loss.</string>
<string name="address_qr_code_message_token_format" translatable="false">Send only %s (%s) from %s network to this address. Sending any other currency will result in its irreversible loss.</string>
<string name="address_qr_code_message_format" translatable="false">Send only %s (%s) to this address. Using other tokens and networks may result in loss of funds.</string>
<string name="address_qr_code_message_token_format" translatable="false">Send only %s (%s) from %s network to this address. Using other tokens and networks may result in loss of funds.</string>
<string name="onboarding_twins_interrupt_warning" translatable="false">If the process of re-creating the wallet gets interrupted in any way, you\'ll have to start over.</string>
<string name="onboarding_twin_exit_warning" translatable="false">The twinning process is partly complete. You can\'t exit it now.</string>

View file

@ -85,4 +85,4 @@ dependencies {
testImplementation "com.google.truth:truth:1.1.3"
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
}

View file

@ -2,7 +2,6 @@ package com.tangem.domain.features.addCustomToken.redux
import android.webkit.ValueCallback
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.common.extensions.guard
import com.tangem.common.services.Result
import com.tangem.domain.AddCustomTokenError
@ -571,17 +570,11 @@ private class AddCustomTokenReducer(
supportedTokenNetworkIds = supportedTokenNetworkIds
)
var derivationPathState = state.screenState.derivationPath
derivationPathState = when (card.derivationStyle) {
DerivationStyle.LEGACY -> derivationPathState.copy(isVisible = true)
null, DerivationStyle.NEW -> derivationPathState.copy(isVisible = false)
}
val form = Form(AddCustomTokenState.createFormFields(card, CustomTokenType.Blockchain))
state.copy(
cardDerivationStyle = card.derivationStyle,
form = form,
tangemTechServiceManager = tangemTechServiceManager,
screenState = state.screenState.copy(derivationPath = derivationPathState)
)
}
is OnDestroy -> {

View file

@ -50,7 +50,7 @@ data class AddCustomTokenState(
fun blockchainToName(blockchain: Blockchain, isDerivationPath: Boolean = false): String? {
return when {
isDerivationPath -> blockchain.derivationPath(cardDerivationStyle)?.rawPath
isDerivationPath -> blockchain.derivationPath(DerivationStyle.LEGACY)?.rawPath
else -> {
when (blockchain) {
Blockchain.Unknown -> null
@ -150,10 +150,21 @@ data class AddCustomTokenState(
mainNetwork: Blockchain,
derivationNetwork: Blockchain,
derivationStyle: DerivationStyle?
): com.tangem.common.hdWallet.DerivationPath? = when (derivationNetwork) {
Blockchain.Unknown -> mainNetwork
else -> derivationNetwork
}.derivationPath(derivationStyle)
): com.tangem.common.hdWallet.DerivationPath? {
// If we allow user to select derivations, we need to provide different derivations
// (Legacy style derivations).
// But the mainNetwork derivation depends on whether a user has a card
// with legacy derivations or new style derivations.
val derivationStyleToUse = if (derivationNetwork == Blockchain.Unknown) {
derivationStyle
} else {
DerivationStyle.LEGACY
}
return when (derivationNetwork) {
Blockchain.Unknown -> mainNetwork
else -> derivationNetwork
}.derivationPath(derivationStyleToUse)
}
internal fun createFormFields(card: Card, type: CustomTokenType): List<DataField<*>> {
return listOf(