Updated on 2026-08-14
This commit is contained in:
commit
8b94a08f8b
9 changed files with 54 additions and 21 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class TangemContext {
|
|||
if (blockchain == Blockchain.NftToken) {
|
||||
return card.getTokenSymbol().substring(4) + "<br><small><small> " + getBlockchain().getOfficialName() + " non-fungible token</small></small>";
|
||||
}
|
||||
if (blockchain == Blockchain.StellarAsset) {
|
||||
if (blockchain == Blockchain.StellarAsset || blockchain == Blockchain.BinanceAsset) {
|
||||
return card.getTokenSymbol() + "<br><small><small> " + getBlockchain().getOfficialName() + " asset</small></small>";
|
||||
}
|
||||
if (blockchain == Blockchain.StellarTag) {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public class BinanceAssetEngine extends CoinEngine {
|
|||
if (assetBalance != null) {
|
||||
return assetBalance.toDescriptionString(getDecimals()) + "<br><small><small>+ " + balance.toDescriptionString(getDecimals()) + " for fee</small></small>";
|
||||
}
|
||||
return balance.toDescriptionString(getDecimals());
|
||||
return new Amount(BigDecimal.ZERO, ctx.getCard().tokenSymbol).toDescriptionString(getDecimals()) + "<br><small><small>+ " + balance.toDescriptionString(getDecimals()) + " for fee</small></small>";
|
||||
} 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue