eth token price service updates

This commit is contained in:
julian 2023-02-28 10:36:24 -06:00
parent 4239187602
commit f1bfe72b73
3 changed files with 99 additions and 8 deletions

View file

@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/providers/global/debug_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_api.dart';
import 'package:stackwallet/services/price_service.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@ -156,9 +156,21 @@ class HiddenSettings extends StatelessWidget {
Consumer(builder: (_, ref, __) {
return GestureDetector(
onTap: () async {
final x = await MajesticBankAPI.instance
.getLimit(fromCurrency: 'btc');
print(x);
PriceService.tokenContractAddressesToCheck.add(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
PriceService.tokenContractAddressesToCheck.add(
"0xdAC17F958D2ee523a2206206994597C13D831ec7");
await ref
.read(priceAnd24hChangeNotifierProvider)
.updatePrice();
final x = ref
.read(priceAnd24hChangeNotifierProvider)
.getTokenPrice(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
print(
"PRICE 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48: $x");
},
child: RoundedWhiteContainer(
child: Text(

View file

@ -86,10 +86,12 @@ class PriceAPI {
}
Map<Coin, Tuple2<Decimal, double>> result = {};
try {
final uri = Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero,ethereum,particl&order=market_cap_desc&per_page=10&page=1&sparkline=false");
// final uri = Uri.parse(
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero%2Cbitcoin%2Cepic-cash%2Czcoin%2Cdogecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false");
final uri =
Uri.parse("https://api.coingecko.com/api/v3/coins/markets?vs_currency"
"=${baseCurrency.toLowerCase()}"
"&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,"
"bitcoin-cash,namecoin,wownero,ethereum,particl"
"&order=market_cap_desc&per_page=50&page=1&sparkline=false");
final coinGeckoResponse = await client.get(
uri,
@ -146,4 +148,59 @@ class PriceAPI {
return null;
}
}
Future<Map<String, Tuple2<Decimal, double>>>
getPricesAnd24hChangeForEthTokens({
required Set<String> contractAddresses,
required String baseCurrency,
}) async {
final Map<String, Tuple2<Decimal, double>> tokenPrices = {};
if (contractAddresses.isEmpty) return tokenPrices;
final externalCalls = Prefs.instance.externalCalls;
if ((!Logger.isTestEnv && !externalCalls) ||
!(await Prefs.instance.isExternalCallsSet())) {
Logging.instance.log("User does not want to use external calls",
level: LogLevel.Info);
return tokenPrices;
}
try {
final contractAddressesString =
contractAddresses.reduce((value, element) => "$value,$element");
final uri = Uri.parse(
"https://api.coingecko.com/api/v3/simple/token_price/ethereum"
"?vs_currencies=${baseCurrency.toLowerCase()}&contract_addresses"
"=$contractAddressesString&include_24hr_change=true");
final coinGeckoResponse = await client.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final coinGeckoData = jsonDecode(coinGeckoResponse.body) as Map;
for (final key in coinGeckoData.keys) {
final contractAddress = key as String;
final map = coinGeckoData[contractAddress] as Map;
final price = Decimal.parse(map[baseCurrency.toLowerCase()].toString());
final change24h = double.parse(
map["${baseCurrency.toLowerCase()}_24h_change"].toString());
tokenPrices[contractAddress] = Tuple2(price, change24h);
}
return tokenPrices;
} catch (e, s) {
Logging.instance.log(
"getPricesAnd24hChangeForEthTokens($baseCurrency,$contractAddresses): $e\n$s",
level: LogLevel.Error,
);
// return previous cached values
return tokenPrices;
}
}
}

View file

@ -9,16 +9,24 @@ import 'package:tuple/tuple.dart';
class PriceService extends ChangeNotifier {
late final String baseTicker;
static Set<String> tokenContractAddressesToCheck = {};
final Duration updateInterval = const Duration(seconds: 60);
Timer? _timer;
final Map<Coin, Tuple2<Decimal, double>> _cachedPrices = {
for (final coin in Coin.values) coin: Tuple2(Decimal.zero, 0.0)
};
final Map<String, Tuple2<Decimal, double>> _cachedTokenPrices = {};
final _priceAPI = PriceAPI(Client());
Tuple2<Decimal, double> getPrice(Coin coin) => _cachedPrices[coin]!;
Tuple2<Decimal, double> getTokenPrice(String contractAddress) =>
_cachedTokenPrices[contractAddress.toLowerCase()] ??
Tuple2(Decimal.zero, 0);
PriceService(this.baseTicker);
Future<void> updatePrice() async {
@ -33,6 +41,20 @@ class PriceService extends ChangeNotifier {
}
}
if (tokenContractAddressesToCheck.isNotEmpty) {
final tokenPriceMap = await _priceAPI.getPricesAnd24hChangeForEthTokens(
contractAddresses: tokenContractAddressesToCheck,
baseCurrency: baseTicker,
);
for (final map in tokenPriceMap.entries) {
if (_cachedTokenPrices[map.key] != map.value) {
_cachedTokenPrices[map.key] = map.value;
shouldNotify = true;
}
}
}
if (shouldNotify) {
notifyListeners();
}