Updated on 2026-08-14
This commit is contained in:
parent
60a09ca78c
commit
9652cf62cc
8 changed files with 93 additions and 49 deletions
|
|
@ -4,27 +4,28 @@ import android.net.Uri;
|
|||
import android.text.InputFilter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.data.network.ServerApiCommon;
|
||||
import com.tangem.App;
|
||||
import com.tangem.card_common.data.TangemCard;
|
||||
import com.tangem.card_common.reader.CardProtocol;
|
||||
import com.tangem.card_common.tasks.SignTask;
|
||||
import com.tangem.card_common.util.Util;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.data.local.PendingTransactionsStorage;
|
||||
import com.tangem.data.network.ElectrumRequest;
|
||||
import com.tangem.data.network.ServerApiCommon;
|
||||
import com.tangem.data.network.ServerApiElectrum;
|
||||
import com.tangem.domain.wallet.BTCUtils;
|
||||
import com.tangem.domain.wallet.BalanceValidator;
|
||||
import com.tangem.domain.wallet.Base58;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.domain.wallet.CoinData;
|
||||
import com.tangem.domain.wallet.CoinEngine;
|
||||
import com.tangem.card_common.data.TangemCard;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
import com.tangem.domain.wallet.Transaction;
|
||||
import com.tangem.domain.wallet.UnspentOutputInfo;
|
||||
import com.tangem.domain.wallet.BTCUtils;
|
||||
import com.tangem.card_common.tasks.SignTask;
|
||||
import com.tangem.util.CryptoUtil;
|
||||
import com.tangem.util.DecimalDigitsInputFilter;
|
||||
import com.tangem.util.DerEncodingUtil;
|
||||
import com.tangem.card_common.util.Util;
|
||||
import com.tangem.wallet.R;
|
||||
import com.tangem.data.network.ElectrumRequest;
|
||||
import com.tangem.data.network.ServerApiElectrum;
|
||||
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
|
@ -311,9 +312,7 @@ public class BtcEngine extends CoinEngine {
|
|||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -477,7 +476,8 @@ public class BtcEngine extends CoinEngine {
|
|||
@Override
|
||||
public byte[][] getHashesToSign() throws Exception {
|
||||
byte[][] dataForSign = new byte[unspentOutputs.size()][];
|
||||
if (txForSign.length > 10) throw new Exception("To much hashes in one transaction!");
|
||||
if (txForSign.length > 10)
|
||||
throw new Exception("To much hashes in one transaction!");
|
||||
for (int i = 0; i < unspentOutputs.size(); ++i) {
|
||||
dataForSign[i] = bodyDoubleHash[i];
|
||||
}
|
||||
|
|
@ -530,7 +530,7 @@ public class BtcEngine extends CoinEngine {
|
|||
ServerApiElectrum.ResponseListener electrumListener = new ServerApiElectrum.ResponseListener() {
|
||||
@Override
|
||||
public void onSuccess(ElectrumRequest electrumRequest) {
|
||||
Log.i(TAG, "onSuccess: "+electrumRequest.getMethod());
|
||||
Log.i(TAG, "onSuccess: " + electrumRequest.getMethod());
|
||||
if (electrumRequest.isMethod(ElectrumRequest.METHOD_GetBalance)) {
|
||||
try {
|
||||
String walletAddress = electrumRequest.getParams().getString(0);
|
||||
|
|
@ -544,6 +544,7 @@ public class BtcEngine extends CoinEngine {
|
|||
coinData.setBalanceConfirmed(confBalance);
|
||||
coinData.setBalanceUnconfirmed(unconfirmedBalance);
|
||||
coinData.setValidationNodeDescription(serverApiElectrum.getValidationNodeDescription());
|
||||
checkPending(blockchainRequestsCallbacks);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "FAIL METHOD_GetBalance JSONException");
|
||||
|
|
@ -600,19 +601,19 @@ public class BtcEngine extends CoinEngine {
|
|||
|
||||
if (serverApiElectrum.isRequestsSequenceCompleted()) {
|
||||
blockchainRequestsCallbacks.onComplete(!ctx.hasError());
|
||||
}else{
|
||||
} else {
|
||||
blockchainRequestsCallbacks.onProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(ElectrumRequest electrumRequest) {
|
||||
Log.i(TAG, "onFail: "+electrumRequest.getMethod()+" "+electrumRequest.getError());
|
||||
Log.i(TAG, "onFail: " + electrumRequest.getMethod() + " " + electrumRequest.getError());
|
||||
ctx.setError(electrumRequest.getError());
|
||||
// ctx.setError(R.string.cannot_obtain_data_from_blockchain);
|
||||
if (serverApiElectrum.isRequestsSequenceCompleted()) {
|
||||
blockchainRequestsCallbacks.onComplete(false);//serverApiElectrum.isErrorOccurred(), serverApiElectrum.getError());
|
||||
}else{
|
||||
} else {
|
||||
blockchainRequestsCallbacks.onProgress();
|
||||
}
|
||||
}
|
||||
|
|
@ -624,6 +625,50 @@ public class BtcEngine extends CoinEngine {
|
|||
serverApiElectrum.requestData(ctx, ElectrumRequest.listUnspent(coinData.getWallet()));
|
||||
}
|
||||
|
||||
private void checkPending(BlockchainRequestsCallbacks blockchainRequestsCallbacks) {
|
||||
if (App.pendingTransactionsStorage.hasTransactions(ctx.getCard())) {
|
||||
ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
|
||||
|
||||
ServerApiElectrum.ResponseListener electrumListener = new ServerApiElectrum.ResponseListener() {
|
||||
@Override
|
||||
public void onSuccess(ElectrumRequest electrumRequest) {
|
||||
Log.i(TAG, "onSuccess: " + electrumRequest.getMethod());
|
||||
try {
|
||||
if (electrumRequest.getResultString() != null) {
|
||||
App.pendingTransactionsStorage.removeTransaction(ctx.getCard(), electrumRequest.txHash);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onFail: " + electrumRequest.getMethod() + " " + electrumRequest.getError());
|
||||
}
|
||||
if (serverApiElectrum.isRequestsSequenceCompleted()) {
|
||||
blockchainRequestsCallbacks.onComplete(!ctx.hasError());
|
||||
} else {
|
||||
blockchainRequestsCallbacks.onProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(ElectrumRequest electrumRequest) {
|
||||
Log.i(TAG, "onFail: " + electrumRequest.getMethod() + " " + electrumRequest.getError());
|
||||
// ctx.setError(R.string.cannot_obtain_data_from_blockchain);
|
||||
if (serverApiElectrum.isRequestsSequenceCompleted()) {
|
||||
blockchainRequestsCallbacks.onComplete(false);//serverApiElectrum.isErrorOccurred(), serverApiElectrum.getError());
|
||||
} else {
|
||||
blockchainRequestsCallbacks.onProgress();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
serverApiElectrum.setResponseListener(electrumListener);
|
||||
for (PendingTransactionsStorage.TransactionInfo pendingTx : App.pendingTransactionsStorage.getTransactions(ctx.getCard()).getTransactions()) {
|
||||
String txHash = BTCUtils.toHex(CryptoUtil.doubleSha256(BTCUtils.fromHex(pendingTx.getTx())));
|
||||
serverApiElectrum.requestData(ctx, ElectrumRequest.getTransaction(ctx.getCoinData().getWallet(), txHash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Integer calculateEstimatedTransactionSize(String outputAddress, String outAmount) {
|
||||
//todo - правильней было бы использовать constructTransaction
|
||||
try {
|
||||
|
|
@ -686,15 +731,16 @@ public class BtcEngine extends CoinEngine {
|
|||
//
|
||||
// byte[] realTX = BTCUtils.buildTXForSend(outputAddress, myAddress, unspentOutputs, amount, change);
|
||||
|
||||
SignTask.TransactionToSign ps= constructTransaction(new Amount(outAmount, getBalanceCurrency()),new Amount("0.00",getFeeCurrency()), true, outputAddress );
|
||||
SignTask.TransactionToSign ps = constructTransaction(new Amount(outAmount, getBalanceCurrency()), new Amount("0.00", getFeeCurrency()), true, outputAddress);
|
||||
OnNeedSendTransaction onNeedSendTransactionBackup = onNeedSendTransaction;
|
||||
onNeedSendTransaction =(tx)->{}; // empty function to bypass exception
|
||||
onNeedSendTransaction = (tx) -> {
|
||||
}; // empty function to bypass exception
|
||||
|
||||
byte[][] hashesToSign=ps.getHashesToSign();
|
||||
byte[][] hashesToSign = ps.getHashesToSign();
|
||||
byte[] signFromCard = new byte[64 * hashesToSign.length];
|
||||
byte[] txForSend=ps.onSignCompleted(signFromCard);
|
||||
byte[] txForSend = ps.onSignCompleted(signFromCard);
|
||||
onNeedSendTransaction = onNeedSendTransactionBackup;
|
||||
Log.e(TAG,"txForSend.length="+String.valueOf(txForSend.length));
|
||||
Log.e(TAG, "txForSend.length=" + String.valueOf(txForSend.length));
|
||||
return txForSend.length;
|
||||
|
||||
// Log.e(TAG,"txForSend.length="+String.valueOf(txForSend.length)+" realTX.length="+String.valueOf(realTX.length));
|
||||
|
|
@ -753,9 +799,9 @@ public class BtcEngine extends CoinEngine {
|
|||
break;
|
||||
}
|
||||
|
||||
if(coinData.minFee!=null && coinData.normalFee!=null && coinData.maxFee!=null ) {
|
||||
if (coinData.minFee != null && coinData.normalFee != null && coinData.maxFee != null) {
|
||||
blockchainRequestsCallbacks.onComplete(true);
|
||||
}else{
|
||||
} else {
|
||||
blockchainRequestsCallbacks.onProgress();
|
||||
}
|
||||
}
|
||||
|
|
@ -793,7 +839,7 @@ public class BtcEngine extends CoinEngine {
|
|||
if (resultString == null || resultString.isEmpty()) {
|
||||
ctx.setError("Rejected by node: " + electrumRequest.getError());
|
||||
blockchainRequestsCallbacks.onComplete(false);
|
||||
}else {
|
||||
} else {
|
||||
ctx.setError(null);
|
||||
blockchainRequestsCallbacks.onComplete(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -608,6 +608,7 @@ public class EthEngine extends CoinEngine {
|
|||
serverApiInfura.setResponseListener(responseListener);
|
||||
|
||||
serverApiInfura.requestData(ServerApiInfura.INFURA_ETH_SEND_RAW_TRANSACTION, 67, coinData.getWallet(), "", txStr);
|
||||
|
||||
}
|
||||
|
||||
public int pendingTransactionTimeoutInSeconds() { return 10; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@ package com.tangem.domain.wallet.ltc
|
|||
enum class LitecoinNode(val host: String, val port: Int, val proto: String) {
|
||||
N_001("backup.electrum-ltc.org", 443, "ssl"),
|
||||
N_002("electrum-ltc.petrkr.net", 60002, "ssl"),
|
||||
N_003("technetium.network", 50003, "ssl"),
|
||||
N_004("167.99.146.166", 50002, "ssl"),
|
||||
N_005("electrum-ltc.bysh.me", 50002, "ssl"),
|
||||
N_006("e-3.claudioboxx.com", 50004, "ssl"),
|
||||
N_007("e-1.claudioboxx.com", 50004, "ssl"),
|
||||
N_008("e-2.claudioboxx.com", 50004, "ssl"),
|
||||
N_009("electrum.ltc.xurious.com", 50002, "ssl"),
|
||||
N_003("electrum-ltc.bysh.me", 50002, "ssl"),
|
||||
N_004("e-3.claudioboxx.com", 50004, "ssl"),
|
||||
N_005("e-1.claudioboxx.com", 50004, "ssl"),
|
||||
N_006("e-2.claudioboxx.com", 50004, "ssl"),
|
||||
N_007("electrum.ltc.xurious.com", 50002, "ssl"),
|
||||
}
|
||||
|
|
@ -557,9 +557,4 @@ public class LtcEngine extends BtcEngine {
|
|||
|
||||
serverApiElectrum.requestData(ctx, ElectrumRequest.getFee());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowSelectFeeLevel() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -201,8 +201,8 @@ public class RskEngine extends EthEngine {
|
|||
serverApiRootstock.setResponseListener(responseListener);
|
||||
|
||||
serverApiRootstock.requestData(ServerApiRootstock.ROOTSTOCK_ETH_SEND_RAW_TRANSACTION, 67, coinData.getWallet(), "", txStr);
|
||||
|
||||
}
|
||||
|
||||
public int pendingTransactionTimeoutInSeconds() { return 10; }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,19 +162,19 @@ public class RskTokenEngine extends TokenEngine {
|
|||
gasPrice = gasPrice.substring(2);
|
||||
|
||||
// rounding gas price to integer gwei
|
||||
BigInteger l = new BigInteger(gasPrice, 16);
|
||||
BigInteger gasPriceBI = new BigInteger(gasPrice, 16).divide(BigInteger.valueOf(10000000)).multiply(BigInteger.valueOf(10000000));
|
||||
|
||||
Log.i(TAG, "Rootstock gas price: " + gasPrice + " (" + l.toString() + ")");
|
||||
BigInteger m;
|
||||
Log.i(TAG, "Rootstock gas price: " + gasPrice + " (" + gasPriceBI.toString() + ")");
|
||||
BigInteger gasUsed;
|
||||
if (!amount.getCurrency().equals(Blockchain.Rootstock.getCurrency()))
|
||||
m = BigInteger.valueOf(60000);
|
||||
else m = BigInteger.valueOf(21000);
|
||||
gasUsed = BigInteger.valueOf(60000);
|
||||
else gasUsed = BigInteger.valueOf(21000);
|
||||
|
||||
Log.i(TAG, "fee multiplier: " + m.toString());
|
||||
Log.i(TAG, "fee multiplier: " + gasUsed.toString());
|
||||
|
||||
CoinEngine.InternalAmount weiMinFee = new CoinEngine.InternalAmount(l.multiply(m), "wei");
|
||||
CoinEngine.InternalAmount weiNormalFee = new CoinEngine.InternalAmount(l.multiply(BigInteger.valueOf(12)).divide(BigInteger.valueOf(10)).multiply(m), "wei");
|
||||
CoinEngine.InternalAmount weiMaxFee = new CoinEngine.InternalAmount(l.multiply(BigInteger.valueOf(15)).divide(BigInteger.valueOf(10)).multiply(m), "wei");
|
||||
CoinEngine.InternalAmount weiMinFee = new CoinEngine.InternalAmount(gasPriceBI.multiply(gasUsed), "wei");
|
||||
CoinEngine.InternalAmount weiNormalFee = new CoinEngine.InternalAmount(gasPriceBI.multiply(BigInteger.valueOf(12)).divide(BigInteger.valueOf(10)).multiply(gasUsed), "wei");
|
||||
CoinEngine.InternalAmount weiMaxFee = new CoinEngine.InternalAmount(gasPriceBI.multiply(BigInteger.valueOf(15)).divide(BigInteger.valueOf(10)).multiply(gasUsed), "wei");
|
||||
Log.i(TAG, "min fee : " + weiMinFee.toValueString() + " wei");
|
||||
Log.i(TAG, "normal fee: " + weiNormalFee.toValueString() + " wei");
|
||||
Log.i(TAG, "max fee : " + weiMaxFee.toValueString() + " wei");
|
||||
|
|
@ -251,4 +251,6 @@ public class RskTokenEngine extends TokenEngine {
|
|||
public boolean allowSelectFeeInclusion() {
|
||||
return getBalance().getCurrency().equals(Blockchain.Rootstock.getCurrency());
|
||||
}
|
||||
|
||||
public int pendingTransactionTimeoutInSeconds() { return 10; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -827,4 +827,6 @@ public class TokenEngine extends CoinEngine {
|
|||
public boolean allowSelectFeeInclusion() {
|
||||
return getBalance().getCurrency().equals(Blockchain.Ethereum.getCurrency());
|
||||
}
|
||||
|
||||
public int pendingTransactionTimeoutInSeconds() { return 10; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_min="130dp" />
|
||||
app:layout_constraintWidth_min="100dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrency2"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue