Updated on 2026-08-14

This commit is contained in:
Tangem 2019-01-17 12:55:20 +03:00
parent a2e21a5d11
commit 6a14bb202f
9 changed files with 85 additions and 119 deletions

View file

@ -11,11 +11,11 @@ public enum Blockchain {
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"),
EthereumTestNet("ETH/test", "ETH", 1.0, R.drawable.ic_logo_ethereum_testnet, "Ethereum Testnet"),
Token("Token", "ERC20", 1.0, R.drawable.ic_logo_bat_token, "Ethereum"),
Token("Token", "ETH", 1.0, R.drawable.ic_logo_bat_token, "Ethereum"),
BitcoinCash("BCH", "BCH", 100000000.0, R.drawable.ic_logo_bitcoin_cash, "Bitcoin Cash"),
Litecoin("LTC", "LTC", 100000000.0, R.drawable.ic_logo_bitcoin, "Litecoin"),
Rootstock("RSK", "RBTC", 1.0, R.drawable.ic_logo_bitcoin, "Rootstock"),
RootstockToken("Token", "ERC20", 1.0, R.drawable.ic_logo_bat_token, "Rootstock");
RootstockToken("RSKToken", "RBTC", 1.0, R.drawable.ic_logo_bat_token, "Rootstock");
Blockchain(String ID, String currency, double multiplier, int imageResource, String officialName) {
mID = ID;

View file

@ -2,12 +2,13 @@ package com.tangem.data.network;
import com.tangem.data.network.model.RateInfoResponse;
import java.util.List;
import io.reactivex.Observable;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Query;
public interface CoinmarketApi {
@GET(Server.ApiCoinmarket.Method.V1_TICKER_CONVERT)
Observable<List<RateInfoResponse>> getRateInfoList();
@Headers("X-CMC_PRO_API_KEY: 7850b957-6943-42eb-af73-8d536dd8f73e")
@GET(Server.ApiCoinmarket.Method.PRICE_CONVERSION)
Call<RateInfoResponse> getRateInfo(@Query("amount") int amount, @Query("symbol") String cryptoId);
}

View file

@ -17,7 +17,7 @@ public class Server {
public static final String URL_COINMARKET = ServerURL.API_COINMARKETCAP;
public static class Method {
static final String V1_TICKER_CONVERT = URL_COINMARKET + "v1/ticker/?convert=USD&lmit=10";
static final String PRICE_CONVERSION = URL_COINMARKET + "v1/tools/price-conversion";
}
}

View file

@ -83,32 +83,53 @@ public class ServerApiCommon {
public interface RateInfoDataListener {
void onSuccess(RateInfoResponse rateInfoResponse);
void onFail(String message);
}
public void setRateInfoData(RateInfoDataListener listener) {
rateInfoDataListener = listener;
}
@SuppressLint("CheckResult")
public void rateInfoData(String cryptoId) {
CoinmarketApi coinmarketApi = App.getNetworkComponent().getRetrofitCoinmarketcap().create(CoinmarketApi.class);
coinmarketApi.getRateInfoList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(rateInfoModelList -> {
if (!rateInfoModelList.isEmpty()) {
for (RateInfoResponse rateInfoMode : rateInfoModelList) {
if (rateInfoMode.getId().equals(cryptoId)) {
rateInfoDataListener.onSuccess(rateInfoMode);
Log.i(TAG, "rateInfoData " + cryptoId + " onResponse " + "200");
}
}
} else
Log.e(TAG, "rateInfoData " + cryptoId + " onResponse " + "Empty");
},
// handle error
Throwable::printStackTrace);
Call<RateInfoResponse> call = coinmarketApi.getRateInfo(1, cryptoId);
call.enqueue(new Callback<RateInfoResponse>() {
@Override
public void onResponse(@NonNull Call<RateInfoResponse> call, @NonNull Response<RateInfoResponse> response) {
if (response.code() == 200) {
rateInfoDataListener.onSuccess(response.body());
Log.i(TAG, "coinmarketcap onResponse " + response.code());
} else {
rateInfoDataListener.onFail(String.valueOf(response.code()));
Log.e(TAG, "coinmarketcap onResponse " + response.code());
}
}
@Override
public void onFailure(@NonNull Call<RateInfoResponse> call, @NonNull Throwable t) {
rateInfoDataListener.onFail(String.valueOf(t.getMessage()));
Log.e(TAG, "coinmarketcap onFailure " + t.getMessage());
}
});
// coinmarketApi.getRateInfoList()
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe(rateInfoModelList -> {
// if (!rateInfoModelList.isEmpty()) {
// for (RateInfoResponse rateInfoMode : rateInfoModelList) {
// if (rateInfoMode.getId().equals(cryptoId)) {
// rateInfoDataListener.onSuccess(rateInfoMode);
// Log.i(TAG, "rateInfoData " + cryptoId + " onResponse " + "200");
// }
// }
// } else
// Log.e(TAG, "rateInfoData " + cryptoId + " onResponse " + "Empty");
// },
// // handle error
// Throwable::printStackTrace);
}
/**

View file

@ -2,7 +2,7 @@ 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_COINMARKETCAP = "https://sandbox-api.coinmarketcap.com/"; //TODO: change to "https://pro-api.coinmarketcap.com/" for production environment
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/";

View file

@ -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"
}
}
data class CurrencyRate(
@SerializedName("price")
var price: Float? = null
)

View file

@ -22,6 +22,7 @@ import com.tangem.App
import com.tangem.Constant
import com.tangem.data.Blockchain
import com.tangem.data.network.ServerApiCommon
import com.tangem.data.network.model.RateInfoResponse
import com.tangem.domain.wallet.BalanceValidator
import com.tangem.domain.wallet.CoinEngine
import com.tangem.domain.wallet.CoinEngineFactory
@ -258,12 +259,24 @@ 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
val rateInfoDataListener: ServerApiCommon.RateInfoDataListener = object : ServerApiCommon.RateInfoDataListener {
override fun onSuccess(rateInfoResponse: RateInfoResponse?){
ctx.coinData!!.rate = rateInfoResponse!!.data!!.quote!!.usd!!.price!!
}
override fun onFail(message: String?){
ctx.error = message
}
}
serverApiCommon.setRateInfoData(rateInfoDataListener)
// serverApiCommon.setRateInfoData {
// if (activity == null || !UtilHelper.isOnline(activity!!)) return@setRateInfoData
// val rate = it.priceUsd.toFloat()
// ctx.coinData!!.rate = rate
// ctx.coinData!!.rateAlter = rate
// }
refresh()
@ -695,23 +708,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
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.Rootstock -> "bitcoin"
Blockchain.RootstockToken ->"bitcoin"
else -> {
throw Exception("Can''t get rate for blockchain " + ctx.blockchainName)
}
}
serverApiCommon.rateInfoData(cryptoId)
serverApiCommon.rateInfoData(ctx.blockchain.currency)
} else {
ctx.error = getString(R.string.no_connection)
updateViews()