diff --git a/app/src/main/java/com/tangem/data/Blockchain.java b/app/src/main/java/com/tangem/data/Blockchain.java
index 3224ae7da0..b2771a6bb2 100644
--- a/app/src/main/java/com/tangem/data/Blockchain.java
+++ b/app/src/main/java/com/tangem/data/Blockchain.java
@@ -105,4 +105,25 @@ public enum Blockchain {
return getImageResource();
}
+ public String getUriScheme() {
+ String scheme = null;
+ switch (this) {
+ case Bitcoin:
+ case BitcoinDual:
+ scheme = "bitcoin";
+ break;
+ case Ethereum:
+ case Token:
+ case TokenEmv:
+ scheme = "ethereum";
+ break;
+ case Litecoin:
+ scheme = "litecoin";
+ break;
+ case Ripple:
+ scheme = "ripple";
+ }
+ return scheme;
+ }
+
}
diff --git a/app/src/main/java/com/tangem/wallet/CoinEngine.java b/app/src/main/java/com/tangem/wallet/CoinEngine.java
index 5fce47c602..edf38cad4c 100644
--- a/app/src/main/java/com/tangem/wallet/CoinEngine.java
+++ b/app/src/main/java/com/tangem/wallet/CoinEngine.java
@@ -197,10 +197,11 @@ public abstract class CoinEngine {
public abstract Uri getShareWalletUri();
public Uri getShareWalletUriEx(){
- if (ctx.getBlockchain() == Blockchain.BitcoinCash)
- return getShareWalletUri();
+ String scheme = ctx.getBlockchain().getUriScheme();
+ if (scheme != null)
+ return Uri.parse(scheme + ":" + getShareWalletUri());
else
- return Uri.parse(ctx.getBlockchain().name().toLowerCase() + ":" + getShareWalletUri().toString());
+ return getShareWalletUri();
}
public abstract boolean checkNewTransactionAmount(Amount amount);
diff --git a/app/src/main/java/com/tangem/wallet/TangemContext.java b/app/src/main/java/com/tangem/wallet/TangemContext.java
index 09674de601..9d3c4d5194 100644
--- a/app/src/main/java/com/tangem/wallet/TangemContext.java
+++ b/app/src/main/java/com/tangem/wallet/TangemContext.java
@@ -68,7 +68,7 @@ public class TangemContext {
if (blockchain == Blockchain.NftToken) {
return card.getTokenSymbol().substring(4) + "
" + getBlockchain().getOfficialName() + " non-fungible token";
}
- if (blockchain == Blockchain.StellarAsset) {
+ if (blockchain == Blockchain.StellarAsset || blockchain == Blockchain.BinanceAsset) {
return card.getTokenSymbol() + "
" + getBlockchain().getOfficialName() + " asset";
}
if (blockchain == Blockchain.StellarTag) {
diff --git a/app/src/main/java/com/tangem/wallet/binance/BinanceAssetEngine.java b/app/src/main/java/com/tangem/wallet/binance/BinanceAssetEngine.java
index f5d4b8aeb7..9e336690a3 100644
--- a/app/src/main/java/com/tangem/wallet/binance/BinanceAssetEngine.java
+++ b/app/src/main/java/com/tangem/wallet/binance/BinanceAssetEngine.java
@@ -95,7 +95,7 @@ public class BinanceAssetEngine extends CoinEngine {
if (assetBalance != null) {
return assetBalance.toDescriptionString(getDecimals()) + "
+ " + balance.toDescriptionString(getDecimals()) + " for fee";
}
- return balance.toDescriptionString(getDecimals());
+ return new Amount(BigDecimal.ZERO, ctx.getCard().tokenSymbol).toDescriptionString(getDecimals()) + "
+ " + balance.toDescriptionString(getDecimals()) + " for fee";
} else {
return "";
}
@@ -125,7 +125,7 @@ public class BinanceAssetEngine extends CoinEngine {
@Override
public boolean hasBalanceInfo() {
if (coinData == null) return false;
- return coinData.hasBalanceInfo();
+ return coinData.hasBalanceInfo() || coinData.isError404();
}
public boolean isExtractPossible() {
@@ -135,6 +135,8 @@ public class BinanceAssetEngine extends CoinEngine {
ctx.setMessage(R.string.general_wallet_empty);
} else if (awaitingConfirmation()) {
ctx.setMessage(R.string.loaded_wallet_message_wait);
+ } else if (coinData.getBalance() == null || coinData.getBalance().isZero()) {
+ ctx.setMessage(ctx.getString(R.string.confirm_transaction_error_not_enough_eth_for_fee));
} else {
return true;
}
diff --git a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt
index 48a385a3d8..1b5fa7d2c7 100644
--- a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt
+++ b/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt
@@ -154,17 +154,8 @@ class PrepareTransactionFragment : BaseFragment(), NavigationResultListener, Nfc
val schemeSplit = code!!.split(":")
when (schemeSplit.size) {
2 -> {
- if (ctx.blockchain.officialName.toLowerCase(Locale.ROOT).replace("\\s", "") == schemeSplit[0]) {
- val uri = Uri.parse(schemeSplit[1])
- etWallet?.setText(uri.path)
-// val amount = uri.getQueryParameter("amount") //TODO: enable after redesign
-// if (amount != null) {
-// etAmount?.setText(amount)
-// rgIncFee.check(R.id.rbFeeOut)
-// }
- } else if (ctx.blockchain == Blockchain.Ripple && schemeSplit[0] == "ripple") {
- val uri = Uri.parse(schemeSplit[1])
- etWallet?.setText(uri.path)
+ if (schemeSplit[0] == ctx.blockchain.uriScheme) {
+ etWallet?.setText(schemeSplit[1])
} else {
etWallet?.setText(code)
}
diff --git a/tangem-core/src/main/java/com/tangem/CardSession.kt b/tangem-core/src/main/java/com/tangem/CardSession.kt
index 7a01bae614..6021923099 100644
--- a/tangem-core/src/main/java/com/tangem/CardSession.kt
+++ b/tangem-core/src/main/java/com/tangem/CardSession.kt
@@ -77,7 +77,16 @@ class CardSession(
runnable.run(this) { result ->
when (result) {
is CompletionResult.Success -> stop()
- is CompletionResult.Failure -> stopWithError(result.error)
+ is CompletionResult.Failure -> {
+ if (result.error is TangemSdkError.ExtendedLengthNotSupported) {
+ if (session.environment.terminalKeys != null) {
+ session.environment.terminalKeys = null
+ startWithRunnable(runnable, callback)
+ return@run
+ }
+ }
+ stopWithError(result.error)
+ }
}
callback(result)
}
diff --git a/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt b/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt
index e51d5e5d97..5f8734f685 100644
--- a/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt
+++ b/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt
@@ -17,10 +17,10 @@ data class SessionEnvironment(
var pin1: ByteArray = DEFAULT_PIN.calculateSha256(),
var pin2: ByteArray = DEFAULT_PIN2.calculateSha256(),
var card: Card? = null,
- val terminalKeys: KeyPair? = null,
+ var terminalKeys: KeyPair? = null,
var encryptionMode: EncryptionMode = EncryptionMode.NONE,
var encryptionKey: ByteArray? = null,
- val cvc: ByteArray? = null,
+ var cvc: ByteArray? = null,
var cardFilter: CardFilter = CardFilter(),
val handleErrors: Boolean = true
) {
diff --git a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt b/tangem-core/src/main/java/com/tangem/TangemSdkError.kt
index bf0e5842a8..bcf51d0617 100644
--- a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt
+++ b/tangem-core/src/main/java/com/tangem/TangemSdkError.kt
@@ -16,6 +16,10 @@ sealed class TangemSdkError(val code: Int) : Exception(code.toString()) {
* (e.g. a user detaches card from the phone's NFC module) while the NFC session is in progress.
*/
class TagLost : TangemSdkError(10001)
+ /**
+ * This error is returned when NFC driver on an Android device does not support sending more than 261 bytes.
+ */
+ class ExtendedLengthNotSupported : TangemSdkError(10002)
class SerializeCommandError : TangemSdkError(20001)
diff --git a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcReader.kt b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcReader.kt
index 8640e30abc..aa5ce9972e 100644
--- a/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcReader.kt
+++ b/tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcReader.kt
@@ -75,7 +75,7 @@ class NfcReader : CardReader {
val rawResponse: ByteArray?
try {
- Log.i(this::class.simpleName!!, "Sending data to the card")
+ Log.i(this::class.simpleName!!, "Sending data to the card, size is ${data?.size}")
rawResponse = isoDep?.transceive(data)
} catch (exception: TagLostException) {
callback?.invoke(CompletionResult.Failure(TangemSdkError.TagLost()))
@@ -83,6 +83,11 @@ class NfcReader : CardReader {
return
} catch (exception: Exception) {
Log.i(this::class.simpleName!!, exception.localizedMessage ?: "Error tranceiving data")
+ // The messages of errors can vary on different Android devices,
+ // but we try to identify it by parsing the message.
+ if (exception.message?.contains("length") == true) {
+ callback?.invoke(CompletionResult.Failure(TangemSdkError.ExtendedLengthNotSupported()))
+ }
isoDep = null
return
}