call, @NonNull Throwable t) {
+ responseListener.onFail(method, String.valueOf(t.getMessage()));
+ Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiMatic.java b/app/src/main/java/com/tangem/data/network/ServerApiMatic.java
new file mode 100644
index 0000000000..8686efa7ef
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/ServerApiMatic.java
@@ -0,0 +1,105 @@
+package com.tangem.data.network;
+
+import androidx.annotation.NonNull;
+import android.util.Log;
+
+import com.tangem.App;
+import com.tangem.data.network.model.InfuraBody;
+import com.tangem.data.network.model.InfuraResponse;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class ServerApiMatic {
+ private static String TAG = ServerApiMatic.class.getSimpleName();
+
+ /**
+ * HTTP
+ * Infura
+ *
+ * eth_getBalance
+ * eth_getTransactionCount
+ * eth_call
+ * eth_sendRawTransaction
+ * eth_gasPrice
+ */
+ public static final String MATIC_ETH_GET_BALANCE = "eth_getBalance";
+ public static final String MATIC_ETH_GET_TRANSACTION_COUNT = "eth_getTransactionCount";
+ public static final String MATIC_ETH_GET_PENDING_COUNT = "eth_getPendingCount";
+ public static final String MATIC_ETH_CALL = "eth_call";
+ public static final String MATIC_ETH_SEND_RAW_TRANSACTION = "eth_sendRawTransaction";
+ public static final String MATIC_ETH_GAS_PRICE = "eth_gasPrice";
+
+ private int requestsCount=0;
+
+ public boolean isRequestsSequenceCompleted() {
+ Log.i(TAG, String.format("isRequestsSequenceCompleted: %s (%d requests left)", String.valueOf(requestsCount <= 0), requestsCount));
+ return requestsCount <= 0;
+ }
+
+ private ResponseListener responseListener;
+
+ public interface ResponseListener {
+ void onSuccess(String method, InfuraResponse infuraResponse);
+
+ void onFail(String method, String message);
+ }
+
+ public void setResponseListener(ResponseListener listener) {
+ responseListener = listener;
+ }
+
+ public void requestData(String method, int id, String wallet, String contract, String tx) {
+ requestsCount++;
+ MaticApi maticApi = App.Companion.getNetworkComponent().getRetrofitMaticTesnet().create(MaticApi.class);
+
+ InfuraBody infuraBody;
+ switch (method) {
+ case MATIC_ETH_GET_BALANCE:
+ case MATIC_ETH_GET_TRANSACTION_COUNT:
+ infuraBody = new InfuraBody(method, new String[]{wallet, "latest"}, id);
+ break;
+ case MATIC_ETH_GET_PENDING_COUNT:
+ infuraBody = new InfuraBody(MATIC_ETH_GET_TRANSACTION_COUNT, new String[]{wallet, "pending"}, id);
+ break;
+ case MATIC_ETH_CALL:
+ String address = wallet.substring(2);
+ infuraBody = new InfuraBody(method, new Object[]{new InfuraBody.EthCallParams("0x70a08231000000000000000000000000" + address, contract), "latest"}, id);
+ break;
+
+ case MATIC_ETH_SEND_RAW_TRANSACTION:
+ infuraBody = new InfuraBody(method, new String[]{tx}, id);
+ break;
+
+ case MATIC_ETH_GAS_PRICE:
+ infuraBody = new InfuraBody(method, id);
+ break;
+
+ default:
+ infuraBody = new InfuraBody();
+ }
+
+ Call call = maticApi.matic(infuraBody);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.code() == 200) {
+ requestsCount--;
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ } else {
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ responseListener.onFail(method, String.valueOf(t.getMessage()));
+ Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiRipple.java b/app/src/main/java/com/tangem/data/network/ServerApiRipple.java
new file mode 100644
index 0000000000..ddbe82e090
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/ServerApiRipple.java
@@ -0,0 +1,117 @@
+package com.tangem.data.network;
+
+import android.util.Log;
+
+import com.tangem.data.network.model.RippleBody;
+import com.tangem.data.network.model.RippleResponse;
+
+import java.util.HashMap;
+
+import androidx.annotation.NonNull;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class ServerApiRipple {
+ private static String TAG = ServerApiRipple.class.getSimpleName();
+
+ public static final String RIPPLE_ACCOUNT_INFO = "account_info";
+ public static final String RIPPLE_ACCOUNT_UNCONFIRMED = "account_unconfirmed";
+ public static final String RIPPLE_SUBMIT = "submit";
+ public static final String RIPPLE_FEE = "fee";
+ public static final String RIPPLE_SERVER_STATE = "server_state";
+
+ private int requestsCount = 0;
+
+ public static String lastNode;
+
+ public boolean isRequestsSequenceCompleted() {
+ Log.i(TAG, String.format("isRequestsSequenceCompleted: %s (%d requests left)", String.valueOf(requestsCount <= 0), requestsCount));
+ return requestsCount <= 0;
+ }
+
+ private ResponseListener responseListener;
+
+ public interface ResponseListener {
+ void onSuccess(String method, RippleResponse rippleResponse);
+
+ void onFail(String method, String message);
+ }
+
+ public void setResponseListener(ResponseListener listener) {
+ responseListener = listener;
+ }
+
+ public void requestData(String method, String wallet, String tx) {
+ requestsCount++;
+ String rippleURL = "https://s1.ripple.com:51234"; //TODO: make random selection
+ lastNode = rippleURL; //TODO: show node instead of URL
+
+ Retrofit retrofitRipple = new Retrofit.Builder()
+ .baseUrl(rippleURL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+
+ RippleApi rippleApi = retrofitRipple.create(RippleApi.class);
+
+ RippleBody rippleBody;
+ HashMap paramsMap;
+
+ switch (method) {
+ case RIPPLE_ACCOUNT_INFO:
+ paramsMap = new HashMap<>();
+ paramsMap.put("account", wallet);
+ paramsMap.put("ledger_index", "validated");
+ rippleBody = new RippleBody(method, paramsMap);
+ break;
+
+ case RIPPLE_ACCOUNT_UNCONFIRMED:
+ paramsMap = new HashMap<>();
+ paramsMap.put("account", wallet);
+ paramsMap.put("ledger_index", "current");
+// paramsMap.put("queue", "true"); TODO: make queue check if needed
+ rippleBody = new RippleBody(RIPPLE_ACCOUNT_INFO, paramsMap);
+ break;
+
+ case RIPPLE_SERVER_STATE:
+ rippleBody = new RippleBody(method, new HashMap<>());
+ break;
+
+ case RIPPLE_FEE:
+ rippleBody = new RippleBody(method, new HashMap<>());
+ break;
+
+ case RIPPLE_SUBMIT:
+ paramsMap = new HashMap<>();
+ paramsMap.put("tx_blob", tx);
+ rippleBody = new RippleBody(method, paramsMap);
+ break;
+
+ default:
+ rippleBody = new RippleBody();
+ }
+
+ Call call = rippleApi.ripple(rippleBody);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.code() == 200) {
+ requestsCount--;
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ } else {
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ responseListener.onFail(method, String.valueOf(t.getMessage()));
+ Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiRootstock.java b/app/src/main/java/com/tangem/data/network/ServerApiRootstock.java
new file mode 100644
index 0000000000..198f5cc6b0
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/ServerApiRootstock.java
@@ -0,0 +1,105 @@
+package com.tangem.data.network;
+
+import androidx.annotation.NonNull;
+import android.util.Log;
+
+import com.tangem.App;
+import com.tangem.data.network.model.InfuraBody;
+import com.tangem.data.network.model.InfuraResponse;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class ServerApiRootstock {
+ private static String TAG = ServerApiRootstock.class.getSimpleName();
+
+ /**
+ * HTTP
+ * Rootstock
+ *
+ * eth_getBalance
+ * eth_getTransactionCount
+ * eth_call
+ * eth_sendRawTransaction
+ * eth_gasPrice
+ */
+ public static final String ROOTSTOCK_ETH_GET_BALANCE = "eth_getBalance";
+ public static final String ROOTSTOCK_ETH_GET_TRANSACTION_COUNT = "eth_getTransactionCount";
+ public static final String ROOTSTOCK_ETH_GET_PENDING_COUNT = "eth_getPendingCount";
+ public static final String ROOTSTOCK_ETH_CALL = "eth_call";
+ public static final String ROOTSTOCK_ETH_SEND_RAW_TRANSACTION = "eth_sendRawTransaction";
+ public static final String ROOTSTOCK_ETH_GAS_PRICE = "eth_gasPrice";
+
+ private int requestsCount=0;
+
+ public boolean isRequestsSequenceCompleted() {
+ Log.i(TAG, String.format("isRequestsSequenceCompleted: %s (%d requests left)", String.valueOf(requestsCount <= 0), requestsCount));
+ return requestsCount <= 0;
+ }
+
+ private ResponseListener responseListener;
+
+ public interface ResponseListener {
+ void onSuccess(String method, InfuraResponse infuraResponse);
+
+ void onFail(String method, String message);
+ }
+
+ public void setResponseListener(ResponseListener listener) {
+ responseListener = listener;
+ }
+
+ public void requestData(String method, int id, String wallet, String contract, String tx) {
+ requestsCount++;
+ RootstockApi rootstockApi = App.Companion.getNetworkComponent().getRetrofitRootstock().create(RootstockApi.class);
+
+ InfuraBody infuraBody;
+ switch (method) {
+ case ROOTSTOCK_ETH_GET_BALANCE:
+ case ROOTSTOCK_ETH_GET_TRANSACTION_COUNT:
+ infuraBody = new InfuraBody(method, new String[]{wallet, "latest"}, id);
+ break;
+ case ROOTSTOCK_ETH_GET_PENDING_COUNT:
+ infuraBody = new InfuraBody(ROOTSTOCK_ETH_GET_TRANSACTION_COUNT, new String[]{wallet, "pending"}, id);
+ break;
+ case ROOTSTOCK_ETH_CALL:
+ String address = wallet.substring(2);
+ infuraBody = new InfuraBody(method, new Object[]{new InfuraBody.EthCallParams("0x70a08231000000000000000000000000" + address, contract), "latest"}, id);
+ break;
+
+ case ROOTSTOCK_ETH_SEND_RAW_TRANSACTION:
+ infuraBody = new InfuraBody(method, new String[]{tx}, id);
+ break;
+
+ case ROOTSTOCK_ETH_GAS_PRICE:
+ infuraBody = new InfuraBody(method, id);
+ break;
+
+ default:
+ infuraBody = new InfuraBody();
+ }
+
+ Call call = rootstockApi.rootstock(infuraBody);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.code() == 200) {
+ requestsCount--;
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ } else {
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ responseListener.onFail(method, String.valueOf(t.getMessage()));
+ Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/ServerURL.java b/app/src/main/java/com/tangem/data/network/ServerURL.java
index 4703dd6436..42bd4a288a 100644
--- a/app/src/main/java/com/tangem/data/network/ServerURL.java
+++ b/app/src/main/java/com/tangem/data/network/ServerURL.java
@@ -2,9 +2,14 @@ package com.tangem.data.network;
class ServerURL {
static final String API_TANGEM = "https://verify.tangem.com/";
- static final String API_COINMARKETCAP = "https://api.coinmarketcap.com/";
- static final String API_INFURA = "https://mainnet.infura.io/v3/";
+ static final String API_COINMARKETCAP = "https://pro-api.coinmarketcap.com/";
+ static final String API_INFURA = "https://mainnet.infura.io/";
static final String API_ESTIMATEFEE = "https://estimatefee.com/";
static final String API_UPDATE_VERSION = "https://raw.githubusercontent.com/";
+ static final String API_ROOTSTOCK = "https://public-node.rsk.co/";
+ static final String API_BLOCKCYPHER = "https://api.blockcypher.com/";
+ static final String API_BINANCE = "https://dex.binance.org/";
+ static final String API_BINANCE_TESTNET = "https://testnet-dex.binance.org/";
+ static final String API_MATIC_TESTNET = "https://testnet2.matic.network";
static final String API_STELLAR = "https://horizon-testnet.stellar.org";
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/AdaliteBody.java b/app/src/main/java/com/tangem/data/network/model/AdaliteBody.java
new file mode 100644
index 0000000000..a8208d01cf
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/AdaliteBody.java
@@ -0,0 +1,9 @@
+package com.tangem.data.network.model;
+
+public class AdaliteBody {
+ private String signedTx;
+
+ public AdaliteBody(String signedTx) {
+ this.signedTx = signedTx;
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/model/AdaliteResponse.kt b/app/src/main/java/com/tangem/data/network/model/AdaliteResponse.kt
new file mode 100644
index 0000000000..d560d5fefc
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/AdaliteResponse.kt
@@ -0,0 +1,45 @@
+package com.tangem.data.network.model
+
+import com.google.gson.annotations.SerializedName
+
+data class AdaliteResponse(
+ @SerializedName("Right")
+ var right: AdaliteAddressData? = null
+)
+
+data class AdaliteResponseUtxo(
+ @SerializedName("Right")
+ var right: List
+)
+
+data class AdaliteAddressData(
+ @SerializedName("caAddress")
+ var caAddress: String? = null,
+
+ @SerializedName("caBalance")
+ var caBalance: AdaliteCoins? = null,
+
+ @SerializedName("caTxList")
+ var caTxList: List
+)
+
+data class AdaliteCoins(
+ @SerializedName("getCoin")
+ var getCoin: Long? = null
+)
+
+data class AdaliteUtxoData(
+ @SerializedName("cuId")
+ var cuId: String? = null,
+
+ @SerializedName("cuOutIndex")
+ var cuOutIndex: Int? = null,
+
+ @SerializedName("cuCoins")
+ var cuCoins: AdaliteCoins? = null
+)
+
+data class AdaliteTxData(
+ @SerializedName("ctbId")
+ var ctbId: String? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/BinanceFee.kt b/app/src/main/java/com/tangem/data/network/model/BinanceFee.kt
new file mode 100644
index 0000000000..061b9dbb27
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/BinanceFee.kt
@@ -0,0 +1,16 @@
+package com.tangem.data.network.model
+
+import com.google.gson.annotations.SerializedName
+
+data class BinanceFees(
+ @SerializedName("fixed_fee_params")
+ var fixed_fee_params: BinanceFixedFee? = null
+)
+
+data class BinanceFixedFee(
+ @SerializedName("msg_type")
+ var msg_type: String? = null,
+
+ @SerializedName("fee")
+ var fee: Int? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/BlockcypherBody.java b/app/src/main/java/com/tangem/data/network/model/BlockcypherBody.java
new file mode 100644
index 0000000000..065b899dcf
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/BlockcypherBody.java
@@ -0,0 +1,9 @@
+package com.tangem.data.network.model;
+
+public class BlockcypherBody {
+ private String tx;
+
+ public BlockcypherBody(String tx) {
+ this.tx = tx;
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/model/BlockcypherResponse.kt b/app/src/main/java/com/tangem/data/network/model/BlockcypherResponse.kt
new file mode 100644
index 0000000000..d86b7e0840
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/BlockcypherResponse.kt
@@ -0,0 +1,45 @@
+package com.tangem.data.network.model
+
+import com.google.gson.annotations.SerializedName
+
+data class BlockcypherResponse(
+ @SerializedName("address")
+ var address: String? = null,
+
+ @SerializedName("balance")
+ var balance: Long? = null,
+
+ @SerializedName("unconfirmed_balance")
+ var unconfirmed_balance: Long? = null,
+
+ @SerializedName("txrefs")
+ var txrefs: List? = null
+)
+
+data class BlockcypherTxref(
+ @SerializedName("tx_hash")
+ var tx_hash: String? = null,
+
+ @SerializedName("tx_output_n")
+ var tx_output_n: Int? = null,
+
+ @SerializedName("value")
+ var value: Long? = null,
+
+ @SerializedName("confirmations")
+ var confirmations: Long? = null,
+
+ @SerializedName("script")
+ var script: String? = null
+)
+
+data class BlockcypherFee(
+ @SerializedName("low_fee_per_kb")
+ var low_fee_per_kb: Long? = null,
+
+ @SerializedName("medium_fee_per_kb")
+ var medium_fee_per_kb: Long? = null,
+
+ @SerializedName("high_fee_per_kb")
+ var high_fee_per_kb: Long? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/InfuraBody.java b/app/src/main/java/com/tangem/data/network/model/InfuraBody.java
index bf3aa67f29..7f104e419e 100644
--- a/app/src/main/java/com/tangem/data/network/model/InfuraBody.java
+++ b/app/src/main/java/com/tangem/data/network/model/InfuraBody.java
@@ -4,6 +4,7 @@ public class InfuraBody {
private String method;
private Object[] params;
private int id;
+ private String jsonrpc = "2.0";
public InfuraBody() {
}
diff --git a/app/src/main/java/com/tangem/data/network/model/InfuraResponse.kt b/app/src/main/java/com/tangem/data/network/model/InfuraResponse.kt
index 692ece2119..d565ef79c8 100644
--- a/app/src/main/java/com/tangem/data/network/model/InfuraResponse.kt
+++ b/app/src/main/java/com/tangem/data/network/model/InfuraResponse.kt
@@ -10,8 +10,8 @@ data class InfuraResponse(
var id: Int? = null,
@SerializedName("result")
- var result: String = "",
+ var result: String? = null,
@SerializedName("error")
- var error: String = ""
+ var error: Object
)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/InsightBody.java b/app/src/main/java/com/tangem/data/network/model/InsightBody.java
new file mode 100644
index 0000000000..4d8951adfa
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/InsightBody.java
@@ -0,0 +1,9 @@
+package com.tangem.data.network.model;
+
+public class InsightBody {
+ private String rawtx;
+
+ public InsightBody(String rawtx){
+ this.rawtx = rawtx;
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/model/InsightResponse.kt b/app/src/main/java/com/tangem/data/network/model/InsightResponse.kt
new file mode 100644
index 0000000000..4910b36695
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/InsightResponse.kt
@@ -0,0 +1,38 @@
+package com.tangem.data.network.model
+
+import com.google.gson.annotations.SerializedName
+
+data class InsightResponse(
+ @SerializedName("balanceSat")
+ var balanceSat: Long? = null,
+
+ @SerializedName("unconfirmedBalanceSat")
+ var unconfirmedBalanceSat: Long? = null,
+
+ @SerializedName("addrStr")
+ var addrStr: String = "",
+
+ @SerializedName("txid")
+ var txid: String = "",
+
+ @SerializedName("satoshis")
+ var satoshis: Long? = null,
+
+ @SerializedName("height")
+ var height: Int? = null,
+
+ @SerializedName("2")
+ var fee2: String = "",
+
+ @SerializedName("3")
+ var fee3: String = "",
+
+ @SerializedName("6")
+ var fee6: String = "",
+
+ @SerializedName("rawtx")
+ var rawtx: String = "",
+
+ @SerializedName("error")
+ var error: String = ""
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/RateInfoResponse.kt b/app/src/main/java/com/tangem/data/network/model/RateInfoResponse.kt
index 359c450fec..6fd76e8581 100644
--- a/app/src/main/java/com/tangem/data/network/model/RateInfoResponse.kt
+++ b/app/src/main/java/com/tangem/data/network/model/RateInfoResponse.kt
@@ -1,76 +1,23 @@
package com.tangem.data.network.model
-import android.os.Parcelable
import com.google.gson.annotations.SerializedName
-import kotlinx.android.parcel.Parcelize
-@Parcelize
data class RateInfoResponse(
- @SerializedName(ID)
- var id: String = "",
+ @SerializedName("data")
+ var data: RateData? = null
+)
- @SerializedName(NAME)
- var name: String = "",
+data class RateData(
+ @SerializedName("quote")
+ var quote: Quote? = null
+)
- @SerializedName(SYMBOL)
- var symbol: String = "",
+data class Quote(
+ @SerializedName("USD")
+ var usd: CurrencyRate? = null
+)
- @SerializedName(RANK)
- var rank: String = "",
-
- @SerializedName(PRICE_USD)
- var priceUsd: String = "",
-
- @SerializedName(PRICE_BTC)
- var priceBtc: String = "",
-
- @SerializedName(VOLUME_USD_24H)
- var volumeUsd24h: String = "",
-
- @SerializedName(MARKET_CAP_USD)
- var marketCapUsd: String = "",
-
- @SerializedName(AVAILABLE_SUPPLY)
- var availableSupply: String = "",
-
- @SerializedName(TOTAL_SUPPLY)
- var totalSupply: String = "",
-
- @SerializedName(MAX_SUPPLY)
- var maxSupply: String = "",
-
- @SerializedName(PERCENT_CHANGE_1H)
- var percentChange1h: String = "",
-
- @SerializedName(PERCENT_CHANGE_24H)
- var percentChange24h: String = "",
-
- @SerializedName(PERCENT_CHANGE_7H)
- var percentChange7h: String = "",
-
- @SerializedName(LAST_UPDATED)
- var lastUpdated: String = ""
-
-) : Parcelable {
-
- companion object {
- val TAG: String = RateInfoResponse::class.java.simpleName
-
- const val ID = "id"
- const val NAME = "name"
- const val SYMBOL = "symbol"
- const val RANK = "rank"
- const val PRICE_USD = "price_usd"
- const val PRICE_BTC = "price_btc"
- const val VOLUME_USD_24H = "24h_volume_usd"
- const val MARKET_CAP_USD = "market_cap_usd"
- const val AVAILABLE_SUPPLY = "available_supply"
- const val TOTAL_SUPPLY = "total_supply"
- const val MAX_SUPPLY = "max_supply"
- const val PERCENT_CHANGE_1H = "percent_change_1h"
- const val PERCENT_CHANGE_24H = "percent_change_24h"
- const val PERCENT_CHANGE_7H = "percent_change_7d"
- const val LAST_UPDATED = "last_updated"
- }
-
-}
\ No newline at end of file
+data class CurrencyRate(
+ @SerializedName("price")
+ var price: Float? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/model/RippleBody.java b/app/src/main/java/com/tangem/data/network/model/RippleBody.java
new file mode 100644
index 0000000000..0423f357a1
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/RippleBody.java
@@ -0,0 +1,24 @@
+package com.tangem.data.network.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class RippleBody {
+ private String method;
+ private ArrayList> params;
+
+ public RippleBody() {
+ }
+
+ //for RIPPLE_FEE
+ public RippleBody(String method) {
+ this.method = method;
+ }
+
+ public RippleBody(String method, HashMap paramsMap) {
+ this.method = method;
+ ArrayList> paramsList = new ArrayList<>();
+ paramsList.add(paramsMap);
+ this.params = paramsList;
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/model/RippleResponse.kt b/app/src/main/java/com/tangem/data/network/model/RippleResponse.kt
new file mode 100644
index 0000000000..4a865aca67
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/model/RippleResponse.kt
@@ -0,0 +1,78 @@
+package com.tangem.data.network.model
+
+import com.google.gson.annotations.SerializedName
+
+data class RippleResponse(
+ @SerializedName("result")
+ var result: RippleResult? = null
+)
+
+data class RippleResult(
+ @SerializedName("account_data")
+ var account_data: RippleAccountData? = null,
+
+ @SerializedName("validated")
+ var validated: Boolean? = null,
+
+ //for RIPPLE_FEE
+ @SerializedName("drops")
+ var drops: RippleFeeDrops? = null,
+
+ //for RIPPLE_SUBMIT
+ @SerializedName("engine_result_code")
+ var engine_result_code: Int? = null,
+
+ //for RIPPLE_SUBMIT
+ @SerializedName ("engine_result_message")
+ var engine_result_message: String? = null,
+
+ //for RIPPLE_SUBMIT
+ @SerializedName("error")
+ var error: String? = null,
+
+ //for RIPPLE_SUBMIT
+ @SerializedName("error_exception")
+ var error_exception: String? = null,
+
+ //for RIPPLE_SERVER_STATE
+ @SerializedName("state")
+ var state: RippleState? = null,
+
+ //for "Account not found error"
+ @SerializedName("error_code")
+ var error_code: Int? = null
+)
+
+data class RippleAccountData(
+ @SerializedName("Account")
+ var account: String? = null,
+
+ @SerializedName("Balance")
+ var balance: String? = null,
+
+ @SerializedName("Sequence")
+ var sequence: Long? = null
+)
+
+data class RippleFeeDrops(
+ //enough to put tx to queue
+ @SerializedName("minimum_fee")
+ var minimum_fee: String? = null,
+
+ //enough to put tx to current ledger
+ @SerializedName("open_ledger_fee")
+ var open_ledger_fee: String? = null,
+
+ @SerializedName("median_fee")
+ var median_fee: String? = null
+)
+
+data class RippleState(
+ @SerializedName("validated_ledger")
+ var validated_ledger: RippleLedger? = null
+)
+
+data class RippleLedger(
+ @SerializedName("reserve_base")
+ var reserve_base: Long? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/AppModule.java b/app/src/main/java/com/tangem/di/AppModule.java
deleted file mode 100644
index 308a52a931..0000000000
--- a/app/src/main/java/com/tangem/di/AppModule.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.tangem.di;
-
-import android.content.Context;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.inject.Singleton;
-
-@Singleton
-public class AppModule {
- private Context appContext;
-
- public AppModule(@NotNull Context context) {
- appContext = context;
- }
-
- Context provideContext() {
- return appContext;
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/AppModule.kt b/app/src/main/java/com/tangem/di/AppModule.kt
new file mode 100644
index 0000000000..6fa481881b
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/AppModule.kt
@@ -0,0 +1,18 @@
+package com.tangem.di
+
+import android.app.Application
+import android.content.Context
+import dagger.Module
+import javax.inject.Singleton
+import dagger.Provides
+
+@Module
+class AppModule {
+
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/Navigator.kt b/app/src/main/java/com/tangem/di/Navigator.kt
index 3a620229c4..a1204b9470 100644
--- a/app/src/main/java/com/tangem/di/Navigator.kt
+++ b/app/src/main/java/com/tangem/di/Navigator.kt
@@ -3,11 +3,17 @@ package com.tangem.di
import android.app.Activity
import android.nfc.Tag
import com.tangem.Constant
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.activity.*
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.PrepareTransactionActivity
+import com.tangem.ui.activity.*
+import com.tangem.wallet.BuildConfig
class Navigator {
+ fun showSettings(context: Activity) {
+ context.startActivity(SettingsActivity.callingIntent(context))
+ }
+
fun showMain(context: Activity) {
context.startActivity(MainActivity.callingIntent(context))
}
@@ -68,8 +74,15 @@ class Navigator {
context.startActivityForResult(PurgeActivity.callingIntent(context, ctx), Constant.REQUEST_CODE_PURGE)
}
- fun showPreparePayment(context: Activity, ctx: TangemContext) {
- context.startActivityForResult(PreparePaymentActivity.callingIntent(context, ctx), Constant.REQUEST_CODE_SEND_PAYMENT)
+ fun showPrepareTransaction(context: Activity, ctx: TangemContext) {
+ when (BuildConfig.FLAVOR) {
+ Constant.FLAVOR_TANGEM_CARDANO -> {
+ context.startActivity(PrepareTransactionActivity.callingIntent(context, ctx))
+ }
+ else -> {
+ context.startActivityForResult(PrepareTransactionActivity.callingIntent(context, ctx), Constant.REQUEST_CODE_SEND_TRANSACTION)
+ }
+ }
}
fun showCreateNewWallet(context: Activity, ctx: TangemContext) {
diff --git a/app/src/main/java/com/tangem/di/NavigatorComponent.java b/app/src/main/java/com/tangem/di/NavigatorComponent.java
deleted file mode 100644
index 23bd390f21..0000000000
--- a/app/src/main/java/com/tangem/di/NavigatorComponent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.tangem.di;
-
-import com.tangem.presentation.activity.EmptyWalletActivity;
-import com.tangem.presentation.activity.LoadedWalletActivity;
-import com.tangem.presentation.activity.LogoActivity;
-import com.tangem.presentation.activity.MainActivity;
-import com.tangem.presentation.activity.PrepareCryptonitOtherApiWithdrawalActivity;
-import com.tangem.presentation.activity.PrepareKrakenWithdrawalActivity;
-import com.tangem.presentation.activity.PreparePaymentActivity;
-import com.tangem.presentation.activity.VerifyCardActivity;
-
-import javax.inject.Singleton;
-
-import dagger.Component;
-
-@Singleton
-@Component(modules = {
-// AppModule.class,
- NavigatorModule.class})
-public interface NavigatorComponent {
-
- void inject(LogoActivity activity);
-
- void inject(MainActivity activity);
-
- void inject(PreparePaymentActivity activity);
-
- void inject(PrepareCryptonitOtherApiWithdrawalActivity activity);
-
- void inject(PrepareKrakenWithdrawalActivity activity);
-
- void inject(LoadedWalletActivity activity);
-
- void inject(VerifyCardActivity activity);
-
- void inject(EmptyWalletActivity activity);
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NavigatorComponent.kt b/app/src/main/java/com/tangem/di/NavigatorComponent.kt
new file mode 100644
index 0000000000..25990b46a1
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/NavigatorComponent.kt
@@ -0,0 +1,39 @@
+package com.tangem.di
+
+import com.tangem.ui.activity.EmptyWalletActivity
+import com.tangem.ui.activity.LoadedWalletActivity
+import com.tangem.ui.activity.LogoActivity
+import com.tangem.ui.activity.MainActivity
+import com.tangem.ui.activity.PrepareCryptonitOtherApiWithdrawalActivity
+import com.tangem.ui.activity.PrepareKrakenWithdrawalActivity
+import com.tangem.ui.PrepareTransactionActivity
+import com.tangem.ui.activity.PurgeActivity
+import com.tangem.ui.activity.VerifyCardActivity
+
+import javax.inject.Singleton
+
+import dagger.Component
+
+@Singleton
+@Component(modules = [NavigatorModule::class])
+interface NavigatorComponent {
+
+ fun inject(activity: LogoActivity)
+
+ fun inject(activity: MainActivity)
+
+ fun inject(activity: PurgeActivity)
+
+ fun inject(activity: PrepareTransactionActivity)
+
+ fun inject(activity: PrepareCryptonitOtherApiWithdrawalActivity)
+
+ fun inject(activity: PrepareKrakenWithdrawalActivity)
+
+ fun inject(activity: LoadedWalletActivity)
+
+ fun inject(activity: VerifyCardActivity)
+
+ fun inject(activity: EmptyWalletActivity)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NavigatorModule.java b/app/src/main/java/com/tangem/di/NavigatorModule.java
deleted file mode 100644
index 94a8dda3d5..0000000000
--- a/app/src/main/java/com/tangem/di/NavigatorModule.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.tangem.di;
-
-import javax.inject.Singleton;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class NavigatorModule {
-
- @Singleton
- @Provides
- Navigator provideNavigator() {
- return new Navigator();
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NavigatorModule.kt b/app/src/main/java/com/tangem/di/NavigatorModule.kt
new file mode 100644
index 0000000000..0028345e74
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/NavigatorModule.kt
@@ -0,0 +1,31 @@
+package com.tangem.di
+
+import com.tangem.ui.dialog.WaitSecurityDelayDialogNew
+
+import javax.inject.Singleton
+
+import dagger.Module
+import dagger.Provides
+
+@Module
+internal class NavigatorModule {
+
+ @Singleton
+ @Provides
+ fun provideNavigator(): Navigator {
+ return Navigator()
+ }
+
+ @Singleton
+ @Provides
+ fun provideToastHelper(): ToastHelper {
+ return ToastHelper()
+ }
+
+ @Singleton
+ @Provides
+ fun provideWaitSecurityDelayDialogNew(): WaitSecurityDelayDialogNew {
+ return WaitSecurityDelayDialogNew()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NetworkComponent.java b/app/src/main/java/com/tangem/di/NetworkComponent.java
deleted file mode 100644
index 4de9763426..0000000000
--- a/app/src/main/java/com/tangem/di/NetworkComponent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.tangem.di;
-
-import com.tangem.data.network.Server;
-
-import java.net.Socket;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import dagger.Component;
-import retrofit2.Retrofit;
-
-@Singleton
-@Component(modules = {NetworkModule.class})
-public interface NetworkComponent {
-
- @Named(Server.ApiInfura.URL_INFURA)
- Retrofit getRetrofitInfura();
-
- @Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
- Retrofit getRetrofitEstimatefee();
-
- @Named(Server.ApiCoinmarket.URL_COINMARKET)
- Retrofit getRetrofitCoinmarketcap();
-
- @Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
- Retrofit getRetrofitGithubusercontent();
-
- @Named("socket")
- Socket getSocket();
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NetworkComponent.kt b/app/src/main/java/com/tangem/di/NetworkComponent.kt
new file mode 100644
index 0000000000..cc5a3ef060
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/NetworkComponent.kt
@@ -0,0 +1,41 @@
+package com.tangem.di
+
+import com.tangem.data.network.Server
+
+import java.net.Socket
+
+import javax.inject.Named
+import javax.inject.Singleton
+
+import dagger.Component
+import retrofit2.Retrofit
+
+@Singleton
+@Component(modules = [NetworkModule::class])
+interface NetworkComponent {
+
+ @get:Named(Server.ApiInfura.URL_INFURA)
+ val retrofitInfura: Retrofit
+
+ @get:Named(Server.ApiMaticTesnet.URL_MATIC_TESTNET)
+ val retrofitMaticTesnet: Retrofit
+
+ @get:Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
+ val retrofitEstimatefee: Retrofit
+
+ @get:Named(Server.ApiCoinmarket.URL_COINMARKET)
+ val retrofitCoinmarketcap: Retrofit
+
+ @get:Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
+ val retrofitGitHubUserContent: Retrofit
+
+ @get:Named(Server.ApiRootstock.URL_ROOTSTOCK)
+ val retrofitRootstock: Retrofit
+
+ @get:Named(Server.ApiBlockcypher.URL_BLOCKCYPHER)
+ val retrofitBlockcypher: Retrofit
+
+ @get:Named("socket")
+ val socket: Socket
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NetworkModule.java b/app/src/main/java/com/tangem/di/NetworkModule.java
deleted file mode 100644
index 86e669389e..0000000000
--- a/app/src/main/java/com/tangem/di/NetworkModule.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.tangem.di;
-
-import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
-import com.tangem.data.network.Server;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketException;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import dagger.Module;
-import dagger.Provides;
-import okhttp3.OkHttpClient;
-import okhttp3.logging.HttpLoggingInterceptor;
-import retrofit2.Retrofit;
-import retrofit2.converter.gson.GsonConverterFactory;
-
-@Module
-class NetworkModule {
-
- @Singleton
- @Provides
- @Named(Server.ApiInfura.URL_INFURA)
- Retrofit provideRetrofitInfura() {
- return new Retrofit.Builder()
- .baseUrl(Server.ApiInfura.URL_INFURA)
- .addConverterFactory(GsonConverterFactory.create())
- .build();
- }
-
- @Singleton
- @Provides
- @Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
- Retrofit provideRetrofitEstimatefee() {
- return new Retrofit.Builder()
- .baseUrl(Server.ApiEstimatefee.URL_ESTIMATEFEE)
- .addConverterFactory(GsonConverterFactory.create())
- .build();
- }
-
- @Singleton
- @Provides
- @Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
- Retrofit provideGithubusercontent() {
- return new Retrofit.Builder()
- .baseUrl(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
- .addConverterFactory(GsonConverterFactory.create())
- .client(createOkHttpClient())
- .build();
- }
-
- @Singleton
- @Provides
- @Named(Server.ApiCoinmarket.URL_COINMARKET)
- Retrofit provideRetrofitCoinmarketcap() {
- return new Retrofit.Builder()
- .baseUrl(Server.ApiCoinmarket.URL_COINMARKET)
- .addConverterFactory(GsonConverterFactory.create())
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .build();
- }
-
- private OkHttpClient createOkHttpClient() {
- return new OkHttpClient.Builder().
- addInterceptor(createHttpLoggingInterceptor()).
- build();
- }
-
- private HttpLoggingInterceptor createHttpLoggingInterceptor() {
- HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
- logging.setLevel(HttpLoggingInterceptor.Level.BODY);
- return logging;
- }
-
- @Provides
- @Named("socket")
- Socket provideSocket() {
- Socket socket = new Socket();
- try {
- socket.setSoTimeout(2000);
- try {
- socket.bind(new InetSocketAddress(0));
- } catch (IOException e) {
- e.printStackTrace();
- }
- } catch (SocketException e) {
- e.printStackTrace();
- }
-
- return socket;
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/NetworkModule.kt b/app/src/main/java/com/tangem/di/NetworkModule.kt
new file mode 100644
index 0000000000..912ec80d24
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/NetworkModule.kt
@@ -0,0 +1,141 @@
+package com.tangem.di
+
+import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+import com.tangem.data.network.Server
+import com.tangem.wallet.BuildConfig
+
+import java.io.IOException
+import java.net.InetSocketAddress
+import java.net.Socket
+import java.net.SocketException
+
+import javax.inject.Named
+import javax.inject.Singleton
+
+import dagger.Module
+import dagger.Provides
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+@Module
+internal class NetworkModule {
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiInfura.URL_INFURA)
+ fun provideRetrofitInfura(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiInfura.URL_INFURA)
+ .addConverterFactory(GsonConverterFactory.create())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiRootstock.URL_ROOTSTOCK)
+ fun provideRetrofitRootstock(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiRootstock.URL_ROOTSTOCK)
+ .addConverterFactory(GsonConverterFactory.create())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiMaticTesnet.URL_MATIC_TESTNET)
+ fun provideRetrofitMaticTestnet(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiMaticTesnet.URL_MATIC_TESTNET)
+ .addConverterFactory(GsonConverterFactory.create())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
+ fun provideRetrofitEstimatefee(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiEstimatefee.URL_ESTIMATEFEE)
+ .addConverterFactory(GsonConverterFactory.create())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
+ fun provideGithubusercontent(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
+ .addConverterFactory(GsonConverterFactory.create())
+ .client(createOkHttpClient())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiCoinmarket.URL_COINMARKET)
+ fun provideRetrofitCoinmarketcap(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiCoinmarket.URL_COINMARKET)
+ .addConverterFactory(GsonConverterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+// if (BuildConfig.DEBUG)
+// builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ @Singleton
+ @Provides
+ @Named(Server.ApiBlockcypher.URL_BLOCKCYPHER)
+ fun provideRetrofitBlockcypher(): Retrofit {
+ val builder = Retrofit.Builder()
+ .baseUrl(Server.ApiBlockcypher.URL_BLOCKCYPHER)
+ .addConverterFactory(GsonConverterFactory.create())
+ .client(createOkHttpClient())
+ if (BuildConfig.DEBUG)
+ builder.client(createOkHttpClient())
+ return builder.build()
+ }
+
+ private fun createOkHttpClient(): OkHttpClient {
+ return OkHttpClient.Builder().addInterceptor(createHttpLoggingInterceptor()).build()
+ }
+
+ private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor {
+ val logging = HttpLoggingInterceptor()
+ logging.level = HttpLoggingInterceptor.Level.BODY
+ return logging
+ }
+
+ @Provides
+ @Named("socket")
+ fun provideSocket(): Socket {
+ val socket = Socket()
+ try {
+ socket.soTimeout = 2000
+ try {
+ socket.bind(InetSocketAddress(0))
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ } catch (e: SocketException) {
+ e.printStackTrace()
+ }
+
+ return socket
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/ToastHelper.kt b/app/src/main/java/com/tangem/di/ToastHelper.kt
new file mode 100644
index 0000000000..664a83d479
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/ToastHelper.kt
@@ -0,0 +1,70 @@
+package com.tangem.di
+
+import android.content.ActivityNotFoundException
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.view.ViewGroup
+import android.widget.Toast
+import com.google.android.material.snackbar.Snackbar
+import com.tangem.Constant
+import com.tangem.wallet.R
+import java.util.*
+
+class ToastHelper {
+ fun showSnackbarUpdateVersion(context: Context, vg: ViewGroup, versionName: String) {
+ Snackbar.make(vg, String.format(context.getString(R.string.new_app_version), versionName), Snackbar.LENGTH_INDEFINITE)
+ .setAction(R.string.update) {
+ try {
+ val intent = Intent(Intent.ACTION_VIEW)
+ intent.data = Uri.parse(Constant.URL_TANGEM)
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ e.printStackTrace()
+ }
+ }.show()
+ }
+
+ fun showSnackbarSuccess(context: Context, vg: ViewGroup, message: String) {
+ val snackbar = Snackbar.make(vg, message, Snackbar.LENGTH_INDEFINITE)
+ val snackView = snackbar.view
+ snackView.setBackgroundColor(context.resources.getColor(R.color.msg_okay))
+ snackbar.setAction(R.string.ok) {
+ snackbar.dismiss()
+ }
+ snackbar.show()
+ }
+
+ fun showSnackbarError(context: Context, vg: ViewGroup, message: String) {
+ val snackbar = Snackbar.make(vg, message, Snackbar.LENGTH_INDEFINITE)
+ val snackView = snackbar.view
+ snackView.setBackgroundColor(context.resources.getColor(R.color.msg_err))
+ snackbar.setAction(R.string.ok) {
+ snackbar.dismiss()
+ }
+ snackbar.show()
+ }
+
+ fun showSnackbarWarning(context: Context, vg: ViewGroup, message: String) {
+ val snackbar = Snackbar.make(vg, message, Snackbar.LENGTH_LONG)
+ val snackView = snackbar.view
+ snackView.setBackgroundColor(context.resources.getColor(R.color.msg_err))
+ snackbar.show()
+ }
+
+ private var singleToast: Toast? = null
+ private var showTime: Date = Date()
+
+ fun showSingleToast(context: Context?, text: String) {
+ if (singleToast == null || !singleToast!!.view.isShown || showTime.time + 2000 < Date().time) {
+ if (singleToast != null)
+ singleToast!!.cancel()
+ if (context != null) {
+ singleToast = Toast.makeText(context, text, Toast.LENGTH_LONG)
+ singleToast!!.show()
+ showTime = Date()
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/di/ToastHelperComponent.kt b/app/src/main/java/com/tangem/di/ToastHelperComponent.kt
new file mode 100644
index 0000000000..24d5165c5e
--- /dev/null
+++ b/app/src/main/java/com/tangem/di/ToastHelperComponent.kt
@@ -0,0 +1,25 @@
+package com.tangem.di
+
+import com.tangem.ui.ConfirmTransactionActivity
+import com.tangem.ui.PrepareTransactionActivity
+import com.tangem.ui.activity.EmptyWalletActivity
+import com.tangem.ui.activity.LoadedWalletActivity
+import com.tangem.ui.activity.MainActivity
+import dagger.Component
+import javax.inject.Singleton
+
+@Singleton
+@Component(modules = [NavigatorModule::class])
+interface ToastHelperComponent {
+
+ fun inject(activity: MainActivity)
+
+ fun inject(activity: LoadedWalletActivity)
+
+ fun inject(activity: ConfirmTransactionActivity)
+
+ fun inject(activity: PrepareTransactionActivity)
+
+ fun inject(activity: EmptyWalletActivity)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt b/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt
deleted file mode 100644
index 528c9d3147..0000000000
--- a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.tangem.domain.wallet
-
-import android.util.Log
-
-import com.tangem.domain.wallet.btc.BtcEngine
-import com.tangem.domain.wallet.eth.EthEngine
-import com.tangem.domain.wallet.token.TokenEngine
-import com.tangem.domain.wallet.bch.BtcCashEngine
-import com.tangem.data.Blockchain
-import com.tangem.domain.wallet.ltc.LtcEngine
-import com.tangem.domain.wallet.xlm.XlmEngine
-
-/**
- * Factory for create specific engine
- *
- * @param Blockchain
- * @param TangemContext
- *
- */
-
-object CoinEngineFactory {
- private val TAG = CoinEngineFactory::class.java.simpleName
-
- fun create(blockchain: Blockchain): CoinEngine? {
- return when (blockchain) {
- Blockchain.Bitcoin, Blockchain.BitcoinTestNet -> BtcEngine()
- Blockchain.BitcoinCash -> BtcCashEngine()
- Blockchain.Ethereum, Blockchain.EthereumTestNet -> EthEngine()
- Blockchain.Token -> TokenEngine()
- Blockchain.Litecoin -> LtcEngine()
- Blockchain.StellarTestNet, Blockchain.Stellar -> XlmEngine()
- else -> null
- }
- }
-
- fun create(context: TangemContext): CoinEngine? {
- var result: CoinEngine?
- try {
- result = if (Blockchain.BitcoinCash == context.blockchain)
- BtcCashEngine(context)
- else if (Blockchain.Bitcoin == context.blockchain || Blockchain.BitcoinTestNet == context.blockchain)
- BtcEngine(context)
- else if (Blockchain.Ethereum == context.blockchain || Blockchain.EthereumTestNet == context.blockchain)
- EthEngine(context)
- else if (Blockchain.Token == context.blockchain)
- TokenEngine(context)
- else if (Blockchain.Litecoin == context.blockchain)
- LtcEngine(context)
- else if (Blockchain.Stellar == context.blockchain || Blockchain.StellarTestNet == context.blockchain)
- XlmEngine(context)
- else
- return null
- } catch (e: Exception) {
- e.printStackTrace()
- result = null
- Log.e(TAG, "Can't create CoinEngine!")
- }
- return result
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashNode.kt b/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashNode.kt
deleted file mode 100644
index e08f74eacf..0000000000
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashNode.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.tangem.domain.wallet.bch
-
-enum class BitcoinCashNode(val host: String, val port: Int, val proto: String) {
- N_001("electrumx.hillsideinternet.com", 50002, "ssl"),
- N_002("bch0.kister.net", 50002, "ssl"),
- N_003("abc1.hsmiths.com", 60002, "ssl"),
- N_004("bch.curalle.ovh", 50002, "ssl"),
- N_005("207.180.215.112", 52002, "ssl"),
- N_006("bch.imaginary.cash", 50002, "ssl"),
- N_007("dedi.jochen-hoenicke.de", 51002, "ssl"),
- N_008("crypto.mldlabs.com", 50002, "ssl"),
- N_009("bch.electrumx.cash", 50002, "ssl"),
- N_010("electroncash.cascharia.com", 50002, "ssl"),
- N_011("bch.crypto.mldlabs.com", 50002, "ssl"),
- N_012("electron-cash.dragon.zone", 50002, "ssl"),
- N_013("electron.coinucopia.io", 50002, "ssl"),
- N_014("blackie.c3-soft.com", 50002, "ssl"),
- N_015("electroncash.ueo.ch", 51002, "ssl"),
- N_016("electrum.imaginary.cash", 50002, "ssl"),
- N_017("35.157.238.5", 51002, "ssl"),
- N_018("bitcoincash.quangld.com", 50002, "ssl"),
- N_019("bch.stitthappens.com", 50002, "ssl"),
- N_020("electroncash.dk", 50002, "ssl"),
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/btc/BitcoinNode.kt b/app/src/main/java/com/tangem/domain/wallet/btc/BitcoinNode.kt
deleted file mode 100644
index 0d5d7cb997..0000000000
--- a/app/src/main/java/com/tangem/domain/wallet/btc/BitcoinNode.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.tangem.domain.wallet.btc
-
-enum class BitcoinNode(val host: String, val port: Int, val proto: String) {
- N_001("electrum.anduck.net", 50001, "tcp"),
- N_002("ip119.ip-54-37-91.eu", 50001, "tcp"),
- N_003("electrum.qtornado.com", 50001, "tcp"),
- N_004("ip239.ip-54-36-234.eu", 50001, "tcp"),
- N_005("electrum-server.ninja", 50001, "tcp"),
- N_006("174.138.11.174", 50001, "tcp"),
- N_007("ndnd.selfhost.eu", 50001, "tcp"),
- N_008("btc.cihar.com", 50001, "tcp"),
- N_009("vps.hsmiths.com", 8080, "tcp"),
- N_010("electrum.hsmiths.com", 8080, "tcp"),
- N_011("ip120.ip-54-37-91.eu", 50001, "tcp"),
- N_012("vps.hsmiths.com", 50001, "tcp"),
- N_013("orannis.com", 50001, "tcp"),
- N_014("ip101.ip-54-37-91.eu", 50001, "tcp"),
- N_015("e-x.not.fyi", 50001, "tcp"),
- N_016("electrum.hsmiths.com", 50001, "tcp"),
- N_017("electrum.vom-stausee.de", 50001, "tcp"),
- N_018("bitcoin.corgi.party", 50001, "tcp"),
- N_019("electrum2.eff.ro", 50001, "tcp"),
- N_020("electrum.coinucopia.io", 50001, "tcp"),
- N_021("electrum.eff.ro", 50001, "tcp"),
- N_022("btc.xskyx.net", 50001, "tcp"),
- N_023("kirsche.emzy.de", 50001, "tcp"),
- N_024("electrum.petrkr.net", 50001, "tcp"),
- N_025("btc.knas.systems", 50001, "tcp"),
- N_026("b.ooze.cc", 50002, "ssl"),
- N_027("electrum.nute.net", 50002, "ssl"),
- N_028("ndnd.selfhost.eu", 50002, "ssl"),
- N_029("electrum.coinop.cc", 50002, "ssl"),
- N_030("orannis.com", 50002, "ssl"),
- N_031("electrum.vom-stausee.de", 50002, "ssl"),
- N_032("ip119.ip-54-37-91.eu", 50002, "ssl"),
- N_033("ip101.ip-54-37-91.eu", 50002, "ssl"),
- N_034("electrum2.villocq.com", 50002, "ssl"),
- N_035("dedi.jochen-hoenicke.de", 50002, "ssl"),
- N_036("174.138.11.174", 50002, "ssl"),
- N_037("tomscryptos.com", 50002, "ssl"),
- N_038("elec.luggs.co", 443, "ssl"),
- N_039("ip239.ip-54-36-234.eu", 50002, "ssl"),
- N_040("bitcoins.sk", 50002, "ssl"),
- N_041("btc.cihar.com", 50002, "ssl"),
- N_042("e-x.not.fyi", 50002, "ssl"),
- N_043("ip120.ip-54-37-91.eu", 50002, "ssl"),
- N_044("electrum.villocq.com", 50002, "ssl"),
- N_045("electrum.anduck.net", 50012, "ssl"),
- N_046("technetium.network", 50002, "ssl"),
- N_047("electrum.coinucopia.io", 50002, "ssl"),
- N_048("currentlane.lovebitco.in", 50002, "ssl"),
- N_049("dimon.trimon.de", 50002, "ssl"),
- N_050("rbx.curalle.ovh", 50002, "ssl"),
- N_051("btc.gravitech.net", 50002, "ssl"),
- N_052("hetzner01.fischl-online.de", 50002, "ssl"),
- N_053("fn.48.org", 50002, "ssl"),
- N_054("185.64.116.15", 50002, "ssl"),
- N_055("kirsche.emzy.de", 50002, "ssl"),
- N_056("109.192.105.174", 50002, "ssl"),
- N_057("fedaykin.goip.de", 50002, "ssl"),
- N_058("vps.hsmiths.com", 50002, "ssl"),
- N_059("104.250.141.242", 50002, "ssl"),
- N_060("electrum.qtornado.com", 50002, "ssl"),
- N_061("electrum-server.ninja", 50002, "ssl"),
- N_062("electrum2.eff.ro", 50002, "ssl"),
- N_063("electrum.hsmiths.com", 995, "ssl"),
- N_064("electrum.hsmiths.com", 50002, "ssl"),
- N_065("139.162.14.142", 50002, "ssl"),
- N_066("electrum.eff.ro", 50002, "ssl"),
- N_067("electrum.taborsky.cz", 50002, "ssl"),
- N_068("electrum.festivaldelhumor.org", 50002, "ssl"),
- N_069("electrum.petrkr.net", 50002, "ssl"),
- N_070("us.electrum.be", 50002, "ssl"),
- N_071("bitcoin-node.org", 50002, "ssl"),
- N_072("vmd27610.contaboserver.net", 50002, "ssl"),
- N_073("electrumx.soon.it", 50002, "ssl"),
- N_074("vmd30612.contaboserver.net", 50002, "ssl"),
- N_075("enode.duckdns.org", 50002, "ssl"),
- N_076("81-7-13-84.blue.kundencontroller.de", 50002, "ssl"),
- N_077("electrum.scumm.it", 50002, "ssl"),
- N_078("helicarrier.bauerj.eu", 50002, "ssl"),
- N_079("tardis.bauerj.eu", 50002, "ssl"),
- N_080("such.ninja", 50002, "ssl"),
- N_081("electrum.be", 50002, "ssl"),
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java b/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java
deleted file mode 100644
index 80f0e11d56..0000000000
--- a/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java
+++ /dev/null
@@ -1,824 +0,0 @@
-package com.tangem.domain.wallet.btc;
-
-import android.net.Uri;
-import android.text.InputFilter;
-import android.util.Log;
-
-import com.tangem.data.network.ServerApiCommon;
-import com.tangem.tangemcard.reader.CardProtocol;
-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.tangemcard.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.tangemcard.tasks.SignTask;
-import com.tangem.util.CryptoUtil;
-import com.tangem.util.DecimalDigitsInputFilter;
-import com.tangem.util.DerEncodingUtil;
-import com.tangem.tangemcard.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;
-import org.json.JSONObject;
-
-import java.io.ByteArrayOutputStream;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class BtcEngine extends CoinEngine {
-
- private static final String TAG = BtcEngine.class.getSimpleName();
-
- public BtcData coinData = null;
-
- public BtcEngine(TangemContext context) throws Exception {
- super(context);
- if (context.getCoinData() == null) {
- coinData = new BtcData();
- context.setCoinData(coinData);
- } else if (context.getCoinData() instanceof BtcData) {
- coinData = (BtcData) context.getCoinData();
- } else {
- throw new Exception("Invalid type of Blockchain data for BtcEngine");
- }
- }
-
- public BtcEngine() {
- super();
- }
-
- private static int getDecimals() {
- return 8;
- }
-
-
- private void checkBlockchainDataExists() throws Exception {
- if (coinData == null) throw new Exception("No blockchain data");
- }
-
- @Override
- public boolean awaitingConfirmation() {
- if (coinData == null) return false;
- return coinData.getBalanceUnconfirmed() != 0;
- }
-
- @Override
- public String getBalanceHTML() {
- Amount balance = getBalance();
- if (balance != null) {
- return balance.toDescriptionString(getDecimals());
- } else {
- return "";
- }
- }
-
- @Override
- public String getBalanceCurrency() {
- return "BTC";
- }
-
- @Override
- public String getOfflineBalanceHTML() {
- InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
- Amount offlineAmount = convertToAmount(offlineInternalAmount);
- return offlineAmount.toDescriptionString(getDecimals());
- }
-
- @Override
- public boolean isBalanceNotZero() {
- if (coinData == null) return false;
- if (coinData.getBalanceInInternalUnits() == null) return false;
- return coinData.getBalanceInInternalUnits().notZero();
- }
-
- @Override
- public boolean hasBalanceInfo() {
- if (coinData == null) return false;
- return coinData.hasBalanceInfo();
- }
-
-
- @Override
- 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 getFeeCurrency() {
- return "BTC";
- }
-
- @Override
- public boolean validateAddress(String address) {
- if (address == null || address.isEmpty()) {
- return false;
- }
-
- if (address.length() < 25) {
- return false;
- }
-
- if (address.length() > 35) {
- return false;
- }
-
- if (!address.startsWith("1") && !address.startsWith("2") && !address.startsWith("3") && !address.startsWith("n") && !address.startsWith("m")) {
- return false;
- }
-
- byte[] decAddress = Base58.decodeBase58(address);
-
- if (decAddress == null || decAddress.length == 0) {
- return false;
- }
-
- byte[] rip = new byte[21];
- for (int i = 0; i < 21; ++i) {
- rip[i] = decAddress[i];
- }
-
- byte[] kcv = CryptoUtil.doubleSha256(rip);
-
- for (int i = 0; i < 4; ++i) {
- if (kcv[i] != decAddress[21 + i])
- return false;
- }
-
- if (ctx.getBlockchain() != Blockchain.BitcoinTestNet && ctx.getBlockchain() != Blockchain.Bitcoin) {
- return false;
- }
-
- if (ctx.getBlockchain() == Blockchain.BitcoinTestNet && (address.startsWith("1") || address.startsWith("3"))) {
- return false;
- }
-
- return true;
- }
-
-
- @Override
- public boolean isNeedCheckNode() {
- return true;
- }
-
- @Override
- public Uri getShareWalletUriExplorer() {
- return Uri.parse((ctx.getBlockchain() == Blockchain.Bitcoin ? "https://blockchain.info/address/" : "https://testnet.blockchain.info/address/") + ctx.getCoinData().getWallet());
- }
-
- @Override
- public Uri getShareWalletUri() {
- if (ctx.getCard().getDenomination() != null) {
- return Uri.parse("bitcoin:" + ctx.getCoinData().getWallet() + "?amount=" + convertToAmount(convertToInternalAmount(ctx.getCard().getDenomination())).toValueString(8));
- } else {
- return Uri.parse("bitcoin:" + ctx.getCoinData().getWallet());
- }
- }
-
- @Override
- public InputFilter[] getAmountInputFilters() {
- return new InputFilter[]{new DecimalDigitsInputFilter(getDecimals())};
- }
-
- @Override
- public boolean checkNewTransactionAmount(Amount amount) {
- if (coinData == null) return false;
- if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) {
- return false;
- }
- return true;
- }
-
- @Override
- public boolean checkNewTransactionAmountAndFee(Amount amountValue, Amount feeValue, Boolean isIncludeFee) {
- InternalAmount fee;
- InternalAmount amount;
-
- try {
- checkBlockchainDataExists();
- amount = convertToInternalAmount(amountValue);
- fee = convertToInternalAmount(feeValue);
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
-
- if (fee == null || amount == null)
- return false;
-
- if (fee.isZero() || amount.isZero())
- return false;
-
- if (isIncludeFee && (amount.compareTo(coinData.getBalanceInInternalUnits()) > 0 || amount.compareTo(fee) < 0))
- return false;
-
- if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits()) > 0)
- return false;
-
- return true;
- }
-
- @Override
- public boolean validateBalance(BalanceValidator balanceValidator) {
- try {
- if (((ctx.getCard().getOfflineBalance() == null) && !ctx.getCoinData().isBalanceReceived()) || (!ctx.getCoinData().isBalanceReceived() && (ctx.getCard().getRemainingSignatures() != ctx.getCard().getMaxSignatures()))) {
- balanceValidator.setScore(0);
- balanceValidator.setFirstLine("Unknown balance");
- balanceValidator.setSecondLine("Balance cannot be verified. Swipe down to refresh.");
- return false;
- }
-
- // Workaround before new back-end
-// if (card.getRemainingSignatures() == card.getMaxSignatures()) {
-// firstLine = "Verified balance";
-// secondLine = "Balance confirmed in blockchain. ";
-// secondLine += "Verified note identity. ";
-// return;
-// }
-
- if (coinData.getBalanceUnconfirmed() != 0) {
- balanceValidator.setScore(0);
- balanceValidator.setFirstLine("Transaction in progress");
- balanceValidator.setSecondLine("Wait for confirmation in blockchain");
- return false;
- }
-
- if (coinData.isBalanceReceived() && coinData.isBalanceEqual()) {
- balanceValidator.setScore(100);
- balanceValidator.setFirstLine("Verified balance");
- balanceValidator.setSecondLine("Balance confirmed in blockchain");
- if (coinData.getBalanceInInternalUnits().isZero()) {
- balanceValidator.setFirstLine("Empty wallet");
- balanceValidator.setSecondLine("");
- }
- }
-
- // rule 4 TODO: need to check SignedHashed against number of outputs in blockchain
-// if((card.getRemainingSignatures() != card.getMaxSignatures()) && card.getBalance() != 0)
-// {
-// score = 80;
-// firstLine = "Unguaranteed balance";
-// secondLine = "Potential unsent transaction. Redeem immediately if accept. ";
-// return;
-// }
-
- 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. ");
- }
-
-// if(card.getFailedBalanceRequestCounter()!=0) {
-// score -= 5 * card.getFailedBalanceRequestCounter();
-// secondLine += "Not all nodes have returned balance. Swipe down or tap again. ";
-// if(score <= 0)
-// return;
-// }
-
- //
-// if(card.isBalanceReceived() && !card.isBalanceEqual()) {
-// score = 0;
-// firstLine = "Disputed balance";
-// secondLine += " Cannot obtain trusted balance at the moment. Try to tap and check this banknote later.";
-// return;
-// }
-
- return true;
- }
- catch (Exception e)
- {
- e.printStackTrace();
- return false;
- }
- }
-
- @Override
- public Amount getBalance() {
- if (!hasBalanceInfo()) return null;
- return convertToAmount(coinData.getBalanceInInternalUnits());
- }
-
- @Override
- public String evaluateFeeEquivalent(String 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 "";
- Amount balance = getBalance();
- if (balance == null) return "";
- return balance.toEquivalentString(coinData.getRate());
- }
-
- @Override
- public String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
- byte netSelectionByte;
- switch (ctx.getBlockchain()) {
- case Bitcoin:
- netSelectionByte = (byte) 0x00; //0 - MainNet 0x6f - TestNet
- break;
- default:
- netSelectionByte = (byte) 0x6f; //0 - MainNet 0x6f - TestNet
- break;
- }
-
- byte hash1[] = Util.calculateSHA256(pkUncompressed);
- byte hash2[] = Util.calculateRIPEMD160(hash1);
-
- ByteBuffer BB = ByteBuffer.allocate(hash2.length + 1);
-
- BB.put(netSelectionByte);
- BB.put(hash2);
-
- byte hash3[] = Util.calculateSHA256(BB.array());
- byte hash4[] = Util.calculateSHA256(hash3);
-
- BB = ByteBuffer.allocate(hash2.length + 5);
- BB.put(netSelectionByte); //BB.put((byte) 0x6f);
- BB.put(hash2);
- BB.put(hash4[0]);
- BB.put(hash4[1]);
- BB.put(hash4[2]);
- BB.put(hash4[3]);
-
- return org.bitcoinj.core.Base58.encode(BB.array());
- }
-
- @Override
- public Amount convertToAmount(InternalAmount internalAmount) {
- BigDecimal d = internalAmount.divide(new BigDecimal("100000000"));
- return new Amount(d, getBalanceCurrency());
- }
-
- @Override
- public Amount convertToAmount(String strAmount, String currency) {
- return new Amount(strAmount, currency);
- }
-
- @Override
- public InternalAmount convertToInternalAmount(Amount amount) {
- BigDecimal d = amount.multiply(new BigDecimal("100000000"));
- return new InternalAmount(d, "Satoshi");
- }
-
- @Override
- public InternalAmount convertToInternalAmount(byte[] bytes) {
- 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");
- }
-
- @Override
- public byte[] convertToByteArray(InternalAmount internalAmount) {
- byte[] bytes = Util.longToByteArray(internalAmount.longValueExact());
- byte[] reversed = new byte[bytes.length];
- for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
- return reversed;
- }
-
- @Override
- public CoinData createCoinData() {
- return new BtcData();
- }
-
- @Override
- public String getUnspentInputsDescription() {
- return coinData.getUnspentInputsDescription();
- }
-
- @Override
- public SignTask.PaymentToSign constructPayment(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception {
- final ArrayList unspentOutputs;
- checkBlockchainDataExists();
-
- String myAddress = ctx.getCoinData().getWallet();
- byte[] pbKey = ctx.getCard().getWalletPublicKey();
-
- // Build script for our address
- List rawTxList = coinData.getUnspentTransactions();
- byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
-
- // Collect unspent
- unspentOutputs = BTCUtils.getOutputs(rawTxList, outputScriptWeAreAbleToSpend);
-
- long fullAmount = 0;
- for (int i = 0; i < unspentOutputs.size(); ++i) {
- fullAmount += unspentOutputs.get(i).value;
- }
-
- long fees = convertToInternalAmount(feeValue).longValueExact();
- long amount = convertToInternalAmount(amountValue).longValueExact();
- long change = fullAmount - amount;
- if (IncFee) {
- amount = amount - fees;
- } else {
- change = change - fees;
- }
-
- final long amountFinal = amount;
- final long changeFinal = change;
-
- if (amount + fees > fullAmount) {
- throw new CardProtocol.TangemException_WrongAmount(String.format("Balance (%d) < change (%d) + amount (%d)", fullAmount, change, amount));
- }
-
- final byte[][] txForSign = new byte[unspentOutputs.size()][];
- final byte[][] bodyDoubleHash = new byte[unspentOutputs.size()][];
- final byte[][] bodyHash = new byte[unspentOutputs.size()][];
-
- for (int i = 0; i < unspentOutputs.size(); ++i) {
- txForSign[i] = BTCUtils.buildTXForSign(myAddress, targetAddress, myAddress, unspentOutputs, i, amount, change);
- bodyHash[i] = Util.calculateSHA256(txForSign[i]);
- bodyDoubleHash[i] = Util.calculateSHA256(bodyHash[i]);
- }
-
- return new SignTask.PaymentToSign() {
-
- @Override
- public boolean isSigningMethodSupported(TangemCard.SigningMethod signingMethod) {
- return signingMethod == TangemCard.SigningMethod.Sign_Hash || signingMethod == TangemCard.SigningMethod.Sign_Raw;
- }
-
- @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!");
- for (int i = 0; i < unspentOutputs.size(); ++i) {
- dataForSign[i] = bodyDoubleHash[i];
- }
- return dataForSign;
- }
-
- @Override
- public byte[] getRawDataToSign() throws Exception {
- ByteArrayOutputStream bs = new ByteArrayOutputStream();
- for (int i = 0; i < txForSign.length; i++) {
- if (i != 0 && txForSign[0].length != txForSign[i].length)
- throw new Exception("Hashes length must be identical!");
- bs.write(txForSign[i]);
- }
-
- return bs.toByteArray();
- }
-
- @Override
- public String getHashAlgToSign() {
- return "sha-256x2";
- }
-
- @Override
- public byte[] getIssuerTransactionSignature(byte[] dataToSignByIssuer) throws Exception {
- throw new Exception("Issuer validation not supported!");
- }
-
- @Override
- public byte[] onSignCompleted(byte[] signFromCard) throws Exception {
- for (int i = 0; i < unspentOutputs.size(); ++i) {
- BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, i * 64, 32 + i * 64));
- BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64));
- s = CryptoUtil.toCanonicalised(s);
-
- unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDer(r, s, pbKey);
- }
-
- byte[] txForSend = BTCUtils.buildTXForSend(targetAddress, myAddress, unspentOutputs, amountFinal, changeFinal);
- notifyOnNeedSendPayment(txForSend);
- return txForSend;
- }
- };
- }
-
- @Override
- public void requestBalanceAndUnspentTransactions(BlockchainRequestsCallbacks blockchainRequestsCallbacks) {
- final ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
-
- ServerApiElectrum.ElectrumRequestDataListener electrumListener = new ServerApiElectrum.ElectrumRequestDataListener() {
- @Override
- public void onSuccess(ElectrumRequest electrumRequest) {
- Log.i(TAG, "onSuccess: "+electrumRequest.getMethod());
- if (electrumRequest.isMethod(ElectrumRequest.METHOD_GetBalance)) {
- try {
- String walletAddress = electrumRequest.getParams().getString(0);
- if (!walletAddress.equals(coinData.getWallet())) {
- // todo - check
- throw new Exception("Invalid wallet address in answer!");
- }
- Long confBalance = electrumRequest.getResult().getLong("confirmed");
- Long unconfirmedBalance = electrumRequest.getResult().getLong("unconfirmed");
- coinData.setBalanceReceived(true);
- coinData.setBalanceConfirmed(confBalance);
- coinData.setBalanceUnconfirmed(unconfirmedBalance);
- coinData.setValidationNodeDescription(serverApiElectrum.getValidationNodeDescription());
- } catch (JSONException e) {
- e.printStackTrace();
- Log.e(TAG, "FAIL METHOD_GetBalance JSONException");
- } catch (Exception e) {
- e.printStackTrace();
- Log.e(TAG, "FAIL METHOD_GetBalance Exception");
- }
- } else if (electrumRequest.isMethod(ElectrumRequest.METHOD_ListUnspent)) {
- try {
- String walletAddress = electrumRequest.getParams().getString(0);
- JSONArray jsUnspentArray = electrumRequest.getResultArray();
- try {
- coinData.getUnspentTransactions().clear();
- for (int i = 0; i < jsUnspentArray.length(); i++) {
- JSONObject jsUnspent = jsUnspentArray.getJSONObject(i);
- BtcData.UnspentTransaction trUnspent = new BtcData.UnspentTransaction();
- trUnspent.txID = jsUnspent.getString("tx_hash");
- trUnspent.Amount = jsUnspent.getInt("value");
- trUnspent.Height = jsUnspent.getInt("height");
- coinData.getUnspentTransactions().add(trUnspent);
- }
- } catch (JSONException e) {
- e.printStackTrace();
- Log.e(TAG, "FAIL METHOD_ListUnspent JSONException");
- }
-
- for (int i = 0; i < jsUnspentArray.length(); i++) {
- JSONObject jsUnspent = jsUnspentArray.getJSONObject(i);
- Integer height = jsUnspent.getInt("height");
- String hash = jsUnspent.getString("tx_hash");
- if (height != -1) {
- if (blockchainRequestsCallbacks.allowAdvance()) {
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getTransaction(walletAddress, hash));
- } else {
- ctx.setError("Terminated by user");
- }
- }
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- } else if (electrumRequest.isMethod(ElectrumRequest.METHOD_GetTransaction)) {
- try {
- String txHash = electrumRequest.txHash;
- String raw = electrumRequest.getResultString();
- for (BtcData.UnspentTransaction tx : coinData.getUnspentTransactions()) {
- if (tx.txID.equals(txHash))
- tx.Raw = raw;
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- 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(electrumRequest.getError());
- if (serverApiElectrum.isRequestsSequenceCompleted()) {
- blockchainRequestsCallbacks.onComplete(false);//serverApiElectrum.isErrorOccurred(), serverApiElectrum.getError());
- }else{
- blockchainRequestsCallbacks.onProgress();
- }
- }
- };
-
- serverApiElectrum.setElectrumRequestData(electrumListener);
-
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.checkBalance(coinData.getWallet()));
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.listUnspent(coinData.getWallet()));
- }
-
- protected Integer calculateEstimatedTransactionSize(String outputAddress, String outAmount) {
- //todo - правильней было бы использовать constructPayment
- try {
-// String myAddress = coinData.getWallet();
-// byte[] pbKey = ctx.getCard().getWalletPublicKey();
-// byte[] pbComprKey = ctx.getCard().getWalletPublicKeyRar();
-//
-// // build script for our address
-// List rawTxList = coinData.getUnspentTransactions();
-// byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
-//
-// // collect unspent
-// ArrayList unspentOutputs = BTCUtils.getOutputs(rawTxList, outputScriptWeAreAbleToSpend);
-//
-// Long fullAmount = 0L;
-// for (int i = 0; i < unspentOutputs.size(); i++) {
-// fullAmount += unspentOutputs.get(i).value;
-// }
-//
-// // get first unspent
-//// val outPut = unspentOutputs[0]
-//// val outPutIndex = outPut.outputIndex
-//
-// // get prev TX id;
-//// val prevTXID = rawTxList[0].txID//"f67b838d6e2c0c587f476f583843e93ff20368eaf96a798bdc25e01f53f8f5d2";
-//
-// Long fees = FormatUtil.ConvertStringToLong("0.00");
-// Long amount = FormatUtil.ConvertStringToLong(outAmount);
-// amount -= fees;
-//
-// Long change = fullAmount - fees - amount;
-//
-// if (amount + fees > fullAmount) {
-// throw new Exception(String.format("Balance (%d) < amount (%d) + (%d)", fullAmount, change, amount));
-// }
-//
-// byte[][] hashesForSign = new byte[unspentOutputs.size()][];
-//
-// for (int i = 0; i < unspentOutputs.size(); i++) {
-// byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, myAddress, unspentOutputs, i, amount, change);
-// byte[] hashData = Util.calculateSHA256(newTX);
-// byte[] doubleHashData = Util.calculateSHA256(hashData);
-//// Log.e("TX_BODY_1", BTCUtils.toHex(newTX))
-//// Log.e("TX_HASH_1", BTCUtils.toHex(hashData))
-//// Log.e("TX_HASH_2", BTCUtils.toHex(doubleHashData))
-//
-//// unspentOutputs[i].bodyDoubleHash = doubleHashData
-//// unspentOutputs[i].bodyHash = hashData
-// hashesForSign[i] = doubleHashData;
-// }
-//
-// byte[] signFromCard = new byte[64 * unspentOutputs.size()];
-//
-// for (int i = 0; i < unspentOutputs.size(); i++) {
-// BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, i * 64, 32 + i * 64));
-// BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64));
-// byte[] encodingSign = DerEncodingUtil.packSignDer(r, s, pbKey);
-// unspentOutputs.get(i).scriptForBuild = encodingSign;
-// }
-//
-// byte[] realTX = BTCUtils.buildTXForSend(outputAddress, myAddress, unspentOutputs, amount, change);
-
- SignTask.PaymentToSign ps=constructPayment(new Amount(outAmount, getBalanceCurrency()),new Amount("0.00",getFeeCurrency()), true, outputAddress );
- OnNeedSendPayment onNeedSendPaymentBackup=onNeedSendPayment;
- onNeedSendPayment=(tx)->{}; // empty function to bypass exception
-
- byte[][] hashesToSign=ps.getHashesToSign();
- byte[] signFromCard = new byte[64 * hashesToSign.length];
- byte[] txForSend=ps.onSignCompleted(signFromCard);
- onNeedSendPayment=onNeedSendPaymentBackup;
- 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));
-//
-// return realTX.length;
-
- } catch (Exception e) {
- e.printStackTrace();
- Log.e(TAG, "Can't calculate transaction size -> use default!");
- return 256;
- }
- }
-
- @Override
- public void requestFee(BlockchainRequestsCallbacks blockchainRequestsCallbacks, String targetAddress, Amount amount) throws Exception {
- final int calcSize = calculateEstimatedTransactionSize(targetAddress, amount.toValueString());
- Log.e(TAG, String.format("Estimated tx size %d", calcSize));
- coinData.minFee = null;
- coinData.maxFee = null;
- coinData.normalFee = null;
-
- final ServerApiCommon serverApiCommon = new ServerApiCommon();
-
- final ServerApiCommon.EstimateFeeListener estimateFeeListener = new ServerApiCommon.EstimateFeeListener() {
- @Override
- public void onSuccess(int blockCount, String estimateFeeResponse) {
- BigDecimal fee = new BigDecimal(estimateFeeResponse); // BTC per 1 kb
-
- if (fee.equals(BigDecimal.ZERO)) {
- if (blockchainRequestsCallbacks.allowAdvance()) {
- serverApiCommon.estimateFee(blockCount);
- }
- return;
- }
-
- if (calcSize != 0) {
- fee = fee.multiply(new BigDecimal(calcSize)).divide(new BigDecimal(1024), BigDecimal.ROUND_DOWN); // per Kb -> per byte
- } else {
- if (blockchainRequestsCallbacks.allowAdvance()) {
- serverApiCommon.estimateFee(blockCount);
- }
- return;
- }
-
- fee = fee.setScale(8, RoundingMode.DOWN);
-
- switch (blockCount) {
- case ServerApiCommon.ESTIMATE_FEE_MINIMAL:
- coinData.minFee = new CoinEngine.Amount(fee, getFeeCurrency());
- break;
- case ServerApiCommon.ESTIMATE_FEE_NORMAL:
- coinData.normalFee = new CoinEngine.Amount(fee, getFeeCurrency());
- break;
- case ServerApiCommon.ESTIMATE_FEE_PRIORITY:
- coinData.maxFee = new CoinEngine.Amount(fee, getFeeCurrency());
- break;
- }
-
- if(coinData.minFee!=null && coinData.normalFee!=null && coinData.maxFee!=null ) {
- blockchainRequestsCallbacks.onComplete(true);
- }else{
- blockchainRequestsCallbacks.onProgress();
- }
- }
-
- @Override
- public void onFail(int blockCount, String message) {
- // TODO - add fail counter to terminate after NNN tries
- if (blockchainRequestsCallbacks.allowAdvance()) {
- serverApiCommon.estimateFee(blockCount);
- return;
- }
- ctx.setError(ctx.getContext().getString(R.string.cannot_calculate_fee_wrong_data_received_from_node));
- blockchainRequestsCallbacks.onComplete(false);
- }
- };
- serverApiCommon.setEstimateFee(estimateFeeListener);
-
- serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_PRIORITY);
- serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_NORMAL);
- serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_MINIMAL);
-
- }
-
- @Override
- public void requestSendTransaction(BlockchainRequestsCallbacks blockchainRequestsCallbacks, byte[] txForSend) {
- final ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
- final String txStr = BTCUtils.toHex(txForSend);
-
- ServerApiElectrum.ElectrumRequestDataListener electrumListener = new ServerApiElectrum.ElectrumRequestDataListener() {
- @Override
- public void onSuccess(ElectrumRequest electrumRequest) {
- if (electrumRequest.isMethod(ElectrumRequest.METHOD_SendTransaction)) {
- try {
- String resultString = electrumRequest.getResultString();
- if (resultString == null || resultString.isEmpty()) {
- ctx.setError("Rejected by node: " + electrumRequest.getError());
- blockchainRequestsCallbacks.onComplete(false);
- }else {
- ctx.setError(null);
- blockchainRequestsCallbacks.onComplete(true);
- }
- } catch (Exception e) {
- if (e.getMessage() != null) {
- ctx.setError(e.getMessage());
- blockchainRequestsCallbacks.onComplete(false);
- } else {
- ctx.setError(e.getClass().getName());
- blockchainRequestsCallbacks.onComplete(false);
- }
- }
- }
- }
-
- @Override
- public void onFail(ElectrumRequest electrumRequest) {
- ctx.setError(electrumRequest.getError());
- blockchainRequestsCallbacks.onComplete(false);
- }
- };
- serverApiElectrum.setElectrumRequestData(electrumListener);
-
-
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.broadcast(ctx.getCoinData().getWallet(), txStr));
-
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/ltc/LitecoinNode.kt b/app/src/main/java/com/tangem/domain/wallet/ltc/LitecoinNode.kt
deleted file mode 100644
index 0d7ff8c172..0000000000
--- a/app/src/main/java/com/tangem/domain/wallet/ltc/LitecoinNode.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.tangem.domain.wallet.ltc
-
-enum class LitecoinNode(val host: String, val port: Int, val proto: String) {
- N_001("node.ispol.sk", 50004, "ssl"),
- N_002("electrum-ltc.klippb.org", 50002, "ssl"),
- N_003("backup.electrum-ltc.org", 443, "ssl"),
- N_004("electrum-ltc.petrkr.net", 60002, "ssl"),
- N_005("technetium.network", 50003, "ssl"),
- N_006("167.99.146.166", 50002, "ssl"),
- N_007("electrum-ltc.bysh.me", 50002, "ssl"),
- N_008("e-3.claudioboxx.com", 50004, "ssl"),
- N_009("electrum-ltc.wilv.in", 50002, "ssl"),
- N_010("ltc.rentonisk.com", 50002, "ssl"),
- N_011("e-1.claudioboxx.com", 50004, "ssl"),
- N_012("electrum.ltc.xurious.com", 50002, "ssl"),
- N_013("ltc01.knas.systems", 50004, "ssl"),
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/CreateNewWalletActivity.kt b/app/src/main/java/com/tangem/presentation/activity/CreateNewWalletActivity.kt
deleted file mode 100644
index f7f06b0b4a..0000000000
--- a/app/src/main/java/com/tangem/presentation/activity/CreateNewWalletActivity.kt
+++ /dev/null
@@ -1,210 +0,0 @@
-package com.tangem.presentation.activity
-
-import android.app.Activity
-import android.content.Context
-import android.content.Intent
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.view.View
-import android.widget.ProgressBar
-import android.widget.Toast
-import com.tangem.App
-import com.tangem.Constant
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.asBundle
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.tasks.CreateNewWalletTask
-import com.tangem.tangemcard.util.Util
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.activity_create_new_wallet.*
-
-class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
- companion object {
- fun callingIntent(context: Context, ctx: TangemContext): Intent {
- val intent = Intent(context, CreateNewWalletActivity::class.java)
- intent.putExtra("UID", ctx.card!!.uid)
- intent.putExtra("Card", ctx.card!!.asBundle)
- return intent
- }
- }
-
- private lateinit var ctx: TangemContext
- private lateinit var nfcManager: NfcManager
-
- private var createNewWalletTask: CreateNewWalletTask? = null
- private var lastReadSuccess = true
-
- private var progressBar: ProgressBar? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_create_new_wallet)
-
- nfcManager = NfcManager(this, this)
-
- ctx = TangemContext.loadFromBundle(this, intent.extras)
-
- tvCardId.text = ctx.card!!.cidDescription
-
- progressBar = findViewById(R.id.progressBar)
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- // get IsoDep handle and run cardReader thread
- val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
- val uid = tag.id
- val sUID = Util.byteArrayToHexString(uid)
-// Log.v(TAG, "UID: " + sUID);
-
- if (sUID == ctx.card!!.uid) {
- if (lastReadSuccess) {
- isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 5000
- } else {
- isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
- }
- createNewWalletTask = CreateNewWalletTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
- createNewWalletTask!!.start()
- } else {
-// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
- nfcManager.ignoreTag(isoDep.tag)
- }
-
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
-
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- nfcManager.onPause()
- if (createNewWalletTask != null)
- createNewWalletTask!!.cancel(true)
- super.onPause()
- }
-
- public override fun onStop() {
- // dismiss enable NFC dialog
- nfcManager.onStop()
- if (createNewWalletTask != null)
- createNewWalletTask!!.cancel(true)
- super.onStop()
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- progressBar!!.post {
- progressBar!!.visibility = View.VISIBLE
- progressBar!!.progress = 5
- }
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- createNewWalletTask = null
- if (cardProtocol != null) {
- if (cardProtocol.error == null) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.GREEN)
- val intent = Intent()
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
- setResult(Activity.RESULT_OK, intent)
- finish()
- }
- } else {
- lastReadSuccess = false
- if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- val intent = Intent()
- intent.putExtra("message", "Cannot create wallet. Make sure you enter correct PIN2!")
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card!!.asBundle)
- setResult(Constant.RESULT_INVALID_PIN, intent)
- finish()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- } else {
- progressBar!!.post {
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
- if (!NoExtendedLengthSupportDialog.allReadyShowed) {
- NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
- }
- } else {
- Toast.makeText(baseContext, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
- }
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- }
- }
- }
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
- progressBar!!.post { progressBar!!.progress = progress }
- }
-
- override fun onReadCancel() {
- createNewWalletTask = null
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(this, msec)
- }
-
- override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
- }
-
- override fun onReadAfterRequest() {
- WaitSecurityDelayDialog.onReadAfterRequest(this)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.kt b/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.kt
deleted file mode 100644
index d74f7d1cbe..0000000000
--- a/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.kt
+++ /dev/null
@@ -1,269 +0,0 @@
-package com.tangem.presentation.activity
-
-import android.app.Activity
-import android.content.Context
-import android.content.Intent
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.text.Html
-import android.view.View
-import android.widget.Toast
-import com.tangem.App
-import com.tangem.Constant
-import com.tangem.di.Navigator
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.TangemCard
-import com.tangem.tangemcard.data.asBundle
-import com.tangem.tangemcard.data.loadFromBundle
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.tasks.VerifyCardTask
-import com.tangem.tangemcard.util.Util
-import com.tangem.util.LOG
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.activity_empty_wallet.*
-import javax.inject.Inject
-
-class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
- companion object {
- val TAG: String = EmptyWalletActivity::class.java.simpleName
-
- fun callingIntent(context: Context, ctx: TangemContext): Intent {
- val intent = Intent(context, EmptyWalletActivity::class.java)
- ctx.saveToIntent(intent)
- return intent
- }
- }
-
- private lateinit var nfcManager: NfcManager
- private lateinit var ctx: TangemContext
- private var lastReadSuccess = true
- private var verifyCardTask: VerifyCardTask? = null
- private var requestPIN2Count = 0
-
- @Inject
- internal lateinit var navigator: Navigator
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_empty_wallet)
-
- App.getNavigatorComponent().inject(this)
-
- nfcManager = NfcManager(this, this)
-
- ctx = TangemContext.loadFromBundle(this, intent.extras)
-
- tvIssuer.text = ctx.card!!.issuerDescription
-
- if (ctx.card!!.tokenSymbol.length > 1) {
- val html = Html.fromHtml(ctx.blockchainName)
- tvBlockchain.text = html
- } else
- tvBlockchain.text = ctx.blockchainName
-
- tvCardID.text = ctx.card!!.cidDescription
- imgBlockchain.setImageResource(ctx.blockchain.getImageResource(this, ctx.card!!.tokenSymbol))
-
- if (ctx.card!!.useDefaultPIN1()) {
- imgPIN.setImageResource(R.drawable.unlock_pin1)
- imgPIN.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
- } else {
- imgPIN.setImageResource(R.drawable.lock_pin1)
- imgPIN.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_user_PIN1_code, Toast.LENGTH_LONG).show() }
- }
-
- if (ctx.card!!.pauseBeforePIN2 > 0 && (ctx.card!!.useDefaultPIN2()!! || !ctx.card!!.useSmartSecurityDelay())) {
- imgPIN2orSecurityDelay.setImageResource(R.drawable.timer)
- imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, String.format(getString(R.string.this_banknote_will_enforce), ctx.card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
-
- } else if (ctx.card!!.useDefaultPIN2()!!) {
- imgPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2)
- imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_default_PIN2_code, Toast.LENGTH_LONG).show() }
- } else {
- imgPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2)
- imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_user_PIN2_code, Toast.LENGTH_LONG).show() }
- }
-
- if (ctx.card!!.useDevelopersFirmware()!!) {
- imgDeveloperVersion.setImageResource(R.drawable.ic_developer_version)
- imgDeveloperVersion.visibility = View.VISIBLE
- imgDeveloperVersion.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.unlocked_banknote_only_development_use, Toast.LENGTH_LONG).show() }
- } else
- imgDeveloperVersion.visibility = View.INVISIBLE
-
- // set listeners
- btnNewWallet.setOnClickListener {
- requestPIN2Count = 0
- val intent = Intent(baseContext, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
- intent.putExtra("UID", ctx.card!!.uid)
- intent.putExtra("Card", ctx.card!!.asBundle)
- startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2)
- }
- }
-
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- super.onPause()
- nfcManager.onPause()
- }
-
- public override fun onStop() {
- super.onStop()
- nfcManager.onStop()
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- if (requestCode == Constant.REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY) {
- if (resultCode == Activity.RESULT_OK) {
-
- if (data != null) {
- data.putExtra("modification", "updateAndViewCard")
- data.putExtra("updateDelay", 0)
- setResult(Activity.RESULT_OK, data)
- }
- finish()
- } else {
- if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
- val updatedCard = TangemCard(data.getStringExtra("UID"))
- updatedCard.loadFromBundle(data.getBundleExtra("Card"))
- ctx.card = updatedCard
- }
- if (resultCode == Constant.RESULT_INVALID_PIN && requestPIN2Count < 2) {
- requestPIN2Count++
- val intent = Intent(baseContext, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
- intent.putExtra("UID", ctx.card!!.uid)
- intent.putExtra("Card", ctx.card!!.asBundle)
- startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2)
- return
- }
- }
- setResult(resultCode, data)
- finish()
- } else if (requestCode == Constant.REQUEST_CODE_REQUEST_PIN2) {
- if (resultCode == Activity.RESULT_OK) {
- navigator.showCreateNewWallet(this, ctx)
- }
- }
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
- val uid = tag.id
- val sUID = Util.byteArrayToHexString(uid)
- if (ctx.card!!.uid != sUID) {
- LOG.d(TAG, "Invalid UID: $sUID")
- nfcManager.ignoreTag(isoDep.tag)
- return
- } else {
- LOG.d(TAG, "UID: $sUID")
- }
-
- if (lastReadSuccess) {
- isoDep.timeout = 1000
- } else {
- isoDep.timeout = 65000
- }
- //lastTag = tag;
- verifyCardTask = VerifyCardTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, App.firmwaresStorage, this)
- verifyCardTask!!.start()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- progressBar!!.post {
- progressBar!!.visibility = View.VISIBLE
- progressBar!!.progress = 5
- }
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- verifyCardTask = null
- if (cardProtocol != null) {
- if (cardProtocol.error == null) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.GREEN)
-// val intent = Intent(this@EmptyWalletActivity, VerifyCardActivity::class.java)
-// intent.putExtra("UID", cardProtocol.card.uid)
-// intent.putExtra("Card", cardProtocol.card.asBundle)
-// startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD)
- //addCard(cardProtocol.getCard());
- }
- } else {
- // remove last UIDs because of error and no card read
- progressBar!!.post {
- lastReadSuccess = false
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
- if (!NoExtendedLengthSupportDialog.allReadyShowed) {
- NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
- }
- } else {
- Toast.makeText(this@EmptyWalletActivity, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
- }
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- }
- }
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
- progressBar!!.post { progressBar!!.progress = progress }
- }
-
- override fun onReadCancel() {
- verifyCardTask = null
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(this, msec)
- }
-
- override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
- }
-
- override fun onReadAfterRequest() {
- WaitSecurityDelayDialog.onReadAfterRequest(this)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt b/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt
deleted file mode 100644
index dd8bc8b525..0000000000
--- a/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt
+++ /dev/null
@@ -1,422 +0,0 @@
-package com.tangem.presentation.activity
-
-import android.Manifest
-import android.app.Activity
-import android.content.Context
-import android.content.Intent
-import android.content.pm.ActivityInfo
-import android.content.pm.PackageManager
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.support.v4.app.ActivityCompat
-import android.support.v4.content.ContextCompat
-import android.support.v7.app.AppCompatActivity
-import android.support.v7.widget.PopupMenu
-import android.util.Log
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
-import android.view.animation.Animation
-import android.view.animation.DecelerateInterpolator
-import android.view.animation.Transformation
-import android.widget.RelativeLayout
-import android.widget.Toast
-import com.scottyab.rootbeer.RootBeer
-import com.tangem.App
-import com.tangem.Constant
-import com.tangem.data.Logger
-import com.tangem.data.network.ServerApiCommon
-import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
-import com.tangem.tangemcard.tasks.ReadCardInfoTask
-import com.tangem.di.Navigator
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.RootFoundDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.TangemCard
-import com.tangem.tangemcard.data.loadFromBundle
-import com.tangem.tangemcard.data.saveToBundle
-import com.tangem.util.CommonUtil
-import com.tangem.util.LOG
-import com.tangem.util.PhoneUtility
-import com.tangem.wallet.BuildConfig
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.activity_main.*
-import java.io.File
-import java.util.*
-import javax.inject.Inject
-
-class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, PopupMenu.OnMenuItemClickListener {
-
- companion object {
- val TAG: String = MainActivity::class.java.simpleName
-
- fun callingIntent(context: Context) = Intent(context, MainActivity::class.java)
- }
-
- private lateinit var nfcManager: NfcManager
- private var zipFile: File? = null
- private var antenna: DeviceNFCAntennaLocation? = null
- private var unsuccessReadCount = 0
- private var lastTag: Tag? = null
- private var readCardInfoTask: ReadCardInfoTask? = null
- private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = null
-
- @Inject
- internal lateinit var navigator: Navigator
-
- override fun onNewIntent(intent: Intent?) {
- super.onNewIntent(intent)
- if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
- val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
- if (tag != null && onNfcReaderCallback != null)
- onNfcReaderCallback!!.onTagDiscovered(tag)
- }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
-
- App.getNavigatorComponent().inject(this)
-
- requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
-
- nfcManager = NfcManager(this, this)
-
- verifyPermissions()
-
- requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
-
- setNfcAdapterReaderCallback(this)
-
- rippleBackgroundNfc.startRippleAnimation()
-
- antenna = DeviceNFCAntennaLocation()
- antenna!!.getAntennaLocation()
-
- // set card orientation
- when (antenna!!.orientation) {
- DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
- ivHandCardHorizontal.visibility = View.VISIBLE
- ivHandCardVertical.visibility = View.GONE
- }
-
- DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
- ivHandCardVertical.visibility = View.VISIBLE
- ivHandCardHorizontal.visibility = View.GONE
- }
- }
-
- // set card z position
- when (antenna!!.z) {
- DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
- DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
- }
-
- // set phone name
- if (antenna!!.fullName != "")
- tvNFCHint.text = String.format(getString(R.string.scan_banknote), antenna!!.fullName)
- else
- tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
-
- animate()
-
- // NFC
- val intent = intent
- if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
- val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
- if (tag != null && onNfcReaderCallback != null) {
- onNfcReaderCallback!!.onTagDiscovered(tag)
- }
- }
-
- // check if root device
- val rootBeer = RootBeer(this)
- if (rootBeer.isRootedWithoutBusyBoxCheck && !BuildConfig.DEBUG)
- RootFoundDialog().show(supportFragmentManager, RootFoundDialog.TAG)
-
- // set listeners
- fab.setOnClickListener { showMenu(it) }
-
- val apiHelper = ServerApiCommon()
- apiHelper.setLastVersionListener { response ->
- try {
- if (response.isNullOrEmpty()) return@setLastVersionListener
- val responseVersionName = response.trim(' ', '\n', '\r', '\t')
- val responseBuildVersion = responseVersionName.split('.').last()
- val appBuildVersion = BuildConfig.VERSION_NAME.split('.').last()
- if (responseBuildVersion.toInt() > appBuildVersion.toInt()) Toast.makeText(this, "There is a new application version: $responseVersionName", Toast.LENGTH_LONG).show()
- } catch (E: Exception) {
- E.printStackTrace()
- }
- }
- apiHelper.requestLastVersion()
- }
-
- private fun verifyPermissions() {
- NfcManager.verifyPermissions(this)
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
- Log.e("QRScanActivity", "User hasn't granted permission to use camera")
- ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), Constant.REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS)
- }
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- when (requestCode) {
- Constant.REQUEST_CODE_SEND_EMAIL -> {
- if (zipFile != null) {
- zipFile!!.delete()
- zipFile = null
- }
- }
- Constant.REQUEST_CODE_ENTER_PIN_ACTIVITY -> {
- if (resultCode == Activity.RESULT_OK && lastTag != null)
- onTagDiscovered(lastTag!!)
- else
- ReadCardInfoTask.resetLastReadInfo()
- }
- }
- super.onActivityResult(requestCode, resultCode, data)
- }
-
- override fun onMenuItemClick(item: MenuItem): Boolean {
- return onOptionsItemSelected(item)
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.menu_main, menu)
- if (BuildConfig.DEBUG) {
- for (i in 0 until menu.size()) menu.getItem(i).isVisible = true
- }
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- val id = item.itemId
- when (id) {
- R.id.sendLogs -> {
- var f: File? = null
- try {
- f = Logger.collectLogs(this)
- if (f != null) {
- LOG.e(TAG, String.format("Collect %d log bytes", f.length()))
- CommonUtil.sendEmail(this, zipFile, TAG, "Logs", PhoneUtility.getDeviceInfo(), arrayOf(f))
- } else {
- LOG.e(TAG, "Can't create temporarily log file")
- }
- } catch (e: Exception) {
- e.printStackTrace()
- } finally {
- if (f != null && f.exists())
- f.delete()
- }
- return true
- }
- R.id.managePIN -> {
- navigator.showPinSave(this, false)
- return true
- }
-
- R.id.managePIN2 -> {
- navigator.showPinSave(this, true)
- return true
- }
-
- R.id.about -> {
- navigator.showLogo(this, false)
- return true
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- // get IsoDep handle and run cardReader thread
- val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
-
- LOG.e(TAG, "setTimeout(" + (1000 + 3000 * unsuccessReadCount) + ")")
- if (unsuccessReadCount < 2) {
- isoDep.timeout = 2000 + 5000 * unsuccessReadCount
- } else {
- isoDep.timeout = 90000
- }
- lastTag = tag
-
- readCardInfoTask = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
- readCardInfoTask!!.start()
-
- LOG.i(TAG, "onTagDiscovered " + Arrays.toString(tag.id))
-
- } catch (e: Exception) {
- e.printStackTrace()
- nfcManager.notifyReadResult(false)
- }
- }
-
- public override fun onResume() {
- super.onResume()
- animate()
- ReadCardInfoTask.resetLastReadInfo()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- nfcManager.onPause()
- readCardInfoTask?.cancel(true)
- super.onPause()
- }
-
- public override fun onStop() {
- // dismiss enable NFC dialog
- nfcManager.onStop()
- readCardInfoTask?.cancel(true)
- super.onStop()
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
-
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- readCardInfoTask = null
- if (cardProtocol != null) {
- if (cardProtocol.error == null) {
- nfcManager.notifyReadResult(true)
- rlProgressBar.post {
- rlProgressBar.visibility = View.GONE
-
- // TODO - ??? remove save and load???
- val cardInfo = Bundle()
- cardInfo.putString("UID", cardProtocol.card.uid)
- val bCard = Bundle()
- cardProtocol.card.saveToBundle(bCard)
- cardInfo.putBundle("Card", bCard)
-
- val uid = cardInfo.getString("UID")
- val card = TangemCard(uid)
- card.loadFromBundle(cardInfo.getBundle("Card"))
-
- val ctx = TangemContext(card)
- when {
- card.status == TangemCard.Status.Loaded -> lastTag?.let {
- val engineCoin = CoinEngineFactory.create(ctx)
- ?: throw CardProtocol.TangemException("Can't create CoinEngine!")
- engineCoin.defineWallet()
- //mCard.setWallet(Blockchain.calculateWalletAddress(mCard, pkUncompressed));
-
- navigator.showLoadedWallet(this, it, ctx)
- }
- card.status == TangemCard.Status.Empty -> navigator.showEmptyWallet(this, ctx)
- card.status == TangemCard.Status.Purged -> Toast.makeText(this, R.string.erased_wallet, Toast.LENGTH_SHORT).show()
- card.status == TangemCard.Status.NotPersonalized -> Toast.makeText(this, R.string.not_personalized, Toast.LENGTH_SHORT).show()
- else -> lastTag?.let { navigator.showLoadedWallet(this, it, ctx) }
- }
- }
-
- } else {
- // remove last UIDs because of error and no card read
- rlProgressBar.post {
- Toast.makeText(this, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
- unsuccessReadCount++
-
- if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN)
- navigator.showPinRequest(this, PinRequestActivity.Mode.RequestPIN.toString())
- else {
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
- if (!NoExtendedLengthSupportDialog.allReadyShowed)
- NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
-
- lastTag = null
- ReadCardInfoTask.resetLastReadInfo()
- nfcManager.notifyReadResult(false)
- }
- }
- }
- }
-
- rlProgressBar.postDelayed({
- try {
- rlProgressBar.visibility = View.GONE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadCancel() {
- readCardInfoTask = null
- ReadCardInfoTask.resetLastReadInfo()
- rlProgressBar.postDelayed({
- try {
- rlProgressBar.visibility = View.GONE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(Objects.requireNonNull(this), msec)
- }
-
- override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(Objects.requireNonNull(this), timeout)
- }
-
- override fun onReadAfterRequest() {
- WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(this))
- }
-
- private fun setNfcAdapterReaderCallback(callback: NfcAdapter.ReaderCallback) {
- onNfcReaderCallback = callback
- }
-
- private fun animate() {
- val lp = llHand.layoutParams as RelativeLayout.LayoutParams
- val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
- val dp = resources.displayMetrics.density
- val lm = dp * (69 + antenna!!.x * 75)
- lp.topMargin = (dp * (-100 + antenna!!.y * 250)).toInt()
- lp2.topMargin = (dp * (-125 + antenna!!.y * 250)).toInt()
- llNfc.layoutParams = lp2
-
- val a = object : Animation() {
- override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
- lp.leftMargin = (lm * interpolatedTime).toInt()
- llHand.layoutParams = lp
- }
- }
- a.duration = 2000
- a.interpolator = DecelerateInterpolator()
- llHand.startAnimation(a)
- }
-
- private fun showMenu(v: View) {
- val popup = PopupMenu(this, v)
- val inflater = popup.menuInflater
- inflater.inflate(R.menu.menu_main, popup.menu)
-
- if (BuildConfig.DEBUG) {
- popup.menu.findItem(R.id.managePIN).isEnabled = true
- popup.menu.findItem(R.id.managePIN2).isEnabled = true
- popup.menu.findItem(R.id.sendLogs).isVisible = true
- }
-
- popup.setOnMenuItemClickListener(this)
- popup.show()
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/PurgeActivity.kt b/app/src/main/java/com/tangem/presentation/activity/PurgeActivity.kt
deleted file mode 100644
index 7930a88062..0000000000
--- a/app/src/main/java/com/tangem/presentation/activity/PurgeActivity.kt
+++ /dev/null
@@ -1,199 +0,0 @@
-package com.tangem.presentation.activity
-
-import android.app.Activity
-import android.content.Context
-import android.content.Intent
-import android.content.pm.ActivityInfo
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.view.View
-import android.widget.Toast
-import com.tangem.App
-import com.tangem.tangemcard.tasks.PurgeTask
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.asBundle
-import com.tangem.tangemcard.util.Util
-import com.tangem.util.LOG
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.activity_purge.*
-
-class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
- companion object {
- val TAG: String = PurgeActivity::class.java.simpleName
- const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
-
- fun callingIntent(context: Context, ctx: TangemContext): Intent {
- val intent = Intent(context, PurgeActivity::class.java)
- ctx.saveToIntent(intent)
- return intent
- }
- }
-
- private lateinit var ctx: TangemContext
- private lateinit var nfcManager: NfcManager
- private var purgeTask: PurgeTask? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_purge)
-
- requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
-
- nfcManager = NfcManager(this, this)
-
- ctx = TangemContext.loadFromBundle(this, intent.extras)
-
- tvCardID.text = ctx.card!!.cidDescription
- progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar.visibility = View.INVISIBLE
- }
-
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- nfcManager.onPause()
- purgeTask?.cancel(true)
- super.onPause()
- }
-
- public override fun onStop() {
- // dismiss enable NFC dialog
- nfcManager.onStop()
- purgeTask?.cancel(true)
- super.onStop()
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- // get IsoDep handle and run cardReader thread
- val isoDep = IsoDep.get(tag) ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
- val uid = tag.id
- val sUID = Util.byteArrayToHexString(uid)
- LOG.d(TAG, "UID: $sUID")
-
- if (sUID == ctx.card!!.uid) {
- isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
- purgeTask = PurgeTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
- purgeTask!!.start()
- } else {
- LOG.d(TAG, "Mismatch card UID (" + sUID + " instead of " + ctx.card.uid + ")")
- nfcManager.ignoreTag(isoDep.tag)
- }
-
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
-
- override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(this, msec)
- }
-
- override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
- }
-
- override fun onReadAfterRequest() {
- WaitSecurityDelayDialog.onReadAfterRequest(this)
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- progressBar.post {
- progressBar.visibility = View.VISIBLE
- progressBar.progress = 5
- }
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- purgeTask = null
-
- if (cardProtocol != null) {
- if (cardProtocol.error == null) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.GREEN)
- val intent = Intent()
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
- setResult(Activity.RESULT_OK, intent)
- finish()
- }
- } else {
- if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- val intent = Intent()
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
- intent.putExtra("message", getString(R.string.cannot_erase_wallet))
- setResult(RESULT_INVALID_PIN, intent)
- finish()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- } else {
- progressBar!!.post {
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
- if (!NoExtendedLengthSupportDialog.allReadyShowed)
- NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
- } else
- Toast.makeText(baseContext, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
-
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- }
- }
- }
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
- progressBar!!.post { progressBar!!.progress = progress }
- }
-
- override fun onReadCancel() {
- purgeTask = null
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt b/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt
deleted file mode 100644
index 0763437609..0000000000
--- a/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt
+++ /dev/null
@@ -1,267 +0,0 @@
-package com.tangem.presentation.activity
-
-import android.app.Activity
-import android.content.Intent
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.view.KeyEvent
-import android.view.View
-import android.widget.ProgressBar
-import android.widget.Toast
-import com.tangem.App
-import com.tangem.Constant
-import com.tangem.domain.wallet.CoinEngine
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.asBundle
-import com.tangem.tangemcard.tasks.SignTask
-import com.tangem.tangemcard.util.Util
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.activity_sign_payment.*
-
-class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
- companion object {
- val TAG: String = SignPaymentActivity::class.java.simpleName
- }
-
- private lateinit var nfcManager: NfcManager
- private lateinit var ctx: TangemContext
-
- private var signPaymentTask: SignTask? = null
-
- private lateinit var amount: CoinEngine.Amount
- private lateinit var fee: CoinEngine.Amount
- private var isIncludeFee = true
- private var outAddressStr: String? = null
- private var lastReadSuccess = true
-
- private var progressBar: ProgressBar? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_sign_payment)
-
- nfcManager = NfcManager(this, this)
-
- ctx = TangemContext.loadFromBundle(this, intent.extras)
-
- amount = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_AMOUNT), intent.getStringExtra(Constant.EXTRA_AMOUNT_CURRENCY))
- fee = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_FEE), intent.getStringExtra(Constant.EXTRA_FEE_CURRENCY))
- isIncludeFee = intent.getBooleanExtra(Constant.EXTRA_FEE_INCLUDED, true)
- outAddressStr = intent.getStringExtra(Constant.EXTRA_TARGET_ADDRESS)
-
- tvCardID.text = ctx.card!!.cidDescription
-
- progressBar = findViewById(R.id.progressBar)
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- }
-
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- nfcManager.onPause()
- if (signPaymentTask != null)
- signPaymentTask!!.cancel(true)
- super.onPause()
- }
-
- public override fun onStop() {
- // dismiss enable NFC dialog
- nfcManager.onStop()
- if (signPaymentTask != null)
- signPaymentTask!!.cancel(true)
- super.onStop()
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- if (requestCode == Constant.REQUEST_CODE_SEND_PAYMENT_) {
- setResult(resultCode, data)
- finish()
- return
- }
- super.onActivityResult(requestCode, resultCode, data)
- }
-
- override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
- when (keyCode) {
- KeyEvent.KEYCODE_BACK -> {
- val intent = Intent()
- setResult(Activity.RESULT_CANCELED, intent)
- finish()
- return true
- }
- }
- return super.onKeyDown(keyCode, event)
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- // get IsoDep handle and run cardReader thread
- val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
- val uid = tag.id
- val sUID = Util.byteArrayToHexString(uid)
-
- if (sUID == ctx.card!!.uid) {
- if (lastReadSuccess) {
- isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 5000
- } else {
- isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
- }
-
- val coinEngine = CoinEngineFactory.create(ctx)
- ?: throw CardProtocol.TangemException("Can't create CoinEngine!")
- coinEngine.setOnNeedSendPayment { tx ->
- if (tx != null) {
- val intent = Intent(this, SendTransactionActivity::class.java)
- ctx.saveToIntent(intent)
- intent.putExtra(Constant.EXTRA_TX, tx)
- startActivityForResult(intent, Constant.REQUEST_CODE_SEND_PAYMENT_)
- }
- }
- val paymentToSign = coinEngine.constructPayment(amount, fee, isIncludeFee, outAddressStr)
-
- signPaymentTask = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, paymentToSign)
- signPaymentTask!!.start()
- } else
- nfcManager.ignoreTag(isoDep.tag)
-
- } catch (e: CardProtocol.TangemException_WrongAmount) {
- try {
- val intent = Intent()
- intent.putExtra("message", getString(R.string.cannot_sign_transaction_wrong_amount))
- intent.putExtra("UID", ctx.card.uid)
- intent.putExtra("Card", ctx.card.asBundle)
- setResult(Activity.RESULT_CANCELED, intent)
- finish()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- progressBar!!.post {
- progressBar!!.visibility = View.VISIBLE
- progressBar!!.progress = 5
- }
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
- progressBar!!.post { progressBar!!.progress = progress }
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- signPaymentTask = null
- if (cardProtocol != null) {
- if (cardProtocol.error == null) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.GREEN)
- }
- } else {
- lastReadSuccess = false
- if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) {
- progressBar!!.post {
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- val intent = Intent()
- intent.putExtra("message", getString(R.string.cannot_sign_transaction_make_sure_you_enter_correct_pin_2))
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
- setResult(Constant.RESULT_INVALID_PIN_, intent)
- finish()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- } else {
- if (cardProtocol.error is CardProtocol.TangemException_WrongAmount) {
- try {
- val intent = Intent()
- intent.putExtra("message", getString(R.string.cannot_sign_transaction_wrong_amount))
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
- setResult(Activity.RESULT_CANCELED, intent)
- finish()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- progressBar!!.post {
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
- if (!NoExtendedLengthSupportDialog.allReadyShowed) {
- NoExtendedLengthSupportDialog.message = getText(R.string.the_nfc_adapter_length_apdu).toString() + "\n" + getText(R.string.the_nfc_adapter_length_apdu_advice).toString()
- NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
- }
- } else {
- Toast.makeText(baseContext, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
- }
- progressBar!!.progress = 100
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- }
- }
- }
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadCancel() {
- signPaymentTask = null
-
- progressBar!!.postDelayed({
- try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(this, msec)
- }
-
- override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
- }
-
- override fun onReadAfterRequest() {
- WaitSecurityDelayDialog.onReadAfterRequest(this)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialog.java b/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialog.java
deleted file mode 100644
index d23cf18cbc..0000000000
--- a/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialog.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.tangem.presentation.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ProgressBar;
-
-import com.tangem.wallet.R;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * Created by dvol on 06.03.2018.
- */
-public class WaitSecurityDelayDialog extends DialogFragment {
- ProgressBar progressBar;
- int msTimeout = 60000, msProgress = 0;
- Timer timer;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
-
- LayoutInflater inflater = getActivity().getLayoutInflater();
-
- // Inflate and set the layout for the dialog
- // Pass null as the parent view because its going in the dialog layout
- View v = inflater.inflate(R.layout.dialog_wait_pin2, null);
-
- progressBar = v.findViewById(R.id.progressBar);
- progressBar.setMax(msTimeout);
- progressBar.setProgress(msProgress);
-
- timer = new Timer();
- timer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- progressBar.post(new Runnable() {
- @Override
- public void run() {
- int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
- if (progress < WaitSecurityDelayDialog.this.progressBar.getMax()) {
- WaitSecurityDelayDialog.this.progressBar.setProgress(progress + 1000);
- }
- }
- });
- }
- }, 1000, 1000);
- return new AlertDialog.Builder(getActivity())
- .setIcon(R.drawable.tangem_logo_small_new)
- .setTitle("Security delay")
- .setView(v)
- .setCancelable(false)
- .create();
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- super.onCancel(dialog);
- }
-
- public void setup(int msTimeout, int msProgress) {
- this.msTimeout = msTimeout;
- this.msProgress = msProgress;
- }
-
- public void setRemainingTimeout(final int msec) {
- progressBar.post(new Runnable() {
- @Override
- public void run() {
- int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
- if (timer != null) {
- // we get delay latency from card for first time - don't change progress by timer, only by card answer
- progressBar.setMax(progress + msec);
- timer.cancel();
- timer = null;
- } else {
- int newProgress = progressBar.getMax() - msec;
- if (newProgress > progress) {
- progressBar.setProgress(newProgress);
- } else {
- progressBar.setMax(progress + msec);
- }
- }
- }
- });
- }
-
- static Timer timerToShowDelayDialog = null;
- static WaitSecurityDelayDialog instance = null;
-
-// public static WaitSecurityDelayDialog getInstance() {
-// if (instance == null) {
-// instance = new WaitSecurityDelayDialog();
-// }
-// return instance;
-// }
-
- private final static int MinRemainingDelayToShowDialog=1000;
- private final static int DelayBeforeShowDialog=5000;
-
- public static void onReadBeforeRequest(final Activity activity, final int timeout) {
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (timerToShowDelayDialog != null || timeout < DelayBeforeShowDialog+MinRemainingDelayToShowDialog) return;
- timerToShowDelayDialog = new Timer();
- timerToShowDelayDialog.schedule(new TimerTask() {
- @Override
- public void run() {
- if (WaitSecurityDelayDialog.instance != null) return;
- instance = new WaitSecurityDelayDialog();
- instance.setup(timeout, DelayBeforeShowDialog);
- instance.setCancelable(false);
- instance.show(activity.getFragmentManager(), "WaitSecurityDelayDialog");
- }
- }, DelayBeforeShowDialog);
- }
- });
- }
-
- public static void onReadAfterRequest(final Activity activity) {
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (timerToShowDelayDialog == null) return;
- timerToShowDelayDialog.cancel();
- timerToShowDelayDialog = null;
- }
- });
- }
-
- public static void onReadWait(final Activity activity, final int msec) {
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (timerToShowDelayDialog != null) {
- timerToShowDelayDialog.cancel();
- timerToShowDelayDialog = null;
- }
-
- if (msec == 0) {
- if (instance != null) {
- instance.dismiss();
- instance = null;
- }
- return;
- }
- if (instance == null) {
- if( msec>MinRemainingDelayToShowDialog ) {
- instance = new WaitSecurityDelayDialog();
- // 1000ms - card delay notification interval
- instance.setup(msec + 1000, 1000);
- instance.setCancelable(false);
- instance.show(activity.getFragmentManager(), "WaitSecurityDelayDialog");
- }
- } else {
- instance.setRemainingTimeout(msec);
- }
- }
- });
- }
-}
diff --git a/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialogNew.kt b/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialogNew.kt
deleted file mode 100644
index 80173180d6..0000000000
--- a/app/src/main/java/com/tangem/presentation/dialog/WaitSecurityDelayDialogNew.kt
+++ /dev/null
@@ -1,132 +0,0 @@
-package com.tangem.presentation.dialog
-
-import android.app.Activity
-import android.app.AlertDialog
-import android.app.Dialog
-import android.os.Bundle
-import android.support.v7.app.AppCompatDialogFragment
-import com.tangem.wallet.R
-import kotlinx.android.synthetic.main.dialog_wait_pin2.*
-import java.util.*
-
-class WaitSecurityDelayDialogNew : AppCompatDialogFragment() {
-
- companion object {
- val TAG: String = WaitSecurityDelayDialogNew::class.java.simpleName
-
- private const val MIN_REMAINING_DELAY_TO_SHOW_DIALOG = 1000
- private const val DELAY_BEFORE_SHOW_DIALOG = 5000
- }
-
- private var msTimeout = 60000
- private var msProgress = 0
- private var timer: Timer? = null
- private var timerToShowDelayDialog: Timer? = null
- private var instance: WaitSecurityDelayDialogNew? = null
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val inflater = activity!!.layoutInflater
- val v = inflater.inflate(R.layout.dialog_wait_pin2, null)
-
- progressBar.max = msTimeout
- progressBar.progress = msProgress
-
- timer = Timer()
- timer!!.scheduleAtFixedRate(object : TimerTask() {
- override fun run() {
- progressBar.post {
- val progress = this@WaitSecurityDelayDialogNew.progressBar.progress
- if (progress < this@WaitSecurityDelayDialogNew.progressBar.max) {
- this@WaitSecurityDelayDialogNew.progressBar.progress = progress + 1000
- }
- }
- }
- }, 1000, 1000)
-
- return AlertDialog.Builder(activity)
- .setIcon(R.drawable.tangem_logo_small_new)
- .setTitle(R.string.security_delay)
- .setView(v)
- .setCancelable(false)
- .create()
- }
-
- fun onReadBeforeRequest(activity: Activity, timeout: Int) {
- activity.runOnUiThread(Runnable {
- if (timerToShowDelayDialog != null || timeout < DELAY_BEFORE_SHOW_DIALOG + MIN_REMAINING_DELAY_TO_SHOW_DIALOG)
- return@Runnable
-
- timerToShowDelayDialog = Timer()
- timerToShowDelayDialog!!.schedule(object : TimerTask() {
- override fun run() {
- if (instance != null) return
- instance = WaitSecurityDelayDialogNew()
- instance!!.setup(timeout, DELAY_BEFORE_SHOW_DIALOG)
- instance!!.isCancelable = false
-// instance.show(activity.fragmentManager, TAG)
- }
- }, DELAY_BEFORE_SHOW_DIALOG.toLong())
- })
- }
-
- fun onReadAfterRequest(activity: Activity) {
- activity.runOnUiThread(Runnable {
- if (timerToShowDelayDialog == null) return@Runnable
- timerToShowDelayDialog!!.cancel()
- timerToShowDelayDialog = null
- })
- }
-
- fun onReadWait(activity: Activity, msec: Int) {
- activity.runOnUiThread(Runnable {
- if (timerToShowDelayDialog != null) {
- timerToShowDelayDialog!!.cancel()
- timerToShowDelayDialog = null
- }
-
- if (msec == 0) {
- if (instance != null) {
- instance!!.dismiss()
- instance = null
- }
- return@Runnable
- }
-
- if (instance == null) {
- if (msec > MIN_REMAINING_DELAY_TO_SHOW_DIALOG) {
- instance = WaitSecurityDelayDialogNew()
- // 1000ms - card delay notification interval
- instance!!.setup(msec + 1000, 1000)
- instance!!.isCancelable = false
-// instance.show(activity.fragmentManager, TAG)
- }
- } else {
- instance!!.setRemainingTimeout(msec)
- }
- })
- }
-
- private fun setup(msTimeout: Int, msProgress: Int) {
- this.msTimeout = msTimeout
- this.msProgress = msProgress
- }
-
- private fun setRemainingTimeout(msec: Int) {
- progressBar.post {
- val progress = this@WaitSecurityDelayDialogNew.progressBar.progress
- if (timer != null) {
- // we get delay latency from card for first time - don't change progress by timer, only by card answer
- progressBar.max = progress + msec
- timer!!.cancel()
- timer = null
- } else {
- val newProgress = progressBar.max - msec
- if (newProgress > progress)
- progressBar.progress = newProgress
- else
- progressBar.max = progress + msec
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/viewmodel/BaseViewModel.kt b/app/src/main/java/com/tangem/presentation/viewmodel/BaseViewModel.kt
deleted file mode 100644
index ea21989952..0000000000
--- a/app/src/main/java/com/tangem/presentation/viewmodel/BaseViewModel.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
-
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.tangem.presentation.viewmodel
-
-import android.arch.lifecycle.MutableLiveData
-import android.arch.lifecycle.ViewModel
-import com.tangem.data.network.exception.Failure
-
-/**
- * Base ViewModel class with default Failure handling.
- * @see ViewModel
- * @see Failure
- */
-abstract class BaseViewModel : ViewModel() {
-
- var failure: MutableLiveData = MutableLiveData()
-
- protected fun handleFailure(failure: Failure) {
- this.failure.value = failure
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/viewmodel/LoadedWalletViewModel.kt b/app/src/main/java/com/tangem/presentation/viewmodel/LoadedWalletViewModel.kt
deleted file mode 100644
index 6442aa5778..0000000000
--- a/app/src/main/java/com/tangem/presentation/viewmodel/LoadedWalletViewModel.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.tangem.presentation.viewmodel
-
-import android.arch.lifecycle.MutableLiveData
-import com.tangem.data.network.exception.Failure
-
-class LoadedWalletViewModel : BaseViewModel() {
-
- private val state: MutableLiveData = MutableLiveData()
-
- fun getState() = state
-
- enum class State {
- ServerError,
- Failed,
- Success
- }
-
- fun connectToken(data: String, data2: String) {
-
- }
-
- private fun handleTokensSaveFailure(failure: Failure) {
- state.value = State.Success
- handleFailure(failure)
- }
-
- private fun handleLoginFailure(failure: Failure) {
- when (failure) {
- is Failure.ServerError -> state.value = State.ServerError
- }
- handleFailure(failure)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/activity/CreateNewWalletActivity.kt b/app/src/main/java/com/tangem/ui/activity/CreateNewWalletActivity.kt
new file mode 100644
index 0000000000..1c78b0f103
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/activity/CreateNewWalletActivity.kt
@@ -0,0 +1,192 @@
+package com.tangem.ui.activity
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.nfc.tech.IsoDep
+import android.os.Bundle
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.asBundle
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.CreateNewWalletTask
+import com.tangem.card_common.util.Util
+import com.tangem.wallet.R
+import kotlinx.android.synthetic.main.activity_create_new_wallet.*
+import kotlinx.android.synthetic.main.layout_progress_horizontal.*
+import kotlinx.android.synthetic.main.layout_touch_card.*
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+
+class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
+
+ companion object {
+ fun callingIntent(context: Context, ctx: TangemContext): Intent {
+ val intent = Intent(context, CreateNewWalletActivity::class.java)
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, ctx.card!!.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, ctx.card!!.asBundle)
+ return intent
+ }
+ }
+
+ private lateinit var nfcManager: NfcManager
+ private lateinit var ctx: TangemContext
+
+ private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
+
+ private var createNewWalletTask: CreateNewWalletTask? = null
+ private var lastReadSuccess = true
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_create_new_wallet)
+
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
+ ctx = TangemContext.loadFromBundle(this, intent.extras)
+
+ // init NFC Antenna
+ nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
+ nfcDeviceAntenna.init()
+
+ tvCardId.text = ctx.card!!.cidDescription
+ progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar.visibility = View.INVISIBLE
+ }
+
+ override fun onTagDiscovered(tag: Tag) {
+ // get IsoDep handle and run cardReader thread
+ val isoDep = IsoDep.get(tag)
+ val uid = tag.id
+ val sUID = Util.byteArrayToHexString(uid)
+
+ if (sUID == ctx.card.uid) {
+ if (lastReadSuccess)
+ isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000
+ else
+ isoDep.timeout = ctx.card.pauseBeforePIN2 + 65000
+
+ createNewWalletTask = CreateNewWalletTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
+ createNewWalletTask?.start()
+ } else
+ nfcManager.ignoreTag(isoDep.tag)
+ }
+
+ public override fun onPause() {
+ createNewWalletTask?.cancel(true)
+ super.onPause()
+ }
+
+ override fun onReadStart(cardProtocol: CardProtocol) {
+ rlProgressBar?.post { rlProgressBar.visibility = View.VISIBLE }
+
+ progressBar?.post {
+ progressBar?.visibility = View.VISIBLE
+ progressBar?.progress = 5
+ }
+ }
+
+ override fun onReadFinish(cardProtocol: CardProtocol?) {
+ createNewWalletTask = null
+ if (cardProtocol != null) {
+ if (cardProtocol.error == null) {
+ rlProgressBar.post { rlProgressBar.visibility = View.GONE }
+
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.GREEN)
+ val intent = Intent()
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
+ setResult(Activity.RESULT_OK, intent)
+ finish()
+ }
+ } else {
+ lastReadSuccess = false
+ if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) {
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ val intent = Intent()
+ intent.putExtra(Constant.EXTRA_MESSAGE, getString(R.string.cannot_create_wallet))
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card!!.asBundle)
+ setResult(Constant.RESULT_INVALID_PIN, intent)
+ finish()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ } else {
+ progressBar?.post {
+ if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
+ if (!NoExtendedLengthSupportDialog.allReadyShowed) {
+ NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+ }
+ } else
+ Toast.makeText(this, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
+
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ }
+ }
+ }
+
+ rlProgressBar.postDelayed({ rlProgressBar?.visibility = View.GONE }, 500)
+
+ progressBar?.postDelayed({
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ }, 500)
+ }
+
+ override fun onReadProgress(protocol: CardProtocol, progress: Int) {
+ progressBar?.post { progressBar?.progress = progress }
+ }
+
+ override fun onReadCancel() {
+ createNewWalletTask = null
+
+ progressBar?.postDelayed({
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ }, 500)
+ }
+
+ override fun onReadWait(msec: Int) {
+ WaitSecurityDelayDialog.onReadWait(this, msec)
+ }
+
+ override fun onReadBeforeRequest(timeout: Int) {
+ WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
+ }
+
+ override fun onReadAfterRequest() {
+ WaitSecurityDelayDialog.onReadAfterRequest(this)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/activity/EmptyWalletActivity.kt b/app/src/main/java/com/tangem/ui/activity/EmptyWalletActivity.kt
new file mode 100644
index 0000000000..0b6abbc166
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/activity/EmptyWalletActivity.kt
@@ -0,0 +1,259 @@
+package com.tangem.ui.activity
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.nfc.tech.IsoDep
+import android.os.Build
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import android.text.Html
+import android.view.View
+import android.widget.Toast
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.di.Navigator
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.asBundle
+import com.tangem.card_android.data.loadFromBundle
+import com.tangem.card_common.data.TangemCard
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.VerifyCardTask
+import com.tangem.card_common.util.Util
+import com.tangem.util.UtilHelper
+import com.tangem.wallet.R
+import kotlinx.android.synthetic.main.activity_empty_wallet.*
+import kotlinx.android.synthetic.main.layout_tangem_card.*
+import javax.inject.Inject
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.di.ToastHelper
+
+class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
+ companion object {
+ val TAG: String = EmptyWalletActivity::class.java.simpleName
+ fun callingIntent(context: Context, ctx: TangemContext): Intent {
+ val intent = Intent(context, EmptyWalletActivity::class.java)
+ ctx.saveToIntent(intent)
+ return intent
+ }
+ }
+
+ @Inject
+ internal lateinit var navigator: Navigator
+ @Inject
+ internal lateinit var toastHelper: ToastHelper
+
+ private lateinit var nfcManager: NfcManager
+ private lateinit var ctx: TangemContext
+
+ private var lastReadSuccess = true
+ private var verifyCardTask: VerifyCardTask? = null
+ private var requestPIN2Count = 0
+
+ private var cardProtocol: CardProtocol? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_empty_wallet)
+
+ App.navigatorComponent.inject(this)
+ App.toastHelperComponent.inject(this)
+
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
+ ctx = TangemContext.loadFromBundle(this, intent.extras)
+
+ tvIssuer.text = ctx.card!!.issuerDescription
+
+ if (ctx.card!!.tokenSymbol.length > 1) {
+ @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(ctx.blockchainName, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(ctx.blockchainName)
+ tvBlockchain.text = html
+ } else
+ tvBlockchain.text = ctx.blockchainName
+
+ tvCardID.text = ctx.card!!.cidDescription
+ ivTangemCard.setImageBitmap(App.localStorage.getCardArtworkBitmap(ctx.card))
+
+ // set listeners
+ btnNewWallet.setOnClickListener {
+ requestPIN2Count = 0
+ val intent = Intent(baseContext, PinRequestActivity::class.java)
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, ctx.card!!.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, ctx.card!!.asBundle)
+ startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2)
+ }
+
+ btnDetails.setOnClickListener {
+ if (cardProtocol != null)
+ navigator.showVerifyCard(this, ctx)
+ else
+ toastHelper.showSingleToast(this, getString(R.string.need_attach_card_again))
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == Constant.REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY) {
+ if (resultCode == Activity.RESULT_OK) {
+ if (data != null) {
+ data.putExtra(Constant.EXTRA_MODIFICATION, "updateAndViewCard")
+ data.putExtra("updateDelay", 0)
+ setResult(Activity.RESULT_OK, data)
+ }
+ finish()
+ } else {
+ if (data != null && data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
+ val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
+ updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
+ ctx.card = updatedCard
+ }
+ if (resultCode == Constant.RESULT_INVALID_PIN && requestPIN2Count < 2) {
+ requestPIN2Count++
+ val intent = Intent(baseContext, PinRequestActivity::class.java)
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, ctx.card!!.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, ctx.card!!.asBundle)
+ startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2)
+ return
+ }
+ }
+ setResult(resultCode, data)
+ finish()
+ } else if (requestCode == Constant.REQUEST_CODE_REQUEST_PIN2) {
+ if (resultCode == Activity.RESULT_OK) {
+ navigator.showCreateNewWallet(this, ctx)
+ }
+ }
+ }
+
+ override fun onTagDiscovered(tag: Tag) {
+ try {
+ val isoDep = IsoDep.get(tag)
+ val uid = tag.id
+ val sUID = Util.byteArrayToHexString(uid)
+ if (ctx.card.uid != sUID) {
+ nfcManager.ignoreTag(isoDep.tag)
+ return
+ }
+
+ if (lastReadSuccess)
+ isoDep.timeout = 1000
+ else
+ isoDep.timeout = 65000
+
+ verifyCardTask = VerifyCardTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, App.firmwaresStorage, this)
+ verifyCardTask?.start()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun onReadStart(cardProtocol: CardProtocol) {
+ rlProgressBar?.post { rlProgressBar.visibility = View.VISIBLE }
+
+ progressBar?.post {
+ progressBar?.visibility = View.VISIBLE
+ progressBar?.progress = 5
+ }
+ }
+
+ override fun onReadFinish(cardProtocol: CardProtocol?) {
+ verifyCardTask = null
+ if (cardProtocol != null) {
+ if (cardProtocol.error == null) {
+ rlProgressBar?.post { rlProgressBar.visibility = View.GONE }
+
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.GREEN)
+ this.cardProtocol = cardProtocol
+ }
+ } else {
+ // remove last UIDs because of error and no card read
+ progressBar?.post {
+ lastReadSuccess = false
+ if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
+ if (!NoExtendedLengthSupportDialog.allReadyShowed)
+ NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+ } else
+ Toast.makeText(this@EmptyWalletActivity, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
+
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ }
+ }
+
+ rlProgressBar?.postDelayed({
+ try {
+ rlProgressBar?.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onReadProgress(protocol: CardProtocol, progress: Int) {
+ progressBar?.post { progressBar!!.progress = progress }
+ }
+
+ override fun onReadCancel() {
+ verifyCardTask = null
+
+ rlProgressBar?.postDelayed({
+ try {
+ rlProgressBar?.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onReadWait(msec: Int) {
+ WaitSecurityDelayDialog.onReadWait(this, msec)
+ }
+
+ override fun onReadBeforeRequest(timeout: Int) {
+ WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
+ }
+
+ override fun onReadAfterRequest() {
+ WaitSecurityDelayDialog.onReadAfterRequest(this)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.kt b/app/src/main/java/com/tangem/ui/activity/LoadedWalletActivity.kt
similarity index 74%
rename from app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/LoadedWalletActivity.kt
index f7a24d8c28..1106fe391c 100644
--- a/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/LoadedWalletActivity.kt
@@ -1,16 +1,17 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.content.Context
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
import com.tangem.di.Navigator
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.fragment.LoadedWallet
+import com.tangem.di.ToastHelper
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.fragment.LoadedWalletFragment
import com.tangem.wallet.R
import javax.inject.Inject
@@ -18,6 +19,8 @@ class LoadedWalletActivity : AppCompatActivity() {
@Inject
lateinit var navigator: Navigator
+ @Inject
+ internal lateinit var toastHelper: ToastHelper
companion object {
fun callingIntent(context: Context, lastTag: Tag, ctx: TangemContext): Intent {
@@ -32,12 +35,13 @@ class LoadedWalletActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_loaded_wallet)
- App.getNavigatorComponent().inject(this)
+ App.navigatorComponent.inject(this)
+ App.toastHelperComponent.inject(this)
if (intent.extras!!.containsKey(NfcAdapter.EXTRA_TAG)) {
val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
if (tag != null) {
- val fragment = supportFragmentManager.findFragmentById(R.id.loaded_wallet_fragment) as LoadedWallet
+ val fragment = supportFragmentManager.findFragmentById(R.id.loaded_wallet_fragment) as LoadedWalletFragment
fragment.onTagDiscovered(tag)
}
}
diff --git a/app/src/main/java/com/tangem/presentation/activity/LogoActivity.kt b/app/src/main/java/com/tangem/ui/activity/LogoActivity.kt
similarity index 54%
rename from app/src/main/java/com/tangem/presentation/activity/LogoActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/LogoActivity.kt
index 51e36440be..841440d8f8 100644
--- a/app/src/main/java/com/tangem/presentation/activity/LogoActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/LogoActivity.kt
@@ -1,22 +1,21 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
-import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
import com.tangem.di.Navigator
+import com.tangem.wallet.TangemContext
import com.tangem.wallet.BuildConfig
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_logo.*
import javax.inject.Inject
class LogoActivity : AppCompatActivity() {
-
companion object {
-
fun callingIntent(context: Context, autoHide: Boolean): Intent {
val intent = Intent(context, LogoActivity::class.java)
intent.putExtra(Constant.EXTRA_AUTO_HIDE, autoHide)
@@ -24,35 +23,54 @@ class LogoActivity : AppCompatActivity() {
}
}
- private val hideRunnable = Runnable { this.hide() }
-
@Inject
internal lateinit var navigator: Navigator
+ private val hideRunnable = Runnable { this.hide() }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_logo)
- App.getNavigatorComponent().inject(this)
+ App.navigatorComponent.inject(this)
ivLogo.setOnClickListener { hide() }
}
- @SuppressLint("SetTextI18n")
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
+ // set beta version name
if (BuildConfig.DEBUG)
- tvAppVersion.text = "BETA v." + BuildConfig.VERSION_NAME + "\n" + "dev" + "\n" + "build " + BuildConfig.VERSION_CODE
+ tvAppVersion.text = String.format(getString(R.string.version_name_debug), BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
else
- tvAppVersion.text = "BETA v." + BuildConfig.VERSION_NAME
+ tvAppVersion.text = String.format(getString(R.string.version_name_release), BuildConfig.VERSION_NAME)
+
+ // set flavor app name
+ when (BuildConfig.FLAVOR) {
+ Constant.FLAVOR_TANGEM_CARDANO -> {
+ tvExtension.visibility = View.VISIBLE
+ tvExtension.text = getString(R.string.cardano)
+ }
+ else -> {
+ tvExtension.visibility = View.GONE
+ }
+ }
if (intent.getBooleanExtra(Constant.EXTRA_AUTO_HIDE, true))
ivLogo.postDelayed(hideRunnable, Constant.MILLIS_AUTO_HIDE.toLong())
}
private fun hide() {
- navigator.showMain(this)
+ when (BuildConfig.FLAVOR) {
+ Constant.FLAVOR_TANGEM_CARDANO -> {
+ navigator.showPrepareTransaction(this, TangemContext())
+ }
+ else -> {
+ navigator.showMain(this)
+ }
+ }
+
finish()
}
diff --git a/app/src/main/java/com/tangem/ui/activity/MainActivity.kt b/app/src/main/java/com/tangem/ui/activity/MainActivity.kt
new file mode 100644
index 0000000000..075ff25409
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/activity/MainActivity.kt
@@ -0,0 +1,88 @@
+@file:Suppress("ObsoleteExperimentalCoroutines")
+
+package com.tangem.ui.activity
+
+import android.Manifest
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.navigation.NavController
+import androidx.navigation.Navigation
+import com.scottyab.rootbeer.RootBeer
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.di.Navigator
+import com.tangem.di.ToastHelper
+import com.tangem.ui.dialog.RootFoundDialog
+import com.tangem.wallet.BuildConfig
+import com.tangem.wallet.R
+import javax.inject.Inject
+
+class MainActivity : AppCompatActivity() {
+
+ companion object {
+ val TAG: String = MainActivity::class.java.simpleName
+ fun callingIntent(context: Context) = Intent(context, MainActivity::class.java)
+ }
+
+ lateinit var navController: NavController
+ @Inject
+ internal lateinit var navigator: Navigator
+ @Inject
+ internal lateinit var toastHelper: ToastHelper
+
+// private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = null
+
+// override fun onNewIntent(intent: Intent?) {
+// super.onNewIntent(intent)
+// if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
+// val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
+// if (tag != null && onNfcReaderCallback != null)
+// onNfcReaderCallback?.onTagDiscovered(tag)
+// }
+// }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ navController = Navigation.findNavController(this, R.id.nav_host_fragment)
+
+ App.navigatorComponent.inject(this)
+ App.toastHelperComponent.inject(this)
+
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+
+ verifyPermissions()
+
+// // NFC
+// val intent = intent
+// if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
+// val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
+// if (tag != null && onNfcReaderCallback != null) {
+// onNfcReaderCallback?.onTagDiscovered(tag)
+// }
+// }
+
+ // check if root device
+ val rootBeer = RootBeer(this)
+ if (rootBeer.isRootedWithoutBusyBoxCheck && !BuildConfig.DEBUG)
+ RootFoundDialog().show(supportFragmentManager, RootFoundDialog.TAG)
+ }
+
+ private fun verifyPermissions() {
+ NfcManager.verifyPermissions(this)
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), Constant.REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/PinRequestActivity.kt b/app/src/main/java/com/tangem/ui/activity/PinRequestActivity.kt
similarity index 84%
rename from app/src/main/java/com/tangem/presentation/activity/PinRequestActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PinRequestActivity.kt
index 0fa74bd5c3..a881cc687d 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PinRequestActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PinRequestActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.Manifest
import android.annotation.SuppressLint
@@ -13,30 +13,33 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
-import android.support.v4.app.ActivityCompat
-import android.support.v7.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.appcompat.app.AppCompatActivity
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Button
import com.tangem.Constant
import com.tangem.data.fingerprint.StartFingerprintReaderTask
-import com.tangem.tangemcard.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcManager
import com.tangem.data.fingerprint.FingerprintHelper
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.tangemcard.android.data.PINStorage
-import com.tangem.tangemcard.data.TangemCard
-import com.tangem.tangemcard.data.loadFromBundle
-import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
-import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.wallet.TangemContext
+import com.tangem.card_android.android.data.PINStorage
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.data.loadFromBundle
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.card_common.data.TangemCard
+import com.tangem.util.LOG
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_pin_request.*
import kotlinx.android.synthetic.main.layout_pin_buttons.*
import java.io.IOException
class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, FingerprintHelper.FingerprintHelperListener {
-
companion object {
+ val TAG: String = PinRequestActivity::class.java.simpleName
+
fun callingIntent(context: Activity, mode: String): Intent {
val intent = Intent(context, PinRequestActivity::class.java)
intent.putExtra(Constant.EXTRA_MODE, mode)
@@ -81,12 +84,11 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
}
}
+ private lateinit var nfcManager: NfcManager
+
lateinit var mode: Mode
private var allowFingerprint = false
- private var nfcManager: NfcManager? = null
-
var startFingerprintReaderTask: StartFingerprintReaderTask? = null
-
private var fingerprintManager: FingerprintManager? = null
private var fingerprintHelper: FingerprintHelper? = null
@@ -99,6 +101,7 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
setContentView(R.layout.activity_pin_request)
nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
mode = Mode.valueOf(intent.getStringExtra(Constant.EXTRA_MODE))
@@ -170,34 +173,26 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
override fun onPause() {
super.onPause()
-
- if (fingerprintHelper != null)
- fingerprintHelper!!.cancel()
+ fingerprintHelper?.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
-
- nfcManager!!.onPause()
}
override fun onStop() {
super.onStop()
- if (fingerprintHelper != null)
- fingerprintHelper!!.cancel()
+ fingerprintHelper?.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
-
- nfcManager!!.onStop()
}
override fun onResume() {
super.onResume()
- nfcManager!!.onResume()
if (allowFingerprint)
startFingerprintReader()
}
@@ -205,33 +200,33 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
override fun onTagDiscovered(tag: Tag) {
try {
Log.w(javaClass.name, "Ignore discovered tag!")
- nfcManager!!.ignoreTag(tag)
+ nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
override fun authenticationFailed(error: String) {
- doLog(error)
+ LOG.w(TAG, error)
}
@TargetApi(Build.VERSION_CODES.M)
override fun authenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
- doLog("Authentication succeeded!")
+ LOG.i(TAG, "Authentication succeeded!")
val cipher = result.cryptoObject.cipher
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
val resultData = Intent()
val pin = PINStorage.loadEncryptedPIN(cipher)
- resultData.putExtra("newPIN", pin)
- resultData.putExtra("confirmPIN", pin)
+ resultData.putExtra(Constant.EXTRA_NEW_PIN, pin)
+ resultData.putExtra(Constant.EXTRA_CONFIRM_PIN, pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
val resultData = Intent()
val pin = PINStorage.loadEncryptedPIN2(cipher)
- resultData.putExtra("newPIN2", pin)
- resultData.putExtra("confirmPIN2", pin)
+ resultData.putExtra(Constant.EXTRA_NEW_PIN_2, pin)
+ resultData.putExtra(Constant.EXTRA_CONFIRM_PIN_2, pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestPIN) {
@@ -245,38 +240,33 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
finish()
}
- fun doLog(text: String) {
- // Log.e("FP", text);
- }
-
- @SuppressLint("SetTextI18n")
private fun buttonClick(button: Button) {
- tvPin!!.text = tvPin!!.text.toString() + button.text as String
+ tvPin.text = tvPin.text.toString() + button.text.toString()
}
@SuppressLint("NewApi")
private fun testFingerPrintSettings(): Boolean {
- doLog("Testing Fingerprint Settings")
+ LOG.i(TAG, "Testing Fingerprint SettingsFragment")
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
if (!keyguardManager.isKeyguardSecure) {
- doLog("User hasn't enabled Lock Screen")
+ LOG.i(TAG, "User hasn't enabled Lock Screen")
return false
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
- doLog("User hasn't granted permission to use Fingerprint")
+ LOG.i(TAG, "User hasn't granted permission to use Fingerprint")
return false
}
if (!fingerprintManager!!.hasEnrolledFingerprints()) {
- doLog("User hasn't registered any fingerprints")
+ LOG.i(TAG, "User hasn't registered any fingerprints")
return false
}
- doLog("Fingerprint authentication is set.\n")
+ LOG.i(TAG, "Fingerprint authentication is set.\n")
return true
}
@@ -307,13 +297,13 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
var focusView: View? = null
if (mode == Mode.ConfirmNewPIN) {
- if (pin != intent.getStringExtra("newPIN")) {
+ if (pin != intent.getStringExtra(Constant.EXTRA_NEW_PIN)) {
tvPin!!.error = getString(R.string.error_pin_confirmation_failed)
focusView = tvPin
cancel = true
}
} else if (mode == Mode.ConfirmNewPIN2) {
- if (pin != intent.getStringExtra("newPIN2")) {
+ if (pin != intent.getStringExtra(Constant.EXTRA_NEW_PIN_2)) {
tvPin!!.error = getString(R.string.error_pin_confirmation_failed)
focusView = tvPin
cancel = true
@@ -331,17 +321,17 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
else {
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
val resultData = Intent()
- resultData.putExtra("newPIN", pin)
+ resultData.putExtra(Constant.EXTRA_NEW_PIN, pin)
if (mode == Mode.ConfirmNewPIN)
- resultData.putExtra("confirmPIN", pin)
+ resultData.putExtra(Constant.EXTRA_CONFIRM_PIN, pin)
setResult(Activity.RESULT_OK, resultData)
finish()
} else if (mode == Mode.RequestNewPIN2 || mode == Mode.ConfirmNewPIN2) {
val resultData = Intent()
- resultData.putExtra("newPIN2", pin)
+ resultData.putExtra(Constant.EXTRA_NEW_PIN_2, pin)
if (mode == Mode.ConfirmNewPIN2)
- resultData.putExtra("confirmPIN2", pin)
+ resultData.putExtra(Constant.EXTRA_CONFIRM_PIN_2, pin)
setResult(Activity.RESULT_OK, resultData)
finish()
diff --git a/app/src/main/java/com/tangem/presentation/activity/PinSaveActivity.kt b/app/src/main/java/com/tangem/ui/activity/PinSaveActivity.kt
similarity index 98%
rename from app/src/main/java/com/tangem/presentation/activity/PinSaveActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PinSaveActivity.kt
index 5a2c5b140d..3b51be1a15 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PinSaveActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PinSaveActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.Manifest
import android.annotation.SuppressLint
@@ -14,8 +14,8 @@ import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
-import android.support.v4.app.ActivityCompat
-import android.support.v7.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.appcompat.app.AppCompatActivity
import android.text.TextUtils
import android.view.View
import android.widget.Button
@@ -23,7 +23,7 @@ import android.widget.Toast
import com.tangem.Constant
import com.tangem.data.fingerprint.ConfirmWithFingerprintTask
import com.tangem.data.fingerprint.FingerprintHelper
-import com.tangem.tangemcard.android.data.PINStorage
+import com.tangem.card_android.android.data.PINStorage
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_pin_save.*
import kotlinx.android.synthetic.main.layout_pin_buttons.*
@@ -39,7 +39,6 @@ import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
class PinSaveActivity : AppCompatActivity(), FingerprintHelper.FingerprintHelperListener {
-
companion object {
val TAG: String = PinSaveActivity::class.java.simpleName
diff --git a/app/src/main/java/com/tangem/presentation/activity/PinSwapActivity.kt b/app/src/main/java/com/tangem/ui/activity/PinSwapActivity.kt
similarity index 73%
rename from app/src/main/java/com/tangem/presentation/activity/PinSwapActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PinSwapActivity.kt
index 8a38bae83c..813d237ea9 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PinSwapActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PinSwapActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.app.Activity
import android.content.Context
@@ -9,26 +9,29 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.widget.ProgressBar
import android.widget.Toast
import com.tangem.App
import com.tangem.Constant
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.*
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.tasks.SwapPINTask
-import com.tangem.tangemcard.util.Util
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.*
+import com.tangem.card_common.data.TangemCard
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.SwapPINTask
+import com.tangem.card_common.util.Util
import com.tangem.util.LOG
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_pin_swap.*
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
companion object {
val TAG: String = PinSwapActivity::class.java.simpleName
@@ -43,8 +46,8 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
}
private lateinit var nfcManager: NfcManager
- private var card: TangemCard? = null
+ private lateinit var card: TangemCard;
private var newPIN: String? = null
private var newPIN2: String? = null
@@ -57,35 +60,33 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
setContentView(R.layout.activity_pin_swap)
nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
card = TangemCard(intent.getStringExtra(EXTRA_TANGEM_CARD_UID))
- card!!.loadFromBundle(intent.extras!!.getBundle(EXTRA_TANGEM_CARD))
+
+ card.loadFromBundle(intent.extras!!.getBundle(EXTRA_TANGEM_CARD))
newPIN = intent.getStringExtra(Constant.EXTRA_NEW_PIN)
newPIN2 = intent.getStringExtra(Constant.EXTRA_NEW_PIN_2)
- tvCardID.text = card!!.cidDescription
+ tvCardID.text = card.cidDescription
progressBar = findViewById(R.id.progressBar)
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
}
override fun onTagDiscovered(tag: Tag) {
try {
// get IsoDep handle and run cardReader thread
val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
val uid = tag.id
val sUID = Util.byteArrayToHexString(uid)
- LOG.d(TAG, "UID: $sUID")
-
- if (sUID == card!!.uid) {
- isoDep.timeout = card!!.pauseBeforePIN2 + 65000
+ if (sUID == card.uid) {
+ isoDep.timeout = card.pauseBeforePIN2 + 65000
swapPinTask = SwapPINTask(card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, newPIN, newPIN2)
- swapPinTask!!.start()
+ swapPinTask?.start()
} else {
- LOG.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card!!.uid + ")")
nfcManager.ignoreTag(isoDep.tag)
}
} catch (e: Exception) {
@@ -93,23 +94,13 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
}
}
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
public override fun onPause() {
- nfcManager.onPause()
- if (swapPinTask != null)
- swapPinTask!!.cancel(true)
+ swapPinTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
- // dismiss enable NFC dialog
- nfcManager.onStop()
- if (swapPinTask != null)
- swapPinTask!!.cancel(true)
+ swapPinTask?.cancel(true)
super.onStop()
}
@@ -129,8 +120,8 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
progressBar!!.progress = 100
progressBar!!.progressTintList = ColorStateList.valueOf(Color.GREEN)
val intent = Intent()
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
setResult(Activity.RESULT_OK, intent)
finish()
}
@@ -145,9 +136,9 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar!!.visibility = View.INVISIBLE
val intent = Intent()
- intent.putExtra("message", "Cannot change PIN(s). Make sure you enter correct PIN2!")
- intent.putExtra("UID", cardProtocol.card.uid)
- intent.putExtra("Card", cardProtocol.card.asBundle)
+ intent.putExtra(Constant.EXTRA_MESSAGE, "Cannot change PIN(s). Make sure you enter correct PIN2!")
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
setResult(RESULT_INVALID_PIN, intent)
finish()
} catch (e: Exception) {
@@ -168,11 +159,11 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
}
}
- progressBar!!.postDelayed({
+ progressBar?.postDelayed({
try {
- progressBar!!.progress = 0
- progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar!!.visibility = View.INVISIBLE
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
} catch (e: Exception) {
e.printStackTrace()
}
diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt b/app/src/main/java/com/tangem/ui/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt
similarity index 83%
rename from app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt
index fe4deaf57d..b7a279ea90 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PrepareCryptonitOtherApiWithdrawalActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.annotation.SuppressLint
import android.app.Activity
@@ -7,16 +7,17 @@ import android.graphics.Color
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import android.view.View
import com.tangem.App
import com.tangem.Constant
import com.tangem.data.Blockchain
import com.tangem.data.network.CryptonitOtherApi
import com.tangem.di.Navigator
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.tangemcard.android.reader.NfcManager
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.*
import java.io.IOException
@@ -28,8 +29,9 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
val TAG: String = PrepareCryptonitOtherApiWithdrawalActivity::class.java.simpleName
}
+ private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
- private var nfcManager: NfcManager? = null
+
private var cryptonit: CryptonitOtherApi? = null
@Inject
@@ -40,9 +42,10 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_cryptonit_other_api_withdrawal)
- App.getNavigatorComponent().inject(this)
+ App.navigatorComponent.inject(this)
nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
@@ -128,47 +131,6 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
doRequestBalance()
}
- private fun doRequestBalance() {
- if (cryptonit!!.havaAccountInfo()) {
- rlProgressBar.visibility = View.VISIBLE
- tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
- tvError.visibility = View.INVISIBLE
- cryptonit!!.requestBalance(ctx.blockchain.currency, "USD")
- } else {
- tvError.visibility = View.VISIBLE
- tvError.text = getString(R.string.cryptonit_not_enough_account_data)
- }
- }
-
-// private fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
-// this.addTextChangedListener(object : TextWatcher {
-// override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
-// }
-//
-// override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
-// }
-//
-// override fun afterTextChanged(editable: Editable?) {
-// afterTextChanged.invoke(editable.toString())
-// }
-// })
-// }
-
- public override fun onResume() {
- super.onResume()
- nfcManager!!.onResume()
- }
-
- public override fun onPause() {
- super.onPause()
- nfcManager!!.onPause()
- }
-
- public override fun onStop() {
- super.onStop()
- nfcManager!!.onStop()
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
@@ -193,12 +155,22 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
override fun onTagDiscovered(tag: Tag) {
try {
-// Log.w(javaClass.name, "Ignore discovered tag!")
- nfcManager!!.ignoreTag(tag)
+ nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
+ }
+ private fun doRequestBalance() {
+ if (cryptonit!!.havaAccountInfo()) {
+ rlProgressBar.visibility = View.VISIBLE
+ tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
+ tvError.visibility = View.INVISIBLE
+ cryptonit!!.requestBalance(ctx.blockchain.currency, "USD")
+ } else {
+ tvError.visibility = View.VISIBLE
+ tvError.text = getString(R.string.cryptonit_not_enough_account_data)
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt b/app/src/main/java/com/tangem/ui/activity/PrepareCryptonitWithdrawalActivity.kt
similarity index 85%
rename from app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PrepareCryptonitWithdrawalActivity.kt
index 9a166fea3e..798d1eff9a 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PrepareCryptonitWithdrawalActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.annotation.SuppressLint
import android.content.Context
@@ -6,17 +6,18 @@ import android.graphics.Color
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import android.text.InputFilter
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import com.tangem.data.network.Cryptonit
-import com.tangem.tangemcard.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcManager
import com.tangem.data.Blockchain
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
import com.tangem.util.DecimalDigitsInputFilter
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_withdrawal.*
@@ -29,19 +30,20 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
}
private lateinit var ctx: TangemContext
- private var nfcManager: NfcManager? = null
- private var cryptonit: Cryptonit? = null
+ private lateinit var nfcManager: NfcManager
+ private var cryptonit: Cryptonit? = null
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_cryptonit_withdrawal)
- nfcManager = NfcManager(this, this)
-
ctx = TangemContext.loadFromBundle(this, intent.extras)
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
cryptonit = Cryptonit(this)
etUsername.setText(cryptonit!!.username)
@@ -56,17 +58,17 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
tvFeeCurrency.text = engine.feeCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toValueString())
- etAmount.filters=engine.amountInputFilters
+ etAmount.filters = engine.amountInputFilters
- etAmount.setOnEditorActionListener { lv, actionId, event ->
+ etAmount.setOnEditorActionListener { lv, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
val imm = lv.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(lv.windowToken, 0)
true
- } else {
+ } else
false
- }
}
+
when (ctx.blockchain) {
Blockchain.Bitcoin -> {
etAmount.filters = arrayOf(DecimalDigitsInputFilter(5))
@@ -90,7 +92,6 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
val strAmount: String = etAmount.text.toString().replace(",", ".")
val strFee: String = etFee.text.toString().replace(",", ".")
val dblAmount: Double = strAmount.toDouble()
- var dblFee: Double = strFee.toDouble()
cryptonit!!.fee = strFee
rlProgressBar.visibility = View.VISIBLE
@@ -125,7 +126,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
cryptonit!!.setWithdrawalListener { response ->
rlProgressBar.visibility = View.INVISIBLE
if (response.success != null && response.success!!) {
- Toast.makeText(this, "Withdrawal successful!", Toast.LENGTH_LONG).show();
+ Toast.makeText(this, R.string.withdrawal_successful, Toast.LENGTH_LONG).show();
finish()
} else {
tvError.visibility = View.VISIBLE
@@ -136,6 +137,14 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
doRequestBalance()
}
+ override fun onTagDiscovered(tag: Tag) {
+ try {
+ nfcManager.ignoreTag(tag)
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ }
+
private fun doRequestBalance() {
if (cryptonit!!.haveAccountInfo()) {
rlProgressBar.visibility = View.VISIBLE
@@ -148,28 +157,4 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
}
}
- public override fun onResume() {
- super.onResume()
- nfcManager!!.onResume()
- }
-
- public override fun onPause() {
- super.onPause()
- nfcManager!!.onPause()
- }
-
- public override fun onStop() {
- super.onStop()
- nfcManager!!.onStop()
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- nfcManager!!.ignoreTag(tag)
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- }
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt b/app/src/main/java/com/tangem/ui/activity/PrepareKrakenWithdrawalActivity.kt
similarity index 88%
rename from app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/PrepareKrakenWithdrawalActivity.kt
index 542362a3db..3609aa8f8e 100644
--- a/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/PrepareKrakenWithdrawalActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.annotation.SuppressLint
import android.app.Activity
@@ -10,7 +10,7 @@ import android.graphics.Color
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
@@ -18,11 +18,12 @@ import android.widget.Toast
import com.tangem.App
import com.tangem.Constant
import com.tangem.data.network.Kraken
-import com.tangem.tangemcard.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcManager
import com.tangem.data.Blockchain
import com.tangem.di.Navigator
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_kraken_withdrawal.*
import java.io.IOException
@@ -38,7 +39,8 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
}
private lateinit var ctx: TangemContext
- private var nfcManager: NfcManager? = null
+ private lateinit var nfcManager: NfcManager
+
private var kraken: Kraken? = null
private var fee: BigDecimal? = null
@@ -50,12 +52,13 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_kraken_withdrawal)
- App.getNavigatorComponent().inject(this)
-
- nfcManager = NfcManager(this, this)
+ App.navigatorComponent.inject(this)
ctx = TangemContext.loadFromBundle(this, intent.extras)
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
kraken = Kraken(this)
tvKey.text = kraken!!.key
@@ -68,7 +71,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
tvCurrency.text = engine!!.balanceCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toValueString())
- etAmount.filters=engine.amountInputFilters
+ etAmount.filters = engine.amountInputFilters
etAmount.setOnEditorActionListener { lv, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
@@ -167,7 +170,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
val builder = AlertDialog.Builder(this)
// Set a title for alert dialog
- builder.setTitle("Please confirm withdraw")
+ builder.setTitle(R.string.please_confirm_withdraw)
// Set a message for alert dialog
builder.setMessage(String.format("Continue with fee %s %s?", fee!!.toString().trimEnd('0'), ctx.blockchain.currency))
@@ -186,23 +189,22 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
rlProgressBar.visibility = View.VISIBLE
tvProgressDescription.text = getString(R.string.kraken_request_withdrawal)
- //Toast.makeText(this, String.format("Withdraw %s!",dblAmount.toString()), Toast.LENGTH_LONG).show()
kraken!!.requestWithdraw(ctx.blockchain.currency, dblAmount.toString(), ctx.coinData!!.wallet)
} catch (e: Exception) {
etAmount.error = getString(R.string.unknown_amount_format)
}
}
DialogInterface.BUTTON_NEGATIVE -> {
- Toast.makeText(this, "Operation canceled!", Toast.LENGTH_LONG).show()
+ Toast.makeText(this, R.string.operation_canceled, Toast.LENGTH_LONG).show()
}
}
}
// Set the alert dialog positive/yes button
- builder.setPositiveButton("YES", dialogClickListener)
+ builder.setPositiveButton(R.string.yes, dialogClickListener)
// Set the alert dialog negative/no button
- builder.setNegativeButton("NO", dialogClickListener)
+ builder.setNegativeButton(R.string.no, dialogClickListener)
// Initialize the AlertDialog using builder object
@@ -224,21 +226,6 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
}
}
- public override fun onResume() {
- super.onResume()
- nfcManager!!.onResume()
- }
-
- public override fun onPause() {
- super.onPause()
- nfcManager!!.onPause()
- }
-
- public override fun onStop() {
- super.onStop()
- nfcManager!!.onStop()
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
@@ -262,12 +249,10 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
override fun onTagDiscovered(tag: Tag) {
try {
-// Log.w(javaClass.name, "Ignore discovered tag!")
- nfcManager!!.ignoreTag(tag)
+ nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
-
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/activity/PurgeActivity.kt b/app/src/main/java/com/tangem/ui/activity/PurgeActivity.kt
new file mode 100644
index 0000000000..c4eec4af3b
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/activity/PurgeActivity.kt
@@ -0,0 +1,236 @@
+package com.tangem.ui.activity
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.nfc.tech.IsoDep
+import android.os.Bundle
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialogNew
+import com.tangem.ui.event.DeletingWalletFinish
+import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.asBundle
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.PurgeTask
+import com.tangem.card_common.util.Util
+import com.tangem.wallet.R
+import kotlinx.android.synthetic.main.activity_purge.*
+import kotlinx.android.synthetic.main.layout_touch_card.*
+import org.greenrobot.eventbus.EventBus
+import javax.inject.Inject
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+
+class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
+ companion object {
+ val TAG: String = PurgeActivity::class.java.simpleName
+
+ fun callingIntent(context: Context, ctx: TangemContext): Intent {
+ val intent = Intent(context, PurgeActivity::class.java)
+ ctx.saveToIntent(intent)
+ return intent
+ }
+
+ const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
+ }
+
+ @Inject
+ internal lateinit var waitSecurityDelayDialogNew: WaitSecurityDelayDialogNew
+
+ private lateinit var nfcManager: NfcManager
+ private lateinit var ctx: TangemContext
+
+ private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
+
+ private var purgeTask: PurgeTask? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_purge)
+
+ App.navigatorComponent.inject(this)
+
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
+ ctx = TangemContext.loadFromBundle(this, intent.extras)
+
+ // init NFC Antenna
+ nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
+ nfcDeviceAntenna.init()
+
+ tvCardID.text = ctx.card.cidDescription
+ progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar.visibility = View.INVISIBLE
+ }
+
+ public override fun onStop() {
+ purgeTask?.cancel(true)
+ super.onStop()
+ }
+
+ override fun onTagDiscovered(tag: Tag) {
+ try {
+ // get IsoDep handle and run cardReader thread
+ val isoDep = IsoDep.get(tag)
+ val uid = tag.id
+ val sUID = Util.byteArrayToHexString(uid)
+ if (sUID == ctx.card.uid) {
+ isoDep.timeout = ctx.card.pauseBeforePIN2 + 65000
+ purgeTask = PurgeTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
+ purgeTask?.start()
+ } else {
+ nfcManager.ignoreTag(isoDep.tag)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun onReadWait(msec: Int) {
+ WaitSecurityDelayDialog.onReadWait(this, msec)
+
+// val readWait = ReadWait()
+// readWait.msec = msec
+// EventBus.getDefault().post(readWait)
+ }
+
+ override fun onReadBeforeRequest(timeout: Int) {
+ WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
+
+// if (!waitSecurityDelayDialogNew.isAdded)
+// waitSecurityDelayDialogNew.show(supportFragmentManager, WaitSecurityDelayDialogNew.TAG)
+//
+//
+// val readBeforeRequest = ReadBeforeRequest()
+// readBeforeRequest.timeout = timeout
+// EventBus.getDefault().post(readBeforeRequest)
+ }
+
+ override fun onReadAfterRequest() {
+ WaitSecurityDelayDialog.onReadAfterRequest(this)
+
+// val readAfterRequest = ReadAfterRequest()
+// EventBus.getDefault().post(readAfterRequest)
+ }
+
+ override fun onReadStart(cardProtocol: CardProtocol) {
+ rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
+
+ progressBar.post {
+ progressBar.visibility = View.VISIBLE
+ progressBar.progress = 5
+ }
+ }
+
+ override fun onReadFinish(cardProtocol: CardProtocol?) {
+ purgeTask = null
+
+ if (cardProtocol != null) {
+ if (cardProtocol.error == null) {
+ rlProgressBar.post { rlProgressBar.visibility = View.GONE }
+
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.GREEN)
+
+ val intent = Intent()
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
+ setResult(Activity.RESULT_OK, intent)
+
+ EventBus.getDefault().post(DeletingWalletFinish())
+
+ finish()
+ }
+ } else {
+ if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) {
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+
+ val intent = Intent()
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
+ intent.putExtra(Constant.EXTRA_MESSAGE, getString(R.string.cannot_erase_wallet))
+ setResult(RESULT_INVALID_PIN, intent)
+ finish()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ } else {
+ progressBar?.post {
+ if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
+ if (!NoExtendedLengthSupportDialog.allReadyShowed)
+ NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+ } else
+ Toast.makeText(baseContext, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
+
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ }
+ }
+ }
+
+ rlProgressBar?.postDelayed({
+ try {
+ rlProgressBar.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onReadProgress(protocol: CardProtocol, progress: Int) {
+ progressBar?.post { progressBar?.progress = progress }
+ }
+
+ override fun onReadCancel() {
+ purgeTask = null
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/QrScanActivity.kt b/app/src/main/java/com/tangem/ui/activity/QrScanActivity.kt
similarity index 93%
rename from app/src/main/java/com/tangem/presentation/activity/QrScanActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/QrScanActivity.kt
index 9d4e4d0585..82e542ed4c 100644
--- a/app/src/main/java/com/tangem/presentation/activity/QrScanActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/QrScanActivity.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.Manifest
import android.app.Activity
@@ -6,14 +6,13 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
-import android.support.v4.app.ActivityCompat
-import android.support.v7.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.appcompat.app.AppCompatActivity
import com.google.zxing.Result
import com.tangem.Constant
import me.dm7.barcodescanner.zxing.ZXingScannerView
class QrScanActivity : AppCompatActivity(), ZXingScannerView.ResultHandler {
-
companion object {
fun callingIntent(context: Context): Intent {
return Intent(context, QrScanActivity::class.java)
diff --git a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt b/app/src/main/java/com/tangem/ui/activity/SendTransactionActivity.kt
similarity index 79%
rename from app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/SendTransactionActivity.kt
index f1a72721ac..c5614cc845 100644
--- a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/SendTransactionActivity.kt
@@ -1,19 +1,22 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import android.view.KeyEvent
import android.widget.Toast
+import com.tangem.App
import com.tangem.Constant
-import com.tangem.domain.wallet.CoinEngine
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.event.TransactionFinishWithError
-import com.tangem.presentation.event.TransactionFinishWithSuccess
-import com.tangem.tangemcard.android.reader.NfcManager
+import com.tangem.wallet.CoinEngine
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.event.TransactionFinishWithError
+import com.tangem.ui.event.TransactionFinishWithSuccess
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_common.util.Util
import com.tangem.util.UtilHelper
import com.tangem.wallet.R
import org.greenrobot.eventbus.EventBus
@@ -21,15 +24,17 @@ import java.io.IOException
class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
- private lateinit var ctx: TangemContext
- private var tx: ByteArray? = null
private lateinit var nfcManager: NfcManager
+ private lateinit var ctx: TangemContext
+
+ private var tx: ByteArray? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_send_transaction)
nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
tx = intent.getByteArrayExtra(Constant.EXTRA_TX)
@@ -39,9 +44,10 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
engine!!.requestSendTransaction(
object : CoinEngine.BlockchainRequestsCallbacks {
override fun onComplete(success: Boolean) {
- if (success)
+ if (success) {
+ App.pendingTransactionsStorage.putTransaction(ctx.card, Util.bytesToHex(tx), engine.pendingTransactionTimeoutInSeconds())
finishWithSuccess()
- else
+ }else
finishWithError(ctx.error)
}
@@ -66,21 +72,6 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
return super.onKeyDown(keyCode, event)
}
- public override fun onResume() {
- super.onResume()
- nfcManager.onResume()
- }
-
- public override fun onPause() {
- super.onPause()
- nfcManager.onPause()
- }
-
- public override fun onStop() {
- super.onStop()
- nfcManager.onStop()
- }
-
override fun onTagDiscovered(tag: Tag) {
try {
nfcManager.ignoreTag(tag)
diff --git a/app/src/main/java/com/tangem/ui/activity/SettingsActivity.kt b/app/src/main/java/com/tangem/ui/activity/SettingsActivity.kt
new file mode 100644
index 0000000000..51c4aa2564
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/activity/SettingsActivity.kt
@@ -0,0 +1,30 @@
+package com.tangem.ui.activity
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import com.tangem.wallet.R
+
+class SettingsActivity : AppCompatActivity() {
+ companion object {
+ fun callingIntent(context: Context) = Intent(context, SettingsActivity::class.java)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_settings)
+
+ initToolbar()
+ }
+
+ private fun initToolbar() {
+ val toolbar = findViewById(R.id.toolbar)
+ toolbar.setTitle(R.string.settings)
+ toolbar.setNavigationIcon(android.R.drawable.ic_menu_close_clear_cancel)
+ setSupportActionBar(toolbar)
+ toolbar.setNavigationOnClickListener { finish() }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/activity/VerifyCardActivity.kt b/app/src/main/java/com/tangem/ui/activity/VerifyCardActivity.kt
similarity index 81%
rename from app/src/main/java/com/tangem/presentation/activity/VerifyCardActivity.kt
rename to app/src/main/java/com/tangem/ui/activity/VerifyCardActivity.kt
index 408a7e36ca..394d7c41e0 100644
--- a/app/src/main/java/com/tangem/presentation/activity/VerifyCardActivity.kt
+++ b/app/src/main/java/com/tangem/ui/activity/VerifyCardActivity.kt
@@ -1,14 +1,14 @@
-package com.tangem.presentation.activity
+package com.tangem.ui.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
import com.tangem.di.Navigator
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.fragment.VerifyCard
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.fragment.VerifyCard
import com.tangem.wallet.R
import javax.inject.Inject
@@ -29,7 +29,7 @@ class VerifyCardActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_verify_card)
- App.getNavigatorComponent().inject(this)
+ App.navigatorComponent.inject(this)
}
override fun onBackPressed() {
diff --git a/app/src/main/java/com/tangem/presentation/dialog/NoExtendedLengthSupportDialog.kt b/app/src/main/java/com/tangem/ui/dialog/NoExtendedLengthSupportDialog.kt
similarity index 90%
rename from app/src/main/java/com/tangem/presentation/dialog/NoExtendedLengthSupportDialog.kt
rename to app/src/main/java/com/tangem/ui/dialog/NoExtendedLengthSupportDialog.kt
index 1fe40d3900..d931e86360 100644
--- a/app/src/main/java/com/tangem/presentation/dialog/NoExtendedLengthSupportDialog.kt
+++ b/app/src/main/java/com/tangem/ui/dialog/NoExtendedLengthSupportDialog.kt
@@ -1,9 +1,9 @@
-package com.tangem.presentation.dialog
+package com.tangem.ui.dialog
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
-import android.support.v4.app.DialogFragment
+import androidx.fragment.app.DialogFragment
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/presentation/dialog/PINSwapWarningDialog.java b/app/src/main/java/com/tangem/ui/dialog/PINSwapWarningDialog.java
similarity index 77%
rename from app/src/main/java/com/tangem/presentation/dialog/PINSwapWarningDialog.java
rename to app/src/main/java/com/tangem/ui/dialog/PINSwapWarningDialog.java
index b454dfcee5..a977511814 100644
--- a/app/src/main/java/com/tangem/presentation/dialog/PINSwapWarningDialog.java
+++ b/app/src/main/java/com/tangem/ui/dialog/PINSwapWarningDialog.java
@@ -1,18 +1,20 @@
-package com.tangem.presentation.dialog;
+package com.tangem.ui.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
+import com.tangem.Constant;
import com.tangem.wallet.R;
public class PINSwapWarningDialog extends DialogFragment {
public static final String TAG = PINSwapWarningDialog.class.getSimpleName();
- public static final String EXTRA_MESSAGE = "message";
- private String message;
+ private String message = "";
private OnPositiveButton mOnPositiveButton;
public interface OnPositiveButton {
@@ -26,12 +28,14 @@ public class PINSwapWarningDialog extends DialogFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- message = getArguments().getString(EXTRA_MESSAGE);
+ if (getArguments() != null) {
+ message = getArguments().getString(Constant.EXTRA_MESSAGE);
+ }
}
+ @NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
-
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle(R.string.your_money_is_at_risk)
@@ -43,7 +47,7 @@ public class PINSwapWarningDialog extends DialogFragment {
}
@Override
- public void onCancel(DialogInterface dialog) {
+ public void onCancel(@NonNull DialogInterface dialog) {
super.onCancel(dialog);
}
diff --git a/app/src/main/java/com/tangem/presentation/dialog/RootFoundDialog.kt b/app/src/main/java/com/tangem/ui/dialog/RootFoundDialog.kt
similarity index 87%
rename from app/src/main/java/com/tangem/presentation/dialog/RootFoundDialog.kt
rename to app/src/main/java/com/tangem/ui/dialog/RootFoundDialog.kt
index f6aed9beb5..3882cf74dc 100644
--- a/app/src/main/java/com/tangem/presentation/dialog/RootFoundDialog.kt
+++ b/app/src/main/java/com/tangem/ui/dialog/RootFoundDialog.kt
@@ -1,9 +1,9 @@
-package com.tangem.presentation.dialog
+package com.tangem.ui.dialog
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
-import android.support.v4.app.DialogFragment
+import androidx.fragment.app.DialogFragment
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/presentation/dialog/ShowQRCodeDialog.java b/app/src/main/java/com/tangem/ui/dialog/ShowQRCodeDialog.java
similarity index 85%
rename from app/src/main/java/com/tangem/presentation/dialog/ShowQRCodeDialog.java
rename to app/src/main/java/com/tangem/ui/dialog/ShowQRCodeDialog.java
index eb92fe303e..119c2a6e49 100644
--- a/app/src/main/java/com/tangem/presentation/dialog/ShowQRCodeDialog.java
+++ b/app/src/main/java/com/tangem/ui/dialog/ShowQRCodeDialog.java
@@ -1,9 +1,7 @@
-package com.tangem.presentation.dialog;
+package com.tangem.ui.dialog;
-import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -16,10 +14,15 @@ import android.widget.TextView;
import com.tangem.util.UtilHelper;
import com.tangem.wallet.R;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.DialogFragment;
+
/**
* Created by dvol on 06.03.2018.
*/
public class ShowQRCodeDialog extends DialogFragment {
+ public static final String TAG = ShowQRCodeDialog.class.getSimpleName();
+
private ImageView ivQR;
private TextView tvQRaddress;
private Bitmap bmQR;
@@ -66,11 +69,11 @@ public class ShowQRCodeDialog extends DialogFragment {
}
}
- public static void show(final Activity activity, final String content) {
+ public static void show(final AppCompatActivity activity, final String content) {
activity.runOnUiThread(() -> {
ShowQRCodeDialog instance = new ShowQRCodeDialog();
instance.setup(content);
- instance.show(activity.getFragmentManager(), "ShowQRCodeDialog");
+ instance.show(activity.getSupportFragmentManager(), TAG);
});
}
diff --git a/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialog.java b/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialog.java
new file mode 100644
index 0000000000..3186affc30
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialog.java
@@ -0,0 +1,175 @@
+package com.tangem.ui.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+
+import com.tangem.card_common.util.Log;
+import com.tangem.wallet.R;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.DialogFragment;
+
+/**
+ * Created by dvol on 06.03.2018.
+ */
+public class WaitSecurityDelayDialog extends DialogFragment {
+ public static final String TAG = WaitSecurityDelayDialog.class.getSimpleName();
+
+ private ProgressBar progressBar;
+ private int msTimeout = 60000, msProgress = 0;
+ private Timer timer;
+
+ private static Timer timerToShowDelayDialog = null;
+ private static WaitSecurityDelayDialog instance = null;
+
+ private final static int minRemainingDelayToShowDialog = 1000;
+ private final static int delayBeforeShowDialog = 5000;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View v = inflater.inflate(R.layout.dialog_wait_pin2, null);
+
+ progressBar = v.findViewById(R.id.progressBar);
+ progressBar.setMax(msTimeout);
+ progressBar.setProgress(msProgress);
+
+ timer = new Timer();
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ progressBar.post(() -> {
+ int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
+ if (progress < WaitSecurityDelayDialog.this.progressBar.getMax()) {
+ WaitSecurityDelayDialog.this.progressBar.setProgress(progress + 1000);
+ }
+ });
+ }
+ }, 1000, 1000);
+ return new AlertDialog.Builder(getActivity())
+ .setIcon(R.drawable.tangem_logo_small_new)
+ .setTitle(R.string.security_delay)
+ .setView(v)
+ .setCancelable(false)
+ .create();
+ }
+
+ @Override
+ public void onCancel(@NonNull DialogInterface dialog) {
+ super.onCancel(dialog);
+ }
+
+ public static void onReadBeforeRequest(final AppCompatActivity activity, final int timeout) {
+ activity.runOnUiThread(() -> {
+ if (timerToShowDelayDialog != null || timeout < delayBeforeShowDialog + minRemainingDelayToShowDialog)
+ return;
+ timerToShowDelayDialog = new Timer();
+ timerToShowDelayDialog.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ if (WaitSecurityDelayDialog.instance != null) return;
+ instance = new WaitSecurityDelayDialog();
+ instance.setup(timeout, delayBeforeShowDialog);
+ instance.setCancelable(false);
+ instance.show(activity.getSupportFragmentManager(), TAG);
+ }
+ }, delayBeforeShowDialog);
+ });
+ }
+
+ public static void onReadAfterRequest(final Activity activity) {
+ activity.runOnUiThread(() -> {
+ if (timerToShowDelayDialog == null) return;
+ timerToShowDelayDialog.cancel();
+ timerToShowDelayDialog = null;
+ });
+ }
+
+ public static void onReadWait(final AppCompatActivity activity, final int msec) {
+ Log.e(TAG, "onReadWait callback(" + msec + ")");
+ activity.runOnUiThread(() -> {
+ Log.e(TAG, "onReadWait on ui thread(" + msec + ")");
+ if (timerToShowDelayDialog != null) {
+ timerToShowDelayDialog.cancel();
+ timerToShowDelayDialog = null;
+ }
+
+ if (msec == 0) {
+ if (instance != null) {
+ if (instance.isAdded()) {
+ instance.dismiss();
+ instance = null;
+ } else {
+ Log.e(TAG, "onReadWait(0) with not added dialog");
+// instance.progressBar.postDelayed(() -> {
+// Log.e(TAG, "onReadWait(0) dismiss delayed");
+ try {
+ instance.dismiss();
+ instance = null;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+// }, 10000);
+ }
+ }
+ return;
+ }
+
+ if (instance == null) {
+ if (msec > delayBeforeShowDialog + minRemainingDelayToShowDialog) {
+ instance = new WaitSecurityDelayDialog();
+ // 1000ms - card delay notification interval
+ instance.setup(msec + 1000, 1000);
+ instance.setCancelable(false);
+ instance.show(activity.getSupportFragmentManager(), TAG);
+ }
+ } else
+ instance.setRemainingTimeout(msec);
+ });
+ }
+
+ private void setup(int msTimeout, int msProgress) {
+ this.msTimeout = msTimeout;
+ this.msProgress = msProgress;
+ }
+
+ private void setRemainingTimeout(final int msec) {
+ progressBar.post(() -> {
+ int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
+ if (timer != null) {
+ // we get delay latency from card for first time - don't change progress by timer, only by card answer
+ progressBar.setMax(progress + msec);
+ timer.cancel();
+ timer = null;
+ } else {
+ int newProgress = progressBar.getMax() - msec;
+ if (newProgress > progress)
+ progressBar.setProgress(newProgress);
+ else
+ progressBar.setMax(progress + msec);
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialogNew.kt b/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialogNew.kt
new file mode 100644
index 0000000000..b9421af27d
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/dialog/WaitSecurityDelayDialogNew.kt
@@ -0,0 +1,156 @@
+package com.tangem.ui.dialog
+
+import android.annotation.SuppressLint
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatDialogFragment
+import android.widget.ProgressBar
+import com.tangem.ui.event.ReadAfterRequest
+import com.tangem.ui.event.ReadBeforeRequest
+import com.tangem.ui.event.ReadWait
+import com.tangem.util.LOG
+import com.tangem.wallet.R
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import java.util.*
+
+class WaitSecurityDelayDialogNew : AppCompatDialogFragment() {
+
+ companion object {
+ val TAG: String = WaitSecurityDelayDialogNew::class.java.simpleName
+
+ private const val MIN_REMAINING_DELAY_TO_SHOW_DIALOG = 1000
+ private const val DELAY_BEFORE_SHOW_DIALOG = 5000
+ }
+
+ private lateinit var pb: ProgressBar
+
+ private var msTimeout = 60000
+ private var msProgress = 0
+ private var timer: Timer? = null
+ private var timerToShowDelayDialog: Timer? = null
+
+ @SuppressLint("InflateParams")
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val inflater = activity!!.layoutInflater
+ val v = inflater.inflate(R.layout.dialog_wait_pin2, null)
+
+ pb = v.findViewById(R.id.progressBar)
+
+ pb.max = msTimeout
+ pb.progress = msProgress
+
+ timer = Timer()
+ timer!!.scheduleAtFixedRate(object : TimerTask() {
+ override fun run() {
+ pb.post {
+ val progress = pb.progress
+ if (progress < pb.max)
+ pb.progress = progress + 1000
+ }
+ }
+ }, 1000, 1000)
+
+ return AlertDialog.Builder(activity)
+ .setIcon(R.drawable.tangem_logo_small_new)
+ .setTitle(R.string.security_delay)
+ .setView(v)
+ .setCancelable(false)
+ .create()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ EventBus.getDefault().register(this)
+ }
+
+ override fun onStop() {
+ super.onStop()
+ EventBus.getDefault().unregister(this)
+ }
+
+ @Subscribe
+ fun readBeforeRequest(readBeforeRequest: ReadBeforeRequest) {
+ LOG.i(TAG, "readBeforeRequest 111")
+
+ if (timerToShowDelayDialog != null || readBeforeRequest.timeout!! < DELAY_BEFORE_SHOW_DIALOG + MIN_REMAINING_DELAY_TO_SHOW_DIALOG)
+ return
+
+ timerToShowDelayDialog = Timer()
+ timerToShowDelayDialog!!.schedule(object : TimerTask() {
+ override fun run() {
+ setup(readBeforeRequest.timeout!!, DELAY_BEFORE_SHOW_DIALOG)
+ isCancelable = false
+
+// if (!isAdded)
+ show(activity!!.supportFragmentManager, TAG)
+
+// if (isHidden)
+// activity?.supportFragmentManager?.let { show(it, TAG) }
+ }
+ }, DELAY_BEFORE_SHOW_DIALOG.toLong())
+ }
+
+ @Subscribe
+ fun readAfterRequest(readAfterRequest: ReadAfterRequest) {
+ LOG.i(TAG, "readAfterRequest 222")
+
+ if (timerToShowDelayDialog == null)
+ return
+
+ timerToShowDelayDialog!!.cancel()
+ timerToShowDelayDialog = null
+ }
+
+ @Subscribe
+ fun readWait(readWait: ReadWait) {
+ LOG.i(TAG, "readWait 333")
+
+ if (timerToShowDelayDialog != null) {
+ timerToShowDelayDialog!!.cancel()
+ timerToShowDelayDialog = null
+ }
+
+ if (readWait.msec == 0) {
+ dismiss()
+ return
+ }
+
+ if (readWait.msec!! > MIN_REMAINING_DELAY_TO_SHOW_DIALOG) {
+ // 1000ms - card delay notification interval
+ setup(readWait.msec!! + 1000, 1000)
+ isCancelable = false
+
+ if (isHidden)
+ activity?.supportFragmentManager?.let { show(it, TAG) }
+
+ } else
+ setRemainingTimeout(readWait.msec!!)
+ }
+
+ private fun setup(msTimeout: Int, msProgress: Int) {
+ this.msTimeout = msTimeout
+ this.msProgress = msProgress
+ }
+
+ private fun setRemainingTimeout(msec: Int) {
+ pb.post {
+ val progress = pb.progress
+ if (timer != null) {
+
+ // we get delay latency from card for first time - don't change progress by timer, only by card answer
+ pb.max = progress + msec
+ timer!!.cancel()
+ timer = null
+ } else {
+ val newProgress = pb.max - msec
+ if (pb.max > progress)
+ pb.progress = newProgress
+ else
+ pb.max = progress + msec
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/event/DeletingWalletFinish.kt b/app/src/main/java/com/tangem/ui/event/DeletingWalletFinish.kt
new file mode 100644
index 0000000000..c9683549d5
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/event/DeletingWalletFinish.kt
@@ -0,0 +1,3 @@
+package com.tangem.ui.event
+
+class DeletingWalletFinish
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/event/ReadAfterRequest.kt b/app/src/main/java/com/tangem/ui/event/ReadAfterRequest.kt
new file mode 100644
index 0000000000..8c61063c75
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/event/ReadAfterRequest.kt
@@ -0,0 +1,3 @@
+package com.tangem.ui.event
+
+class ReadAfterRequest
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/event/ReadBeforeRequest.kt b/app/src/main/java/com/tangem/ui/event/ReadBeforeRequest.kt
new file mode 100644
index 0000000000..203b0e1edb
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/event/ReadBeforeRequest.kt
@@ -0,0 +1,5 @@
+package com.tangem.ui.event
+
+class ReadBeforeRequest {
+ var timeout: Int? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/event/ReadWait.kt b/app/src/main/java/com/tangem/ui/event/ReadWait.kt
new file mode 100644
index 0000000000..cd4e013295
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/event/ReadWait.kt
@@ -0,0 +1,5 @@
+package com.tangem.ui.event
+
+class ReadWait {
+ var msec: Int? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/event/TransactionFinishWithError.kt b/app/src/main/java/com/tangem/ui/event/TransactionFinishWithError.kt
similarity index 64%
rename from app/src/main/java/com/tangem/presentation/event/TransactionFinishWithError.kt
rename to app/src/main/java/com/tangem/ui/event/TransactionFinishWithError.kt
index bc5c5cb58c..fd21ee0083 100644
--- a/app/src/main/java/com/tangem/presentation/event/TransactionFinishWithError.kt
+++ b/app/src/main/java/com/tangem/ui/event/TransactionFinishWithError.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.event
+package com.tangem.ui.event
class TransactionFinishWithError {
var message: String? = null
diff --git a/app/src/main/java/com/tangem/presentation/event/TransactionFinishWithSuccess.kt b/app/src/main/java/com/tangem/ui/event/TransactionFinishWithSuccess.kt
similarity index 65%
rename from app/src/main/java/com/tangem/presentation/event/TransactionFinishWithSuccess.kt
rename to app/src/main/java/com/tangem/ui/event/TransactionFinishWithSuccess.kt
index 689c418d27..00d24a8b33 100644
--- a/app/src/main/java/com/tangem/presentation/event/TransactionFinishWithSuccess.kt
+++ b/app/src/main/java/com/tangem/ui/event/TransactionFinishWithSuccess.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.event
+package com.tangem.ui.event
class TransactionFinishWithSuccess {
var message: String? = null
diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt b/app/src/main/java/com/tangem/ui/fragment/LoadedWalletFragment.kt
similarity index 75%
rename from app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt
rename to app/src/main/java/com/tangem/ui/fragment/LoadedWalletFragment.kt
index fe06ec58f9..d965fa6d2e 100644
--- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt
+++ b/app/src/main/java/com/tangem/ui/fragment/LoadedWalletFragment.kt
@@ -1,4 +1,4 @@
-package com.tangem.presentation.fragment
+package com.tangem.ui.fragment
import android.app.Activity
import android.app.AlertDialog
@@ -6,70 +6,77 @@ import android.content.*
import android.content.Context.CLIPBOARD_SERVICE
import android.content.pm.PackageManager
import android.content.res.ColorStateList
+import android.media.MediaPlayer
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
+import android.os.Build
import android.os.Bundle
-import android.support.v4.app.Fragment
-import android.support.v4.content.ContextCompat
import android.text.Html
+import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProviders
import com.tangem.App
import com.tangem.Constant
import com.tangem.data.Blockchain
import com.tangem.data.network.ServerApiCommon
-import com.tangem.domain.wallet.BalanceValidator
-import com.tangem.domain.wallet.CoinEngine
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.activity.LoadedWalletActivity
-import com.tangem.presentation.activity.PinRequestActivity
-import com.tangem.presentation.activity.PrepareCryptonitWithdrawalActivity
-import com.tangem.presentation.activity.PrepareKrakenWithdrawalActivity
-import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
-import com.tangem.presentation.dialog.PINSwapWarningDialog
-import com.tangem.presentation.dialog.ShowQRCodeDialog
-import com.tangem.presentation.dialog.WaitSecurityDelayDialog
-import com.tangem.presentation.event.TransactionFinishWithError
-import com.tangem.presentation.event.TransactionFinishWithSuccess
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.android.reader.NfcReader
-import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
-import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD_UID
-import com.tangem.tangemcard.data.TangemCard
-import com.tangem.tangemcard.data.loadFromBundle
-import com.tangem.tangemcard.reader.CardProtocol
-import com.tangem.tangemcard.tasks.VerifyCardTask
-import com.tangem.tangemcard.util.Util
-import com.tangem.tangemserver.android.ServerApiTangem
-import com.tangem.tangemserver.android.model.CardVerifyAndGetInfo
+import com.tangem.wallet.BalanceValidator
+import com.tangem.wallet.CoinEngine
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.activity.LoadedWalletActivity
+import com.tangem.ui.activity.PinRequestActivity
+import com.tangem.ui.activity.PrepareCryptonitWithdrawalActivity
+import com.tangem.ui.activity.PrepareKrakenWithdrawalActivity
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.PINSwapWarningDialog
+import com.tangem.ui.dialog.ShowQRCodeDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.ui.event.DeletingWalletFinish
+import com.tangem.ui.event.TransactionFinishWithError
+import com.tangem.ui.event.TransactionFinishWithSuccess
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.card_android.data.loadFromBundle
+import com.tangem.card_common.data.TangemCard
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.VerifyCardTask
+import com.tangem.card_common.util.Util
+import com.tangem.server_android.ServerApiTangem
+import com.tangem.server_android.model.CardVerifyAndGetInfo
import com.tangem.util.LOG
import com.tangem.util.UtilHelper
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.fr_loaded_wallet.*
+import kotlinx.android.synthetic.main.layout_btn_details.*
+import kotlinx.android.synthetic.main.layout_tangem_card.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.io.InputStream
import java.util.*
import kotlin.concurrent.timerTask
-class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener {
+class LoadedWalletFragment : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener {
companion object {
- val TAG: String = LoadedWallet::class.java.simpleName
+ val TAG: String = LoadedWalletFragment::class.java.simpleName
}
+ private lateinit var viewModel: LoadedWalletViewModel
+ private lateinit var ctx: TangemContext
private lateinit var nfcManager: NfcManager
-
+ private lateinit var mpSecondScanSound: MediaPlayer
private var serverApiCommon: ServerApiCommon = ServerApiCommon()
private var serverApiTangem: ServerApiTangem = ServerApiTangem()
-
-
- private lateinit var ctx: TangemContext
-
private var lastTag: Tag? = null
private var lastReadSuccess = true
private var verifyCardTask: VerifyCardTask? = null
@@ -78,25 +85,43 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private var newPIN = ""
private var newPIN2 = ""
private var cardProtocol: CardProtocol? = null
- private val inactiveColor: ColorStateList by lazy { resources.getColorStateList(R.color.btn_dark) }
- private val activeColor: ColorStateList by lazy { resources.getColorStateList(R.color.colorAccent) }
+ private val inactiveColor: ColorStateList by lazy {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ resources.getColorStateList(R.color.btn_dark, activity?.theme)
+ else
+ @Suppress("DEPRECATION")
+ resources.getColorStateList(R.color.btn_dark)
+ }
+ private val activeColor: ColorStateList by lazy {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ resources.getColorStateList(R.color.colorAccent, activity?.theme)
+ else
+ @Suppress("DEPRECATION")
+ resources.getColorStateList(R.color.colorAccent)
+ }
private var requestCounter: Int = 0
set(value) {
field = value
LOG.i(TAG, "requestCounter, set $field")
if (field <= 0) {
LOG.e(TAG, "+++++++++++ FINISH REFRESH")
- if (srl != null && srl.isRefreshing) srl.isRefreshing = false
- //updateViews()
- } else if (srl != null && !srl.isRefreshing) srl.isRefreshing = true
+ if (srl != null && srl.isRefreshing)
+ srl.isRefreshing = false
+ } else if (srl != null && !srl.isRefreshing)
+ srl.isRefreshing = true
}
+
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- nfcManager = NfcManager(activity, this)
-
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
+ nfcManager = NfcManager(activity!!, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
lastTag = activity?.intent?.getParcelableExtra(Constant.EXTRA_LAST_DISCOVERED_TAG)
+
+ mpSecondScanSound = MediaPlayer.create(activity, R.raw.scan_card_sound)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -106,8 +131,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (ctx.blockchain == Blockchain.Token)
- tvBalance.setSingleLine(false)
+ val engine = CoinEngineFactory.create(ctx)
+
+ tvBalance.setSingleLine(!engine!!.needMultipleLinesForBalance())
ivTangemCard.setImageBitmap(App.localStorage.getCardArtworkBitmap(ctx.card))
@@ -121,10 +147,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
tvWallet.setOnClickListener { doShareWallet(false) }
- btnExplore.setOnClickListener {
- val engine = CoinEngineFactory.create(ctx)
- startActivity(Intent(Intent.ACTION_VIEW, engine?.shareWalletUriExplorer))
- }
+ btnExplore.setOnClickListener { startActivity(Intent(Intent.ACTION_VIEW, engine.walletExplorerUri)) }
+
btnCopy.setOnClickListener { doShareWallet(false) }
btnLoad.setOnClickListener {
@@ -135,12 +159,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
when (items[which]) {
getString(R.string.in_app) -> {
try {
- val engine = CoinEngineFactory.create(ctx)
- val intent = Intent(Intent.ACTION_VIEW, engine!!.shareWalletUri)
+ val intent = Intent(Intent.ACTION_VIEW, engine.shareWalletUri)
intent.addCategory(Intent.CATEGORY_DEFAULT)
startActivity(intent)
} catch (e: ActivityNotFoundException) {
- UtilHelper.showSingleToast(context, getString(R.string.no_compatible_wallet))
+ (activity as LoadedWalletActivity).toastHelper.showSingleToast(context, getString(R.string.no_compatible_wallet))
}
}
@@ -149,20 +172,19 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
getString(R.string.load_via_qr) -> {
- val engine = CoinEngineFactory.create(ctx)
- ShowQRCodeDialog.show(activity, engine!!.shareWalletUri.toString())
+ ShowQRCodeDialog.show(activity as AppCompatActivity?, engine.shareWalletUri.toString())
}
getString(R.string.via_cryptonit) -> {
val intent = Intent(activity, PrepareCryptonitWithdrawalActivity::class.java)
ctx.saveToIntent(intent)
- startActivityForResult(intent, Constant.REQUEST_CODE_RECEIVE_PAYMENT)
+ startActivityForResult(intent, Constant.REQUEST_CODE_RECEIVE_TRANSACTION)
}
getString(R.string.via_kraken) -> {
val intent = Intent(activity, PrepareKrakenWithdrawalActivity::class.java)
ctx.saveToIntent(intent)
- startActivityForResult(intent, Constant.REQUEST_CODE_RECEIVE_PAYMENT)
+ startActivityForResult(intent, Constant.REQUEST_CODE_RECEIVE_TRANSACTION)
}
else -> {
}
@@ -175,14 +197,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
btnExtract.setOnClickListener {
- val engine = CoinEngineFactory.create(ctx)
if (UtilHelper.isOnline(context as Activity))
- if (!engine!!.isExtractPossible)
- UtilHelper.showSingleToast(context, ctx.message)
+ if (!engine.isExtractPossible)
+ (activity as LoadedWalletActivity).toastHelper.showSingleToast(context, ctx.message)
else if (ctx.card!!.remainingSignatures == 0)
- UtilHelper.showSingleToast(context, getString(R.string.card_has_no_remaining_signature))
+ (activity as LoadedWalletActivity).toastHelper.showSingleToast(context, getString(R.string.card_has_no_remaining_signature))
else
- (activity as LoadedWalletActivity).navigator.showPreparePayment(context as Activity, ctx)
+ (activity as LoadedWalletActivity).navigator.showPrepareTransaction(context as Activity, ctx)
else
Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
}
@@ -191,7 +212,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
if (cardProtocol != null)
(activity as LoadedWalletActivity).navigator.showVerifyCard(context as Activity, ctx)
else
- UtilHelper.showSingleToast(context, getString(R.string.need_attach_card_again))
+ (activity as LoadedWalletActivity).toastHelper.showSingleToast(context, getString(R.string.need_attach_card_again))
}
btnNewScan.setOnClickListener { (activity as LoadedWalletActivity).navigator.showMain(context as Activity) }
@@ -257,27 +278,25 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
serverApiTangem.setArtworkListener(artworkListener)
- // request rate info listener
- serverApiCommon.setRateInfoData {
- if (activity == null || !UtilHelper.isOnline(activity!!)) return@setRateInfoData
- val rate = it.priceUsd.toFloat()
- ctx.coinData!!.rate = rate
- ctx.coinData!!.rateAlter = rate
- }
-
refresh()
startVerify(lastTag)
}
- override fun onResume() {
- super.onResume()
- nfcManager.onResume()
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ viewModel = ViewModelProviders.of(this).get(LoadedWalletViewModel::class.java)
+
+ // set rate info to CoinData
+ viewModel.getRateInfo().observe(this, Observer { rate ->
+ ctx.coinData.rate = rate
+ ctx.coinData.rateAlter = rate
+ })
+ viewModel.requestRateInfo(ctx)
}
override fun onPause() {
super.onPause()
- nfcManager.onPause()
if (timerHideErrorAndMessage != null) {
timerHideErrorAndMessage!!.cancel()
timerHideErrorAndMessage = null
@@ -290,11 +309,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
EventBus.getDefault().register(this)
}
- override fun onStop() {
- super.onStop()
- nfcManager.onStop()
- }
-
override fun onDestroy() {
EventBus.getDefault().unregister(this)
super.onDestroy()
@@ -303,10 +317,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
@Subscribe
fun onTransactionFinishWithSuccess(transactionFinishWithSuccess: TransactionFinishWithSuccess) {
ctx.message = transactionFinishWithSuccess.message
- ctx.coinData.clearInfo()
+ //ctx.coinData.clearInfo()
updateViews()
- srl?.isRefreshing=true
- srl?.postDelayed({ refresh() }, 5000)
+ //srl?.isRefreshing = true
+ srl?.postDelayed({ refresh() }, 10000)
}
@Subscribe
@@ -315,6 +329,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
updateViews()
}
+ @Subscribe
+ fun onDeleteWalletFinish(deletingWalletFinish: DeletingWalletFinish) {
+ activity?.finish()
+ }
+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
@@ -349,11 +368,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
pinSwapWarningDialog.setOnRefreshPage { (activity as LoadedWalletActivity).navigator.showPinSwap(context as Activity, newPIN, newPIN2) }
val bundle = Bundle()
if (!CardProtocol.isDefaultPIN(newPIN) || !CardProtocol.isDefaultPIN2(newPIN2))
- bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_forget))
+ bundle.putString(Constant.EXTRA_MESSAGE, getString(R.string.if_you_forget))
else
- bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
+ bundle.putString(Constant.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
pinSwapWarningDialog.arguments = bundle
- pinSwapWarningDialog.show(activity?.supportFragmentManager, PINSwapWarningDialog.TAG)
+ activity?.supportFragmentManager?.let { pinSwapWarningDialog.show(it, PINSwapWarningDialog.TAG) }
}
Constant.REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
@@ -377,8 +396,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
(activity as LoadedWalletActivity).navigator.showPinRequestRequestPin2(context as Activity, PinRequestActivity.Mode.RequestPIN2.toString(), ctx)
return
} else {
- if (data != null && data.extras!!.containsKey("message")) {
- ctx.error = data.getStringExtra("message")
+ if (data != null && data.extras!!.containsKey(Constant.EXTRA_MESSAGE)) {
+ ctx.error = data.getStringExtra(Constant.EXTRA_MESSAGE)
}
}
}
@@ -409,14 +428,14 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
return
} else {
- if (data != null && data.extras!!.containsKey("message")) {
- ctx.error = data.getStringExtra("message")
+ if (data != null && data.extras!!.containsKey(Constant.EXTRA_MESSAGE)) {
+ ctx.error = data.getStringExtra(Constant.EXTRA_MESSAGE)
}
}
updateViews()
}
- Constant.REQUEST_CODE_SEND_PAYMENT, Constant.REQUEST_CODE_RECEIVE_PAYMENT -> {
+ Constant.REQUEST_CODE_SEND_TRANSACTION, Constant.REQUEST_CODE_RECEIVE_TRANSACTION -> {
if (resultCode == Activity.RESULT_OK) {
ctx.coinData?.clearInfo()
srl?.postDelayed({ this.refresh() }, 5000)
@@ -430,14 +449,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
ctx.card = updatedCard
}
-// if (data.extras!!.containsKey("message")) {
-// if (resultCode == Activity.RESULT_OK) {
-// ctx.message = data.getStringExtra("message")
-// } else {
-// ctx.error = data.getStringExtra("message")
-// }
-// }
-// updateViews()
}
}
}
@@ -448,8 +459,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
override fun onReadStart(cardProtocol: CardProtocol) {
- if (rlProgressBar != null)
- rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
+ rlProgressBar?.post { rlProgressBar.visibility = View.VISIBLE }
}
override fun onReadProgress(protocol: CardProtocol, progress: Int) {
@@ -463,8 +473,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
rlProgressBar?.post {
rlProgressBar?.visibility = View.GONE
this.cardProtocol = cardProtocol
- if (!cardProtocol.card.isWalletPublicKeyValid) refresh()
- else updateViews()
+ if (!cardProtocol.card.isWalletPublicKeyValid)
+ refresh()
+ else
+ updateViews()
+
+ mpSecondScanSound.start()
}
} else {
// remove last UIDs because of error and no card read
@@ -472,7 +486,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
lastReadSuccess = false
if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
if (!NoExtendedLengthSupportDialog.allReadyShowed)
- NoExtendedLengthSupportDialog().show(activity?.supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+ activity?.supportFragmentManager?.let { NoExtendedLengthSupportDialog().show(it, NoExtendedLengthSupportDialog.TAG) }
else
Toast.makeText(activity, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
}
@@ -500,11 +514,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
override fun onReadWait(msec: Int) {
- WaitSecurityDelayDialog.onReadWait(activity, msec)
+ WaitSecurityDelayDialog.onReadWait(activity as AppCompatActivity?, msec)
}
override fun onReadBeforeRequest(timeout: Int) {
- WaitSecurityDelayDialog.onReadBeforeRequest(activity, timeout)
+ WaitSecurityDelayDialog.onReadBeforeRequest(activity as AppCompatActivity?, timeout)
}
override fun onReadAfterRequest() {
@@ -554,7 +568,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
5000)
}
- if (srl!!.isRefreshing) {
+ if (srl.isRefreshing) {
tvBalanceLine1.setTextColor(resources.getColor(R.color.primary))
tvBalanceLine1.text = getString(R.string.verifying_in_blockchain)
tvBalanceLine2.text = ""
@@ -563,7 +577,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
} else {
val validator = BalanceValidator()
// TODO why attest=false?
- validator.Check(ctx, false)
+ validator.check(ctx, false)
context?.let { ContextCompat.getColor(it, validator.color) }?.let { tvBalanceLine1.setTextColor(it) }
tvBalanceLine1.text = validator.firstLine
tvBalanceLine2.text = validator.getSecondLine(false)
@@ -572,21 +586,32 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
val engine = CoinEngineFactory.create(ctx)
when {
engine!!.hasBalanceInfo() -> {
- val html = Html.fromHtml(engine.balanceHTML)
+ @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(engine.balanceHTML, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(engine.balanceHTML)
tvBalance.text = html
tvBalanceEquivalent.text = engine.balanceEquivalent
}
- ctx.card!!.offlineBalance != null -> {
- val html = Html.fromHtml(engine.offlineBalanceHTML)
+
+ ctx.card?.offlineBalance != null -> {
+ @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(engine.offlineBalanceHTML, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(engine.offlineBalanceHTML)
tvBalance.text = html
}
- else -> tvBalance.text = getString(R.string.no_data_string)
+
+ else -> tvBalance.text = ""
}
tvWallet.text = ctx.coinData!!.wallet
if (ctx.card!!.tokenSymbol.length > 1) {
- val html = Html.fromHtml(ctx.blockchainName)
+ @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(ctx.blockchainName, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(ctx.blockchainName)
tvBlockchain.text = html
} else
tvBlockchain.text = ctx.blockchainName
@@ -599,9 +624,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
btnExtract.backgroundTintList = inactiveColor
}
- //TODO why ???
-// ctx.error = null
-// ctx.message = null
+ if (engine.isNftToken) {
+ btnLoad.isEnabled = false
+ btnLoad.backgroundTintList = inactiveColor
+ btnExtract.isEnabled = false
+ btnExtract.backgroundTintList = inactiveColor
+ }
}
private fun refresh() {
@@ -618,9 +646,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
updateViews()
- // Bitcoin
- // Litecoin
- // BitcoinCash
+ // Bitcoin, Litecoin, BitcoinCash, Stellar
if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet ||
ctx.blockchain == Blockchain.Litecoin || ctx.blockchain == Blockchain.BitcoinCash ||
ctx.blockchain == Blockchain.Stellar || ctx.blockchain == Blockchain.StellarTestNet ) {
@@ -631,10 +657,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
requestBalanceAndUnspentTransactions()
- requestRateInfo()
+ if (::viewModel.isInitialized)
+ viewModel.requestRateInfo(ctx)
- if( requestCounter==0 )
- {
+ if (requestCounter == 0) {
// if no connection and no requests posted
srl?.isRefreshing = false
updateViews()
@@ -647,16 +673,15 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
requestCounter++
coinEngine!!.requestBalanceAndUnspentTransactions(
object : CoinEngine.BlockchainRequestsCallbacks {
+
+
override fun onComplete(success: Boolean) {
- LOG.i(TAG, "requestBalanceAndUnspentTransactions onComplete: " + success.toString() + ", request counter " + requestCounter.toString())
+ LOG.i(TAG, "requestBalanceAndUnspentTransactions onComplete: $success, request counter $requestCounter")
if (activity == null) return
requestCounter--
if (!success) {
LOG.e(TAG, "requestBalanceAndUnspentTransactions ctx.error: " + ctx.error)
}
-// if (!UtilHelper.isOnline(activity!!)) {
-// ctx.error = getString(R.string.no_connection)
-// }
updateViews()
}
@@ -667,7 +692,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
}
override fun allowAdvance(): Boolean {
- return UtilHelper.isOnline(context as Activity)
+ return try {
+ context?.let { UtilHelper.isOnline(it) }!!
+ } catch (e: KotlinNullPointerException) {
+ e.printStackTrace()
+ false
+ }
}
}
)
@@ -687,48 +717,15 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
} else {
ctx.error = getString(R.string.no_connection)
updateViews()
- //Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
- //LOG.e(TAG, "+++++++++++ Hide refresh 1")
- //srl?.isRefreshing = false
- }
- }
-
- private fun requestRateInfo() {
- if (UtilHelper.isOnline(context as Activity)) {
- LOG.i(TAG, "requestRateInfo")
-
- // TODO - move requestRateInfo to CoinEngine
- val cryptoId: String = when (ctx.blockchain) {
- Blockchain.Bitcoin -> "bitcoin"
- Blockchain.BitcoinTestNet -> "bitcoin"
- Blockchain.Ethereum -> "ethereum"
- Blockchain.EthereumTestNet -> "ethereum"
- Blockchain.Token -> "ethereum"
- Blockchain.BitcoinCash -> "bitcoin-cash"
- Blockchain.Litecoin -> "litecoin"
- Blockchain.Stellar -> "stellar"
- Blockchain.StellarTestNet -> "stellar"
- else -> {
- throw Exception("Can''t get rate for blockchain " + ctx.blockchainName)
- }
- }
- serverApiCommon.rateInfoData(cryptoId)
- } else {
- ctx.error = getString(R.string.no_connection)
- updateViews()
-// Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
-// LOG.e(TAG, "+++++++++++ Hide refresh 2")
-// srl?.isRefreshing = false
}
}
private fun startVerify(tag: Tag?) {
try {
val isoDep = IsoDep.get(tag)
- ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
- val uid = tag!!.id
+ val uid = tag?.id
val sUID = Util.byteArrayToHexString(uid)
- if (ctx.card.uid != sUID) {
+ if (ctx.card.uid != sUID || cardProtocol != null) {
nfcManager.ignoreTag(isoDep.tag)
return
}
@@ -748,10 +745,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private fun doShareWallet(useURI: Boolean) {
if (useURI) {
val engine = CoinEngineFactory.create(ctx)
- val txtShare = engine!!.shareWalletUri.toString()
+ val txtShare = engine?.shareWalletUri.toString()
val intent = Intent(Intent.ACTION_SEND)
- intent.type = "text/plain"
- intent.putExtra(Intent.EXTRA_SUBJECT, "Wallet address")
+ intent.type = Constant.INTENT_TYPE_TEXT_PLAIN
+ intent.putExtra(Intent.EXTRA_SUBJECT, Constant.WALLET_ADDRESS)
intent.putExtra(Intent.EXTRA_TEXT, txtShare)
val packageManager = activity?.packageManager
diff --git a/app/src/main/java/com/tangem/ui/fragment/LoadedWalletViewModel.kt b/app/src/main/java/com/tangem/ui/fragment/LoadedWalletViewModel.kt
new file mode 100644
index 0000000000..8d59f49b1a
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/fragment/LoadedWalletViewModel.kt
@@ -0,0 +1,42 @@
+package com.tangem.ui.fragment
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.tangem.data.Blockchain
+import com.tangem.data.network.ServerApiCommon
+import com.tangem.data.network.ServerApiCommon.RateInfoListener
+import com.tangem.data.network.model.RateInfoResponse
+import com.tangem.wallet.TangemContext
+
+class LoadedWalletViewModel : ViewModel() {
+ private var serverApiCommon: ServerApiCommon = ServerApiCommon()
+ private lateinit var ctx: TangemContext
+ private val rate: MutableLiveData by lazy {
+ MutableLiveData().also {
+ loadRateInfo()
+ }
+ }
+
+ fun getRateInfo(): LiveData {
+ return rate
+ }
+
+ fun requestRateInfo(ctx: TangemContext) {
+ this.ctx = ctx
+ // TODO - move loadRateInfo to CoinEngine
+ serverApiCommon.requestRateInfo(ctx.blockchain.currency)
+ }
+
+ private fun loadRateInfo() {
+ serverApiCommon.setRateInfoListener(object: RateInfoListener{
+ override fun onSuccess(rateInfoResponse: RateInfoResponse?) {
+ rate.value = rateInfoResponse!!.data!!.quote!!.usd!!.price
+ }
+
+ override fun onFail(message: String?) {
+ ctx.error = message
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt b/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt
new file mode 100644
index 0000000000..0772abc5ab
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt
@@ -0,0 +1,346 @@
+package com.tangem.ui.fragment
+
+import android.app.Activity
+import android.content.Intent
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.nfc.tech.IsoDep
+import android.os.Bundle
+import android.view.*
+import android.widget.PopupMenu
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProviders
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.card_android.data.loadFromBundle
+import com.tangem.card_android.data.saveToBundle
+import com.tangem.card_common.data.TangemCard
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.CustomReadCardTask
+import com.tangem.card_common.tasks.ReadCardInfoTask
+import com.tangem.data.Logger
+import com.tangem.data.network.ServerApiCommon
+import com.tangem.ui.activity.MainActivity
+import com.tangem.ui.activity.PinRequestActivity
+import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
+import com.tangem.ui.dialog.WaitSecurityDelayDialog
+import com.tangem.util.CommonUtil
+import com.tangem.util.LOG
+import com.tangem.util.UtilHelper
+import com.tangem.wallet.BuildConfig
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.R
+import com.tangem.wallet.TangemContext
+import kotlinx.android.synthetic.main.layout_touch_card.*
+import kotlinx.android.synthetic.main.main_fragment.*
+import java.io.File
+import java.util.*
+
+class MainFragment : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener, PopupMenu.OnMenuItemClickListener {
+
+ companion object {
+ fun newInstance() = MainFragment()
+ val TAG: String = MainFragment::class.java.simpleName
+ }
+
+ private lateinit var viewModel: MainViewModel
+ private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
+ private var unsuccessReadCount = 0
+ private lateinit var nfcManager: NfcManager
+ private var task: CustomReadCardTask? = null
+ private var lastTag: Tag? = null
+ private var zipFile: File? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ nfcManager = NfcManager(activity!!, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ setHasOptionsMenu(true)
+ return inflater.inflate(R.layout.main_fragment, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ rippleBackgroundNfc.startRippleAnimation()
+
+ // init NFC Antenna
+ nfcDeviceAntenna = NfcDeviceAntennaLocation(context!!, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
+ nfcDeviceAntenna.init()
+
+ // set phone name
+ if (nfcDeviceAntenna.fullName != "")
+ tvNFCHint.text = String.format(getString(R.string.scan_banknote), nfcDeviceAntenna.fullName)
+ else
+ tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
+
+ // set listeners
+ fab.setOnClickListener { showMenu(it) }
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
+
+ // show snackbar about new version app
+ viewModel.getVersionName().observe(this, Observer { text ->
+ (activity as MainActivity).toastHelper.showSnackbarUpdateVersion(context!!, cl, text)
+ })
+
+ val intent = activity?.intent
+ if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
+ val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
+ onTagDiscovered(tag)
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ nfcDeviceAntenna.animate()
+ }
+
+ override fun onPause() {
+ task?.cancel(true)
+ super.onPause()
+ }
+
+ override fun onStop() {
+ task?.cancel(true)
+ super.onStop()
+ }
+
+ override fun onTagDiscovered(tag: Tag) {
+ try {
+ // get IsoDep handle and run cardReader thread
+ val isoDep = IsoDep.get(tag)
+ if (unsuccessReadCount < 2)
+ isoDep.timeout = 2000 + 5000 * unsuccessReadCount
+ else
+ isoDep.timeout = 90000
+
+ lastTag = tag
+
+ task = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
+ task?.start()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ nfcManager.notifyReadResult(false)
+ }
+ }
+
+ override fun onReadStart(cardProtocol: CardProtocol) {
+ rlProgressBar?.post { rlProgressBar?.visibility = View.VISIBLE }
+ }
+
+ override fun onReadProgress(protocol: CardProtocol, progress: Int) {
+
+ }
+
+ override fun onReadFinish(cardProtocol: CardProtocol?) {
+ task = null
+ if (cardProtocol != null) {
+ if (cardProtocol.error == null) {
+ nfcManager.notifyReadResult(true)
+ rlProgressBar?.post {
+ rlProgressBar?.visibility = View.GONE
+
+ // TODO - ??? remove save and load???
+ val cardInfo = Bundle()
+ val bCard = Bundle()
+
+ cardInfo.putString(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ cardInfo.putBundle(EXTRA_TANGEM_CARD, bCard)
+ cardProtocol.card.saveToBundle(bCard)
+
+ val uid = cardInfo.getString(EXTRA_TANGEM_CARD_UID)
+ val card = TangemCard(uid)
+ cardInfo.getBundle(EXTRA_TANGEM_CARD)?.let { card.loadFromBundle(it) }
+
+ val ctx = TangemContext(card)
+ when {
+ card.status == TangemCard.Status.Loaded -> lastTag?.let {
+ val engineCoin = CoinEngineFactory.create(ctx)
+ if (engineCoin != null) {
+ engineCoin.defineWallet()
+
+// val bundle = Bundle()
+// bundle.putParcelable(Constant.EXTRA_LAST_DISCOVERED_TAG, lastTag)
+// ctx.saveToBundle(bundle)
+// (activity as MainActivity).navController.navigate(R.id.loadedWallet, bundle)
+
+ (activity as MainActivity).navigator.showLoadedWallet(activity!!, it, ctx)
+ }
+ }
+ card.status == TangemCard.Status.Empty -> (activity as MainActivity).navigator.showEmptyWallet(activity!!, ctx)
+ card.status == TangemCard.Status.Purged -> Toast.makeText(context, R.string.erased_wallet, Toast.LENGTH_SHORT).show()
+ card.status == TangemCard.Status.NotPersonalized -> Toast.makeText(context, R.string.not_personalized, Toast.LENGTH_SHORT).show()
+ else -> {
+
+// val bundle = Bundle()
+// bundle.putParcelable(Constant.EXTRA_LAST_DISCOVERED_TAG, lastTag)
+// ctx.saveToBundle(bundle)
+// navController.navigate(R.id.loadedWallet, bundle)
+
+// lastTag?.let { navigator.showLoadedWallet(this, it, ctx) }
+ }
+ }
+ }
+
+ } else {
+ // remove last UIDs because of error and no card read
+ rlProgressBar.post {
+ Toast.makeText(context, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
+ unsuccessReadCount++
+
+ if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN)
+ (activity as MainActivity).navigator.showPinRequest(activity!!, PinRequestActivity.Mode.RequestPIN.toString())
+ else {
+ if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
+ if (!NoExtendedLengthSupportDialog.allReadyShowed)
+ NoExtendedLengthSupportDialog().show(activity!!.supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+
+ lastTag = null
+ ReadCardInfoTask.resetLastReadInfo()
+ nfcManager.notifyReadResult(false)
+ }
+ }
+ }
+ }
+
+ rlProgressBar.postDelayed({
+ try {
+ rlProgressBar.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onReadCancel() {
+ task = null
+ ReadCardInfoTask.resetLastReadInfo()
+ rlProgressBar.postDelayed({
+ try {
+ rlProgressBar.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ when (requestCode) {
+ Constant.REQUEST_CODE_SEND_EMAIL -> {
+ if (zipFile != null) {
+ zipFile!!.delete()
+ zipFile = null
+ }
+ }
+ Constant.REQUEST_CODE_ENTER_PIN_ACTIVITY -> {
+ if (resultCode == Activity.RESULT_OK && lastTag != null)
+ onTagDiscovered(lastTag!!)
+ else
+ ReadCardInfoTask.resetLastReadInfo()
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ inflater.inflate(R.menu.menu_main, menu)
+ if (BuildConfig.DEBUG) {
+ for (i in 0 until menu.size()) menu.getItem(i).isVisible = true
+ }
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.sendLogs -> {
+ var f: File? = null
+ try {
+ f = Logger.collectLogs(activity)
+ if (f != null) {
+ LOG.e(TAG, String.format("Collect %d log bytes", f.length()))
+ CommonUtil.sendEmail(activity, zipFile, TAG, "Logs", UtilHelper.getDeviceInfo(), arrayOf(f))
+ } else {
+ LOG.e(TAG, "Can't create temporarily log file")
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ } finally {
+ if (f != null && f.exists())
+ f.delete()
+ }
+ return true
+ }
+ R.id.managePIN -> {
+ (activity as MainActivity).navigator.showPinSave(activity!!, false)
+// (activity as MainActivity).navController.navigate(R.id.pinSaveActivity)
+ return true
+ }
+
+ R.id.managePIN2 -> {
+ (activity as MainActivity).navigator.showPinSave(activity!!, true)
+// (activity as MainActivity).navController.navigate(R.id.pinSaveActivity)
+ return true
+ }
+
+ R.id.settings -> {
+ (activity as MainActivity).navigator.showSettings(activity!!)
+// (activity as MainActivity).navController.navigate(R.id.settingsActivity)
+ return true
+ }
+
+ R.id.about -> {
+ (activity as MainActivity).navigator.showLogo(activity!!, false)
+// (activity as MainActivity).navController.navigate(R.id.logoActivity)
+ return true
+ }
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ override fun onReadWait(msec: Int) {
+ WaitSecurityDelayDialog.onReadWait(Objects.requireNonNull(activity) as AppCompatActivity?, msec)
+ }
+
+ override fun onReadBeforeRequest(timeout: Int) {
+ WaitSecurityDelayDialog.onReadBeforeRequest(Objects.requireNonNull(activity) as AppCompatActivity?, timeout)
+ }
+
+ override fun onReadAfterRequest() {
+ WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(activity))
+ }
+
+ override fun onMenuItemClick(item: MenuItem?): Boolean {
+ return onOptionsItemSelected(item!!)
+ }
+
+ private fun showMenu(v: View) {
+ val popup = PopupMenu(context, v)
+ val inflater = popup.menuInflater
+ inflater.inflate(R.menu.menu_main, popup.menu)
+
+ if (BuildConfig.DEBUG) {
+ popup.menu.findItem(R.id.managePIN).isEnabled = true
+ popup.menu.findItem(R.id.managePIN2).isEnabled = true
+ popup.menu.findItem(R.id.sendLogs).isVisible = true
+ }
+
+ popup.setOnMenuItemClickListener(this)
+ popup.show()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/fragment/MainViewModel.kt b/app/src/main/java/com/tangem/ui/fragment/MainViewModel.kt
new file mode 100644
index 0000000000..d9b47667c1
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/fragment/MainViewModel.kt
@@ -0,0 +1,38 @@
+package com.tangem.ui.fragment
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.tangem.Constant
+import com.tangem.data.network.ServerApiCommon
+import com.tangem.wallet.BuildConfig
+
+class MainViewModel : ViewModel() {
+ private var serverApiCommon: ServerApiCommon = ServerApiCommon()
+
+ private var versionName = MutableLiveData()
+
+ fun getVersionName(): LiveData {
+ versionName = MutableLiveData()
+ requestVersionName()
+ return versionName
+ }
+
+ private fun requestVersionName() {
+ serverApiCommon.setLastVersionListener { response ->
+ try {
+ if (response.isNullOrEmpty())
+ return@setLastVersionListener
+ val responseVersionName = response.trim(' ', '\n', '\r', '\t')
+ val responseBuildVersion = responseVersionName.split('.').last()
+ val appBuildVersion = BuildConfig.VERSION_NAME.split('.').last()
+ if (responseBuildVersion.toInt() > appBuildVersion.toInt())
+ if (BuildConfig.FLAVOR.equals(Constant.FLAVOR_TANGEM_ACCESS))
+ versionName.value = responseVersionName
+ } catch (E: Exception) {
+ E.printStackTrace()
+ }
+ }
+ serverApiCommon.requestLastVersion()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt b/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt
new file mode 100644
index 0000000000..95f604cba2
--- /dev/null
+++ b/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt
@@ -0,0 +1,25 @@
+package com.tangem.ui.fragment
+
+import android.os.Bundle
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceFragmentCompat
+import com.tangem.wallet.BuildConfig
+import com.tangem.wallet.R
+
+class SettingsFragment : PreferenceFragmentCompat() {
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ addPreferencesFromResource(R.xml.pref_main)
+
+ val categoryCommon = findPreference(getString(R.string.pref_category_common))
+ val selectNodes = findPreference(getString(R.string.pref_select_nodes))
+ val encryptionModes = findPreference(getString(R.string.pref_encryption_modes))
+
+ if (!BuildConfig.DEBUG) {
+ categoryCommon?.removePreference(selectNodes)
+ categoryCommon?.removePreference(encryptionModes)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt b/app/src/main/java/com/tangem/ui/fragment/VerifyCard.kt
similarity index 76%
rename from app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt
rename to app/src/main/java/com/tangem/ui/fragment/VerifyCard.kt
index b9247d0270..f11b61e502 100644
--- a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt
+++ b/app/src/main/java/com/tangem/ui/fragment/VerifyCard.kt
@@ -1,12 +1,11 @@
-package com.tangem.presentation.fragment
+package com.tangem.ui.fragment
import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
+import android.os.Build
import android.os.Bundle
-import android.support.v4.app.Fragment
-import android.support.v4.content.ContextCompat
import android.text.Html
import android.text.format.DateUtils
import android.view.LayoutInflater
@@ -14,31 +13,38 @@ import android.view.View
import android.view.ViewGroup
import android.widget.PopupMenu
import android.widget.Toast
+import androidx.core.content.ContextCompat
import com.tangem.App
import com.tangem.Constant
+import com.tangem.card_android.android.data.PINStorage
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD
+import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
+import com.tangem.card_android.data.loadFromBundle
+import com.tangem.card_common.data.TangemCard
+import com.tangem.card_common.reader.CardProtocol
import com.tangem.data.Blockchain
-import com.tangem.domain.wallet.CoinEngineFactory
-import com.tangem.domain.wallet.TangemContext
-import com.tangem.presentation.activity.*
-import com.tangem.presentation.dialog.PINSwapWarningDialog
-import com.tangem.tangemcard.android.data.PINStorage
-import com.tangem.tangemcard.android.reader.NfcManager
-import com.tangem.tangemcard.data.TangemCard
-import com.tangem.tangemcard.data.loadFromBundle
-import com.tangem.tangemcard.reader.CardProtocol
+import com.tangem.wallet.CoinEngineFactory
+import com.tangem.wallet.TangemContext
+import com.tangem.ui.activity.PinRequestActivity
+import com.tangem.ui.activity.VerifyCardActivity
+import com.tangem.ui.dialog.PINSwapWarningDialog
+import com.tangem.ui.event.DeletingWalletFinish
import com.tangem.wallet.BuildConfig
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.fr_verify_card.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
import java.io.IOException
import java.util.*
-class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
-
+class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
companion object {
val TAG: String = VerifyCard::class.java.simpleName
}
- private var nfcManager: NfcManager? = null
+ private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
private var requestPIN2Count = 0
@@ -48,9 +54,10 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- nfcManager = NfcManager(activity, this)
-
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
+
+ nfcManager = NfcManager(activity!!, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -59,7 +66,6 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
-
updateViews()
srlVerifyCard.setOnRefreshListener { srlVerifyCard.isRefreshing = false }
@@ -69,103 +75,104 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
btnOk.setOnClickListener {
val data = prepareResultIntent()
- data.putExtra(Constant.EXTRA_MODIFICATION, "update")
+ data.putExtra(Constant.EXTRA_MODIFICATION, getString(R.string.update))
activity?.finish()
}
}
- override fun onResume() {
- super.onResume()
- nfcManager!!.onResume()
+ override fun onStart() {
+ super.onStart()
+ if (!EventBus.getDefault().isRegistered(this))
+ EventBus.getDefault().register(this)
}
- override fun onPause() {
- super.onPause()
- nfcManager!!.onPause()
+ override fun onDestroy() {
+ EventBus.getDefault().unregister(this)
+ super.onDestroy()
}
- override fun onStop() {
- super.onStop()
- nfcManager!!.onStop()
+ @Subscribe
+ fun onDeleteWalletFinish(deletingWalletFinish: DeletingWalletFinish) {
+ activity?.finish()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-// var data = data
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
Constant.REQUEST_CODE_ENTER_NEW_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data != null) {
- if (data.extras!!.containsKey("confirmPIN")) {
+ if (data.extras!!.containsKey(Constant.EXTRA_CONFIRM_PIN)) {
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
- newPIN = data.getStringExtra("newPIN")
+ newPIN = data.getStringExtra(Constant.EXTRA_NEW_PIN)
startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("newPIN", data.getStringExtra("newPIN"))
- intent.putExtra("mode", PinRequestActivity.Mode.ConfirmNewPIN.toString())
+ intent.putExtra(Constant.EXTRA_NEW_PIN, data.getStringExtra(Constant.EXTRA_NEW_PIN))
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.ConfirmNewPIN.toString())
startActivityForResult(intent, Constant.REQUEST_CODE_ENTER_NEW_PIN)
}
}
}
+
Constant.REQUEST_CODE_ENTER_NEW_PIN2 -> if (resultCode == Activity.RESULT_OK) {
if (data != null) {
- if (data.extras!!.containsKey("confirmPIN2")) {
+ if (data.extras!!.containsKey(Constant.EXTRA_CONFIRM_PIN_2)) {
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
- newPIN2 = data.getStringExtra("newPIN2")
+ newPIN2 = data.getStringExtra(Constant.EXTRA_NEW_PIN_2)
startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("newPIN2", data.getStringExtra("newPIN2"))
- intent.putExtra("mode", PinRequestActivity.Mode.ConfirmNewPIN2.toString())
+ intent.putExtra(Constant.EXTRA_NEW_PIN_2, data.getStringExtra(Constant.EXTRA_NEW_PIN_2))
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.ConfirmNewPIN2.toString())
startActivityForResult(intent, Constant.REQUEST_CODE_ENTER_NEW_PIN2)
}
}
}
+
Constant.REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (newPIN == "") newPIN = ctx.card!!.pin
- if (newPIN2 == "") newPIN2 = App.pinStorage.getPIN2()
+ if (newPIN2 == "") newPIN2 = App.pinStorage.piN2
val pinSwapWarningDialog = PINSwapWarningDialog()
pinSwapWarningDialog.setOnRefreshPage { (activity as VerifyCardActivity).navigator.showPinSwap(context as Activity, newPIN, newPIN2) }
val bundle = Bundle()
if (!CardProtocol.isDefaultPIN(newPIN) || !CardProtocol.isDefaultPIN2(newPIN2))
- bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_forget))
+ bundle.putString(Constant.EXTRA_MESSAGE, getString(R.string.if_you_forget))
else
- bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
+ bundle.putString(Constant.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
pinSwapWarningDialog.arguments = bundle
- pinSwapWarningDialog.show(activity?.supportFragmentManager, PINSwapWarningDialog.TAG)
+ activity?.supportFragmentManager?.let { pinSwapWarningDialog.show(it, PINSwapWarningDialog.TAG) }
}
Constant.REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
-// data = Intent()
ctx.saveToIntent(data)
- data?.putExtra("modification", "delete")
+ data?.putExtra(Constant.EXTRA_MODIFICATION, Constant.EXTRA_MODIFICATION_DELETE)
} else
- data.putExtra("modification", "update")
- activity!!.setResult(Activity.RESULT_OK, data)
- activity!!.finish()
+ data.putExtra(Constant.EXTRA_MODIFICATION, Constant.EXTRA_MODIFICATION_UPDATE)
+ activity?.setResult(Activity.RESULT_OK, data)
+ activity?.finish()
} else {
- if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
- val updatedCard = TangemCard(data.getStringExtra("UID"))
- updatedCard.loadFromBundle(data.getBundleExtra("Card"))
+ if (data != null && data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
+ val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
+ updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
ctx.card = updatedCard
}
if (resultCode == Constant.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
return
} else {
- if (data != null && data.extras!!.containsKey("message")) {
- ctx.error = data.getStringExtra("message")
+ if (data != null && data.extras!!.containsKey(Constant.EXTRA_MESSAGE)) {
+ ctx.error = data.getStringExtra(Constant.EXTRA_MESSAGE)
}
}
}
@@ -173,19 +180,10 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
Constant.REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK)
(activity as VerifyCardActivity).navigator.showPurge(context as Activity, ctx)
- Constant.REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
- if (data == null) {
- ctx.saveToIntent(data)
- data?.putExtra(Constant.EXTRA_MODIFICATION, "delete")
- } else {
- data.putExtra(Constant.EXTRA_MODIFICATION, "update")
- }
- activity!!.setResult(Activity.RESULT_OK, data)
- activity!!.finish()
- } else {
- if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
- val updatedCard = TangemCard(data.getStringExtra("UID"))
- updatedCard.loadFromBundle(data.getBundleExtra("Card"))
+ else {
+ if (data != null && data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
+ val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
+ updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
ctx.card = updatedCard
}
if (resultCode == Constant.RESULT_INVALID_PIN && requestPIN2Count < 2) {
@@ -196,8 +194,8 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
return
} else {
- if (data != null && data.extras!!.containsKey("message")) {
- ctx.error = data.getStringExtra("message")
+ if (data != null && data.extras!!.containsKey(Constant.EXTRA_MESSAGE)) {
+ ctx.error = data.getStringExtra(Constant.EXTRA_MESSAGE)
}
}
updateViews()
@@ -205,9 +203,9 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
}
}
- override fun onTagDiscovered(tag: Tag) {
+ override fun onTagDiscovered(tag: Tag?) {
try {
- nfcManager!!.ignoreTag(tag)
+ nfcManager.ignoreTag(tag!!)
} catch (e: IOException) {
e.printStackTrace()
}
@@ -250,7 +248,11 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
tvIssuer.text = ctx.card!!.issuerDescription
tvCardRegistredDate.text = DateUtils.formatDateTime(null, ctx.card!!.personalizationDateTime.time, DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NUMERIC_DATE or DateUtils.FORMAT_SHOW_YEAR)
- val html = Html.fromHtml(ctx.blockchainName)
+
+ @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(ctx.blockchainName, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(ctx.blockchainName)
tvBlockchain.text = html
tvValidationNode.text = ctx.coinData!!.validationNodeDescription
@@ -266,7 +268,21 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
else
tvReusable.setText(R.string.one_off_banknote)
- tvSigningMethod.text = ctx.card!!.signingMethod.description
+ var s=""
+ for(signingM in ctx.card!!.allowedSigningMethod) {
+ s += if(signingM==ctx.card!!.signingMethod) {
+ ", ${signingM.description}"
+ } else {
+ ", ${signingM.description}"
+ }
+ }
+ s=s.substring(2,s.length)
+ @Suppress("DEPRECATION")
+ tvSigningMethod.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ Html.fromHtml(s, Html.FROM_HTML_MODE_LEGACY)
+ else
+ Html.fromHtml(s)
+
if (ctx.card!!.status == TangemCard.Status.Loaded || ctx.card!!.status == TangemCard.Status.Purged) {
@@ -369,20 +385,6 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
tvWallet!!.setText(R.string.not_available)
tvWalletIdentity.setText(R.string.no_data_string)
}
-
-// timerHideErrorAndMessage = Timer()
-// timerHideErrorAndMessage!!.schedule(object : TimerTask() {
-// override fun run() {
-// tvError.post {
-// tvMessage!!.visibility = View.GONE
-// tvError!!.visibility = View.GONE
-// mCard!!.error = null
-// mCard!!.message = null
-// }
-// }
-// }, 5000)
-
-
} catch (e: Exception) {
e.printStackTrace()
}
@@ -391,7 +393,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
private fun doSetPin() {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestNewPIN.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestNewPIN.toString())
newPIN = ""
newPIN2 = ""
startActivityForResult(intent, Constant.REQUEST_CODE_ENTER_NEW_PIN)
@@ -400,7 +402,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
private fun doResetPin() {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
newPIN = PINStorage.getDefaultPIN()
newPIN2 = ""
@@ -410,7 +412,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
private fun doResetPin2() {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
newPIN = ""
newPIN2 = PINStorage.getDefaultPIN2()
@@ -420,7 +422,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
private fun doResetPins() {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
newPIN = PINStorage.getDefaultPIN()
newPIN2 = PINStorage.getDefaultPIN2()
@@ -430,7 +432,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
private fun doSetPin2() {
requestPIN2Count = 0
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestNewPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestNewPIN2.toString())
newPIN = ""
newPIN2 = ""
startActivityForResult(intent, Constant.REQUEST_CODE_ENTER_NEW_PIN2)
@@ -447,7 +449,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
}
val intent = Intent(context, PinRequestActivity::class.java)
- intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
+ intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString())
ctx.saveToIntent(intent)
startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
}
diff --git a/app/src/main/java/com/tangem/util/CryptoUtil.java b/app/src/main/java/com/tangem/util/CryptoUtil.java
index 495c29175e..cde631f591 100644
--- a/app/src/main/java/com/tangem/util/CryptoUtil.java
+++ b/app/src/main/java/com/tangem/util/CryptoUtil.java
@@ -2,8 +2,8 @@ package com.tangem.util;
import android.util.Log;
-import com.tangem.domain.wallet.ECDSASignatureETH;
-import com.tangem.tangemcard.util.Util;
+import com.tangem.wallet.ECDSASignatureETH;
+import com.tangem.card_common.util.Util;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1Integer;
@@ -155,7 +155,7 @@ public class CryptoUtil {
// See Bitcoin Core's IsCanonicalSignature, https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
// A canonical signature exists of: <30> <02> <02>
// Where R and S are not negative (their first byte has its highest bit not set), and not
- // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
+ // excessively padded (do not init with a 0 byte, unless an otherwise negative number follows,
// in which case a single 0 byte is necessary and even required).
if (signature.length < 9 || signature.length > 73)
return false;
diff --git a/app/src/main/java/com/tangem/util/DerEncodingUtil.java b/app/src/main/java/com/tangem/util/DerEncodingUtil.java
index a7894d6e44..3ff4a66391 100644
--- a/app/src/main/java/com/tangem/util/DerEncodingUtil.java
+++ b/app/src/main/java/com/tangem/util/DerEncodingUtil.java
@@ -1,6 +1,6 @@
package com.tangem.util;
-import com.tangem.domain.wallet.btc.BitcoinOutputStream;
+import com.tangem.wallet.btc.BitcoinOutputStream;
import org.spongycastle.asn1.ASN1Integer;
import org.spongycastle.asn1.DERSequenceGenerator;
diff --git a/app/src/main/java/com/tangem/util/DeviceName.java b/app/src/main/java/com/tangem/util/DeviceName.java
index 0879e7f674..f577dd16bb 100644
--- a/app/src/main/java/com/tangem/util/DeviceName.java
+++ b/app/src/main/java/com/tangem/util/DeviceName.java
@@ -28,7 +28,7 @@ package com.tangem.util;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
- import android.support.annotation.WorkerThread;
+ import androidx.annotation.WorkerThread;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.IOException;
diff --git a/app/src/main/java/com/tangem/util/PhoneUtility.java b/app/src/main/java/com/tangem/util/PhoneUtility.java
deleted file mode 100644
index 9bb2f92515..0000000000
--- a/app/src/main/java/com/tangem/util/PhoneUtility.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.tangem.util;
-
-import android.os.Build;
-
-/**
- * Created by Ilia on 20.04.2018.
- */
-
-public class PhoneUtility {
- public static String GetPhoneName()
- {
- return DeviceName.getDeviceName();
-
- }
-
- public static String getDeviceInfo() {
- StringBuilder stringBuilder = new StringBuilder();
-
- stringBuilder.append("----------------------------------------\n");
- stringBuilder.append("MODEL: ").append(Build.MODEL).append("\n");
- stringBuilder.append("ID: ").append(Build.ID).append("\n");
- stringBuilder.append("Manufacturer: ").append(Build.MANUFACTURER).append("\n");
- stringBuilder.append("Brand: ").append(Build.BRAND).append("\n");
- stringBuilder.append("Hardware: ").append(Build.HARDWARE).append("\n");
- stringBuilder.append("Version: ").append(Build.VERSION.RELEASE).append(", ").append(Build.VERSION.INCREMENTAL).append("\n");
- stringBuilder.append("OS: ").append(Build.VERSION.BASE_OS).append("\n");
- stringBuilder.append("SDK: ").append(Build.VERSION.SDK_INT).append("\n");
- stringBuilder.append("BOARD: ").append(Build.BOARD).append("\n");
- stringBuilder.append("FINGERPRINT: ").append(Build.FINGERPRINT).append("\n");
- stringBuilder.append("----------------------------------------\n");
-
- return stringBuilder.toString();
-
- }
-}
diff --git a/app/src/main/java/com/tangem/util/UtilHelper.kt b/app/src/main/java/com/tangem/util/UtilHelper.kt
index 9b144c074e..914520d6e2 100644
--- a/app/src/main/java/com/tangem/util/UtilHelper.kt
+++ b/app/src/main/java/com/tangem/util/UtilHelper.kt
@@ -1,11 +1,11 @@
package com.tangem.util
-import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.net.ConnectivityManager
import android.net.NetworkInfo
+import android.os.Build
import android.widget.Toast
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
@@ -37,7 +37,7 @@ object UtilHelper {
return bmp
}
- fun isOnline(context: Activity): Boolean {
+ fun isOnline(context: Context): Boolean {
return try {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val netInfo: NetworkInfo?
@@ -49,19 +49,19 @@ object UtilHelper {
}
}
- private var singleToast: Toast? = null
- private var showTime: Date = Date()
-
- fun showSingleToast(context: Context?, text: String) {
- if (singleToast == null || !singleToast!!.view.isShown || showTime.time + 2000 < Date().time) {
- if (singleToast != null)
- singleToast!!.cancel()
- if (context != null) {
- singleToast = Toast.makeText(context, text, Toast.LENGTH_LONG)
- singleToast!!.show()
- showTime = Date()
- }
- }
+ fun getDeviceInfo(): String {
+ return "----------------------------------------\n" +
+ "MODEL: " + Build.MODEL + "\n" +
+ "ID: " + Build.ID + "\n" +
+ "Manufacturer: " + Build.MANUFACTURER + "\n" +
+ "Brand: " + Build.BRAND + "\n" +
+ "Hardware: " + Build.HARDWARE + "\n" +
+ "Version: " + Build.VERSION.RELEASE + ", " + Build.VERSION.INCREMENTAL + "\n" +
+ "OS: " + Build.VERSION.BASE_OS + "\n" +
+ "SDK: " + Build.VERSION.SDK_INT + "\n" +
+ "BOARD: " + Build.BOARD + "\n" +
+ "FINGERPRINT: " + Build.FINGERPRINT + "\n" +
+ "----------------------------------------\n"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/BCHUtils.java b/app/src/main/java/com/tangem/wallet/BCHUtils.java
similarity index 98%
rename from app/src/main/java/com/tangem/domain/wallet/BCHUtils.java
rename to app/src/main/java/com/tangem/wallet/BCHUtils.java
index 91da8e43cf..7c36d50153 100644
--- a/app/src/main/java/com/tangem/domain/wallet/BCHUtils.java
+++ b/app/src/main/java/com/tangem/wallet/BCHUtils.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 29.09.2017.
@@ -6,12 +6,12 @@ package com.tangem.domain.wallet;
import android.util.Log;
-import com.tangem.domain.wallet.btc.BitcoinException;
-import com.tangem.domain.wallet.btc.BitcoinOutputStream;
-import com.tangem.domain.wallet.btc.BtcData;
+import com.tangem.wallet.btc.BitcoinException;
+import com.tangem.wallet.btc.BitcoinOutputStream;
+import com.tangem.wallet.btc.BtcData;
import com.tangem.util.CryptoUtil;
import com.tangem.util.FormatUtil;
-import com.tangem.tangemcard.util.Util;
+import com.tangem.card_common.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
diff --git a/app/src/main/java/com/tangem/domain/wallet/BTCUtils.java b/app/src/main/java/com/tangem/wallet/BTCUtils.java
similarity index 97%
rename from app/src/main/java/com/tangem/domain/wallet/BTCUtils.java
rename to app/src/main/java/com/tangem/wallet/BTCUtils.java
index 973d4ed231..180495a55e 100644
--- a/app/src/main/java/com/tangem/domain/wallet/BTCUtils.java
+++ b/app/src/main/java/com/tangem/wallet/BTCUtils.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 29.09.2017.
@@ -6,12 +6,12 @@ package com.tangem.domain.wallet;
import android.util.Log;
-import com.tangem.domain.wallet.btc.BitcoinException;
-import com.tangem.domain.wallet.btc.BitcoinOutputStream;
-import com.tangem.domain.wallet.btc.BtcData;
+import com.tangem.wallet.btc.BitcoinException;
+import com.tangem.wallet.btc.BitcoinOutputStream;
+import com.tangem.wallet.btc.BtcData;
import com.tangem.util.CryptoUtil;
import com.tangem.util.FormatUtil;
-import com.tangem.tangemcard.util.Util;
+import com.tangem.card_common.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
diff --git a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java b/app/src/main/java/com/tangem/wallet/BalanceValidator.java
similarity index 84%
rename from app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java
rename to app/src/main/java/com/tangem/wallet/BalanceValidator.java
index e5ada4f494..1919d5f2ff 100644
--- a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java
+++ b/app/src/main/java/com/tangem/wallet/BalanceValidator.java
@@ -1,12 +1,13 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
-import com.tangem.tangemcard.data.TangemCard;
-import com.tangem.wallet.R;
+import com.tangem.App;
+import com.tangem.card_common.data.TangemCard;
public class BalanceValidator {
private String firstLine;
private String secondLine;
private int score;
+ private boolean hasPending;
public String getFirstLine() {
return firstLine;
@@ -38,6 +39,10 @@ public class BalanceValidator {
}
public int getColor() {
+ if( hasPending )
+ {
+ return R.color.primary_dark;
+ }
if (score > 89) {
return R.color.confirmed;
} else if (score > 74) {
@@ -49,7 +54,7 @@ public class BalanceValidator {
}
}
- public void Check(TangemContext ctx, Boolean attest) {
+ public void check(TangemContext ctx, Boolean attest) {
firstLine = "Verification failed";
secondLine = "";
TangemCard card = ctx.getCard();
@@ -57,6 +62,15 @@ public class BalanceValidator {
if (!engine.validateBalance(this)) return;
+ hasPending=App.pendingTransactionsStorage.hasTransactions(card);
+
+ if( hasPending )
+ {
+ firstLine = "Pending transaction...";
+ secondLine = "Swipe down to refresh";
+ return;
+ }
+
// Verify card?
if (attest) {
diff --git a/app/src/main/java/com/tangem/domain/wallet/Base58.java b/app/src/main/java/com/tangem/wallet/Base58.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/Base58.java
rename to app/src/main/java/com/tangem/wallet/Base58.java
index 1cfeb7c019..0948e420fc 100644
--- a/app/src/main/java/com/tangem/domain/wallet/Base58.java
+++ b/app/src/main/java/com/tangem/wallet/Base58.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import java.math.BigInteger;
diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinData.java b/app/src/main/java/com/tangem/wallet/CoinData.java
similarity index 97%
rename from app/src/main/java/com/tangem/domain/wallet/CoinData.java
rename to app/src/main/java/com/tangem/wallet/CoinData.java
index 9447ee6935..35b94be391 100644
--- a/app/src/main/java/com/tangem/domain/wallet/CoinData.java
+++ b/app/src/main/java/com/tangem/wallet/CoinData.java
@@ -1,12 +1,10 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import android.os.Bundle;
import android.util.Log;
import com.tangem.data.Blockchain;
-import java.util.concurrent.atomic.AtomicInteger;
-
public abstract class CoinData {
public CoinData() {
@@ -143,7 +141,7 @@ public abstract class CoinData {
public void clearInfo() {
setIsBalanceEqual(false);
- setBalanceReceived(false); // TODO check
+ setBalanceReceived(false);
setValidationNodeDescription("");
minFee=null;
maxFee=null;
diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java b/app/src/main/java/com/tangem/wallet/CoinEngine.java
similarity index 81%
rename from app/src/main/java/com/tangem/domain/wallet/CoinEngine.java
rename to app/src/main/java/com/tangem/wallet/CoinEngine.java
index 83b0f987bf..ea0a0dfb6d 100644
--- a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java
+++ b/app/src/main/java/com/tangem/wallet/CoinEngine.java
@@ -1,11 +1,12 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import android.net.Uri;
import android.text.InputFilter;
-import com.tangem.tangemcard.reader.CardProtocol;
-import com.tangem.tangemcard.tasks.SignTask;
+import com.tangem.card_common.reader.CardProtocol;
+import com.tangem.card_common.tasks.SignTask;
+import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
@@ -15,13 +16,14 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
+import co.nstant.in.cbor.CborException;
+
/**
* Created by Ilia on 15.02.2018.
*/
public abstract class CoinEngine {
-
public static class InternalAmount extends BigDecimal {
private String currency;
@@ -181,18 +183,15 @@ public abstract class CoinEngine {
public abstract boolean isBalanceNotZero();
-// public abstract byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception;
-
- // TODO - change isExtractPossible to isExtractPossible and if not - return string message
+ // TODO - return string message
public abstract boolean isExtractPossible();
- public abstract Uri getShareWalletUriExplorer();
+ public abstract Uri getWalletExplorerUri();
public abstract Uri getShareWalletUri();
public abstract boolean checkNewTransactionAmount(Amount amount);
- // TODO - move minFeeInInternalUnits to CoinData
public abstract boolean checkNewTransactionAmountAndFee(Amount amount, Amount fee, Boolean isFeeIncluded);
public abstract boolean validateBalance(BalanceValidator balanceValidator);
@@ -217,7 +216,7 @@ public abstract class CoinEngine {
public abstract boolean validateAddress(String address);
- public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException;
+ public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException, CborException, IOException, Exception;
public abstract Amount convertToAmount(InternalAmount internalAmount) throws Exception;
@@ -245,47 +244,47 @@ public abstract class CoinEngine {
}
/**
- * Create instance of {@link SignTask.PaymentToSign} used for transaction signing and sending
+ * Create instance of {@link SignTask.TransactionToSign} used for transaction signing and sending
*
* Transaction processing sequence:
* 1. User enter transaction attributes
- * 2. Application create instance of {@link SignTask.PaymentToSign} by call {@see constructPayment}
- * 3. Application set notification when transaction were prepared {@see setOnNeedSendPayment} and start {@link SignTask}
+ * 2. Application create instance of {@link SignTask.TransactionToSign} by call {@see constructTransaction}
+ * 3. Application set notification when transaction were prepared {@see setOnNeedSendTransaction} and init {@link SignTask}
* 4. User tap card and card sign transaction
- * 5. Application receive {@link CoinEngine.OnNeedSendPayment} notification with prepared raw transaction
- * 6. Application show user information that transaction ready for sending and start sending procedure by call {@see requestSendTransaction}
+ * 5. Application receive {@link OnNeedSendTransaction} notification with prepared raw transaction
+ * 6. Application show user information that transaction ready for sending and init sending procedure by call {@see requestSendTransaction}
* 7. Application receive notification of sending result through {@link CoinEngine.BlockchainRequestsCallbacks} and show result to user
*
* @param amountValue - amount of desired transaction
* @param feeValue - fee amount of desired transaction
* @param IncFee - true if fee amount is included in amountValue (amountValue is total amount of transaction)
* @param targetAddress - target address of transaction
- * @return instance of {@link SignTask.PaymentToSign}
+ * @return instance of {@link SignTask.TransactionToSign}
* @throws Exception if something goes wrong
*/
- public abstract SignTask.PaymentToSign constructPayment(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception;
+ public abstract SignTask.TransactionToSign constructTransaction(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception;
/**
* Interface used to notify main application when new transaction is prepared to send
*/
- public interface OnNeedSendPayment {
- void onPaymentPrepared(byte[] txForSend);
+ public interface OnNeedSendTransaction {
+ void onTransactionPrepared(byte[] txForSend);
}
- protected OnNeedSendPayment onNeedSendPayment;
+ protected OnNeedSendTransaction onNeedSendTransaction;
/**
* Set notification callback when new transaction is prepared to send
*/
- public void setOnNeedSendPayment(OnNeedSendPayment onNeedSendPayment) {
- this.onNeedSendPayment = onNeedSendPayment;
+ public void setOnNeedSendTransaction(OnNeedSendTransaction onNeedSendTransaction) {
+ this.onNeedSendTransaction = onNeedSendTransaction;
}
- protected void notifyOnNeedSendPayment(byte[] txForSend) throws Exception {
- if (onNeedSendPayment == null)
- throw new Exception("Payment signed but no callback defined to send!");
- onNeedSendPayment.onPaymentPrepared(txForSend);
+ protected void notifyOnNeedSendTransaction(byte[] txForSend) throws Exception {
+ if (onNeedSendTransaction == null)
+ throw new Exception("Transaction was signed but no callback defined to send!");
+ onNeedSendTransaction.onTransactionPrepared(txForSend);
}
/**
@@ -341,4 +340,34 @@ public abstract class CoinEngine {
* @throws Exception if something goes wrong
*/
public abstract void requestSendTransaction(BlockchainRequestsCallbacks blockchainRequestsCallbacks, byte[] txForSend) throws Exception;
+
+
+ /**
+ * @return true if blockchain need multiple lines to show balance (e.g. need show additional balance information, Token count for example)
+ */
+ public boolean needMultipleLinesForBalance() {
+ return false;
+ }
+
+ /**
+ * @return true to allow user select fee level - min, normal or priority
+ */
+ public boolean allowSelectFeeLevel() {
+ return true;
+ }
+
+ /**
+ * @return true to allow user select include or exclude fee
+ */
+ public boolean allowSelectFeeInclusion() {
+ return true;
+ }
+
+ public boolean isNftToken() {
+ return false;
+ }
+
+
+ public int pendingTransactionTimeoutInSeconds() { return 30; }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt
new file mode 100644
index 0000000000..030e8ea07f
--- /dev/null
+++ b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt
@@ -0,0 +1,109 @@
+package com.tangem.wallet
+
+import android.util.Log
+
+import com.tangem.wallet.btc.BtcEngine
+import com.tangem.wallet.eth.EthEngine
+import com.tangem.wallet.token.TokenEngine
+import com.tangem.wallet.bch.BtcCashEngine
+import com.tangem.data.Blockchain
+import com.tangem.wallet.binance.BinanceEngine
+import com.tangem.wallet.cardano.CardanoData
+import com.tangem.wallet.cardano.CardanoEngine
+import com.tangem.wallet.ltc.LtcEngine
+import com.tangem.wallet.matic.MaticTokenEngine
+import com.tangem.wallet.nftToken.NftTokenEngine
+import com.tangem.wallet.rsk.RskEngine
+import com.tangem.wallet.rsk.RskTokenEngine
+import com.tangem.wallet.xrp.XrpEngine
+
+/**
+ * Factory for create specific engine
+ *
+ * @param
+ * Blockchain
+ * @param TangemContext
+ *
+ */
+
+object CoinEngineFactory {
+ private val TAG = CoinEngineFactory::class.java.simpleName
+
+ fun create(blockchain: Blockchain): CoinEngine? {
+ return when (blockchain) {
+ Blockchain.Bitcoin, Blockchain.BitcoinTestNet -> BtcEngine()
+ Blockchain.BitcoinCash -> BtcCashEngine()
+ Blockchain.Ethereum, Blockchain.EthereumTestNet -> EthEngine()
+ Blockchain.Token -> TokenEngine()
+ Blockchain.NftToken -> NftTokenEngine()
+ Blockchain.Litecoin -> LtcEngine()
+ Blockchain.Rootstock -> RskEngine()
+ Blockchain.RootstockToken -> RskTokenEngine()
+ Blockchain.Cardano -> CardanoEngine()
+ Blockchain.Ripple -> XrpEngine()
+ Blockchain.Binance, Blockchain.BinanceTestNet -> BinanceEngine()
+ Blockchain.Matic, Blockchain.MaticTestNet -> MaticTokenEngine()
+ else -> null
+ }
+ }
+
+ fun create(context: TangemContext): CoinEngine? {
+ var result: CoinEngine?
+ try {
+ result = if (Blockchain.BitcoinCash == context.blockchain)
+ BtcCashEngine(context)
+ else if (Blockchain.Bitcoin == context.blockchain || Blockchain.BitcoinTestNet == context.blockchain)
+ BtcEngine(context)
+ else if (Blockchain.Ethereum == context.blockchain || Blockchain.EthereumTestNet == context.blockchain)
+ EthEngine(context)
+ else if (Blockchain.Token == context.blockchain)
+ TokenEngine(context)
+ else if (Blockchain.NftToken == context.blockchain)
+ NftTokenEngine(context)
+ else if (Blockchain.Litecoin == context.blockchain)
+ LtcEngine(context)
+ else if (Blockchain.Rootstock == context.blockchain)
+ RskEngine(context)
+ else if (Blockchain.RootstockToken == context.blockchain)
+ RskTokenEngine(context)
+ else if (Blockchain.Cardano == context.blockchain)
+ CardanoEngine(context)
+ else if (Blockchain.Ripple == context.blockchain)
+ XrpEngine(context)
+ else if (Blockchain.Binance == context.blockchain || Blockchain.BinanceTestNet == context.blockchain)
+ BinanceEngine(context)
+ else if (Blockchain.Matic == context.blockchain || Blockchain.MaticTestNet == context.blockchain)
+ MaticTokenEngine(context
+
+ )
+ else
+ return null
+ } catch (e: Exception) {
+ e.printStackTrace()
+ result = null
+ Log.e(TAG, "Can't create CoinEngine!")
+ }
+ return result
+ }
+
+ fun createCardano(context: TangemContext): CoinEngine? {
+ var result: CoinEngine?
+ try {
+ result = CardanoEngine(context)//EthEngine(context)//
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ result = null
+ Log.e(TAG, "Can't create Cardano CoinEngine!")
+ }
+ return result
+ }
+
+ fun createCardanoData(): CoinData? {
+ return CardanoData()//EthData()// CardanoData()
+ }
+
+ fun isCardano(blockchainID: String): Boolean {
+ return blockchainID==Blockchain.Cardano.id//Ethereum.id
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/Digest.java b/app/src/main/java/com/tangem/wallet/Digest.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/Digest.java
rename to app/src/main/java/com/tangem/wallet/Digest.java
index 5e01c1dba6..b3924d61c7 100644
--- a/app/src/main/java/com/tangem/domain/wallet/Digest.java
+++ b/app/src/main/java/com/tangem/wallet/Digest.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 18.12.2017.
diff --git a/app/src/main/java/com/tangem/domain/wallet/DigestEngine.java b/app/src/main/java/com/tangem/wallet/DigestEngine.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/DigestEngine.java
rename to app/src/main/java/com/tangem/wallet/DigestEngine.java
index 5d7f092f82..8dd130353d 100644
--- a/app/src/main/java/com/tangem/domain/wallet/DigestEngine.java
+++ b/app/src/main/java/com/tangem/wallet/DigestEngine.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import java.security.MessageDigest;
diff --git a/app/src/main/java/com/tangem/domain/wallet/ECDSASignatureETH.java b/app/src/main/java/com/tangem/wallet/ECDSASignatureETH.java
similarity index 96%
rename from app/src/main/java/com/tangem/domain/wallet/ECDSASignatureETH.java
rename to app/src/main/java/com/tangem/wallet/ECDSASignatureETH.java
index 186ab80e43..a4b9741a1d 100644
--- a/app/src/main/java/com/tangem/domain/wallet/ECDSASignatureETH.java
+++ b/app/src/main/java/com/tangem/wallet/ECDSASignatureETH.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import java.math.BigInteger;
diff --git a/app/src/main/java/com/tangem/domain/wallet/EthTransaction.java b/app/src/main/java/com/tangem/wallet/EthTransaction.java
similarity index 98%
rename from app/src/main/java/com/tangem/domain/wallet/EthTransaction.java
rename to app/src/main/java/com/tangem/wallet/EthTransaction.java
index aa13d6d93e..c7ba6e98b3 100644
--- a/app/src/main/java/com/tangem/domain/wallet/EthTransaction.java
+++ b/app/src/main/java/com/tangem/wallet/EthTransaction.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import android.util.Log;
@@ -82,7 +82,8 @@ public class EthTransaction {
Kovan(42),
Ethereum_Classic_mainnet(61),
Ethereum_Classic_testnet(62),
- Geth_private_chains(1337);
+ Geth_private_chains(1337),
+ Matic_Testnet(8995);
private int value;
diff --git a/app/src/main/java/com/tangem/domain/wallet/Keccak256.java b/app/src/main/java/com/tangem/wallet/Keccak256.java
similarity index 94%
rename from app/src/main/java/com/tangem/domain/wallet/Keccak256.java
rename to app/src/main/java/com/tangem/wallet/Keccak256.java
index ba0d30fe41..bd8c2b5ded 100644
--- a/app/src/main/java/com/tangem/domain/wallet/Keccak256.java
+++ b/app/src/main/java/com/tangem/wallet/Keccak256.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 18.12.2017.
diff --git a/app/src/main/java/com/tangem/domain/wallet/KeccakCore.java b/app/src/main/java/com/tangem/wallet/KeccakCore.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/KeccakCore.java
rename to app/src/main/java/com/tangem/wallet/KeccakCore.java
index 7b5fe7a76e..015b33bb49 100644
--- a/app/src/main/java/com/tangem/domain/wallet/KeccakCore.java
+++ b/app/src/main/java/com/tangem/wallet/KeccakCore.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
diff --git a/app/src/main/java/com/tangem/domain/wallet/RLP.java b/app/src/main/java/com/tangem/wallet/RLP.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/RLP.java
rename to app/src/main/java/com/tangem/wallet/RLP.java
index cd581e9145..7ec159ead9 100644
--- a/app/src/main/java/com/tangem/domain/wallet/RLP.java
+++ b/app/src/main/java/com/tangem/wallet/RLP.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 07.01.2018.
diff --git a/app/src/main/java/com/tangem/domain/wallet/RLPElement.java b/app/src/main/java/com/tangem/wallet/RLPElement.java
similarity index 81%
rename from app/src/main/java/com/tangem/domain/wallet/RLPElement.java
rename to app/src/main/java/com/tangem/wallet/RLPElement.java
index a94de8a740..ae82526c2d 100644
--- a/app/src/main/java/com/tangem/domain/wallet/RLPElement.java
+++ b/app/src/main/java/com/tangem/wallet/RLPElement.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import java.io.Serializable;
diff --git a/app/src/main/java/com/tangem/domain/wallet/RLPList.java b/app/src/main/java/com/tangem/wallet/RLPList.java
similarity index 96%
rename from app/src/main/java/com/tangem/domain/wallet/RLPList.java
rename to app/src/main/java/com/tangem/wallet/RLPList.java
index 90915c9f27..14164502b3 100644
--- a/app/src/main/java/com/tangem/domain/wallet/RLPList.java
+++ b/app/src/main/java/com/tangem/wallet/RLPList.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import java.util.ArrayList;
diff --git a/app/src/main/java/com/tangem/domain/wallet/TangemContext.java b/app/src/main/java/com/tangem/wallet/TangemContext.java
similarity index 63%
rename from app/src/main/java/com/tangem/domain/wallet/TangemContext.java
rename to app/src/main/java/com/tangem/wallet/TangemContext.java
index 5802887489..9c2d9bbfa2 100644
--- a/app/src/main/java/com/tangem/domain/wallet/TangemContext.java
+++ b/app/src/main/java/com/tangem/wallet/TangemContext.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
import android.content.Context;
import android.content.Intent;
@@ -6,12 +6,11 @@ import android.os.Bundle;
import com.tangem.Constant;
import com.tangem.data.Blockchain;
-import com.tangem.tangemcard.data.TangemCard;
-import com.tangem.tangemcard.data.TangemCardExtensionsKt;
-
+import com.tangem.card_android.data.TangemCardExtensionsKt;
+import com.tangem.card_common.data.TangemCard;
public class TangemContext {
-// public static final String EXTRA_BLOCKCHAIN_DATA = "BLOCKCHAIN_DATA";
+ // public static final String EXTRA_BLOCKCHAIN_DATA = "BLOCKCHAIN_DATA";
private Context context;
private TangemCard card;
private CoinData coinData;
@@ -23,15 +22,22 @@ public class TangemContext {
}
public TangemContext(TangemCard card) {
+
this.card = card;
}
public Blockchain getBlockchain() {
if (card == null) return Blockchain.Unknown;
- Blockchain blockchain=Blockchain.fromId(card.getBlockchainID());
- if( (blockchain==Blockchain.Ethereum || blockchain==Blockchain.EthereumTestNet)&& card.isToken() )
- {
- return Blockchain.Token;
+ Blockchain blockchain = Blockchain.fromId(card.getBlockchainID());
+ if ((blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestNet) && card.isToken()) {
+ if (card.getTokenSymbol().startsWith("NFT:")) {
+ return Blockchain.NftToken;
+ } else {
+ return Blockchain.Token;
+ }
+ }
+ if ((blockchain == Blockchain.Rootstock) && card.isToken()) {
+ return Blockchain.RootstockToken;
}
return blockchain;
}
@@ -44,13 +50,15 @@ public class TangemContext {
// private String blockchainName = "";
public String getBlockchainName() {
- Blockchain blockchain=getBlockchain();
- if( (blockchain==Blockchain.Ethereum || blockchain==Blockchain.EthereumTestNet)&& card.isToken() ) {
+ Blockchain blockchain = getBlockchain();
+ if (blockchain == Blockchain.Token || blockchain == Blockchain.RootstockToken) {
String token = card.getTokenSymbol();
- return token + "
" + getBlockchain().getOfficialName() + " ERC20 token";
- }else {
- return blockchain.getOfficialName();
+ return token + "
" + getBlockchain().getOfficialName() + " smart contract token";
}
+ if (blockchain == Blockchain.NftToken) {
+ return card.getTokenSymbol().substring(4) + "
" + getBlockchain().getOfficialName() + " NFT token";
+ }
+ return blockchain.getOfficialName();
}
public Context getContext() {
@@ -81,12 +89,16 @@ public class TangemContext {
this.error = error;
}
+ public void setError(int valueId) {
+ this.error = getString(valueId);
+ }
+
public String getError() {
return error;
}
public boolean hasError() {
- return error!=null && !error.isEmpty();
+ return error != null && !error.isEmpty();
}
public void setMessage(String value) {
@@ -124,6 +136,21 @@ public class TangemContext {
return tangemContext;
}
+ public void saveToBundle(Bundle intent) {
+
+ if (card != null) {
+ intent.putString(TangemCardExtensionsKt.EXTRA_TANGEM_CARD_UID, card.getUID());
+ intent.putBundle(TangemCardExtensionsKt.EXTRA_TANGEM_CARD, TangemCardExtensionsKt.getAsBundle(card));
+ }
+
+ if (coinData != null) {
+ intent.putBundle(Constant.EXTRA_BLOCKCHAIN_DATA, coinData.asBundle());
+ }
+
+ intent.putString("Error", error);
+ intent.putString("Message", message);
+ }
+
public void saveToIntent(Intent intent) {
if (card != null) {
@@ -137,7 +164,6 @@ public class TangemContext {
intent.putExtra("Error", error);
intent.putExtra("Message", message);
-
}
public String getString(int stringId) {
@@ -147,13 +173,13 @@ public class TangemContext {
public void setDenomination(byte[] denomination) {
try {
- CoinEngine engine= CoinEngineFactory.INSTANCE.create(getBlockchain());
- CoinEngine.InternalAmount internalAmount=engine.convertToInternalAmount(denomination);
- CoinEngine.Amount amount=engine.convertToAmount(internalAmount);
- card.setDenomination(denomination,amount.toString());
+ CoinEngine engine = CoinEngineFactory.INSTANCE.create(getBlockchain());
+ CoinEngine.InternalAmount internalAmount = engine.convertToInternalAmount(denomination);
+ CoinEngine.Amount amount = engine.convertToAmount(internalAmount);
+ card.setDenomination(denomination, amount.toString());
} catch (Exception e) {
e.printStackTrace();
- card.setDenomination(denomination,"N/A");
+ card.setDenomination(denomination, "N/A");
}
}
diff --git a/app/src/main/java/com/tangem/domain/wallet/Transaction.java b/app/src/main/java/com/tangem/wallet/Transaction.java
similarity index 99%
rename from app/src/main/java/com/tangem/domain/wallet/Transaction.java
rename to app/src/main/java/com/tangem/wallet/Transaction.java
index 792a116802..0d4e54fd51 100644
--- a/app/src/main/java/com/tangem/domain/wallet/Transaction.java
+++ b/app/src/main/java/com/tangem/wallet/Transaction.java
@@ -1,12 +1,12 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 29.09.2017.
*/
-import com.tangem.domain.wallet.btc.BitcoinException;
-import com.tangem.domain.wallet.btc.BitcoinInputStream;
-import com.tangem.domain.wallet.btc.BitcoinOutputStream;
+import com.tangem.wallet.btc.BitcoinException;
+import com.tangem.wallet.btc.BitcoinInputStream;
+import com.tangem.wallet.btc.BitcoinOutputStream;
import com.tangem.util.CryptoUtil;
import java.io.ByteArrayOutputStream;
@@ -32,7 +32,7 @@ public final class Transaction {
try {
bais = new BitcoinInputStream(rawBytes);
version = bais.readInt32();
- if (version != 1 && version != 2 && version != 3) {
+ if (version != 1 && version != 2 && version != 3 && version != -1273714314) {
throw new BitcoinException(BitcoinException.ERR_UNSUPPORTED, "Unsupported TX version", version);
}
diff --git a/app/src/main/java/com/tangem/domain/wallet/UnspentOutputInfo.java b/app/src/main/java/com/tangem/wallet/UnspentOutputInfo.java
similarity index 95%
rename from app/src/main/java/com/tangem/domain/wallet/UnspentOutputInfo.java
rename to app/src/main/java/com/tangem/wallet/UnspentOutputInfo.java
index 88191c50b6..d2f790b24e 100644
--- a/app/src/main/java/com/tangem/domain/wallet/UnspentOutputInfo.java
+++ b/app/src/main/java/com/tangem/wallet/UnspentOutputInfo.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet;
+package com.tangem.wallet;
/**
* Created by Ilia on 29.09.2017.
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressDecodedParts.java b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressDecodedParts.java
similarity index 93%
rename from app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressDecodedParts.java
rename to app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressDecodedParts.java
index c3229f4ca6..104c19c31f 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressDecodedParts.java
+++ b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressDecodedParts.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
// Helper class for CashAddr
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressType.java b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressType.java
similarity index 91%
rename from app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressType.java
rename to app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressType.java
index d140031086..1beab277b6 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashAddressType.java
+++ b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashAddressType.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
/**
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBase32.java b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashBase32.java
similarity index 97%
rename from app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBase32.java
rename to app/src/main/java/com/tangem/wallet/bch/BitcoinCashBase32.java
index 0ddb910295..5e1a6a8c5d 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBase32.java
+++ b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashBase32.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
import java.util.HashMap;
import java.util.Map;
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBitArrayConverter.java b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashBitArrayConverter.java
similarity index 98%
rename from app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBitArrayConverter.java
rename to app/src/main/java/com/tangem/wallet/bch/BitcoinCashBitArrayConverter.java
index 770f16fbbe..3f92f9445c 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BitcoinCashBitArrayConverter.java
+++ b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashBitArrayConverter.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
/**
* Copyright (c) 2018 Tobias Brandt
*
diff --git a/app/src/main/java/com/tangem/wallet/bch/BitcoinCashNode.kt b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashNode.kt
new file mode 100644
index 0000000000..bb76b8a698
--- /dev/null
+++ b/app/src/main/java/com/tangem/wallet/bch/BitcoinCashNode.kt
@@ -0,0 +1,14 @@
+package com.tangem.wallet.bch
+
+enum class BitcoinCashNode(val host: String, val port: Int, val proto: String) {
+ N_001("electrumx.hillsideinternet.com", 50002, "ssl"),
+// N_002("dedi.jochen-hoenicke.de", 51002, "ssl"),
+// N_003("crypto.mldlabs.com", 50002, "ssl"),
+// N_004("electroncash.cascharia.com", 50002, "ssl"),
+// N_005("bch.crypto.mldlabs.com", 50002, "ssl"),
+ N_006("electron.coinucopia.io", 50002, "ssl"),
+ N_007("blackie.c3-soft.com", 50002, "ssl"),
+ N_008("electrum.imaginary.cash", 50002, "ssl"),
+// N_009("bitcoincash.quangld.com", 50002, "ssl"),
+// N_010("bch.stitthappens.com", 50002, "ssl"),
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java b/app/src/main/java/com/tangem/wallet/bch/BtcCashEngine.java
similarity index 90%
rename from app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java
rename to app/src/main/java/com/tangem/wallet/bch/BtcCashEngine.java
index 61c55ba38f..f29bc7e7f4 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java
+++ b/app/src/main/java/com/tangem/wallet/bch/BtcCashEngine.java
@@ -1,30 +1,27 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
import android.net.Uri;
import android.text.InputFilter;
import android.util.Log;
import com.tangem.data.network.ElectrumRequest;
-import com.tangem.data.network.ServerApiCommon;
import com.tangem.data.network.ServerApiElectrum;
-import com.tangem.domain.wallet.BCHUtils;
-import com.tangem.domain.wallet.BTCUtils;
-import com.tangem.tangemcard.reader.CardProtocol;
-import com.tangem.domain.wallet.BalanceValidator;
-import com.tangem.data.Blockchain;
-import com.tangem.domain.wallet.btc.BtcData;
-import com.tangem.domain.wallet.CoinData;
-import com.tangem.domain.wallet.CoinEngine;
-import com.tangem.tangemcard.data.TangemCard;
-import com.tangem.domain.wallet.TangemContext;
-import com.tangem.domain.wallet.Transaction;
-import com.tangem.domain.wallet.UnspentOutputInfo;
-import com.tangem.tangemcard.tasks.SignTask;
+import com.tangem.wallet.BCHUtils;
+import com.tangem.wallet.BTCUtils;
+import com.tangem.card_common.reader.CardProtocol;
+import com.tangem.wallet.BalanceValidator;
+import com.tangem.wallet.btc.BtcData;
+import com.tangem.wallet.CoinData;
+import com.tangem.wallet.CoinEngine;
+import com.tangem.card_common.data.TangemCard;
+import com.tangem.wallet.TangemContext;
+import com.tangem.wallet.Transaction;
+import com.tangem.wallet.UnspentOutputInfo;
+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.tangemcard.util.Util;
-import com.tangem.util.FormatUtil;
+import com.tangem.card_common.util.Util;
import com.tangem.wallet.R;
import org.json.JSONArray;
@@ -188,7 +185,7 @@ public class BtcCashEngine extends CoinEngine {
}
@Override
- public Uri getShareWalletUriExplorer() {
+ public Uri getWalletExplorerUri() {
return Uri.parse("https://bch.btc.com/" + ctx.getCoinData().getWallet());
}
@@ -457,7 +454,7 @@ public class BtcCashEngine extends CoinEngine {
@Override
- public SignTask.PaymentToSign constructPayment(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception {
+ public SignTask.TransactionToSign constructTransaction(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception {
checkBlockchainDataExists();
String srcLegacyAddress = convertToLegacyAddress(ctx.getCoinData().getWallet());
@@ -503,7 +500,7 @@ public class BtcCashEngine extends CoinEngine {
bodyDoubleHash[i] = Util.calculateSHA256(bodyHash[i]);
}
- return new SignTask.PaymentToSign() {
+ return new SignTask.TransactionToSign() {
@Override
public boolean isSigningMethodSupported(TangemCard.SigningMethod signingMethod) {
@@ -554,7 +551,7 @@ public class BtcCashEngine extends CoinEngine {
byte[] txForSend = BCHUtils.buildTXForSend(destLegacyAddress, srcLegacyAddress, unspentOutputs, amountFinal, changeFinal);
- notifyOnNeedSendPayment(txForSend);
+ notifyOnNeedSendTransaction(txForSend);
return txForSend;
}
};
@@ -564,7 +561,7 @@ public class BtcCashEngine extends CoinEngine {
public void requestBalanceAndUnspentTransactions(BlockchainRequestsCallbacks blockchainRequestsCallbacks) throws Exception {
final ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
- ServerApiElectrum.ElectrumRequestDataListener electrumBodyListener = new ServerApiElectrum.ElectrumRequestDataListener() {
+ ServerApiElectrum.ResponseListener electrumBodyListener = new ServerApiElectrum.ResponseListener() {
@Override
public void onSuccess(ElectrumRequest electrumRequest) {
if (electrumRequest.isMethod(ElectrumRequest.METHOD_GetBalance)) {
@@ -594,7 +591,7 @@ public class BtcCashEngine extends CoinEngine {
JSONObject jsUnspent = jsUnspentArray.getJSONObject(i);
BtcData.UnspentTransaction trUnspent = new BtcData.UnspentTransaction();
trUnspent.txID = jsUnspent.getString("tx_hash");
- trUnspent.Amount = jsUnspent.getInt("value");
+ trUnspent.Amount = jsUnspent.getLong("value");
trUnspent.Height = jsUnspent.getInt("height");
coinData.getUnspentTransactions().add(trUnspent);
}
@@ -609,7 +606,7 @@ public class BtcCashEngine extends CoinEngine {
String hash = jsUnspent.getString("tx_hash");
if (height != -1) {
if (blockchainRequestsCallbacks.allowAdvance()) {
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getTransaction(walletAddress, hash));
+ serverApiElectrum.requestData(ctx, ElectrumRequest.getTransaction(walletAddress, hash));
} else {
ctx.setError("Terminated by user");
}
@@ -652,24 +649,25 @@ public class BtcCashEngine extends CoinEngine {
}
};
- serverApiElectrum.setElectrumRequestData(electrumBodyListener);
+ serverApiElectrum.setResponseListener(electrumBodyListener);
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.checkBalance(convertToLegacyAddress(coinData.getWallet())));
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.listUnspent(convertToLegacyAddress(coinData.getWallet())));
+ serverApiElectrum.requestData(ctx, ElectrumRequest.checkBalance(convertToLegacyAddress(coinData.getWallet())));
+ serverApiElectrum.requestData(ctx, ElectrumRequest.listUnspent(convertToLegacyAddress(coinData.getWallet())));
}
private Integer calculateEstimatedTransactionSize(String outputAddress, String outAmount) {
try {
- SignTask.PaymentToSign ps=constructPayment(new Amount(outAmount, getBalanceCurrency()),new Amount("0.00",getFeeCurrency()), true, outputAddress );
- OnNeedSendPayment onNeedSendPaymentBackup=onNeedSendPayment;
- onNeedSendPayment=(tx)->{}; // empty function to bypass exception
+ 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
byte[][] hashesToSign=ps.getHashesToSign();
byte[] signFromCard = new byte[64 * hashesToSign.length];
+ Arrays.fill(signFromCard, (byte) 0x01);
byte[] txForSend=ps.onSignCompleted(signFromCard);
- onNeedSendPayment=onNeedSendPaymentBackup;
+ onNeedSendTransaction = onNeedSendTransactionBackup;
Log.e(TAG,"txForSend.length="+String.valueOf(txForSend.length));
- return txForSend.length;
+ return txForSend.length +1;
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Can't calculate transaction size -> use default!");
@@ -689,7 +687,7 @@ public class BtcCashEngine extends CoinEngine {
final ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
- final ServerApiElectrum.ElectrumRequestDataListener electrumListener = new ServerApiElectrum.ElectrumRequestDataListener () {
+ final ServerApiElectrum.ResponseListener electrumListener = new ServerApiElectrum.ResponseListener() {
@Override
public void onSuccess(ElectrumRequest electrumRequest) {
BigDecimal fee;
@@ -698,13 +696,13 @@ public class BtcCashEngine extends CoinEngine {
fee = new BigDecimal(electrumRequest.getResultString()); //fee per KB
if (fee.equals(BigDecimal.ZERO)) {
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getFee());
+ serverApiElectrum.requestData(ctx, ElectrumRequest.getFee());
}
// if (calcSize != 0) {
fee = fee.multiply(new BigDecimal(calcSize)).divide(new BigDecimal(1024)); // (per KB -> per byte)*size
// } else {
-// serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getFee());
+// serverApiElectrum.requestData(ctx, ElectrumRequest.getFee());
// }
//compare fee to usual relay fee
@@ -735,9 +733,9 @@ public class BtcCashEngine extends CoinEngine {
blockchainRequestsCallbacks.onComplete(false);
}
};
- serverApiElectrum.setElectrumRequestData(electrumListener);
+ serverApiElectrum.setResponseListener(electrumListener);
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getFee());
+ serverApiElectrum.requestData(ctx, ElectrumRequest.getFee());
}
@Override
@@ -745,7 +743,7 @@ public class BtcCashEngine extends CoinEngine {
final ServerApiElectrum serverApiElectrum = new ServerApiElectrum();
final String txStr = BTCUtils.toHex(txForSend);
- ServerApiElectrum.ElectrumRequestDataListener electrumBodyListener = new ServerApiElectrum.ElectrumRequestDataListener() {
+ ServerApiElectrum.ResponseListener electrumBodyListener = new ServerApiElectrum.ResponseListener() {
@Override
public void onSuccess(ElectrumRequest electrumRequest) {
if (electrumRequest.isMethod(ElectrumRequest.METHOD_SendTransaction)) {
@@ -776,11 +774,15 @@ public class BtcCashEngine extends CoinEngine {
blockchainRequestsCallbacks.onComplete(false);
}
};
- serverApiElectrum.setElectrumRequestData(electrumBodyListener);
+ serverApiElectrum.setResponseListener(electrumBodyListener);
- serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.broadcast(ctx.getCoinData().getWallet(), txStr));
+ serverApiElectrum.requestData(ctx, ElectrumRequest.broadcast(ctx.getCoinData().getWallet(), txStr));
}
+ @Override
+ public boolean allowSelectFeeLevel() {
+ return false;
+ }
}
diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/CashAddr.java b/app/src/main/java/com/tangem/wallet/bch/CashAddr.java
similarity index 98%
rename from app/src/main/java/com/tangem/domain/wallet/bch/CashAddr.java
rename to app/src/main/java/com/tangem/wallet/bch/CashAddr.java
index d73f88f8d7..5dbf111c97 100644
--- a/app/src/main/java/com/tangem/domain/wallet/bch/CashAddr.java
+++ b/app/src/main/java/com/tangem/wallet/bch/CashAddr.java
@@ -1,4 +1,4 @@
-package com.tangem.domain.wallet.bch;
+package com.tangem.wallet.bch;
import java.math.BigInteger;
import java.util.Arrays;
@@ -44,7 +44,8 @@ public class CashAddr {
byte[] checksumBytes = calculateChecksumBytesPolymod(allChecksumInput);
checksumBytes = convertBits(checksumBytes, 8, 5, true);
String cashAddress = BitcoinCashBase32.encode(concatenateByteArrays(payloadBytes, checksumBytes));
- return prefixString + SEPARATOR + cashAddress;
+ //return prefixString + SEPARATOR + cashAddress;
+ return cashAddress;
}
public static BitcoinCashAddressDecodedParts decodeCashAddress(String bitcoinCashAddress) {
diff --git a/app/src/main/java/com/tangem/wallet/binance/BinanceData.java b/app/src/main/java/com/tangem/wallet/binance/BinanceData.java
new file mode 100644
index 0000000000..de90f5c65a
--- /dev/null
+++ b/app/src/main/java/com/tangem/wallet/binance/BinanceData.java
@@ -0,0 +1,98 @@
+package com.tangem.wallet.binance;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.tangem.wallet.CoinData;
+import com.tangem.wallet.CoinEngine;
+
+public class BinanceData extends CoinData {
+ private String balance, chainId;
+ private Long sequence;
+ private Integer accountNumber;
+ private boolean error404 = false;
+
+ @Override
+ public void loadFromBundle(Bundle B) {
+ super.loadFromBundle(B);
+
+ if (B.containsKey("Balance")) balance = B.getString("Balance");
+ else balance = null;
+ if (B.containsKey("ChainId")) chainId = B.getString("ChainId");
+ else chainId = null;
+ if (B.containsKey("Sequence")) sequence = B.getLong("Sequence");
+ else sequence = null;
+ if (B.containsKey("AccountNumber")) accountNumber = B.getInt("AccountNumber");
+ else accountNumber = null;
+ if (B.containsKey("Error404")) error404 = B.getBoolean("Error404");
+ else error404 = false;
+ }
+
+ @Override
+ public void saveToBundle(Bundle B) {
+ super.saveToBundle(B);
+ try {
+ if (balance != null) B.putString("Balance", balance);
+ if (chainId != null) B.putString("ChainId", chainId);
+ if (sequence != null) B.putLong("Sequence", sequence);
+ if (accountNumber != null) B.putInt("AccountNumber", accountNumber);
+ if (error404) B.putBoolean("Error404", true);
+ } catch (Exception e) {
+ Log.e("Can't save to bundle ", e.getMessage());
+ }
+ }
+
+ @Override
+ public void clearInfo() {
+ super.clearInfo();
+ balance = null;
+ chainId = null;
+ sequence = null;
+ accountNumber = null;
+ error404 = false;
+ }
+
+ public CoinEngine.Amount getBalance() {
+ return new CoinEngine.Amount(balance, "BNB");
+ }
+
+ public void setBalance(String balance) {
+ this.balance = balance;
+ }
+
+ public boolean hasBalanceInfo() {
+ return balance != null;
+ }
+
+ public Integer getAccountNumber() {
+ return accountNumber;
+ }
+
+ public void setAccountNumber(Integer accountNumber) {
+ this.accountNumber = accountNumber;
+ }
+
+ public Long getSequence() {
+ return sequence;
+ }
+
+ public void setSequence(Long sequence) {
+ this.sequence = sequence;
+ }
+
+ public String getChainId() {
+ return chainId;
+ }
+
+ public void setChainId(String chain_id) {
+ this.chainId = chain_id;
+ }
+
+ public boolean isError404() {
+ return error404;
+ }
+
+ public void setError404(boolean error404) {
+ this.error404 = error404;
+ }
+}
diff --git a/app/src/main/java/com/tangem/wallet/binance/BinanceEngine.java b/app/src/main/java/com/tangem/wallet/binance/BinanceEngine.java
new file mode 100644
index 0000000000..d3927dee8d
--- /dev/null
+++ b/app/src/main/java/com/tangem/wallet/binance/BinanceEngine.java
@@ -0,0 +1,564 @@
+package com.tangem.wallet.binance;
+
+import android.net.Uri;
+import android.text.InputFilter;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+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.network.BinanceApi;
+import com.tangem.data.network.Server;
+import com.tangem.data.network.ServerApiBinance;
+import com.tangem.data.network.model.BinanceFees;
+import com.tangem.util.CryptoUtil;
+import com.tangem.util.DecimalDigitsInputFilter;
+import com.tangem.wallet.BalanceValidator;
+import com.tangem.wallet.CoinData;
+import com.tangem.wallet.CoinEngine;
+import com.tangem.wallet.R;
+import com.tangem.wallet.TangemContext;
+import com.tangem.wallet.binance.client.BinanceDexApiClientFactory;
+import com.tangem.wallet.binance.client.BinanceDexApiRestClient;
+import com.tangem.wallet.binance.client.BinanceDexEnvironment;
+import com.tangem.wallet.binance.client.domain.broadcast.TransactionOption;
+import com.tangem.wallet.binance.client.domain.broadcast.Transfer;
+import com.tangem.wallet.binance.client.encoding.Bech32;
+import com.tangem.wallet.binance.client.encoding.Crypto;
+import com.tangem.wallet.binance.client.encoding.message.MessageType;
+import com.tangem.wallet.binance.client.encoding.message.TransactionRequestAssemblerExtSign;
+import com.tangem.wallet.binance.client.encoding.message.TransferMessage;
+
+import org.bitcoinj.core.Utils;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+
+public class BinanceEngine extends CoinEngine {
+ private static final String TAG = BinanceEngine.class.getSimpleName();
+
+ public BinanceData coinData = null;
+ private BinanceDexApiRestClient client = null;
+
+ public BinanceEngine(TangemContext context) throws Exception {
+ super(context);
+ if (context.getCoinData() == null) {
+ coinData = new BinanceData();
+ context.setCoinData(coinData);
+ } else if (context.getCoinData() instanceof BinanceData) {
+ coinData = (BinanceData) context.getCoinData();
+ } else {
+ throw new Exception("Invalid type of Blockchain data for " + TAG);
+ }
+ if (ctx.getBlockchain() == Blockchain.Binance) {
+ client = BinanceDexApiClientFactory.newInstance().newRestClient(BinanceDexEnvironment.PROD.getBaseUrl());
+ coinData.setChainId("Binance-Chain-Tigris");
+ } else if (ctx.getBlockchain() == Blockchain.BinanceTestNet) {
+ client = BinanceDexApiClientFactory.newInstance().newRestClient(BinanceDexEnvironment.TEST_NET.getBaseUrl());
+ coinData.setChainId("Binance-Chain-Nile");
+ } else {
+ throw new Exception("Invalid blockchain for BinanceEngine");
+ }
+ }
+
+ public BinanceEngine() {
+ super();
+ }
+
+ private static int getDecimals() {
+ return 8;
+ }
+
+ private void checkBlockchainDataExists() throws Exception {
+ if (coinData == null) throw new Exception("No blockchain data");
+ }
+
+ @Override
+ public boolean awaitingConfirmation() {
+ return false;
+ }
+
+ @Override
+ public String getBalanceHTML() {
+ Amount balance = getBalance();
+ if (balance != null) {
+ return balance.toDescriptionString(getDecimals());
+ } else {
+ return "";
+ }
+ }
+
+ @Override
+ public String getBalanceCurrency() {
+ return "BNB";
+ }
+
+ @Override
+ public String getOfflineBalanceHTML() { //TODO:check
+ InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
+ Amount offlineAmount = convertToAmount(offlineInternalAmount);
+ return offlineAmount.toDescriptionString(getDecimals());
+ }
+
+ @Override
+ public boolean isBalanceNotZero() {
+ if (coinData == null) return false;
+ if (coinData.getBalance() == null) return false;
+ return coinData.getBalance().notZero();
+ }
+
+ @Override
+ public boolean hasBalanceInfo() {
+ if (coinData == null) return false;
+ return coinData.hasBalanceInfo();
+ }
+
+ 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
+ public String getFeeCurrency() {
+ return "BNB";
+ }
+
+ @Override
+ public boolean validateAddress(String address) {
+ if (address == null || address.isEmpty()) {
+ return false;
+ }
+
+ try {
+ Crypto.decodeAddress(address);
+ } catch (Exception e) {
+ return false;
+ }
+
+ if (ctx.getBlockchain() == Blockchain.Binance && !address.startsWith("bnb1")) {
+ return false;
+ }
+
+ if (ctx.getBlockchain() == Blockchain.BinanceTestNet && !address.startsWith("tbnb1")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isNeedCheckNode() {
+ return true;
+ }
+
+ @Override
+ public Uri getWalletExplorerUri() {
+ if (ctx.getBlockchain() == Blockchain.Binance) {
+ return Uri.parse("https://explorer.binance.org/address/" + ctx.getCoinData().getWallet());
+ } else if (ctx.getBlockchain() == Blockchain.BinanceTestNet) {
+ return Uri.parse("https://testnet-explorer.binance.org/address/" + ctx.getCoinData().getWallet());
+ } else {
+ Log.e(TAG, "Invalid blockchain for BinanceEngine");
+ return Uri.parse("https://explorer.binance.org/address/" + ctx.getCoinData().getWallet());
+ }
+ }
+
+ public Uri getShareWalletUri() {
+ return Uri.parse(ctx.getCoinData().getWallet());
+ }
+
+ @Override
+ public InputFilter[] getAmountInputFilters() {
+ return new InputFilter[]{new DecimalDigitsInputFilter(getDecimals())};
+ }
+
+ @Override
+ public boolean checkNewTransactionAmount(Amount amount) {
+ if (coinData == null) return false;
+ return amount.compareTo(coinData.getBalance()) <= 0;
+ }
+
+ @Override
+ public boolean checkNewTransactionAmountAndFee(Amount amountValue, Amount feeValue, Boolean isIncludeFee) {
+ try {
+ checkBlockchainDataExists();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ if (feeValue == null || amountValue == null)
+ return false;
+
+ if (feeValue.isZero() || amountValue.isZero())
+ return false;
+
+ if (isIncludeFee && (amountValue.compareTo(coinData.getBalance()) > 0 || amountValue.compareTo(feeValue) < 0))
+ return false;
+
+ if (!isIncludeFee && amountValue.add(feeValue).compareTo(coinData.getBalance()) > 0)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public boolean validateBalance(BalanceValidator balanceValidator) {
+ try {
+ if (((ctx.getCard().getOfflineBalance() == null) && !ctx.getCoinData().isBalanceReceived()) || (!ctx.getCoinData().isBalanceReceived() && (ctx.getCard().getRemainingSignatures() != ctx.getCard().getMaxSignatures()))) {
+
+ if(coinData.isError404()) {
+ balanceValidator.setScore(0);
+ balanceValidator.setFirstLine("No account or network error");
+ balanceValidator.setSecondLine("To create account send funds to this address");
+ } else {
+ balanceValidator.setScore(0);
+ balanceValidator.setFirstLine("Unknown balance");
+ balanceValidator.setSecondLine("Balance cannot be verified. Swipe down to refresh.");
+ return false;
+ }
+ }
+
+ if (coinData.isBalanceReceived()) {
+ balanceValidator.setScore(100);
+ balanceValidator.setFirstLine("Verified balance");
+ balanceValidator.setSecondLine("Balance confirmed in blockchain");
+ if (coinData.getBalance().isZero()) {
+ balanceValidator.setFirstLine("Empty wallet");
+ balanceValidator.setSecondLine("");
+ }
+ }
+
+ if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.getBalance().notZero()) {
+ balanceValidator.setScore(80);
+ balanceValidator.setFirstLine("Verified offline balance");
+ balanceValidator.setSecondLine("Can't obtain balance from blockchain. Restore internet connection to be more confident. ");
+ }
+
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public Amount getBalance() {
+ if (!hasBalanceInfo()) return null;
+ return coinData.getBalance();
+ }
+
+ @Override
+ public String evaluateFeeEquivalent(String 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 "";
+ Amount balance = getBalance();
+ if (balance == null) return "";
+ return balance.toEquivalentString(coinData.getRate());
+ }
+
+ public String calculateAddress(byte[] pkCompressed) throws Exception {
+ byte[] pubKeyHash = Utils.sha256hash160(pkCompressed);
+
+ if (ctx.getBlockchain() == Blockchain.Binance) {
+ return Bech32.encode("bnb", Crypto.convertBits(pubKeyHash, 0, pubKeyHash.length, 8, 5, false));
+ } else if (ctx.getBlockchain() == Blockchain.BinanceTestNet) {
+ return Bech32.encode("tbnb", Crypto.convertBits(pubKeyHash, 0, pubKeyHash.length, 8, 5, false));
+ } else {
+ throw new Exception("Invalid blockchain for BinanceEngine");
+ }
+ }
+
+ @Override
+ public Amount convertToAmount(InternalAmount internalAmount) {
+ return new Amount(internalAmount, getBalanceCurrency());
+ }
+
+ @Override
+ public Amount convertToAmount(String strAmount, String currency) {
+ return new Amount(strAmount, currency);
+ }
+
+ @Override
+ public InternalAmount convertToInternalAmount(Amount amount) {
+ return new InternalAmount(amount, getBalanceCurrency());
+ }
+
+ @Override
+ public InternalAmount convertToInternalAmount(byte[] bytes) {
+ 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), getBalanceCurrency());
+ }
+
+ @Override
+ public byte[] convertToByteArray(InternalAmount internalAmount) {
+ return Util.longToByteArray(internalAmount.longValueExact());
+ }
+
+ @Override
+ public CoinData createCoinData() {
+ return new BinanceData();
+ }
+
+ @Override
+ public String getUnspentInputsDescription() {
+ return "";
+ }
+
+ @Override
+ public void defineWallet() throws CardProtocol.TangemException {
+ try {
+ String wallet = calculateAddress(ctx.getCard().getWalletPublicKeyRar());
+ ctx.getCoinData().setWallet(wallet);
+ } catch (Exception e) {
+ ctx.getCoinData().setWallet("ERROR");
+ throw new CardProtocol.TangemException("Can't define wallet address");
+ }
+ }
+
+ @Override
+ public SignTask.TransactionToSign constructTransaction(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception {
+ checkBlockchainDataExists();
+
+ String amount;
+
+ if (IncFee) {
+ amount = amountValue.subtract(feeValue).setScale(getDecimals(), RoundingMode.DOWN).toPlainString();
+ } else {
+ amount = amountValue.setScale(getDecimals(), RoundingMode.DOWN).toPlainString();
+ }
+
+ byte[] pubKey = ctx.getCard().getWalletPublicKeyRar();
+ byte[] pubKeyPrefix = MessageType.PubKey.getTypePrefixBytes();
+ byte[] pubKeyForSign = new byte[pubKey.length + pubKeyPrefix.length + 1];
+ System.arraycopy(pubKeyPrefix, 0, pubKeyForSign, 0, pubKeyPrefix.length);
+ pubKeyForSign[pubKeyPrefix.length] = (byte) 33;
+ System.arraycopy(pubKey, 0, pubKeyForSign, pubKeyPrefix.length + 1, pubKey.length);
+
+ Transfer transfer = new Transfer();
+ transfer.setCoin("BNB");
+ transfer.setFromAddress(ctx.getCoinData().getWallet());
+ transfer.setToAddress(targetAddress);
+ transfer.setAmount(amount);
+
+ TransactionOption options = TransactionOption.DEFAULT_INSTANCE;
+
+ TransactionRequestAssemblerExtSign txAssembler = client.prepareTransfer(transfer, coinData, pubKeyForSign, options, true);
+ // TransactionRequestAssembler.buildTransfer as reference
+ TransferMessage msgBean = txAssembler.createTransferMessage(transfer);
+ byte[] msg = txAssembler.encodeTransferMessage(msgBean);
+ byte[] dataForSign = txAssembler.prepareForSign(msgBean);
+
+ return new SignTask.TransactionToSign() {
+
+ @Override
+ public boolean isSigningMethodSupported(TangemCard.SigningMethod signingMethod) {
+ return signingMethod == TangemCard.SigningMethod.Sign_Hash || signingMethod == TangemCard.SigningMethod.Sign_Raw;
+ }
+
+ @Override
+ public byte[][] getHashesToSign() throws NoSuchAlgorithmException {
+ byte[][] hashForSign = new byte[1][];
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ hashForSign[0] = digest.digest(dataForSign);
+ return hashForSign;
+ }
+
+ @Override
+ public byte[] getRawDataToSign() {
+ return dataForSign;
+ }
+
+ @Override
+ public String getHashAlgToSign() {
+ return "sha-256";
+ }
+
+ @Override
+ public byte[] getIssuerTransactionSignature(byte[] dataToSignByIssuer) throws Exception {
+ throw new Exception("Transaction validation by issuer not supported in this version");
+ }
+
+ @Override
+ public byte[] onSignCompleted(byte[] signFromCard) throws Exception {
+ int size = signFromCard.length / 2;
+ BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0, size));
+ BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, size, size * 2));
+ s = CryptoUtil.toCanonicalised(s);
+
+ byte[] resultSig = new byte[64];
+ System.arraycopy(Utils.bigIntegerToBytes(r, 32), 0, resultSig, 0, 32);
+ System.arraycopy(Utils.bigIntegerToBytes(s, 32), 0, resultSig, 32, 32);
+
+ // TransactionRequestAssembler.buildTransfer as reference
+ byte[] signature = txAssembler.encodeSignature(resultSig);
+ byte[] txForSend = txAssembler.encodeStdTx(msg, signature);
+
+ notifyOnNeedSendTransaction(txForSend);
+ return txForSend;
+ }
+ };
+ }
+
+ public void requestBalanceAndUnspentTransactions(BlockchainRequestsCallbacks blockchainRequestsCallbacks) {
+ try {
+ ServerApiBinance serverApiBinance = new ServerApiBinance();
+
+ ServerApiBinance.ResponseListener responseListener = new ServerApiBinance.ResponseListener() {
+ @Override
+ public void onSuccess() {
+ blockchainRequestsCallbacks.onComplete(true);
+ }
+
+ @Override
+ public void onFail() {
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ };
+
+ serverApiBinance.setResponseListener(responseListener);
+ serverApiBinance.getBalance(ctx, client);
+
+ if (ctx.getBlockchain() == Blockchain.Binance) {
+ coinData.setValidationNodeDescription(Server.ApiBinance.URL_BINANCE);
+ } else if (ctx.getBlockchain() == Blockchain.BinanceTestNet) {
+ coinData.setValidationNodeDescription(Server.ApiBinanceTestnet.URL_BINANCE_TESTNET);
+ } else {
+ throw new Exception("Invalid blockchain for BinanceEngine");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.e(TAG, "FAIL Binance balance exception");
+ ctx.setError(e.getMessage());
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ }
+
+ public void requestFee(BlockchainRequestsCallbacks blockchainRequestsCallbacks, String targetAddress, Amount amount) {
+ try {
+ String baseUrl;
+
+ if (ctx.getBlockchain() == Blockchain.Binance) {
+ baseUrl = Server.ApiBinance.Method.API_V1;
+ } else if (ctx.getBlockchain() == Blockchain.BinanceTestNet) {
+ baseUrl = Server.ApiBinanceTestnet.Method.API_V1;
+ } else {
+ throw new Exception("Invalid blockchain for BinanceEngine");
+ }
+
+ Retrofit retrofitBinance = new Retrofit.Builder()
+ .baseUrl(baseUrl)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+
+ BinanceApi binanceApi = retrofitBinance.create(BinanceApi.class);
+ Call> call = binanceApi.binanceFees();
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+ if (response.code() == 200) {
+ for (BinanceFees fee : response.body()) {
+ if (fee.getFixed_fee_params() != null) {
+ Long longFee = Long.valueOf(fee.getFixed_fee_params().getFee());
+ Amount feeAmount = new Amount(BigDecimal.valueOf(longFee).divide(BigDecimal.valueOf(100000000)).setScale(8, RoundingMode.DOWN), getFeeCurrency());
+ coinData.minFee = coinData.normalFee = coinData.maxFee = feeAmount;
+ Log.i(TAG, "requestFee onResponse " + response.code());
+ blockchainRequestsCallbacks.onComplete(true);
+ }
+ }
+ } else {
+ ctx.setError(response.code());
+ Log.e(TAG, "requestFee onResponse " + response.code());
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ ctx.setError(t.getMessage());
+ Log.e(TAG, "requestFee onFailure " + t.getMessage());
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ });
+ } catch (Exception e) {
+ ctx.setError(e.getMessage());
+ e.printStackTrace();
+ Log.e(TAG, "FAIL Binance fee exception");
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ }
+
+ public void requestSendTransaction(BlockchainRequestsCallbacks blockchainRequestsCallbacks, byte[] txForSend) {
+// RequestBody requestBody = TransactionRequestAssemblerExtSign.createRequestBody(txForSend);
+ try {
+ ServerApiBinance serverApiBinance = new ServerApiBinance();
+
+ ServerApiBinance.ResponseListener responseListener = new ServerApiBinance.ResponseListener() {
+ @Override
+ public void onSuccess() {
+ ctx.setError(null);
+ blockchainRequestsCallbacks.onComplete(true);
+ }
+
+ @Override
+ public void onFail() {
+ ctx.setError("Broadcast error");
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ };
+
+ serverApiBinance.setResponseListener(responseListener);
+ serverApiBinance.sendTransaction(txForSend, client);
+
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ ctx.setError(e.getMessage());
+ blockchainRequestsCallbacks.onComplete(false);
+ }
+ }
+
+ public int pendingTransactionTimeoutInSeconds() {
+ return 9;
+ }
+
+ public boolean allowSelectFeeLevel() {
+ return false;
+ }
+}
diff --git a/app/src/main/java/com/tangem/wallet/binance/client/BinanceDexApi.java b/app/src/main/java/com/tangem/wallet/binance/client/BinanceDexApi.java
new file mode 100644
index 0000000000..95342b68bd
--- /dev/null
+++ b/app/src/main/java/com/tangem/wallet/binance/client/BinanceDexApi.java
@@ -0,0 +1,82 @@
+package com.tangem.wallet.binance.client;
+
+import com.tangem.wallet.binance.client.domain.*;
+import okhttp3.RequestBody;
+import retrofit2.Call;
+import retrofit2.http.*;
+
+import java.util.List;
+
+public interface BinanceDexApi {
+ @GET("/api/v1/time")
+ Call