Updated on 2026-08-14

This commit is contained in:
Tangem 2019-08-30 16:55:21 +03:00
commit 65aaa4521d
71 changed files with 1016 additions and 304 deletions

View file

@ -0,0 +1,25 @@
package com.tangem.data.network;
import com.tangem.data.network.model.BlockchainInfoAddress;
import com.tangem.data.network.model.BlockchainInfoUnspents;
import io.reactivex.Single;
import okhttp3.ResponseBody;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface BlockchainInfoApi {
@GET(Server.ApiBlockchainInfo.Method.ADDRESS)
Single<BlockchainInfoAddress> blockchainInfoAddress(@Path("address") String address);
@GET(Server.ApiBlockchainInfo.Method.UTXO)
Single<BlockchainInfoUnspents> blockchainInfoUnspents(@Query("active") String address);
@FormUrlEncoded
@POST(Server.ApiBlockchainInfo.Method.PUSH)
Single<ResponseBody> blockchainInfoPush(@Field("tx") String tx);
}

View file

@ -3,7 +3,6 @@ package com.tangem.data.network;
import com.tangem.data.network.model.RateInfoResponse;
import io.reactivex.Observable;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Query;

View file

@ -118,4 +118,15 @@ public class Server {
static final String PUSH = MAIN + "/txs/push";
}
}
public static class ApiBlockchainInfo {
public static final String URL_BLOCKCHAININFO = ServerURL.API_BLOCKCHAIN_INFO;
public static class Method {
static final String ADDRESS = URL_BLOCKCHAININFO + "rawaddr/{address}?limit=5";
static final String UTXO = URL_BLOCKCHAININFO + "unspent";
// static final String TX = URL_BLOCKCHAININFO + "rawtx/{txHash}";
static final String PUSH = URL_BLOCKCHAININFO + "pushtx";
}
}
}

View file

@ -0,0 +1,46 @@
package com.tangem.data.network;
import android.util.Log;
import com.tangem.App;
import com.tangem.data.network.model.BlockchainInfoAddress;
import com.tangem.data.network.model.BlockchainInfoAddressAndUnspents;
import com.tangem.data.network.model.BlockchainInfoUnspents;
import java.util.ArrayList;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
public class ServerApiBlockchainInfo {
private static String TAG = ServerApiBlockchainInfo.class.getSimpleName();
public void getAddressAndUnspents(String wallet, SingleObserver<BlockchainInfoAddressAndUnspents> addressAndUnspentsObserver) {
Log.i(TAG, "new getAddressAndUnspents request");
BlockchainInfoApi api = App.Companion.getNetworkComponent().getRetrofitBlockchainInfo().create(BlockchainInfoApi.class);
Single<BlockchainInfoAddress> addressObservable = api.blockchainInfoAddress(wallet);
Single<BlockchainInfoUnspents> unspentsObservable = api.blockchainInfoUnspents(wallet)
.onErrorReturnItem(new BlockchainInfoUnspents(new ArrayList<>()));
Single.zip(addressObservable, unspentsObservable, BlockchainInfoAddressAndUnspents::new)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(addressAndUnspentsObserver);
}
public void sendTransaction(String tx, SingleObserver<ResponseBody> sendObserver) {
Log.i(TAG, "new getAddress request");
BlockchainInfoApi api = App.Companion.getNetworkComponent().getRetrofitBlockchainInfo().create(BlockchainInfoApi.class);
Single<ResponseBody> sendObservable = api.blockchainInfoPush(tx)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
sendObservable.subscribe(sendObserver);
}
}

View file

@ -2,6 +2,8 @@ package com.tangem.data.network;
import android.util.Log;
import androidx.annotation.NonNull;
import com.tangem.App;
import com.tangem.data.Blockchain;
import com.tangem.data.network.model.BlockcypherBody;
@ -11,13 +13,12 @@ import com.tangem.data.network.model.BlockcypherTx;
import java.util.Random;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ServerApiBlockcypher {
private static String TAG = ServerApiRipple.class.getSimpleName();
private static String TAG = ServerApiBlockcypher.class.getSimpleName();
public static final String BLOCKCYPHER_ADDRESS = "blockcypher_address";
public static final String BLOCKCYPHER_FEE = "blockcypher_fee";

View file

@ -7,18 +7,16 @@ import com.tangem.wallet.eos.EosPushTransactionRequest;
import io.jafka.jeos.EosApi;
import io.jafka.jeos.EosApiFactory;
import io.jafka.jeos.core.request.chain.transaction.PushTransactionRequest;
import io.jafka.jeos.core.response.chain.account.Account;
import io.jafka.jeos.core.response.chain.transaction.PushedTransaction;
import io.jafka.jeos.impl.EosApiServiceGenerator;
import io.jafka.jeos.impl.EosChainApiService;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class ServerApiEos {
private static String TAG = ServerApiBinance.class.getSimpleName();
private static String TAG = ServerApiEos.class.getSimpleName();
public static void getBalance(String wallet, Observer<Account> accountObserver) {
Log.i(TAG, "new getBalance request");

View file

@ -2,12 +2,13 @@ package com.tangem.data.network;
import android.util.Log;
import androidx.annotation.NonNull;
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;
@ -25,7 +26,14 @@ public class ServerApiRipple {
private int requestsCount = 0;
public static String lastNode;
private final String rippleURL1 = "https://s1.ripple.com:51234"; //TODO: make random selection, add more?, move
private final String rippleURL2 = "https://s2.ripple.com:51234";
private String currentURL = rippleURL1;
public String getCurrentURL() {
return currentURL;
}
public boolean isRequestsSequenceCompleted() {
Log.i(TAG, String.format("isRequestsSequenceCompleted: %s (%d requests left)", String.valueOf(requestsCount <= 0), requestsCount));
@ -46,11 +54,9 @@ public class ServerApiRipple {
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)
.baseUrl(currentURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
@ -93,6 +99,38 @@ public class ServerApiRipple {
rippleBody = new RippleBody();
}
Call<RippleResponse> call = rippleApi.ripple(rippleBody);
call.enqueue(new Callback<RippleResponse>() {
@Override
public void onResponse(@NonNull Call<RippleResponse> call, @NonNull Response<RippleResponse> response) {
if (response.code() == 200) {
requestsCount--;
responseListener.onSuccess(method, response.body());
Log.i(TAG, "requestData " + method + " onResponse " + response.code());
} else {
retryRequest(method, rippleBody);
Log.e(TAG, "requestData " + method + " onResponse " + response.code());
}
}
@Override
public void onFailure(@NonNull Call<RippleResponse> call, @NonNull Throwable t) {
retryRequest(method, rippleBody);
Log.e(TAG, "requestData " + method + " onFailure " + t.getMessage());
}
});
}
private void retryRequest(String method, RippleBody rippleBody) {
currentURL = rippleURL2;
Retrofit retrofitRipple = new Retrofit.Builder()
.baseUrl(currentURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RippleApi rippleApi = retrofitRipple.create(RippleApi.class);
Call<RippleResponse> call = rippleApi.ripple(rippleBody);
call.enqueue(new Callback<RippleResponse>() {
@Override

View file

@ -14,4 +14,5 @@ class ServerURL {
static final String API_MATIC_TESTNET = "https://testnet2.matic.network";
static final String API_STELLAR = "https://horizon.stellar.org/";
static final String API_STELLAR_TESTNET = "https://horizon-testnet.stellar.org";
static final String API_BLOCKCHAIN_INFO = "https://blockchain.info/";
}

View file

@ -0,0 +1,43 @@
package com.tangem.data.network.model
import com.google.gson.annotations.SerializedName
data class BlockchainInfoAddress(
@SerializedName("final_balance")
var final_balance: Long? = null,
@SerializedName("txs")
var txs: List<BlockchainInfoTransaction>? = null
)
data class BlockchainInfoTransaction(
@SerializedName("hash")
var hash: String? = null,
@SerializedName("block_height")
var block_height: Long? = null
)
data class BlockchainInfoUnspents(
@SerializedName("unspent_outputs")
var unspent_outputs: List<BlockchainInfoUtxo>
)
data class BlockchainInfoUtxo(
@SerializedName("tx_hash_big_endian")
var tx_hash_big_endian: String? = null,
@SerializedName("tx_output_n")
var tx_output_n: Int? = null,
@SerializedName("value")
var value: Long? = null,
@SerializedName("script")
var script: String? = null
)
data class BlockchainInfoAddressAndUnspents(
var address: BlockchainInfoAddress,
var unspents: BlockchainInfoUnspents
)