Updated on 2026-08-14
This commit is contained in:
commit
df787030ea
21 changed files with 69 additions and 52 deletions
|
|
@ -80,8 +80,10 @@ class App : Application() {
|
|||
)
|
||||
}
|
||||
|
||||
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(Analytics.isEnabled())
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled())
|
||||
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(
|
||||
Analytics.isEnabled() && !BuildConfig.DEBUG
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildToastHelperComponent(): ToastHelperComponent {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public enum Blockchain {
|
|||
Rootstock("RSK", "RBTC", 1.0, R.drawable.tangem2, "RSK"),
|
||||
RootstockToken("RskToken", "RBTC", 1.0, R.drawable.tangem2, "RSK"),
|
||||
Cardano("CARDANO", "ADA", 1000000.0, R.drawable.tangem2, "Cardano"),
|
||||
Ripple ("XRP", "XRP", 1000000.0, R.drawable.ic_logo_xrp, "XRP"),
|
||||
Ripple("XRP", "XRP", 1000000.0, R.drawable.ic_logo_xrp, "XRP"),
|
||||
Binance("BINANCE", "BNB", 100000000.0, R.drawable.ic_logo_binance, "Binance"),
|
||||
BinanceTestNet("BINANCE/test", "BNB", 100000000.0, R.drawable.ic_logo_binance, "Binance Testnet"),
|
||||
Matic("MATIC", "MTX", 1.0, R.drawable.tangem2, "Matic"),
|
||||
|
|
@ -89,37 +89,18 @@ public enum Blockchain {
|
|||
return mImageResource;
|
||||
}
|
||||
|
||||
public int getImageResource(android.content.Context context, String name) {
|
||||
if (name==null || name.isEmpty())
|
||||
return getImageResource();
|
||||
|
||||
name = name.toLowerCase();
|
||||
|
||||
int resourceId = context.getResources().getIdentifier(name + "_token", "drawable", context.getPackageName());
|
||||
|
||||
if (resourceId <= 0)
|
||||
return R.drawable.ic_logo_ethereum;
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public static int getLogoImageResource(String blockchainID, String symbolName) {
|
||||
switch (blockchainID) {
|
||||
case "BTC":
|
||||
return R.drawable.ic_logo_bitcoin;
|
||||
|
||||
case "Token":
|
||||
public int getLogoImageResource(String symbolName) {
|
||||
switch (this) {
|
||||
case Token:
|
||||
if (symbolName.equals("SEED"))
|
||||
return R.drawable.ic_logo_seed;
|
||||
else
|
||||
return R.drawable.ic_logo_ethereum;
|
||||
|
||||
case "ETH":
|
||||
return R.drawable.ic_logo_ethereum;
|
||||
|
||||
case "XLM":
|
||||
return R.drawable.ic_logo_stellar;
|
||||
break;
|
||||
case RootstockToken:
|
||||
if (symbolName.equals("RIF"))
|
||||
return R.drawable.ic_logo_rif;
|
||||
}
|
||||
return R.drawable.tangem2;
|
||||
|
||||
return getImageResource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
|
|||
if (!Analytics.isEnabled()) {
|
||||
analytics.logEvent(AnalyticsEvent.ANALYTICS_TURNED_OFF.event, bundleOf())
|
||||
}
|
||||
analytics.setAnalyticsCollectionEnabled(Analytics.isEnabled())
|
||||
analytics.setAnalyticsCollectionEnabled(Analytics.isEnabled() && !BuildConfig.DEBUG)
|
||||
}
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled())
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter.
|
|||
|
||||
tvInputs.text = engine!!.unspentInputsDescription
|
||||
|
||||
ivBlockchain.setImageResource(Blockchain.getLogoImageResource(ctx.card!!.blockchainID, ctx.card!!.tokenSymbol))
|
||||
ivBlockchain.setImageResource(ctx.blockchain.getLogoImageResource(ctx.card!!.tokenSymbol))
|
||||
|
||||
var s = ""
|
||||
for (signingM in ctx.card!!.allowedSigningMethod) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ enum class AnalyticsParam(val param: String) {
|
|||
FIRMWARE("firmware"),
|
||||
;
|
||||
}
|
||||
|
||||
class Analytics {
|
||||
companion object {
|
||||
fun setCardData(ctx: TangemContext): Bundle {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class BtcData extends CoinData {
|
|||
super();
|
||||
}
|
||||
|
||||
private Long balanceConfirmed, balanceUnconfirmed;
|
||||
protected Long balanceConfirmed, balanceUnconfirmed;
|
||||
|
||||
private boolean useBlockcypher = false;
|
||||
|
||||
|
|
|
|||
16
app/src/main/java/com/tangem/wallet/ducatus/DucatusData.java
Normal file
16
app/src/main/java/com/tangem/wallet/ducatus/DucatusData.java
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.wallet.ducatus;
|
||||
|
||||
import com.tangem.wallet.CoinEngine;
|
||||
import com.tangem.wallet.btc.BtcData;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class DucatusData extends BtcData {
|
||||
public CoinEngine.InternalAmount getBalanceInInternalUnits() {
|
||||
if (balanceConfirmed != null) {
|
||||
return new CoinEngine.InternalAmount(BigDecimal.valueOf(balanceConfirmed), "Satoshi");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,15 +46,15 @@ import io.reactivex.observers.DisposableSingleObserver;
|
|||
|
||||
public class DucatusEngine extends BtcEngine {
|
||||
private static final String TAG = DucatusEngine.class.getSimpleName();
|
||||
public BtcData coinData = null;
|
||||
public DucatusData coinData = null;
|
||||
|
||||
public DucatusEngine(TangemContext context) throws Exception {
|
||||
super(context);
|
||||
this.ctx = context;
|
||||
if (context.getCoinData() == null) {
|
||||
coinData = new BtcData();
|
||||
coinData = new DucatusData();
|
||||
context.setCoinData(coinData);
|
||||
} else if (context.getCoinData() instanceof BtcData) {
|
||||
coinData = (BtcData) context.getCoinData();
|
||||
} else if (context.getCoinData() instanceof DucatusData) {
|
||||
coinData = (DucatusData) context.getCoinData();
|
||||
} else {
|
||||
throw new Exception("Invalid type of Blockchain data for DucatusEngine");
|
||||
}
|
||||
|
|
@ -380,7 +380,7 @@ public class DucatusEngine extends BtcEngine {
|
|||
|
||||
@Override
|
||||
public CoinData createCoinData() {
|
||||
return new BtcData();
|
||||
return new DucatusData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -7,14 +7,11 @@ import com.tangem.tangem_card.reader.CardProtocol.TangemException
|
|||
import com.tangem.tangem_card.tasks.SignTask
|
||||
import com.tangem.tangem_card.util.Util
|
||||
import com.tangem.wallet.*
|
||||
import com.tangem.wallet.binance.client.domain.Account
|
||||
import com.tangem.wallet.flowDemo.proto.Observation
|
||||
import com.tangem.wallet.flowDemo.proto.ObserveServiceGrpc
|
||||
import io.grpc.ManagedChannelBuilder
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Function
|
||||
import io.reactivex.observers.DisposableSingleObserver
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
|
@ -247,4 +244,8 @@ class FlowDemoEngine : CoinEngine {
|
|||
override fun createCoinData(): CoinData {
|
||||
return FlowDemoData()
|
||||
}
|
||||
|
||||
override fun isNftToken(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -109,8 +109,8 @@ public class XlmAssetEngine extends CoinEngine {
|
|||
@Override
|
||||
public boolean isBalanceNotZero() {
|
||||
if (coinData == null) return false;
|
||||
return (coinData.getXlmBalance() != null && coinData.getXlmBalance().notZero() &&
|
||||
coinData.getAssetBalance() != null && coinData.getAssetBalance().notZero());
|
||||
return (coinData.getXlmBalance() != null && coinData.getXlmBalance().notZero()) ||
|
||||
(coinData.getAssetBalance() != null && coinData.getAssetBalance().notZero());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -128,6 +128,8 @@ public class XlmAssetEngine extends CoinEngine {
|
|||
ctx.setMessage(R.string.general_wallet_empty);
|
||||
} else if (awaitingConfirmation()) {
|
||||
ctx.setMessage(R.string.loaded_wallet_message_wait);
|
||||
} else if (coinData.getXlmBalance() == null || coinData.getXlmBalance().isZero()) {
|
||||
ctx.setMessage(ctx.getString(R.string.confirm_transaction_error_not_enough_xlm_for_fee));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -259,7 +261,7 @@ public class XlmAssetEngine extends CoinEngine {
|
|||
balanceValidator.setScore(100);
|
||||
balanceValidator.setFirstLine(R.string.balance_validator_first_line_verified_balance);
|
||||
balanceValidator.setSecondLine(R.string.balance_validator_second_line_confirmed_in_blockchain);
|
||||
if (coinData.getXlmBalance().isZero()) {
|
||||
if (!isBalanceNotZero()) {
|
||||
balanceValidator.setFirstLine(R.string.balance_validator_first_line_empty_wallet);
|
||||
balanceValidator.setSecondLine(R.string.empty_string);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@
|
|||
<string name="confirm_transaction_error_cannot_calculate_fee">Cannot calculate fee! Wrong data received from the node</string>
|
||||
<string name="confirm_transaction_error_incoming_transaction_unconfirmed">Please wait for confirmation of incoming transaction</string>
|
||||
<string name="confirm_transaction_error_not_enough_eth_for_fee">Not enough ETH funds for fee</string>
|
||||
<string name="confirm_transaction_error_not_enough_xlm_for_fee">Not enough XLM funds for fee</string>
|
||||
<string name="confirm_transaction_error_not_enough_rbtc_for_fee">Not enough RBTC funds for fee</string>
|
||||
<string name="confirm_transaction_error_not_enough_xlm_for_create">Target account is not created! Send 1+ XLM to create it</string>
|
||||
<string name="confirm_transaction_error_pin_2_is_required">PIN2 is required to sign the payment</string>
|
||||
|
|
|
|||
|
|
@ -47,10 +47,11 @@ class LocalStorage
|
|||
artworks = HashMap()
|
||||
}
|
||||
|
||||
if (artworks.count() < 43) {
|
||||
if (artworks.count() < 44) {
|
||||
// forceSave=true only on the last one
|
||||
putResourceArtworkToCatalog(R.drawable.card_default, false)
|
||||
putResourceArtworkToCatalog(R.drawable.card_default_nft, false)
|
||||
putResourceArtworkToCatalog(R.drawable.card_id_issuer, false)
|
||||
putResourceArtworkToCatalog(R.drawable.card_ru006, false)
|
||||
putResourceArtworkToCatalog(R.drawable.card_ru007, false)
|
||||
putResourceArtworkToCatalog(R.drawable.card_ru011, false)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class PersonalizeResources() {
|
|||
initProductMask(holder)
|
||||
initSettingsMask(holder)
|
||||
initSettingsMaskProtocolEnc(holder)
|
||||
initSettingsMaskNde(holder)
|
||||
initSettingsMaskNdef(holder)
|
||||
initPins(holder)
|
||||
}
|
||||
|
||||
|
|
@ -115,11 +115,13 @@ class PersonalizeResources() {
|
|||
holder.register(SettingsMaskProtocolEnc.AllowStaticEncryption, Resources(R.string.pers_item_allow_fast_encryption, R.string.info_pers_item_allow_fast_encryption))
|
||||
}
|
||||
|
||||
private fun initSettingsMaskNde(holder: TypedHolder<Id, Resources>) {
|
||||
private fun initSettingsMaskNdef(holder: TypedHolder<Id, Resources>) {
|
||||
holder.register(SettingsMaskNdef.UseNdef, Resources(R.string.pers_item_use_ndef, R.string.info_pers_item_use_ndef))
|
||||
holder.register(SettingsMaskNdef.DynamicNdef, Resources(R.string.pers_item_dynamic_ndef, R.string.info_pers_item_dynamic_ndef))
|
||||
holder.register(SettingsMaskNdef.DisablePrecomputedNdef, Resources(R.string.pers_item_disable_precomputed_ndef, R.string.info_pers_item_disable_precomputed_ndef))
|
||||
holder.register(SettingsMaskNdef.Aar, Resources(R.string.pers_item_aar, R.string.info_pers_item_aar))
|
||||
holder.register(SettingsMaskNdef.AarCustom, Resources(R.string.pers_item_custom_aar_package_name, R.string.info_pers_item_custom_aar_package_name))
|
||||
holder.register(SettingsMaskNdef.Uri, Resources(R.string.pers_item_uri, R.string.info_pers_item_uri))
|
||||
}
|
||||
|
||||
private fun initPins(holder: TypedHolder<Id, Resources>) {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ enum class SettingsMaskNdef : BlockItem {
|
|||
DynamicNdef,
|
||||
DisablePrecomputedNdef,
|
||||
Aar,
|
||||
AarCustom
|
||||
AarCustom,
|
||||
Uri,
|
||||
}
|
||||
|
||||
enum class Pins : BlockItem {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ class PersonalizeConfigValuesHolder : BaseTypedHolder<Id, Value>() {
|
|||
register(SettingsMaskNdef.DisablePrecomputedNdef, Value(default.disablePrecomputedNDEF))
|
||||
register(SettingsMaskNdef.Aar, Value(default.aar, Helper.aarList()))
|
||||
register(SettingsMaskNdef.AarCustom, Value(default.aar))
|
||||
register(SettingsMaskNdef.Uri, Value(default.uri))
|
||||
register(Pins.Pin, Value(default.PIN))
|
||||
register(Pins.Pin2, Value(default.PIN2))
|
||||
register(Pins.Pin3, Value(default.PIN3))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class ItemTypes {
|
|||
SigningMethod.SignValidatedTxRaw, SigningMethod.SignValidatedTxIssuer,
|
||||
SigningMethod.SignValidatedTxRawIssuer, SigningMethod.SignExternal, SignHashExProp.RequireTerminalCertSig,
|
||||
SignHashExProp.RequireTerminalTxSig, SignHashExProp.CheckPin3, Denomination.WriteOnPersonalize, Token.ItsToken,
|
||||
ProductMask.Note, ProductMask.Tag, ProductMask.IdCard, ProductMask.IdIssuerCard,SettingsMask.IsReusable, SettingsMask.NeedActivation,
|
||||
ProductMask.Note, ProductMask.Tag, ProductMask.IdCard, ProductMask.IdIssuerCard, SettingsMask.IsReusable, SettingsMask.NeedActivation,
|
||||
SettingsMask.ForbidPurge, SettingsMask.AllowSelectBlockchain, SettingsMask.UseBlock, SettingsMask.OneApdu,
|
||||
SettingsMask.UseCvc, SettingsMask.AllowSwapPin, SettingsMask.AllowSwapPin2, SettingsMask.ForbidDefaultPin,
|
||||
SettingsMask.SmartSecurityDelay, SettingsMask.ProtectIssuerDataAgainstReplay,
|
||||
|
|
@ -29,7 +29,7 @@ class ItemTypes {
|
|||
|
||||
val editTextList = mutableListOf(
|
||||
CardNumber.Series, CardNumber.BatchId, Common.BlockchainCustom, SignHashExProp.CryptoExKey, Token.Symbol,
|
||||
Token.ContractAddress, Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, SettingsMaskNdef.AarCustom
|
||||
Token.ContractAddress, Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, SettingsMaskNdef.AarCustom, SettingsMaskNdef.Uri
|
||||
)
|
||||
|
||||
val numberList = mutableListOf(
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ class ItemsToPersonalizeConfig : ItemsToModel<PersonalizeConfig> {
|
|||
export.disablePrecomputedNDEF = getTyped(SettingsMaskNdef.DisablePrecomputedNdef)
|
||||
export.aar = getTyped(SettingsMaskNdef.Aar)
|
||||
export.aarCustom = getTyped(SettingsMaskNdef.AarCustom)
|
||||
export.uri = getTyped(SettingsMaskNdef.Uri)
|
||||
export.PIN = getTyped(Pins.Pin)
|
||||
export.PIN2 = getTyped(Pins.Pin2)
|
||||
export.PIN3 = getTyped(Pins.Pin3)
|
||||
|
|
|
|||
|
|
@ -166,7 +166,8 @@ class PersonalizeConfigToItem : ModelToItems<PersonalizeConfig> {
|
|||
SettingsMaskNdef.DynamicNdef,
|
||||
SettingsMaskNdef.DisablePrecomputedNdef,
|
||||
SettingsMaskNdef.Aar,
|
||||
SettingsMaskNdef.AarCustom
|
||||
SettingsMaskNdef.AarCustom,
|
||||
SettingsMaskNdef.Uri
|
||||
).forEach { createItem(block, it) }
|
||||
return block
|
||||
}
|
||||
|
|
@ -248,6 +249,9 @@ class PersonalizeConfigToCardConfig : Converter<PersonalizeConfig, CardConfig> {
|
|||
|
||||
|
||||
val ndefs = mutableListOf<NdefRecord>()
|
||||
if (from.uri.isNotEmpty()) {
|
||||
ndefs.add(NdefRecord(NdefRecord.Type.URI, from.uri))
|
||||
}
|
||||
when (from.aar) {
|
||||
"None" -> null
|
||||
"--- CUSTOM ---" -> NdefRecord(NdefRecord.Type.AAR, from.aarCustom)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class PersonalizeConfig {
|
|||
var disablePrecomputedNDEF = false
|
||||
var aar = "com.tangem.wallet"
|
||||
var aarCustom = ""
|
||||
var uri = "https://tangem.com"
|
||||
|
||||
|
||||
// Pins
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
<string name="pers_item_disable_precomputed_ndef">Disable precomputed NDEF</string>
|
||||
<string name="pers_item_aar">AAR</string>
|
||||
<string name="pers_item_custom_aar_package_name">Custom AAR package name</string>
|
||||
<string name="pers_item_uri">Url</string>
|
||||
<string name="pers_item_pin">PIN</string>
|
||||
<string name="pers_item_pin2">PIN2</string>
|
||||
<string name="pers_item_pin3">PIN3</string>
|
||||
|
|
@ -155,6 +156,7 @@
|
|||
</string>
|
||||
<string name="info_pers_item_aar">Android Application Record. Android Application ID, Package name of Android apllication. Android OS will open this app or send user to Google Play page if it\'s not installed. If this field is empty, Android OS will try to open URI from URI field.</string>
|
||||
<string name="info_pers_item_custom_aar_package_name"></string>
|
||||
<string name="info_pers_item_uri"></string>
|
||||
<string name="info_pers_item_pin">PIN1 code to access the card. Default unhashed value: ‘000000’.</string>
|
||||
<string name="info_pers_item_pin2">PIN2 code to confirm transaction signatures and swap PIN operations. Default unhashed value: ‘000’.</string>
|
||||
<string name="info_pers_item_pin3">PIN3 code to confirm POS transaction with amount that exceed pin-less floor limit.</string>
|
||||
|
|
|
|||
BIN
tangem-sdk-old/src/main/res/drawable/ic_logo_rif.png
Normal file
BIN
tangem-sdk-old/src/main/res/drawable/ic_logo_rif.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Loading…
Add table
Add a link
Reference in a new issue