diff --git a/.idea/navEditor.xml b/.idea/navEditor.xml
index 4548c6069e..09d3bc259e 100644
--- a/.idea/navEditor.xml
+++ b/.idea/navEditor.xml
@@ -8,13 +8,25 @@
@@ -200,8 +274,8 @@
@@ -212,8 +286,8 @@
-
-
+
+
@@ -224,8 +298,8 @@
-
-
+
+
@@ -236,8 +310,8 @@
-
-
+
+
@@ -257,8 +331,8 @@
-
-
+
+
@@ -269,8 +343,8 @@
-
-
+
+
@@ -281,8 +355,8 @@
-
-
+
+
@@ -307,8 +381,8 @@
-
-
+
+
@@ -328,8 +402,8 @@
-
-
+
+
@@ -340,8 +414,8 @@
-
-
+
+
@@ -352,8 +426,8 @@
-
-
+
+
@@ -364,8 +438,8 @@
-
-
+
+
@@ -380,13 +454,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -411,6 +518,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index 2f79e7f860..0a834a88d3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -164,4 +164,7 @@ dependencies {
implementation 'io.jafka:jeos:0.9.15'
// implementation 'one.block:eosiojava:0.1.0'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.61'
+
+ implementation 'io.fotoapparat:fotoapparat:2.6.1'
+ implementation 'com.otaliastudios:cameraview:2.6.1'
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/Blockchain.java b/app/src/main/java/com/tangem/data/Blockchain.java
index 782234d4ed..3f3a033388 100644
--- a/app/src/main/java/com/tangem/data/Blockchain.java
+++ b/app/src/main/java/com/tangem/data/Blockchain.java
@@ -10,6 +10,7 @@ public enum Blockchain {
Bitcoin("BTC", "BTC", 100000000.0, R.drawable.ic_logo_bitcoin, "Bitcoin"),
BitcoinTestNet("BTC/test", "BTC", 100000000.0, R.drawable.ic_logo_bitcoin_testnet, "Bitcoin Testnet"),
Ethereum("ETH", "ETH", 1.0, R.drawable.ic_logo_ethereum, "Ethereum"),
+ EthereumId("ETH/ID", "ETH", 1.0, R.drawable.ic_logo_ethereum, "Ethereum ID"),
EthereumTestNet("ETH/test", "ETH", 1.0, R.drawable.ic_logo_ethereum_testnet, "Ethereum Testnet"),
Token("Token", "ETH", 1.0, R.drawable.ic_logo_bat_token, "Ethereum"),
NftToken("NftToken", "", 1.0, R.drawable.tangem2, "Ethereum"),
@@ -23,10 +24,13 @@ public enum Blockchain {
BinanceTestNet("BINANCE/test", "BNB", 100000000.0, R.drawable.tangem2, "Binance Testnet"),
Matic("MATIC", "MTX", 1.0, R.drawable.tangem2, "Matic"),
MaticTestNet("MATIC/test", "MTX", 1.0, R.drawable.tangem2, "Matic Testnet"),
- Stellar("XLM", "XLM", 1000000.0, R.drawable.ic_logo_stellar, "Stellar"),
- StellarTestNet("XLM/test", "XLM", 1000000.0, R.drawable.ic_logo_stellar, "Stellar Testnet"),
+ Stellar("XLM", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar"),
+ StellarTestNet("XLM/test", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar Testnet"),
StellarAsset("Asset", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar"),
- Eos("EOS", "EOS", 10000.0, R.drawable.tangem2, "EOS");
+ StellarTag("XLM-Tag", "XLM", 1000000.0, R.drawable.ic_logo_stellar, "Stellar"),
+ Eos("EOS", "EOS", 10000.0, R.drawable.tangem2, "EOS"),
+ Ducatus("DUC", "DUC", 100000000.0, R.drawable.tangem2, "Ducatus"),
+ Tezos("TEZOS", "XTZ", 10000000.0, R.drawable.tangem2, "Tezos");
Blockchain(String ID, String currency, double multiplier, int imageResource, String officialName) {
mID = ID;
diff --git a/app/src/main/java/com/tangem/data/network/BlockcypherApi.java b/app/src/main/java/com/tangem/data/network/BlockcypherApi.java
index d8de09d725..8bba6dfdee 100644
--- a/app/src/main/java/com/tangem/data/network/BlockcypherApi.java
+++ b/app/src/main/java/com/tangem/data/network/BlockcypherApi.java
@@ -15,13 +15,13 @@ import retrofit2.http.Query;
public interface BlockcypherApi {
@GET(Server.ApiBlockcypher.Method.MAIN)
- Call blockcypherMain(@Path("blockchain") String blockchain, @Path("network") String network);
+ Call blockcypherMain(@Path("blockchain") String blockchain, @Path("network") String network, @Query("token") String token);
@GET(Server.ApiBlockcypher.Method.ADDRESS)
- Call blockcypherAddress(@Path("blockchain") String blockchain, @Path("network") String network, @Path("address") String address);
+ Call blockcypherAddress(@Path("blockchain") String blockchain, @Path("network") String network, @Path("address") String address, @Query("token") String token);
@GET(Server.ApiBlockcypher.Method.TXS)
- Call blockcypherTxs(@Path("blockchain") String blockchain, @Path("network") String network, @Path("txHash") String txHash);
+ Call blockcypherTxs(@Path("blockchain") String blockchain, @Path("network") String network, @Path("txHash") String txHash, @Query("token") String token);
@Headers("Content-Type: application/json")
@POST(Server.ApiBlockcypher.Method.PUSH)
diff --git a/app/src/main/java/com/tangem/data/network/DucatusApi.java b/app/src/main/java/com/tangem/data/network/DucatusApi.java
new file mode 100644
index 0000000000..53957f70fc
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/DucatusApi.java
@@ -0,0 +1,25 @@
+package com.tangem.data.network;
+
+import com.tangem.data.network.model.BitcoreBalance;
+import com.tangem.data.network.model.BitcoreSendBody;
+import com.tangem.data.network.model.BitcoreSendResponse;
+import com.tangem.data.network.model.BitcoreUtxo;
+
+import java.util.List;
+
+import io.reactivex.Single;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+
+public interface DucatusApi {
+ @GET(Server.ApiDucatus.Method.BALANCE)
+ Single ducatusBalance(@Path("address") String address);
+
+ @GET(Server.ApiDucatus.Method.UTXO)
+ Single> ducatusUnspents(@Path("address") String address);
+
+ @POST(Server.ApiDucatus.Method.SEND)
+ Single ducatusSend(@Body BitcoreSendBody body);
+}
diff --git a/app/src/main/java/com/tangem/data/network/InsightApi.java b/app/src/main/java/com/tangem/data/network/InsightApi.java
index 63eb570f1c..4095326dc5 100644
--- a/app/src/main/java/com/tangem/data/network/InsightApi.java
+++ b/app/src/main/java/com/tangem/data/network/InsightApi.java
@@ -2,6 +2,7 @@ package com.tangem.data.network;
import com.tangem.data.network.model.InsightBody;
import com.tangem.data.network.model.InsightResponse;
+import com.tangem.data.network.model.InsightUtxo;
import java.util.List;
@@ -18,7 +19,7 @@ public interface InsightApi {
Call insightAddress(@Path("address") String address);
@GET(ServerApiInsight.INSIGHT_UNSPENT_OUTPUTS)
- Call> insightUnspent(@Path("address") String address);
+ Call> insightUnspent(@Path("address") String address);
@GET(ServerApiInsight.INSIGHT_TRANSACTION)
Call insightTransaction(@Path("txId") String txId);
diff --git a/app/src/main/java/com/tangem/data/network/Server.java b/app/src/main/java/com/tangem/data/network/Server.java
index 1b0570150a..14117ed83b 100644
--- a/app/src/main/java/com/tangem/data/network/Server.java
+++ b/app/src/main/java/com/tangem/data/network/Server.java
@@ -129,4 +129,14 @@ public class Server {
static final String PUSH = URL_BLOCKCHAININFO + "pushtx";
}
}
+
+ public static class ApiDucatus {
+ public static final String URL_DUCATUS = ServerURL.API_DUCATUS + "api/DUC/mainnet/";
+
+ public static class Method {
+ static final String BALANCE = URL_DUCATUS + "address/{address}/balance";
+ static final String UTXO = URL_DUCATUS + "address/{address}/?unspent=true";
+ static final String SEND = URL_DUCATUS + "tx/send";
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiBitcore.java b/app/src/main/java/com/tangem/data/network/ServerApiBitcore.java
new file mode 100644
index 0000000000..de9de087eb
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/ServerApiBitcore.java
@@ -0,0 +1,47 @@
+package com.tangem.data.network;
+
+import com.tangem.App;
+import com.tangem.data.network.model.BitcoreBalance;
+import com.tangem.data.network.model.BitcoreBalanceAndUnspents;
+import com.tangem.data.network.model.BitcoreSendBody;
+import com.tangem.data.network.model.BitcoreSendResponse;
+import com.tangem.data.network.model.BitcoreUtxo;
+import com.tangem.tangem_card.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.reactivex.Single;
+import io.reactivex.SingleObserver;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+public class ServerApiBitcore {
+ private static String TAG = ServerApiBitcore.class.getSimpleName();
+
+ public void getBalanceAndUnspents(String wallet, SingleObserver balanceAndUnspentsObserver) {
+ Log.i(TAG, "new getAddressAndUnspents request");
+ DucatusApi api = App.Companion.getNetworkComponent().getRetrofitDucatus().create(DucatusApi.class);
+
+ Single balanceObservable = api.ducatusBalance(wallet);
+
+ Single> unspentsObservable = api.ducatusUnspents(wallet)
+ .onErrorReturnItem(new ArrayList<>());
+
+ Single.zip(balanceObservable, unspentsObservable, BitcoreBalanceAndUnspents::new)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(balanceAndUnspentsObserver);
+ }
+
+ public void sendTransaction(String tx, SingleObserver sendObserver) {
+ Log.i(TAG, "new getAddress request");
+ DucatusApi api = App.Companion.getNetworkComponent().getRetrofitDucatus().create(DucatusApi.class);
+
+ Single sendObservable = api.ducatusSend(new BitcoreSendBody(tx))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+
+ sendObservable.subscribe(sendObserver);
+ }
+}
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java b/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java
index 6b8bc2a6f1..88e38c3037 100644
--- a/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java
+++ b/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java
@@ -32,8 +32,9 @@ public class ServerApiBlockcypher {
return requestsCount <= 0;
}
- private ResponseListener responseListener;
+ private String apiKey = null;
+ private ResponseListener responseListener;
private TxResponseListener txResponseListener;
public interface ResponseListener {
@@ -71,17 +72,24 @@ public class ServerApiBlockcypher {
switch (method) {
case BLOCKCYPHER_ADDRESS:
- Call addressCall = blockcypherApi.blockcypherAddress(blockchain, network, wallet);
+ Call addressCall = blockcypherApi.blockcypherAddress(blockchain, network, wallet, apiKey);
addressCall.enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
requestsCount--;
- if (response.code() == 200) {
- 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());
+ switch (response.code()) {
+ case 200:
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
+ case 429:
+ apiKey = getRandomApiKey();
+ requestData(blockchainID, method, wallet, tx);
+ break;
+ default:
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
}
}
@@ -95,17 +103,24 @@ public class ServerApiBlockcypher {
break;
case BLOCKCYPHER_FEE:
- Call feeCall = blockcypherApi.blockcypherMain(blockchain, network);
+ Call feeCall = blockcypherApi.blockcypherMain(blockchain, network, apiKey);
feeCall.enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
requestsCount--;
- if (response.code() == 200) {
- 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());
+ switch (response.code()) {
+ case 200:
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
+ case 429:
+ apiKey = getRandomApiKey();
+ requestData(blockchainID, method, wallet, tx);
+ break;
+ default:
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
}
}
@@ -119,17 +134,24 @@ public class ServerApiBlockcypher {
break;
case BLOCKCYPHER_TXS:
- Call txsCall = blockcypherApi.blockcypherTxs(blockchain, network, tx);
+ Call txsCall = blockcypherApi.blockcypherTxs(blockchain, network, tx, apiKey);
txsCall.enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call,@NonNull Response response) {
requestsCount--;
- if (response.code() == 200) {
- txResponseListener.onSuccess(response.body());
- Log.i(TAG, "requestData " + method + " onResponse " + response.code());
- } else {
- txResponseListener.onFail(String.valueOf(response.code()));
- Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ switch (response.code()) {
+ case 200:
+ txResponseListener.onSuccess(response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
+ case 429:
+ apiKey = getRandomApiKey();
+ requestData(blockchainID, method, wallet, tx);
+ break;
+ default:
+ txResponseListener.onFail(String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
}
}
@@ -143,19 +165,24 @@ public class ServerApiBlockcypher {
break;
case BLOCKCYPHER_SEND:
- BlockcypherToken blockcypherToken = BlockcypherToken.values()[new Random().nextInt(BlockcypherToken.values().length)];
-
- Call sendCall = blockcypherApi.blockcypherPush(blockchain, network, new BlockcypherBody(tx), blockcypherToken.getToken());
+ Call sendCall = blockcypherApi.blockcypherPush(blockchain, network, new BlockcypherBody(tx), apiKey);
sendCall.enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
requestsCount--;
- if (response.code() == 201) {
- 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());
+ switch (response.code()) {
+ case 201:
+ responseListener.onSuccess(method, response.body());
+ Log.i(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
+ case 429:
+ apiKey = getRandomApiKey();
+ requestData(blockchainID, method, wallet, tx);
+ break;
+ default:
+ responseListener.onFail(method, String.valueOf(response.code()));
+ Log.e(TAG, "requestData " + method + " onResponse " + response.code());
+ break;
}
}
@@ -175,4 +202,9 @@ public class ServerApiBlockcypher {
break;
}
}
+
+ private String getRandomApiKey() {
+ return BlockcypherToken
+ .values()[new Random().nextInt(BlockcypherToken.values().length)].getToken();
+ }
}
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiInsight.java b/app/src/main/java/com/tangem/data/network/ServerApiInsight.java
index e3eae3384a..5a768471e6 100644
--- a/app/src/main/java/com/tangem/data/network/ServerApiInsight.java
+++ b/app/src/main/java/com/tangem/data/network/ServerApiInsight.java
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import com.tangem.data.network.model.InsightBody;
import com.tangem.data.network.model.InsightResponse;
+import com.tangem.data.network.model.InsightUtxo;
import java.util.List;
@@ -18,11 +19,11 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class ServerApiInsight {
private static String TAG = ServerApiInsight.class.getSimpleName();
- public static final String INSIGHT_ADDRESS = "/addr/{address}";
- public static final String INSIGHT_UNSPENT_OUTPUTS = "/addr/{address}/utxo";
- public static final String INSIGHT_TRANSACTION = "/rawtx/{txId}";
- public static final String INSIGHT_FEE = "/utils/estimatefee?nbBlocks=2,3,6";
- public static final String INSIGHT_SEND = "/tx/send";
+ public static final String INSIGHT_ADDRESS = "addr/{address}";
+ public static final String INSIGHT_UNSPENT_OUTPUTS = "addr/{address}/utxo";
+ public static final String INSIGHT_TRANSACTION = "rawtx/{txId}";
+ public static final String INSIGHT_FEE = "utils/estimatefee?nbBlocks=2,3,6";
+ public static final String INSIGHT_SEND = "tx/send";
private int requestsCount = 0;
@@ -38,7 +39,7 @@ public class ServerApiInsight {
public interface ResponseListener {
void onSuccess(String method, InsightResponse insightResponse);
- void onSuccess(String method, List utxoList);
+ void onSuccess(String method, List utxoList);
void onFail(String method, String message);
}
@@ -49,7 +50,7 @@ public class ServerApiInsight {
public void requestData(String method, String wallet, String tx) {
requestsCount++;
- String insightURL = "http://130.185.109.17:3001/insigth-api"; //TODO: make random selection
+ String insightURL = "https://insight.ducatus.io/insight-lite-api/"; //TODO: make random selection
this.lastNode = insightURL; //TODO: show node instead of URL
Retrofit retrofitInsight = new Retrofit.Builder()
@@ -61,10 +62,10 @@ public class ServerApiInsight {
InsightApi insightApi = retrofitInsight.create(InsightApi.class);
if (method.equals(INSIGHT_UNSPENT_OUTPUTS)) {
- Call> call = insightApi.insightUnspent(wallet);
- call.enqueue(new Callback>() {
+ Call> call = insightApi.insightUnspent(wallet);
+ call.enqueue(new Callback>() {
@Override
- public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
requestsCount--;
if (response.code() == 200) {
@@ -77,7 +78,7 @@ public class ServerApiInsight {
}
@Override
- public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
requestsCount--;
responseListener.onFail(method, String.valueOf(t.getMessage()));
Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
@@ -92,13 +93,9 @@ public class ServerApiInsight {
call = insightApi.insightAddress(wallet);
break;
- case INSIGHT_TRANSACTION:
- call = insightApi.insightTransaction(tx);
- break;
-
- case INSIGHT_FEE:
- call = insightApi.insightFee();
- break;
+// case INSIGHT_FEE:
+// call = insightApi.insightFee();
+// break;
case INSIGHT_SEND:
call = insightApi.insightSend(new InsightBody(tx));
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiStellar.java b/app/src/main/java/com/tangem/data/network/ServerApiStellar.java
index f364820eb1..77427e3fc4 100644
--- a/app/src/main/java/com/tangem/data/network/ServerApiStellar.java
+++ b/app/src/main/java/com/tangem/data/network/ServerApiStellar.java
@@ -33,7 +33,7 @@ import io.reactivex.schedulers.Schedulers;
public class ServerApiStellar {
public ServerApiStellar(Blockchain blockchain) {
- if (blockchain == Blockchain.Stellar || blockchain == Blockchain.StellarAsset) {
+ if (blockchain == Blockchain.Stellar || blockchain == Blockchain.StellarAsset || blockchain == Blockchain.StellarTag) {
currentURL = ServerURL.API_STELLAR;
} else {
currentURL = ServerURL.API_STELLAR_TESTNET;
@@ -173,10 +173,11 @@ public class ServerApiStellar {
stellarRequest.setError(null);
try {
Server server;
- if (ctx.getBlockchain() == Blockchain.Stellar || ctx.getBlockchain() == Blockchain.StellarAsset) {
+ Blockchain blockchain = ctx.getBlockchain();
+ if (blockchain == Blockchain.Stellar || blockchain == Blockchain.StellarAsset || blockchain == Blockchain.StellarTag) {
Network.usePublicNetwork();
server = new Server(currentURL);
- } else if (ctx.getBlockchain() == Blockchain.StellarTestNet) {
+ } else if (blockchain == Blockchain.StellarTestNet) {
Network.useTestNetwork();
server = new Server(currentURL);
} else {
diff --git a/app/src/main/java/com/tangem/data/network/ServerApiTezos.java b/app/src/main/java/com/tangem/data/network/ServerApiTezos.java
new file mode 100644
index 0000000000..b5300912ca
--- /dev/null
+++ b/app/src/main/java/com/tangem/data/network/ServerApiTezos.java
@@ -0,0 +1,139 @@
+package com.tangem.data.network;
+
+import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import com.tangem.data.network.model.TezosAccountResponse;
+import com.tangem.data.network.model.TezosForgeBody;
+import com.tangem.data.network.model.TezosHeaderResponse;
+import com.tangem.data.network.model.TezosPreapplyBody;
+import com.tangem.tangem_card.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.reactivex.Single;
+import io.reactivex.SingleObserver;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.OkHttpClient;
+import okhttp3.logging.HttpLoggingInterceptor;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import retrofit2.converter.scalars.ScalarsConverterFactory;
+
+public class ServerApiTezos {
+ private static String TAG = ServerApiTezos.class.getSimpleName();
+
+ private final String letzbakeURI = "https://teznode.letzbake.com";
+ private final String tezrpcURI = "https://mainnet.tezrpc.me";
+
+ static final String TEZOS_ADDRESS = "chains/main/blocks/head/context/contracts/{address}";
+ static final String TEZOS_HEADER = "chains/main/blocks/head/header";
+ static final String TEZOS_MANAGER_KEY = "chains/main/blocks/head/context/contracts/{address}/manager_key";
+ static final String TEZOS_FORGE_OPERATIONS = "chains/main/blocks/head/helpers/forge/operations";
+ static final String TEZOS_PREAPPLY_OPERATIONS = "chains/main/blocks/head/helpers/preapply/operations";
+ static final String TEZOS_RUN_OPERATION = "chains/main/blocks/head/helpers/scripts/run_operation";
+ static final String TEZOS_INJECT_OPERATIONS = "injection/operation";
+
+ private Retrofit retrofitTezos = new Retrofit.Builder()
+ .baseUrl(letzbakeURI)
+ .addConverterFactory(GsonConverterFactory.create())
+ .addConverterFactory(ScalarsConverterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ //logging for testing
+ .client(new OkHttpClient.Builder().addInterceptor(
+ new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
+ ).build())
+
+ .build();
+
+ private TezosApi tezosApi = retrofitTezos.create(TezosApi.class);
+
+ 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;
+ }
+
+ public void getAddress(String wallet, SingleObserver accountObserver) {
+ requestsCount++;
+ Log.i(TAG, "new getAddress request");
+
+ Single accountSingle = tezosApi.getAccount(wallet)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnEvent((object, throwable) -> requestsCount--);
+
+ accountSingle.subscribe(accountObserver);
+ }
+
+ public void getMangerKey(String wallet, SingleObserver accountObserver) {
+ requestsCount++;
+ Log.i(TAG, "new getManagerKey request");
+
+ Single managerKeySingle = tezosApi.getManagerKey(wallet)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnEvent((object, throwable) -> requestsCount--);
+
+ managerKeySingle.subscribe(accountObserver);
+ }
+
+ public TezosHeaderResponse getHeader() throws Exception { // TODO? not async
+ requestsCount++;
+ Log.i(TAG, "new getHeader request");
+
+ Response headerResponse = tezosApi.getHeader().execute();
+
+ requestsCount--;
+ if (headerResponse.code() == 200) {
+ return headerResponse.body();
+ } else {
+ throw new Exception("Wrong header response, code: " + headerResponse.code());
+ }
+ }
+
+ public String forgeOperations(TezosForgeBody tezosForgeBody) throws Exception { // TODO? not async
+ requestsCount++;
+ Log.i(TAG, "new forgeOperations request");
+
+ Response forgeResponse = tezosApi.forgeOperations(tezosForgeBody).execute();
+
+ requestsCount--;
+ if (forgeResponse.code() == 200) {
+ return forgeResponse.body();
+ } else {
+ throw new Exception("Wrong forge response, code: " + forgeResponse.code());
+ }
+ }
+
+ public void peapplyOperations(TezosPreapplyBody tezosPreapplyBody) throws Exception {
+ Log.i(TAG, "new peapplyOperations request");
+
+ List tezosPreapplyBodyList = new ArrayList<>();
+ tezosPreapplyBodyList.add(tezosPreapplyBody);
+ Response preapplyResponse = tezosApi.preapplyOperations(tezosPreapplyBodyList).execute();
+
+ if (preapplyResponse.code() != 200) {
+ String error = "Preapply error: unknown error";
+ if (preapplyResponse.errorBody() != null) {
+ error = "Preapply error: " + preapplyResponse.errorBody().string();
+ }
+ Log.e(TAG, error);
+ throw new Exception(error);
+ }
+ }
+
+ public void injectOperations(String txForSend, SingleObserver