From 964102ccee6a9ca6ccd849c6e90fcb07d9a2dd24 Mon Sep 17 00:00:00 2001 From: James Brown Date: Thu, 28 Nov 2024 14:11:37 +0800 Subject: [PATCH] Update Ticker fetch system (#3410) --- .../app/entity/ticker/BaseTicker.java | 48 ++++ .../entity/{ => ticker}/CoinGeckoTicker.java | 39 +-- .../app/entity/ticker/TNDiscoveryTicker.java | 34 +++ .../app/repository/TokensRealmSource.java | 14 +- .../alphawallet/app/service/IPFSService.java | 2 +- .../app/service/TickerService.java | 241 ++++++------------ .../app/ui/widget/adapter/TokensAdapter.java | 3 + .../holder/WalletSummaryHeaderHolder.java | 2 - .../java/com/alphawallet/app/util/Utils.java | 1 - 9 files changed, 175 insertions(+), 209 deletions(-) create mode 100644 app/src/main/java/com/alphawallet/app/entity/ticker/BaseTicker.java rename app/src/main/java/com/alphawallet/app/entity/{ => ticker}/CoinGeckoTicker.java (60%) create mode 100644 app/src/main/java/com/alphawallet/app/entity/ticker/TNDiscoveryTicker.java diff --git a/app/src/main/java/com/alphawallet/app/entity/ticker/BaseTicker.java b/app/src/main/java/com/alphawallet/app/entity/ticker/BaseTicker.java new file mode 100644 index 0000000000..65f282f81a --- /dev/null +++ b/app/src/main/java/com/alphawallet/app/entity/ticker/BaseTicker.java @@ -0,0 +1,48 @@ +package com.alphawallet.app.entity.ticker; + +import android.text.TextUtils; + +import com.alphawallet.app.entity.tokendata.TokenTicker; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public abstract class BaseTicker +{ + public final String address; + public final double fiatPrice; + public final BigDecimal fiatChange; + + public BaseTicker(String address, double fiatPrice, BigDecimal fiatChange) + { + this.address = address; + this.fiatPrice = fiatPrice; + this.fiatChange = fiatChange; + } + + protected static BigDecimal getFiatChange(String fiatChangeStr) + { + if (TextUtils.isEmpty(fiatChangeStr)) return BigDecimal.ZERO; + + try + { + return new BigDecimal(fiatChangeStr); + } + catch (Exception e) + { + return BigDecimal.ZERO; + } + } + + public TokenTicker toTokenTicker(String currentCurrencySymbolTxt) + { + return new TokenTicker(String.valueOf(fiatPrice), + fiatChange.setScale(3, RoundingMode.DOWN).toString(), currentCurrencySymbolTxt, "", System.currentTimeMillis()); + } + + public TokenTicker toTokenTicker(String currentCurrencySymbolTxt, double conversionRate) + { + return new TokenTicker(String.valueOf(fiatPrice * conversionRate), + fiatChange.setScale(3, RoundingMode.DOWN).toString(), currentCurrencySymbolTxt, "", System.currentTimeMillis()); + } +} diff --git a/app/src/main/java/com/alphawallet/app/entity/CoinGeckoTicker.java b/app/src/main/java/com/alphawallet/app/entity/ticker/CoinGeckoTicker.java similarity index 60% rename from app/src/main/java/com/alphawallet/app/entity/CoinGeckoTicker.java rename to app/src/main/java/com/alphawallet/app/entity/ticker/CoinGeckoTicker.java index cb3087f3d2..12268afe01 100644 --- a/app/src/main/java/com/alphawallet/app/entity/CoinGeckoTicker.java +++ b/app/src/main/java/com/alphawallet/app/entity/ticker/CoinGeckoTicker.java @@ -1,31 +1,20 @@ -package com.alphawallet.app.entity; - -import android.text.TextUtils; - -import com.alphawallet.app.entity.tokendata.TokenTicker; +package com.alphawallet.app.entity.ticker; import org.json.JSONException; import org.json.JSONObject; import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; /** * Created by JB on 21/04/2021. */ -public class CoinGeckoTicker +public class CoinGeckoTicker extends BaseTicker { - public final String address; - public final double fiatPrice; - public final BigDecimal fiatChange; - public CoinGeckoTicker(String address, double fiatPrice, BigDecimal fiatChange) { - this.address = address; - this.fiatChange = fiatChange; - this.fiatPrice = fiatPrice; + super(address, fiatPrice, fiatChange); } public static List buildTickerList(String jsonData, String currencyIsoSymbol, double currentConversionRate) throws JSONException @@ -60,24 +49,4 @@ else if (obj.has("usd")) return res; } - - private static BigDecimal getFiatChange(String fiatChangeStr) - { - if (TextUtils.isEmpty(fiatChangeStr)) return BigDecimal.ZERO; - - try - { - return new BigDecimal(fiatChangeStr); - } - catch (Exception e) - { - return BigDecimal.ZERO; - } - } - - public TokenTicker toTokenTicker(String currentCurrencySymbolTxt) - { - return new TokenTicker(String.valueOf(fiatPrice), - fiatChange.setScale(3, RoundingMode.DOWN).toString(), currentCurrencySymbolTxt, "", System.currentTimeMillis()); - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/alphawallet/app/entity/ticker/TNDiscoveryTicker.java b/app/src/main/java/com/alphawallet/app/entity/ticker/TNDiscoveryTicker.java new file mode 100644 index 0000000000..fc848a2e79 --- /dev/null +++ b/app/src/main/java/com/alphawallet/app/entity/ticker/TNDiscoveryTicker.java @@ -0,0 +1,34 @@ +package com.alphawallet.app.entity.ticker; + + +import com.alphawallet.app.entity.tokendata.TokenTicker; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.math.BigDecimal; +import java.util.Map; + +public class TNDiscoveryTicker extends BaseTicker +{ + public TNDiscoveryTicker(String address, double fiatPrice, BigDecimal fiatChange) + { + super(address, fiatPrice, fiatChange); + } + + public TNDiscoveryTicker(JSONObject result, String address) throws JSONException + { + super(address, result.getDouble("usdPrice"), getFiatChange(result.getString("24hrPercentChange"))); + } + + public static void toTokenTickers(Map tickers, JSONArray result, String currentCurrencySymbolTxt, double currentConversionRate) throws JSONException + { + for (int i = 0; i < result.length(); i++) + { + JSONObject thisTickerObject = result.getJSONObject(i); + TNDiscoveryTicker thisTicker = new TNDiscoveryTicker(thisTickerObject, thisTickerObject.getString("contract")); + tickers.put(thisTickerObject.getString("contract"), thisTicker.toTokenTicker(currentCurrencySymbolTxt, currentConversionRate)); + } + } +} diff --git a/app/src/main/java/com/alphawallet/app/repository/TokensRealmSource.java b/app/src/main/java/com/alphawallet/app/repository/TokensRealmSource.java index ea6142ee42..e090f70b1a 100644 --- a/app/src/main/java/com/alphawallet/app/repository/TokensRealmSource.java +++ b/app/src/main/java/com/alphawallet/app/repository/TokensRealmSource.java @@ -1,5 +1,6 @@ package com.alphawallet.app.repository; +import static com.alphawallet.app.service.TickerService.TICKER_STALE_TIMEOUT; import static com.alphawallet.app.service.TickerService.TICKER_TIMEOUT; import static com.alphawallet.app.service.TokensService.EXPIRED_CONTRACT; @@ -1409,7 +1410,13 @@ public Map getTickerTimeMap(long chainId, List erc2 if (realmItem != null) { - updateMap.put(meta.getAddress(), realmItem.getUpdatedTime()); + // how old is the update time? + long updateTime = realmItem.getUpdatedTime(); + long age = System.currentTimeMillis() - updateTime; + if (age < TICKER_STALE_TIMEOUT) //ticker old, don't fetch + { + updateMap.put(meta.getAddress(), realmItem.getUpdatedTime()); + } } } } @@ -1454,10 +1461,7 @@ public void deleteTickers() //.lessThan("updatedTime", System.currentTimeMillis() - TICKER_TIMEOUT) .findAll(); - for (RealmTokenTicker data : realmItems) - { - data.deleteFromRealm(); - } + realmItems.deleteAllFromRealm(); }); } catch (Exception e) diff --git a/app/src/main/java/com/alphawallet/app/service/IPFSService.java b/app/src/main/java/com/alphawallet/app/service/IPFSService.java index 36b82f05c8..ed819119c8 100644 --- a/app/src/main/java/com/alphawallet/app/service/IPFSService.java +++ b/app/src/main/java/com/alphawallet/app/service/IPFSService.java @@ -83,7 +83,7 @@ private QueryResponse getFromIPFS(String url) throws IOException if (isTestCode(url)) return loadTestCode(); //try Infura first - String tryIPFS = Utils.resolveIPFS(url, Utils.IPFS_IO_RESOLVER); + String tryIPFS = Utils.resolveIPFS(url, Utils.IPFS_INFURA_RESOLVER); //attempt to load content QueryResponse r; try diff --git a/app/src/main/java/com/alphawallet/app/service/TickerService.java b/app/src/main/java/com/alphawallet/app/service/TickerService.java index e8c46d4a66..10112fa964 100644 --- a/app/src/main/java/com/alphawallet/app/service/TickerService.java +++ b/app/src/main/java/com/alphawallet/app/service/TickerService.java @@ -11,6 +11,7 @@ import static com.alphawallet.ethereum.EthereumNetworkBase.FANTOM_ID; import static com.alphawallet.ethereum.EthereumNetworkBase.GNOSIS_ID; import static com.alphawallet.ethereum.EthereumNetworkBase.HECO_ID; +import static com.alphawallet.ethereum.EthereumNetworkBase.HOLESKY_ID; import static com.alphawallet.ethereum.EthereumNetworkBase.IOTEX_MAINNET_ID; import static com.alphawallet.ethereum.EthereumNetworkBase.KLAYTN_ID; import static com.alphawallet.ethereum.EthereumNetworkBase.LINEA_ID; @@ -29,7 +30,8 @@ import androidx.annotation.Nullable; -import com.alphawallet.app.entity.CoinGeckoTicker; +import com.alphawallet.app.entity.ticker.CoinGeckoTicker; +import com.alphawallet.app.entity.ticker.TNDiscoveryTicker; import com.alphawallet.app.entity.DexGuruTicker; import com.alphawallet.app.entity.tokendata.TokenTicker; import com.alphawallet.app.entity.tokens.Token; @@ -42,8 +44,10 @@ import com.alphawallet.app.repository.TokenRepository; import com.alphawallet.app.repository.TokensRealmSource; import com.alphawallet.app.util.BalanceUtils; +import com.alphawallet.token.entity.ContractAddress; import com.alphawallet.token.entity.EthereumReadBuffer; +import org.json.JSONArray; import org.json.JSONObject; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturnDecoder; @@ -87,13 +91,15 @@ public class TickerService { private static final int UPDATE_TICKER_CYCLE = 5; //5 Minutes private static final String MEDIANIZER = "0x729D19f657BD0614b4985Cf1D82531c67569197B"; - private static final String MARKET_ORACLE_CONTRACT = "0xdAcAf435f241B1a062B021abEED9CA2F76F22F8D"; + private static final String MARKET_ORACLE_CONTRACT = "0x40805417CD347dB17829725C74b8E5990dC251d8"; private static final String CONTRACT_ADDR = "[CONTRACT_ADDR]"; private static final String CHAIN_IDS = "[CHAIN_ID]"; private static final String CURRENCY_TOKEN = "[CURRENCY]"; private static final String COINGECKO_CHAIN_CALL = "https://api.coingecko.com/api/v3/simple/price?ids=" + CHAIN_IDS + "&vs_currencies=" + CURRENCY_TOKEN + "&include_24hr_change=true"; private static final String COINGECKO_API = String.format("https://api.coingecko.com/api/v3/simple/token_price/%s?contract_addresses=%s&vs_currencies=%s&include_24hr_change=true", CHAIN_IDS, CONTRACT_ADDR, CURRENCY_TOKEN); + private static final String TOKEN_DISCOVERY_API = String.format("https://api.token-discovery.tokenscript.org/get-raw-token-price?blockchain=evm&smartContract=%s&chain=%s", + CONTRACT_ADDR, CHAIN_IDS); private static final int COINGECKO_MAX_FETCH = 10; private static final String DEXGURU_API = "https://api.dex.guru/v1/tokens/" + CONTRACT_ADDR + "-" + CHAIN_IDS; private static final String CURRENCY_CONV = "currency"; @@ -109,6 +115,7 @@ public class TickerService private static String currentCurrencySymbolTxt; private static String currentCurrencySymbol; private static final ConcurrentLinkedDeque tokenCheckQueue = new ConcurrentLinkedDeque<>(); + private static final ConcurrentLinkedDeque secondaryCheckQueue = new ConcurrentLinkedDeque<>(); private static final Map dexGuruQuery = new ConcurrentHashMap<>(); private static long lastTickerUpdate; private static int keyCycle = 0; @@ -119,9 +126,6 @@ public class TickerService @Nullable private Disposable erc20TickerCheck; - @Nullable - private Disposable dexGuruLookup; - @Nullable private Disposable mainTickerUpdate; @@ -131,6 +135,8 @@ public TickerService(OkHttpClient httpClient, PreferenceRepositoryType sharedPre this.sharedPrefs = sharedPrefs; this.localSource = localSource; + //deleteTickers(); + resetTickerUpdate(); initCurrency(); lastTickerUpdate = 0; @@ -150,6 +156,24 @@ public void updateTickers() .subscribe(); } + private void addAPIHeader(Request.Builder buildRequest) + { + String coinGeckoKey = keyProvider.getCoinGeckoKey(); + String backupKey = keyProvider.getBackupKey(); + + if (!TextUtils.isEmpty(coinGeckoKey)) + { + if (keyCycle%2 == 0) + { + buildRequest.addHeader("x-cg-demo-api-key", coinGeckoKey); + } + else if (keyCycle%2 == 1) + { + buildRequest.addHeader("x-cg-demo-api-key", backupKey); + } + } + } + private void tickerUpdate() { mainTickerUpdate = updateCurrencyConversion() @@ -207,7 +231,6 @@ private Single fetchTickersSeparatelyIfRequired(int tickerCount) else return fetchCoinGeckoChainPrices(); //fetch directly } - private Single fetchCoinGeckoChainPrices() { return Single.fromCallable(() -> { @@ -250,7 +273,7 @@ private Single updateTickersFromOracle(double conversionRate) currentConversionRate = conversionRate; return Single.fromCallable(() -> { int tickerSize = 0; - final Web3j web3j = TokenRepository.getWeb3jService(POLYGON_TEST_ID); + final Web3j web3j = TokenRepository.getWeb3jService(HOLESKY_ID); //fetch current tickers Function function = getTickers(); String responseValue = callSmartContractFunction(web3j, function, MARKET_ORACLE_CONTRACT); @@ -329,8 +352,6 @@ private List nextTickerSet(int count) public Single syncERC20Tickers(long chainId, List erc20Tokens) { - //add to queue here - long staleTime = System.currentTimeMillis() - 10 * DateUtils.MINUTE_IN_MILLIS; //only check networks with value and if there's actually tokens to check if (!EthereumNetworkRepository.hasRealValue(chainId) || erc20Tokens.isEmpty()) { @@ -342,8 +363,7 @@ public Single syncERC20Tickers(long chainId, List erc20T //determine whether to add to checking queue for (TokenCardMeta tcm : erc20Tokens) { - if ((!currentTickerMap.containsKey(tcm.getAddress()) - || currentTickerMap.get(tcm.getAddress()) < staleTime) + if (!currentTickerMap.containsKey(tcm.getAddress()) && !alreadyInQueue(tcm)) { tokenCheckQueue.addLast(tcm); @@ -356,34 +376,19 @@ public Single syncERC20Tickers(long chainId, List erc20T } else { - //start checking the queue - return Single.fromCallable(this::doCoinGeckoCheck).map(count -> { - beginTickerCheck(); - return count; - }); - } - } - - private int doCoinGeckoCheck() - { - //pull first token to get current chainId - List tickerSet = nextTickerSet(COINGECKO_MAX_FETCH); - Map tickerMap = fetchERC20TokenTickers(tickerSet); - localSource.updateERC20Tickers(getChainId(tickerSet), tickerMap); - if (tokenCheckQueue.isEmpty()) - { - stopTickerCheck(); + return Single.fromCallable(this::beginTickerCheck); } - return tickerMap.size(); } - private void beginTickerCheck() + private int beginTickerCheck() { if (!tokenCheckQueue.isEmpty() && (erc20TickerCheck == null || erc20TickerCheck.isDisposed())) { erc20TickerCheck = Observable.interval(2, 2, TimeUnit.SECONDS) - .doOnNext(l -> doCoinGeckoCheck()).subscribe(); + .doOnNext(l -> checkTokenDiscoveryTickers()).subscribe(); } + + return tokenCheckQueue.size(); } private void stopTickerCheck() @@ -406,156 +411,59 @@ private long getChainId(List erc20Tokens) return chainId; } - private Map fetchERC20TokenTickers(List erc20Tokens) + //call API using a Single and return a mapping of TokenTickers to a separate method + private Single> fetchTickers(TokenCardMeta tcm) { - final Map erc20Tickers = new HashMap<>(); - final long chainId = getChainId(erc20Tokens); - if (chainId == 0) { return erc20Tickers; } - - final String apiChainName = coinGeckoChainIdToAPIName.get(chainId); - final String dexGuruName = dexGuruChainIdToAPISymbol.get(chainId); - - if (apiChainName == null) { return erc20Tickers; } - - final Map lookupMap = new HashMap<>(); - - //build ticker header - StringBuilder sb = new StringBuilder(); - boolean isFirst = true; - for (TokenCardMeta tcm : erc20Tokens) - { - lookupMap.put(tcm.getAddress().toLowerCase(), tcm); - if (!isFirst) sb.append(","); - sb.append(tcm.getAddress()); - isFirst = false; - } - - Request.Builder buildRequest = new Request.Builder() - .url(COINGECKO_API.replace(CHAIN_IDS, apiChainName).replace(CONTRACT_ADDR, sb.toString()).replace(CURRENCY_TOKEN, currentCurrencySymbolTxt)) - .get(); + return Single.fromCallable(() -> { + final String apiChainName = coinGeckoChainIdToAPIName.get(tcm.getChain()); + Map tickersMap = new HashMap<>(); //empty array of tickers - addAPIHeader(buildRequest); + //fetch the ticker and process the result + Request.Builder buildRequestTN = new Request.Builder() + .url(TOKEN_DISCOVERY_API.replace(CHAIN_IDS, apiChainName).replace(CONTRACT_ADDR, tcm.getContractAddress().address)).get(); - try (okhttp3.Response response = httpClient.newCall(buildRequest.build()) - .execute()) - { - int code = response.code(); - String responseStr = response.body().string(); - List tickers = CoinGeckoTicker.buildTickerList(responseStr, currentCurrencySymbolTxt, currentConversionRate); - for (CoinGeckoTicker t : tickers) - { - //store ticker - erc20Tickers.put(t.address, t.toTokenTicker(currentCurrencySymbolTxt)); - lookupMap.remove(t.address.toLowerCase()); - } - - if (dexGuruName != null) - { - addDexGuruTickers(lookupMap.values()); - } - else + try (okhttp3.Response response = httpClient.newCall(buildRequestTN.build()) + .execute()) { - addDelayCheckOnTickers(code, chainId, lookupMap); - } - } - catch (Exception e) - { - Timber.e(e); - addDelayCheckOnTickers(0, chainId, lookupMap); - } - - return erc20Tickers; - } - - private void addAPIHeader(Request.Builder buildRequest) - { - String coinGeckoKey = keyProvider.getCoinGeckoKey(); - String backupKey = keyProvider.getBackupKey(); + int code = response.code(); + if (code / 100 != 2) + { + return tickersMap; + } - if (!TextUtils.isEmpty(coinGeckoKey)) - { - if (keyCycle%3 == 0) - { - buildRequest.addHeader("x-cg-demo-api-key", coinGeckoKey); + JSONArray result = new JSONArray(response.body().string()); + TNDiscoveryTicker.toTokenTickers(tickersMap, result, currentCurrencySymbolTxt, currentConversionRate); } - else if (keyCycle%3 == 1) + catch (Exception e) { - buildRequest.addHeader("x-cg-demo-api-key", backupKey); + Timber.e(e); } - keyCycle++; - } - } - private void addDelayCheckOnTickers(int code, long chainId, Map lookupMap) - { - long delayTime = (code/100 == 2) ? DateUtils.DAY_IN_MILLIS * 5 : DateUtils.MINUTE_IN_MILLIS * 30; // if API call was successful, and no ticker was found, don't check for 5 days - final Map blankTickers = new HashMap<>(); //These tokens have no ticker, don't check them again for another hour - for (String address : lookupMap.keySet()) - { - blankTickers.put(address, new TokenTicker(System.currentTimeMillis() + delayTime)); - } - localSource.updateERC20Tickers(chainId, blankTickers); + return tickersMap; + }); } - private void addDexGuruTickers(Collection tokens) + private void checkTokenDiscoveryTickers() { - for (TokenCardMeta tcm : tokens) - { - dexGuruQuery.put(tcm.tokenId, tcm); - } - - if (dexGuruLookup == null || dexGuruLookup.isDisposed()) + TokenCardMeta thisTCM = tokenCheckQueue.pollFirst(); + if (thisTCM == null) { - dexGuruLookup = Observable.interval(500, 1000, TimeUnit.MILLISECONDS) - .doOnNext(l -> getDexGuruTicker()).subscribe(); + //terminate the check cycle + if (erc20TickerCheck != null && !erc20TickerCheck.isDisposed()) erc20TickerCheck.dispose(); + return; } - } - private void getDexGuruTicker() - { - if (dexGuruQuery.keySet().iterator().hasNext()) - { - String key = dexGuruQuery.keySet().iterator().next(); - TokenCardMeta tcm = dexGuruQuery.get(key); - dexGuruQuery.remove(key); - - //fetch next token - Request request = new Request.Builder() - .url(DEXGURU_API.replace(CHAIN_IDS, dexGuruChainIdToAPISymbol.get(tcm.getChain())).replace(CONTRACT_ADDR, tcm.getAddress())) - .get() - .build(); - - try (okhttp3.Response response = httpClient.newCall(request) - .execute()) - { - if ((response.code() / 100) == 2 && response.body() != null) - { - DexGuruTicker t = new DexGuruTicker(response.body().string()); - if (t.verified || ALLOW_UNVERIFIED_TICKERS) + fetchTickers(thisTCM) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.io()) + .subscribe(tickers -> { + //process ticker + if (!tickers.isEmpty()) { - BigDecimal changeValue = new BigDecimal(t.usdChange).setScale(3, RoundingMode.DOWN); - - TokenTicker tTicker = new TokenTicker(String.valueOf(t.usdPrice * currentConversionRate), - changeValue.toString(), currentCurrencySymbolTxt, "", System.currentTimeMillis()); - - localSource.updateERC20Tickers(tcm.getChain(), new HashMap() - {{ - put(tcm.getAddress(), tTicker); - }}); - return; + // update all the received tickers, tickers is an array of TokenTicker, how to convert this to a map? + localSource.updateERC20Tickers(thisTCM.getChain(), tickers); } - } - localSource.updateTicker(tcm.getChain(), tcm.getAddress(), new TokenTicker(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS)); - } - catch (Exception e) - { - Timber.e(e); - } - } - else - { - if (dexGuruLookup != null && !dexGuruLookup.isDisposed()) dexGuruLookup.dispose(); - } + }).isDisposed(); } private void checkPeggedTickers(long chainId, TokenTicker ticker) @@ -854,7 +762,10 @@ private void resetTickerUpdate() public void deleteTickers() { - localSource.deleteTickers(); + Single.fromCallable(() -> { + localSource.deleteTickers(); + return true; + }).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe(); } // Update from https://api.coingecko.com/api/v3/coins/list diff --git a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/TokensAdapter.java b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/TokensAdapter.java index 59771e20e3..dbc2673537 100644 --- a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/TokensAdapter.java +++ b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/TokensAdapter.java @@ -25,6 +25,7 @@ import com.alphawallet.app.ui.widget.entity.ManageTokensSearchItem; import com.alphawallet.app.ui.widget.entity.ManageTokensSortedItem; import com.alphawallet.app.ui.widget.entity.SortedItem; +import com.alphawallet.app.ui.widget.entity.TokenIdSortedItem; import com.alphawallet.app.ui.widget.entity.TokenSortedItem; import com.alphawallet.app.ui.widget.entity.TotalBalanceSortedItem; import com.alphawallet.app.ui.widget.entity.WalletConnectSessionSortedItem; @@ -599,6 +600,8 @@ public void notifyTickerUpdate(List updatedContracts) TokenCardMeta tcm = ((TokenSortedItem) si).value; if (updatedContracts.contains(tcm.getAddress())) { + TokenSortedItem tsi = (TokenSortedItem) si; + tsi.setFiatValue(tokensService.getTokenFiatValue(tcm.getChain(), tcm.getAddress())); notifyItemChanged(i); //optimise update - no need to update elements without tickers } } diff --git a/app/src/main/java/com/alphawallet/app/ui/widget/holder/WalletSummaryHeaderHolder.java b/app/src/main/java/com/alphawallet/app/ui/widget/holder/WalletSummaryHeaderHolder.java index 7fb2ca0f46..cabd484f02 100644 --- a/app/src/main/java/com/alphawallet/app/ui/widget/holder/WalletSummaryHeaderHolder.java +++ b/app/src/main/java/com/alphawallet/app/ui/widget/holder/WalletSummaryHeaderHolder.java @@ -15,12 +15,10 @@ import com.alphawallet.app.R; import com.alphawallet.app.entity.Wallet; import com.alphawallet.app.service.TickerService; -import com.alphawallet.app.ui.widget.entity.WalletClickCallback; import java.math.BigDecimal; import java.math.RoundingMode; -import io.realm.Realm; import timber.log.Timber; public class WalletSummaryHeaderHolder extends BinderViewHolder implements View.OnClickListener diff --git a/app/src/main/java/com/alphawallet/app/util/Utils.java b/app/src/main/java/com/alphawallet/app/util/Utils.java index f0fec93532..368b05c20b 100644 --- a/app/src/main/java/com/alphawallet/app/util/Utils.java +++ b/app/src/main/java/com/alphawallet/app/util/Utils.java @@ -973,7 +973,6 @@ public static boolean isContractCall(Context context, String operationName) private static final String IPFS_PREFIX = "ipfs://"; private static final String IPFS_DESIGNATOR = "/ipfs/"; public static final String IPFS_INFURA_RESOLVER = "https://alphawallet.infura-ipfs.io"; - public static final String IPFS_IO_RESOLVER = "https://ipfs.io"; public static final String IPFS_MATCHER = "^Qm[1-9A-Za-z]{44}(\\/.*)?$"; public static boolean isIPFS(String url)