Updated on 2026-08-14
This commit is contained in:
parent
a2e21a5d11
commit
6a14bb202f
9 changed files with 85 additions and 119 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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/";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
#Tue Sep 25 21:50:16 MSK 2018
|
||||
#Wed Jan 16 11:40:34 MSK 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue