Updated on 2026-08-14

This commit is contained in:
Tangem 2018-10-31 11:17:34 +03:00
parent e122ccd0eb
commit 240b513303
15 changed files with 327 additions and 318 deletions

View file

@ -21,11 +21,11 @@ import java.io.IOException;
public class SignPaymentTask extends Thread {
public static final String TAG = SignPaymentTask.class.getSimpleName();
private String txAmount = "";
private String txFee = "";
private CoinEngine.Amount txAmount;
private CoinEngine.Amount txFee;
private Boolean txIncFee = true;
public void SetTransactionValue(String amount, String fee, Boolean incfee) {
public void SetTransactionValue(CoinEngine.Amount amount, CoinEngine.Amount fee, Boolean incfee) {
txAmount = amount;
txFee = fee;
txIncFee = incfee;
@ -39,7 +39,7 @@ public class SignPaymentTask extends Thread {
private CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public SignPaymentTask(Activity context, TangemContext ctx, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, String amount, String fee, Boolean IncFee, String outAddress) {
public SignPaymentTask(Activity context, TangemContext ctx, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, CoinEngine.Amount amount, CoinEngine.Amount fee, Boolean IncFee, String outAddress) {
mCtx=ctx;
mContext = context;
mNfcManager = nfcManager;
@ -87,7 +87,7 @@ public class SignPaymentTask extends Thread {
// SignBTC_TX(protocol);
// }
CoinEngine engine = CoinEngineFactory.create(mCtx.getCard().getBlockchain());
CoinEngine engine = CoinEngineFactory.create(mCtx);
if (engine != null) {
if (mCtx.getCard().getPauseBeforePIN2() > 0) {
mNotifications.onReadWait(mCtx.getCard().getPauseBeforePIN2());
@ -112,7 +112,7 @@ public class SignPaymentTask extends Thread {
}
Intent intent = new Intent(mContext, SendTransactionActivity.class);
mCtx.saveToBundle(intent.getExtras());
mCtx.saveToIntent(intent);
intent.putExtra(SendTransactionActivity.EXTRA_TX, txStr);
mContext.startActivityForResult(intent, SignPaymentActivity.REQUEST_CODE_SEND_PAYMENT);
}

View file

@ -11,6 +11,7 @@ import com.tangem.util.DecimalDigitsInputFilter;
import com.tangem.util.DerEncodingUtil;
import com.tangem.util.FormatUtil;
import com.tangem.util.Util;
import com.tangem.wallet.R;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
@ -55,15 +56,15 @@ public class BtcCashEngine extends CoinEngine {
}
@Override
public boolean awaitingConfirmation(){
if( coinData ==null ) return false;
public boolean awaitingConfirmation() {
if (coinData == null) return false;
return coinData.getBalanceUnconfirmed() != 0;
}
@Override
public String getBalanceHTML() {
Amount balance=getBalance();
if( balance!=null ) {
Amount balance = getBalance();
if (balance != null) {
return balance.toDescriptionString(getDecimals());
} else {
return "";
@ -71,44 +72,48 @@ public class BtcCashEngine extends CoinEngine {
}
@Override
public String getBalanceCurrencyHTML() {
public String getBalanceCurrency() {
return "BTH";
}
@Override
public String getOfflineBalanceHTML() {
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
Amount offlineAmount = convertToAmount(offlineInternalAmount);
return offlineAmount.toDescriptionString(getDecimals());
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
Amount offlineAmount = convertToAmount(offlineInternalAmount);
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
public boolean isBalanceAlterNotZero() {
return true;
}
@Override
public boolean isBalanceNotZero() {
if( coinData ==null ) return false;
if (coinData == null) return false;
if (coinData.getBalanceInInternalUnits() == null) return false;
return coinData.getBalanceInInternalUnits().notZero();
}
@Override
public boolean hasBalanceInfo(){
if( coinData ==null ) return false;
public boolean hasBalanceInfo() {
if (coinData == null) return false;
return coinData.hasBalanceInfo();
}
@Override
public boolean checkUnspentTransaction() throws Exception {
checkBlockchainDataExists();
return coinData.getUnspentTransactions().size() != 0;
public boolean isExtractPossible() {
if (!hasBalanceInfo()) {
ctx.setMessage(R.string.cannot_obtain_data_from_blockchain);
} else if (!isBalanceNotZero()) {
ctx.setMessage(R.string.wallet_empty);
} else if (awaitingConfirmation()) {
ctx.setMessage(R.string.please_wait_while_previous);
} else if (coinData.getUnspentTransactions().size() == 0) {
ctx.setMessage(R.string.please_wait_for_confirmation);
} else {
return true;
}
return false;
}
@Override
public String getFeeCurrencyHTML() {
public String getFeeCurrency() {
return "mBCH";
}
@ -176,12 +181,12 @@ public class BtcCashEngine extends CoinEngine {
@Override
public InputFilter[] getAmountInputFilters() {
return new InputFilter[] { new DecimalDigitsInputFilter(getDecimals()) };
return new InputFilter[]{new DecimalDigitsInputFilter(getDecimals())};
}
@Override
public boolean checkNewTransactionAmount(Amount amount){
if( coinData ==null ) return false;
public boolean checkNewTransactionAmount(Amount amount) {
if (coinData == null) return false;
if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) {
return false;
}
@ -208,10 +213,10 @@ public class BtcCashEngine extends CoinEngine {
if (fee.isZero() || amount.isZero())
return false;
if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits())>0)
if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits()) > 0)
return false;
if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits())>0)
if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits()) > 0)
return false;
return true;
@ -260,7 +265,7 @@ public class BtcCashEngine extends CoinEngine {
// return;
// }
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.getBalanceInInternalUnits().notZero() ) {
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.getBalanceInInternalUnits().notZero()) {
balanceValidator.setScore(80);
balanceValidator.setFirstLine("Verified offline balance");
balanceValidator.setSecondLine("Can't obtain balance from blockchain. Restore internet connection to be more confident. ");
@ -291,12 +296,18 @@ public class BtcCashEngine extends CoinEngine {
@Override
public String evaluateFeeEquivalent(String fee) {
return getAmountEquivalentDescriptor(ctx.getCard(), fee);
if (!coinData.getAmountEquivalentDescriptionAvailable()) return "";
try {
Amount feeAmount = new Amount(fee, getFeeCurrency());
return feeAmount.toEquivalentString(coinData.getRate());
} catch (Exception e) {
return "";
}
}
@Override
public String getBalanceEquivalent() {
if( coinData ==null || !coinData.getAmountEquivalentDescriptionAvailable() ) return "";
if (coinData == null || !coinData.getAmountEquivalentDescriptionAvailable()) return "";
return getBalance().toEquivalentString(coinData.getRate());
}
@ -337,8 +348,8 @@ public class BtcCashEngine extends CoinEngine {
@Override
public Amount convertToAmount(InternalAmount internalAmount) {
BigDecimal d=internalAmount.divide(new BigDecimal("100000000"));
return new Amount(d, getBalanceCurrencyHTML());
BigDecimal d = internalAmount.divide(new BigDecimal("100000000"));
return new Amount(d, getBalanceCurrency());
}
@Override
@ -348,8 +359,8 @@ public class BtcCashEngine extends CoinEngine {
@Override
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
BigDecimal d=amount.multiply(new BigDecimal("100000000"));
return new InternalAmount(d, getBalanceCurrencyHTML());
BigDecimal d = amount.multiply(new BigDecimal("100000000"));
return new InternalAmount(d, getBalanceCurrency());
}
@Override
@ -357,7 +368,7 @@ public class BtcCashEngine extends CoinEngine {
if (bytes == null) return null;
byte[] reversed = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
return new InternalAmount(Util.byteArrayToLong(reversed),"Satoshi");
return new InternalAmount(Util.byteArrayToLong(reversed), "Satoshi");
}
@Override
@ -383,28 +394,13 @@ public class BtcCashEngine extends CoinEngine {
// return mCard.getAmountDescription(Double.parseDouble(amount));
// }
public static String getAmountEquivalentDescriptionBTC(Double amount, float rate) {
if ((rate > 0) && (amount > 0)) {
return String.format("USD%.2f", amount * rate);
} else {
return "";
}
}
public String getAmountEquivalentDescriptor(TangemCard card, String value) {
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), coinData.getRate());
}
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
checkBlockchainDataExists();
String myAddress = ctx.getCard().getWallet();
byte[] pbKey = ctx.getCard().getWalletPublicKeyRar(); //ALWAYS USING COMPRESS KEY
String outputAddress = toValue;
String changeAddress = myAddress;
// Build script for our address
List<BtcData.UnspentTransaction> rawTxList = coinData.getUnspentTransactions();
@ -419,8 +415,8 @@ public class BtcCashEngine extends CoinEngine {
}
long fees = FormatUtil.ConvertStringToLong(feeValue);
long amount = FormatUtil.ConvertStringToLong(amountValue);
long fees = convertToInternalAmount(feeValue).longValueExact();
long amount = convertToInternalAmount(amountValue).longValueExact();
long change = fullAmount - amount;
if (IncFee) {
amount = amount - fees;
@ -435,7 +431,7 @@ public class BtcCashEngine extends CoinEngine {
byte[][] dataForSign = new byte[unspentOutputs.size()][];
for (int i = 0; i < unspentOutputs.size(); ++i) {
byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, changeAddress, unspentOutputs, i, amount, change);
byte[] newTX = BTCUtils.buildTXForSign(myAddress, targetAddress, myAddress, unspentOutputs, i, amount, change);
byte[] hashData = Util.calculateSHA256(newTX);
byte[] doubleHashData = Util.calculateSHA256(hashData);
@ -474,6 +470,6 @@ public class BtcCashEngine extends CoinEngine {
unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDerBitcoinCash(r, s, pbKey);
}
return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
return BTCUtils.buildTXForSend(targetAddress, myAddress, unspentOutputs, amount, change);
}
}

View file

@ -13,6 +13,7 @@ import com.tangem.util.DecimalDigitsInputFilter;
import com.tangem.util.DerEncodingUtil;
import com.tangem.util.FormatUtil;
import com.tangem.util.Util;
import com.tangem.wallet.R;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
@ -48,57 +49,6 @@ public class BtcEngine extends CoinEngine {
return 8;
}
private static String[] getBitcoinServiceHosts() {
return new String[]{
BitcoinNode.n1.getHost(),
BitcoinNode.n2.getHost(),
BitcoinNode.n3.getHost(),
BitcoinNode.n4.getHost(),
BitcoinNode.n5.getHost(),
BitcoinNode.n6.getHost(),
BitcoinNode.n7.getHost(),
BitcoinNode.n8.getHost(),
BitcoinNode.n9.getHost(),
BitcoinNode.n10.getHost(),
BitcoinNode.n11.getHost(),
BitcoinNode.n12.getHost(),
};
}
private static Integer[] getBitcoinServicePorts() {
return new Integer[]{
BitcoinNode.n1.getPort(),
BitcoinNode.n2.getPort(),
BitcoinNode.n3.getPort(),
BitcoinNode.n4.getPort(),
BitcoinNode.n5.getPort(),
BitcoinNode.n6.getPort(),
BitcoinNode.n7.getPort(),
BitcoinNode.n8.getPort(),
BitcoinNode.n9.getPort(),
BitcoinNode.n10.getPort(),
BitcoinNode.n11.getPort(),
BitcoinNode.n12.getPort(),
};
}
private static String[] getBitcoinTestNetServiceHosts() {
return new String[]{
BitcoinNodeTestNet.n1.getHost(),
BitcoinNodeTestNet.n2.getHost(),
BitcoinNodeTestNet.n3.getHost(),
BitcoinNodeTestNet.n4.getHost()};
}
private static Integer[] getBitcoinTestNetServicePorts() {
return new Integer[]{
BitcoinNodeTestNet.n1.getPort(),
BitcoinNodeTestNet.n2.getPort(),
BitcoinNodeTestNet.n3.getPort(),
BitcoinNodeTestNet.n4.getPort()};
}
static int serviceIndex = 0;
private void checkBlockchainDataExists() throws Exception {
if (coinData == null) throw new Exception("No blockchain data");
@ -121,7 +71,7 @@ public class BtcEngine extends CoinEngine {
}
@Override
public String getBalanceCurrencyHTML() {
public String getBalanceCurrency() {
return "BTC";
}
@ -132,11 +82,6 @@ public class BtcEngine extends CoinEngine {
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
public boolean isBalanceAlterNotZero() {
return true;
}
@Override
public boolean isBalanceNotZero() {
if( coinData ==null ) return false;
@ -152,13 +97,23 @@ public class BtcEngine extends CoinEngine {
@Override
public boolean checkUnspentTransaction() throws Exception {
checkBlockchainDataExists();
return coinData.getUnspentTransactions().size() != 0;
public boolean isExtractPossible() {
if (!hasBalanceInfo()) {
ctx.setMessage(R.string.cannot_obtain_data_from_blockchain);
} else if (!isBalanceNotZero()) {
ctx.setMessage(R.string.wallet_empty);
} else if (awaitingConfirmation()) {
ctx.setMessage(R.string.please_wait_while_previous);
} else if (coinData.getUnspentTransactions().size() == 0) {
ctx.setMessage(R.string.please_wait_for_confirmation);
} else {
return true;
}
return false;
}
@Override
public String getFeeCurrencyHTML() {
public String getFeeCurrency() {
return "BTC";
}
@ -348,8 +303,14 @@ public class BtcEngine extends CoinEngine {
@Override
public String evaluateFeeEquivalent(String fee) {
if( !coinData.getAmountEquivalentDescriptionAvailable() ) return "";
Amount feeAmount=new Amount(fee, getFeeCurrencyHTML());
return feeAmount.toEquivalentString(coinData.getRate());
try {
Amount feeAmount = new Amount(fee, getFeeCurrency());
return feeAmount.toEquivalentString(coinData.getRate());
}
catch (Exception e)
{
return "";
}
}
@Override
@ -395,7 +356,7 @@ public class BtcEngine extends CoinEngine {
@Override
public Amount convertToAmount(InternalAmount internalAmount) {
BigDecimal d=internalAmount.divide(new BigDecimal("100000000"));
return new Amount(d, getBalanceCurrencyHTML());
return new Amount(d, getBalanceCurrency());
}
@Override
@ -406,7 +367,7 @@ public class BtcEngine extends CoinEngine {
@Override
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
BigDecimal d=amount.multiply(new BigDecimal("100000000"));
return new InternalAmount(d, getBalanceCurrencyHTML());
return new InternalAmount(d, getBalanceCurrency());
}
@Override
@ -436,14 +397,12 @@ public class BtcEngine extends CoinEngine {
}
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
checkBlockchainDataExists();
String myAddress = ctx.getCard().getWallet();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
String outputAddress = toValue;
String changeAddress = myAddress;
// Build script for our address
List<BtcData.UnspentTransaction> rawTxList = coinData.getUnspentTransactions();
@ -458,8 +417,8 @@ public class BtcEngine extends CoinEngine {
}
long fees = FormatUtil.ConvertStringToLong(feeValue);
long amount = FormatUtil.ConvertStringToLong(amountValue);
long fees = convertToInternalAmount(feeValue).longValueExact();
long amount = convertToInternalAmount(amountValue).longValueExact();
long change = fullAmount - amount;
if (IncFee) {
amount = amount - fees;
@ -474,7 +433,7 @@ public class BtcEngine extends CoinEngine {
byte[][] dataForSign = new byte[unspentOutputs.size()][];
for (int i = 0; i < unspentOutputs.size(); ++i) {
byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, changeAddress, unspentOutputs, i, amount, change);
byte[] newTX = BTCUtils.buildTXForSign(myAddress, targetAddress, myAddress, unspentOutputs, i, amount, change);
byte[] hashData = Util.calculateSHA256(newTX);
byte[] doubleHashData = Util.calculateSHA256(hashData);
@ -512,7 +471,7 @@ public class BtcEngine extends CoinEngine {
unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDer(r, s, pbKey);
}
return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
return BTCUtils.buildTXForSend(targetAddress, myAddress, unspentOutputs, amount, change);
}
}

View file

@ -5,13 +5,13 @@ import android.text.InputFilter;
import com.tangem.domain.cardReader.CardProtocol;
import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
/**
* Created by Ilia on 15.02.2018.
@ -19,9 +19,6 @@ import java.text.DecimalFormat;
public abstract class CoinEngine {
@Nullable
public static final String EXTRA_ENGINE = "CoinEngine";
public static class InternalAmount extends BigDecimal {
private String currency;
@ -31,7 +28,7 @@ public abstract class CoinEngine {
}
public InternalAmount(String amountString, String currency) {
super(amountString);
super(amountString.replace(',','.'));
this.currency=currency;
}
@ -68,7 +65,7 @@ public abstract class CoinEngine {
}
public Amount(String amountString, String currency) {
super(amountString);
super(amountString.replace(',','.'));
this.currency = currency;
}
@ -97,9 +94,19 @@ public abstract class CoinEngine {
}
public String toDescriptionString(int decimals) {
String pattern = "#0.#######################################"; // If you like 4 zeros
DecimalFormat myFormatter = new DecimalFormat(pattern.substring(0,3+decimals));
return myFormatter.format(this) + " " + currency;
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
symbols.setDecimalSeparator('.');
DecimalFormat df = new DecimalFormat();
df.setDecimalFormatSymbols(symbols);
df.setMaximumFractionDigits(decimals);
df.setMinimumFractionDigits(0);
df.setGroupingUsed(false);
BigDecimal bd=new BigDecimal(unscaledValue(), scale());
bd.setScale(decimals, ROUND_DOWN);
return df.format(bd)+ " " + currency;
}
public String toEditString() {
@ -138,18 +145,15 @@ public abstract class CoinEngine {
public abstract boolean isBalanceNotZero();
public abstract boolean isBalanceAlterNotZero();
public abstract byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception;
public abstract byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception;
public abstract boolean checkUnspentTransaction() throws Exception;
// TODO - change isExtractPossible to isExtractPossible and if not - return string message
public abstract boolean isExtractPossible();
public abstract Uri getShareWalletUriExplorer();
public abstract Uri getShareWalletUri();
// public abstract Long getBalanceLong(TangemCard card);
public abstract boolean checkNewTransactionAmount(Amount amount);
// TODO - move minFeeInInternalUnits to CoinData
@ -161,7 +165,7 @@ public abstract class CoinEngine {
public abstract String getBalanceHTML();
public abstract String getBalanceCurrencyHTML();
public abstract String getBalanceCurrency();
public abstract InputFilter[] getAmountInputFilters();
@ -169,18 +173,12 @@ public abstract class CoinEngine {
public abstract String evaluateFeeEquivalent(String fee);
public abstract String getFeeCurrencyHTML();
public abstract String getFeeCurrency();
public abstract boolean isNeedCheckNode();
public abstract String getBalanceEquivalent();
// public abstract String getBalanceValue(TangemCard card);
// public abstract String getAmountDescription(TangemCard card, String amount) throws Exception;
// public abstract String getAmountEquivalentDescriptor(TangemCard card, String value);
public abstract boolean validateAddress(String address);
public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException;
@ -193,9 +191,6 @@ public abstract class CoinEngine {
public abstract byte[] convertToByteArray(InternalAmount internalAmount) throws Exception;
// public abstract CoinEngine swithToBaseEngine();
public abstract CoinData createCoinData();
public abstract String getUnspentInputsDescription();

View file

@ -9,6 +9,7 @@ import com.tangem.domain.cardReader.TLV;
import com.tangem.util.BTCUtils;
import com.tangem.util.CryptoUtil;
import com.tangem.util.DecimalDigitsInputFilter;
import com.tangem.wallet.R;
import org.bitcoinj.core.ECKey;
@ -32,7 +33,7 @@ public class EthEngine extends CoinEngine {
if (ctx.getCoinData() == null) {
coinData = new EthData();
ctx.setCoinData(coinData);
} else if (ctx.getCoinData() instanceof BtcData) {
} else if (ctx.getCoinData() instanceof EthData) {
coinData = (EthData) ctx.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for EthEngine");
@ -71,7 +72,7 @@ public class EthEngine extends CoinEngine {
}
@Override
public String getBalanceCurrencyHTML() {
public String getBalanceCurrency() {
return "ETH";
}
@ -82,14 +83,6 @@ public class EthEngine extends CoinEngine {
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
public boolean isBalanceAlterNotZero() {
return true; //TODO ???
// if( coinData==null ) return false;
// if (coinData.getBalanceAlterInInternalUnits() == null) return false;
// return coinData.getBalanceAlterInInternalUnits().notZero();
}
@Override
public boolean isBalanceNotZero() {
if( coinData ==null ) return false;
@ -98,7 +91,7 @@ public class EthEngine extends CoinEngine {
}
@Override
public String getFeeCurrencyHTML() {
public String getFeeCurrency() {
return "ETH";
}
@ -236,8 +229,17 @@ public class EthEngine extends CoinEngine {
}
@Override
public boolean checkUnspentTransaction() {
return true;
public boolean isExtractPossible() {
if (!hasBalanceInfo()) {
ctx.setMessage(R.string.cannot_obtain_data_from_blockchain);
} else if (!isBalanceNotZero()) {
ctx.setMessage(R.string.wallet_empty);
} else if (awaitingConfirmation()) {
ctx.setMessage(R.string.please_wait_while_previous);
} else {
return true;
}
return false;
}
@Override
@ -331,8 +333,15 @@ public class EthEngine extends CoinEngine {
@Override
public String evaluateFeeEquivalent(String fee) {
Amount feeValue = new Amount(fee, ctx.getBlockchain().getCurrency());
return feeValue.toEquivalentString(coinData.getRate());
try {
Amount feeValue = new Amount(fee, ctx.getBlockchain().getCurrency());
return feeValue.toEquivalentString(coinData.getRate());
}
catch (Exception e)
{
e.printStackTrace();
return "";
}
}
@Override
@ -357,7 +366,7 @@ public class EthEngine extends CoinEngine {
}
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
BigInteger nonceValue = coinData.getConfirmedTXCount();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
@ -365,33 +374,27 @@ public class EthEngine extends CoinEngine {
Issuer issuer = ctx.getCard().getIssuer();
BigInteger fee = new BigInteger(feeValue, 10);
BigInteger gigaK = BigInteger.valueOf(1000000000L);
BigDecimal amountDec = new BigDecimal(amountValue);
amountDec = amountDec.multiply(new BigDecimal("1000000000"));
BigInteger weiFee=convertToInternalAmount(feeValue).toBigIntegerExact();
BigInteger weiAmount=convertToInternalAmount(amountValue).toBigIntegerExact();
BigInteger amount = amountDec.toBigInteger(); //new BigInteger(amountValue, 10);
if (IncFee) {
amount = amount.subtract(fee);
weiAmount = weiAmount.subtract(weiFee);
}
BigInteger nonce = nonceValue;
BigInteger gasPrice = fee.divide(BigInteger.valueOf(21000));
BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(21000)).multiply(gigaK);
BigInteger gasLimit = BigInteger.valueOf(21000);
Integer chainId = ctx.getBlockchain() == Blockchain.Ethereum ? EthTransaction.ChainEnum.Mainnet.getValue() : EthTransaction.ChainEnum.Rinkeby.getValue();
Long multiplicator = 1000000000L;
amount = amount.multiply(BigInteger.valueOf(multiplicator));
gasPrice = gasPrice.multiply(BigInteger.valueOf(multiplicator));
String to = toValue;
String to = targetAddress;
if (to.startsWith("0x") || to.startsWith("0X")) {
to = to.substring(2);
}
EthTransaction tx = EthTransaction.create(to, amount, nonce, gasPrice, gasLimit, chainId);
EthTransaction tx = EthTransaction.create(to, weiAmount, nonce, gasPrice, gasLimit, chainId);
byte[][] hashesForSign = new byte[1][];
byte[] for_hash = tx.getRawHash();

View file

@ -1,6 +1,7 @@
package com.tangem.domain.wallet;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -67,6 +68,10 @@ public class TangemContext {
this.message = value;
}
public void setMessage(int valueId) {
this.message = getString(valueId);
}
public String getMessage() {
return message;
}
@ -94,19 +99,19 @@ public class TangemContext {
return tangemContext;
}
public void saveToBundle(Bundle bundle) {
public void saveToIntent(Intent intent) {
if (card != null) {
bundle.putString(TangemCard.EXTRA_UID, card.getUID());
bundle.putBundle(TangemCard.EXTRA_CARD, card.getAsBundle());
intent.putExtra(TangemCard.EXTRA_UID, card.getUID());
intent.putExtra(TangemCard.EXTRA_CARD, card.getAsBundle());
}
if (coinData != null) {
bundle.putBundle(EXTRA_BLOCKCHAIN_DATA, coinData.asBundle());
intent.putExtra(EXTRA_BLOCKCHAIN_DATA, coinData.asBundle());
}
bundle.putString("Error", error);
bundle.putString("Message", message);
intent.putExtra("Error", error);
intent.putExtra("Message", message);
}

View file

@ -34,7 +34,7 @@ public class TokenEngine extends CoinEngine {
if (ctx.getCoinData() == null) {
coinData = new TokenData();
ctx.setCoinData(coinData);
} else if (ctx.getCoinData() instanceof BtcData) {
} else if (ctx.getCoinData() instanceof TokenData) {
coinData = (TokenData) ctx.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for TokenEngine");
@ -83,7 +83,7 @@ public class TokenEngine extends CoinEngine {
}
@Override
public String getBalanceCurrencyHTML() {
public String getBalanceCurrency() {
String currency = ctx.getCard().getTokenSymbol();
if (Strings.isNullOrEmpty(currency))
return "NoN";
@ -109,7 +109,7 @@ public class TokenEngine extends CoinEngine {
}
@Override
public String getFeeCurrencyHTML() {
public String getFeeCurrency() {
return "ETH";
}
@ -151,7 +151,6 @@ public class TokenEngine extends CoinEngine {
return true;
}
@Override
public boolean isBalanceAlterNotZero() {
if (coinData == null) return false;
if (coinData.getBalanceAlterInInternalUnits() == null) return false;
@ -284,8 +283,19 @@ public class TokenEngine extends CoinEngine {
}
@Override
public boolean checkUnspentTransaction() {
return true;
public boolean isExtractPossible() {
if (!hasBalanceInfo()) {
ctx.setMessage(R.string.cannot_obtain_data_from_blockchain);
} else if (!isBalanceNotZero()) {
ctx.setMessage(R.string.wallet_empty);
} else if (awaitingConfirmation()) {
ctx.setMessage(R.string.please_wait_while_previous);
} else if (!isBalanceAlterNotZero()) {
ctx.setMessage(ctx.getString(R.string.not_enough_eth_for_gas));
} else {
return true;
}
return false;
}
@Override
@ -300,9 +310,7 @@ public class TokenEngine extends CoinEngine {
} else {
return false;
}
}
catch (Exception e)
{
} catch (Exception e) {
e.printStackTrace();
return false;
}
@ -395,8 +403,13 @@ public class TokenEngine extends CoinEngine {
@Override
public String evaluateFeeEquivalent(String fee) {
Amount feeValue = new Amount(fee, getFeeCurrencyHTML());
return feeValue.toEquivalentString(coinData.getRate());
try {
Amount feeValue = new Amount(fee, getFeeCurrency());
return feeValue.toEquivalentString(coinData.getRate());
} catch (Exception e) {
e.printStackTrace();
return "";
}
//
// BigDecimal gweFee = new BigDecimal(fee);
@ -406,41 +419,104 @@ public class TokenEngine extends CoinEngine {
}
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
if (amountValue.getCurrency().equals("ETH")) {
return signETH(feeValue, amountValue, IncFee, targetAddress, protocol);
} else {
return signToken(feeValue, amountValue, IncFee, targetAddress, protocol);
}
}
public byte[] signETH(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
BigInteger nonceValue = coinData.getConfirmedTXCount();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
boolean flag = (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = ctx.getCard().getIssuer();
BigInteger fee = new BigInteger(feeValue, 10);
BigInteger gigaK = BigInteger.valueOf(1000000000L);
BigDecimal amountDecValue = new BigDecimal(amountValue);
BigInteger weiFee = convertToInternalAmount(feeValue).toBigIntegerExact();
BigInteger weiAmount = convertToInternalAmount(amountValue).toBigIntegerExact();
int d = getTokenDecimals();
BigDecimal amountDec = new BigDecimal("10");
amountDec = amountDec.pow(d);
amountDec = amountDecValue.multiply(amountDec);
if (IncFee) {
weiAmount = weiAmount.subtract(weiFee);
}
//amountDec = amountDec.multiply(new BigDecimal("1000000000"));
BigInteger nonce = nonceValue;
BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(21000)).multiply(gigaK);
BigInteger gasLimit = BigInteger.valueOf(21000);
Integer chainId = ctx.getBlockchain() == Blockchain.Ethereum ? EthTransaction.ChainEnum.Mainnet.getValue() : EthTransaction.ChainEnum.Rinkeby.getValue();
String to = targetAddress;
if (to.startsWith("0x") || to.startsWith("0X")) {
to = to.substring(2);
}
EthTransaction tx = EthTransaction.create(to, weiAmount, nonce, gasPrice, gasLimit, chainId);
byte[][] hashesForSign = new byte[1][];
byte[] for_hash = tx.getRawHash();
hashesForSign[0] = for_hash;
byte[] signFromCard = null;
try {
signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), hashesForSign, flag, null, issuer).getTLV(TLV.Tag.TAG_Signature).Value;
// TODO slice signFromCard to hashes.length parts
} catch (Exception ex) {
Log.e("ETH", ex.getMessage());
return null;
}
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0, 32));
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32, 64));
s = CryptoUtil.toCanonicalised(s);
boolean f = ECKey.verify(for_hash, new ECKey.ECDSASignature(r, s), pbKey);
if (!f) {
Log.e("ETH-CHECK", "sign Failed.");
}
tx.signature = new ECDSASignatureETH(r, s);
int v = tx.BruteRecoveryID2(tx.signature, for_hash, pbKey);
if (v != 27 && v != 28) {
Log.e("ETH", "invalid v");
return null;
}
tx.signature.v = (byte) v;
Log.e("ETH_v", String.valueOf(v));
byte[] realTX = tx.getEncoded();
return realTX;
}
public byte[] signToken(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception {
BigInteger nonceValue = coinData.getConfirmedTXCount();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
boolean flag = (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = ctx.getCard().getIssuer();
BigInteger gigaK = BigInteger.valueOf(1000000000L);
BigInteger weiFee = convertToInternalAmount(feeValue).toBigIntegerExact();
InternalAmount amountDec=convertToInternalAmount(amountValue);
BigInteger amount = amountDec.toBigInteger(); //new BigInteger(amountValue, 10);
//amount = amount.subtract(fee);
BigInteger nonce = nonceValue;
BigInteger gasPrice = fee.divide(BigInteger.valueOf(60000));
BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(60000)).multiply(gigaK);
BigInteger gasLimit = BigInteger.valueOf(60000);
Integer chainId = EthTransaction.ChainEnum.Mainnet.getValue();
BigInteger amountZero = BigInteger.ZERO;
Long multiplicator = 1000000000L;
gasPrice = gasPrice.multiply(BigInteger.valueOf(multiplicator));
String to = toValue;
String to = targetAddress;
if (to.startsWith("0x") || to.startsWith("0X")) {
to = to.substring(2);

View file

@ -72,7 +72,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
val html = Html.fromHtml(engine!!.balanceHTML)
tvBalance.text = html
isIncludeFee = intent.getBooleanExtra("IncFee", true)
isIncludeFee = intent.getBooleanExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, true)
if (isIncludeFee)
tvIncFee.setText(R.string.including_fee)
@ -83,10 +83,10 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
else
tvIncFee.visibility = View.VISIBLE
etAmount.setText(intent.getStringExtra(SignPaymentActivity.EXTRA_AMOUNT))
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
tvCurrency2.text = Html.fromHtml(engine.feeCurrencyHTML)
tvCurrency.text = engine.balanceCurrency
tvCurrency2.text = engine.feeCurrency
tvCardID.text = ctx.card!!.cidDescription
etWallet.setText(intent.getStringExtra("Wallet"))
etWallet.setText(intent.getStringExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS))
etFee.setText("")
btnSend.visibility = View.INVISIBLE
@ -126,7 +126,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
try {
val engine = CoinEngineFactory.create(ctx.blockchain)
val engine = CoinEngineFactory.create(ctx)
val eqFee = engine!!.evaluateFeeEquivalent(etFee!!.text.toString())
tvFeeEquivalent.text = eqFee
@ -174,7 +174,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
finishWithError(Activity.RESULT_CANCELED, getString(R.string.the_wallet_is_empty))
return@setOnClickListener
} else if (!engineCoin.checkUnspentTransaction()) {
} else if (!engineCoin.isExtractPossible()) {
finishWithError(Activity.RESULT_CANCELED, getString(R.string.please_wait_for_confirmation_of_incoming_transaction))
return@setOnClickListener
}
@ -187,10 +187,10 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
requestPIN2Count = 0
val intent = Intent(baseContext, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
intent.putExtra("IncFee", isIncludeFee)
intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
}
@ -354,10 +354,8 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
requestPIN2Count++
val intent = Intent(baseContext, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra("Card", card!!.asBundle)
intent.putExtra("IncFee", isIncludeFee)
ctx.saveToIntent(intent)
intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
return
}
@ -366,13 +364,13 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
} else if (requestCode == REQUEST_CODE_REQUEST_PIN2) {
if (resultCode == Activity.RESULT_OK) {
val intent = Intent(baseContext, SignPaymentActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra("Card", card!!.asBundle)
intent.putExtra("Wallet", etWallet!!.text.toString())
ctx.saveToIntent(intent)
intent.putExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, etAmount.text.toString())
intent.putExtra("Fee", etFee.text.toString())
intent.putExtra("IncFee", isIncludeFee)
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_FEE, etFee.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_FEE_CURRENCY, tvCurrency2.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee)
startActivityForResult(intent, REQUEST_CODE_SIGN_PAYMENT)
} else
Toast.makeText(baseContext, R.string.pin_2_is_required_to_sign_the_payment, Toast.LENGTH_LONG).show()

View file

@ -9,15 +9,12 @@ import android.nfc.Tag
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.Html
import android.text.InputFilter
import android.view.View
import com.tangem.data.network.Cryptonit_OtherAPI
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.Blockchain
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemCard
import com.tangem.domain.wallet.TangemContext
import com.tangem.util.DecimalDigitsInputFilter
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.*
import java.io.IOException
@ -58,7 +55,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
tvWallet.text = ctx.card!!.wallet
val engine = CoinEngineFactory.create(ctx)
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
tvCurrency.text = engine.balanceCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters

View file

@ -17,7 +17,6 @@ import com.tangem.data.network.Cryptonit
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.Blockchain
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemCard
import com.tangem.domain.wallet.TangemContext
import com.tangem.util.DecimalDigitsInputFilter
import com.tangem.wallet.R
@ -57,8 +56,8 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
tvWallet.text = ctx.card!!.wallet
val engine = CoinEngineFactory.create(ctx)
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
tvFeeCurrency.text = tvCurrency.text
tvCurrency.text = engine.balanceCurrency
tvFeeCurrency.text = engine.feeCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters

View file

@ -12,7 +12,6 @@ import android.nfc.Tag
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.Html
import android.text.InputFilter
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
@ -21,9 +20,7 @@ import com.tangem.data.network.Kraken
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.Blockchain
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemCard
import com.tangem.domain.wallet.TangemContext
import com.tangem.util.DecimalDigitsInputFilter
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_kraken_withdrawal.*
import java.io.IOException
@ -64,7 +61,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
tvWallet.text = ctx.card!!.wallet
val engine = CoinEngineFactory.create(ctx)
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
tvCurrency.text = engine.balanceCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters

View file

@ -78,7 +78,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
}
btnVerify.setOnClickListener {
val engine1 = CoinEngineFactory.create(ctx.card!!.blockchain)
val engine1 = CoinEngineFactory.create(ctx)
val strAmount: String = etAmount.text.toString().replace(",", ".")
val amount=engine1.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
@ -113,10 +113,11 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
// }
val intent = Intent(baseContext, ConfirmPaymentActivity::class.java)
ctx.saveToBundle(intent.extras)
intent.putExtra("Wallet", etWallet!!.text.toString())
intent.putExtra("IncFee", (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn))
ctx.saveToIntent(intent)
intent.putExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn))
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, strAmount)
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString())
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT)
}
ivCamera.setOnClickListener {

View file

@ -16,6 +16,7 @@ import android.widget.Toast
import com.tangem.data.nfc.SignPaymentTask
import com.tangem.domain.cardReader.CardProtocol
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.CoinEngine
import com.tangem.domain.wallet.TangemCard
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
@ -32,6 +33,11 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
val TAG: String = SignPaymentActivity::class.java.simpleName
const val EXTRA_AMOUNT = "Amount"
const val EXTRA_AMOUNT_CURRENCY = "AmountCurrency"
const val EXTRA_FEE = "Fee"
const val EXTRA_FEE_CURRENCY = "FeeCurrency"
const val EXTRA_FEE_INCLUDED = "FeeIncluded"
const val EXTRA_TARGET_ADDRESS = "TargetAddress"
const val REQUEST_CODE_SEND_PAYMENT = 1
const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
}
@ -41,8 +47,8 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
private var signPaymentTask: SignPaymentTask? = null
private var amountStr: String? = null
private var feeStr: String? = null
private var amount: CoinEngine.Amount? = null
private var fee: CoinEngine.Amount? = null
private var isIncludeFee = true
private var outAddressStr: String? = null
private var lastReadSuccess = true
@ -59,10 +65,10 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
ctx=TangemContext.loadFromBundle(this, intent.extras)
amountStr = intent.getStringExtra(EXTRA_AMOUNT)
feeStr = intent.getStringExtra("Fee")
isIncludeFee = intent.getBooleanExtra("IncFee", true)
outAddressStr = intent.getStringExtra("Wallet")
amount = CoinEngine.Amount(intent.getStringExtra(EXTRA_AMOUNT), intent.getStringExtra(EXTRA_AMOUNT_CURRENCY))
fee = CoinEngine.Amount(intent.getStringExtra(EXTRA_FEE), intent.getStringExtra(EXTRA_FEE_CURRENCY))
isIncludeFee = intent.getBooleanExtra(EXTRA_FEE_INCLUDED, true)
outAddressStr = intent.getStringExtra(EXTRA_TARGET_ADDRESS)
tvCardID.text = ctx.card!!.cidDescription
@ -127,7 +133,7 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
} else {
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
}
signPaymentTask = SignPaymentTask(this, ctx, nfcManager, isoDep, this, amountStr, feeStr, isIncludeFee, outAddressStr)
signPaymentTask = SignPaymentTask(this, ctx, nfcManager, isoDep, this, amount, fee, isIncludeFee, outAddressStr)
signPaymentTask!!.start()
} else {
// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card!!.uid + ")")

View file

@ -159,16 +159,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
// }
getString(R.string.via_cryptonit) -> {
val intent = Intent(activity, PrepareCryptonitWithdrawalActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra("Card", card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT)
}
getString(R.string.via_kraken) -> {
val intent = Intent(activity, PrepareKrakenWithdrawalActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra("Card", card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT)
}
else -> {
@ -203,24 +199,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
btnExtract.setOnClickListener {
val engine=CoinEngineFactory.create(ctx)
if (UtilHelper.isOnline(activity)) {
// TODO - move checks to engine
if (!engine!!.hasBalanceInfo()) {
showSingleToast(R.string.cannot_obtain_data_from_blockchain)
} else if (!engine!!.isBalanceNotZero)
showSingleToast(R.string.wallet_empty)
else if (!engine!!.isBalanceAlterNotZero)
showSingleToast(R.string.not_enough_eth_for_gas)
else if (engine!!.awaitingConfirmation())
showSingleToast(R.string.please_wait_while_previous)
else if (!engine!!.checkUnspentTransaction())
showSingleToast(R.string.please_wait_for_confirmation)
if (!engine!!.isExtractPossible)
showSingleToast(ctx.message)
else if (ctx.card!!.remainingSignatures == 0)
showSingleToast(R.string.card_has_no_remaining_signature)
else {
val intent = Intent(activity, PreparePaymentActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra("Card", card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT)
}
} else
@ -523,9 +508,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
if (data.extras != null && data.extras!!.containsKey("confirmPIN")) {
val intent = Intent(activity, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
newPIN = data.getStringExtra("newPIN")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
@ -541,9 +524,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
if (data.extras != null && data.extras!!.containsKey("confirmPIN2")) {
val intent = Intent(activity, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
newPIN2 = data.getStringExtra("newPIN2")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
@ -575,9 +556,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
ctx.saveToBundle(data.extras)
// data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(data)
data.putExtra("modification", "delete")
} else
data.putExtra("modification", "update")
@ -596,9 +575,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
requestPIN2Count++
val intent = Intent(activity, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
// intent.putExtra("UID", card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
return
} else {
@ -609,17 +586,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) {
val intent = Intent(activity, PurgeActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_PURGE)
}
REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
ctx.saveToBundle(data.extras)
// data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(data)
data.putExtra("modification", "delete")
} else {
data.putExtra("modification", "update")
@ -638,9 +611,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
requestPIN2Count++
val intent = Intent(activity, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
return
} else {
@ -918,7 +889,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private fun openVerifyCard(cardProtocol: CardProtocol) {
val intent = Intent(activity, VerifyCardActivity::class.java)
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD)
}
@ -986,9 +957,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private fun startSwapPINActivity() {
val intent = Intent(activity, PinSwapActivity::class.java)
ctx.saveToBundle(intent.extras)
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
ctx.saveToIntent(intent)
intent.putExtra("newPIN", newPIN)
intent.putExtra("newPIN2", newPIN2)
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN)
@ -1006,4 +975,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
}
private fun showSingleToast(text: String) {
if (singleToast == null || !singleToast!!.view.isShown || showTime.time + 2000 < Date().time) {
if (singleToast != null)
singleToast!!.cancel()
singleToast = Toast.makeText(activity, text, Toast.LENGTH_LONG)
singleToast!!.show()
showTime = Date()
}
}
}

View file

@ -101,7 +101,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
if (data.extras!!.containsKey("confirmPIN")) {
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
newPIN = data.getStringExtra("newPIN")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
@ -117,7 +117,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
if (data.extras!!.containsKey("confirmPIN2")) {
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
newPIN2 = data.getStringExtra("newPIN2")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
@ -147,7 +147,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
ctx.saveToBundle(data.extras)
ctx.saveToIntent(data)
data.putExtra("modification", "delete")
} else
data.putExtra("modification", "update")
@ -163,7 +163,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
requestPIN2Count++
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
return
} else {
@ -174,14 +174,13 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
}
REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) {
val intent = Intent(context, PurgeActivity::class.java)
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_PURGE)
}
REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
ctx.saveToBundle(data.extras)
ctx.saveToIntent(data)
data.putExtra("modification", "delete")
} else {
data.putExtra("modification", "update")
@ -198,7 +197,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
requestPIN2Count++
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
return
} else {
@ -430,7 +429,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
newPIN = PINStorage.getDefaultPIN()
newPIN2 = ""
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
@ -440,7 +439,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
newPIN = ""
newPIN2 = PINStorage.getDefaultPIN2()
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
@ -450,7 +449,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
newPIN = PINStorage.getDefaultPIN()
newPIN2 = PINStorage.getDefaultPIN2()
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
@ -477,13 +476,13 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
}
private fun startSwapPINActivity() {
val intent = Intent(context, PinSwapActivity::class.java)
ctx.saveToBundle(intent.extras)
ctx.saveToIntent(intent)
intent.putExtra("newPIN", newPIN)
intent.putExtra("newPIN2", newPIN2)
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN)
@ -491,7 +490,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
fun prepareResultIntent(): Intent {
val data = Intent()
ctx.saveToBundle(data.extras)
ctx.saveToIntent(data)
return data
}