2023-05-26 21:21:16 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Stack Wallet.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2023 Cypher Stack
|
|
|
|
* All Rights Reserved.
|
|
|
|
* The code is distributed under GPLv3 license, see LICENSE file for details.
|
|
|
|
* Generated by Cypher Stack on 2023-05-26
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2022-08-26 08:11:35 +00:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:decimal/decimal.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
2024-01-16 19:08:28 +00:00
|
|
|
import 'package:isar/isar.dart';
|
|
|
|
import 'package:stackwallet/db/isar/main_db.dart';
|
|
|
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
2023-09-11 20:38:40 +00:00
|
|
|
import 'package:stackwallet/networking/http.dart';
|
2022-08-26 08:11:35 +00:00
|
|
|
import 'package:stackwallet/services/price.dart';
|
2024-05-15 21:20:45 +00:00
|
|
|
import 'package:stackwallet/supported_coins.dart';
|
|
|
|
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
2022-08-26 08:11:35 +00:00
|
|
|
import 'package:tuple/tuple.dart';
|
|
|
|
|
|
|
|
class PriceService extends ChangeNotifier {
|
|
|
|
late final String baseTicker;
|
2024-01-16 19:08:28 +00:00
|
|
|
Future<Set<String>> get tokenContractAddressesToCheck async =>
|
|
|
|
(await MainDB.instance.getEthContracts().addressProperty().findAll())
|
|
|
|
.toSet();
|
2022-08-26 08:11:35 +00:00
|
|
|
final Duration updateInterval = const Duration(seconds: 60);
|
|
|
|
|
|
|
|
Timer? _timer;
|
2024-05-15 21:20:45 +00:00
|
|
|
final Map<CryptoCurrency, Tuple2<Decimal, double>> _cachedPrices = {
|
2024-05-21 18:48:48 +00:00
|
|
|
for (final coin in Coins.enabled) coin: Tuple2(Decimal.zero, 0.0),
|
2022-08-26 08:11:35 +00:00
|
|
|
};
|
2023-02-28 16:36:24 +00:00
|
|
|
|
|
|
|
final Map<String, Tuple2<Decimal, double>> _cachedTokenPrices = {};
|
|
|
|
|
2023-09-11 20:38:40 +00:00
|
|
|
final _priceAPI = PriceAPI(HTTP());
|
2022-08-26 08:11:35 +00:00
|
|
|
|
2024-05-15 21:20:45 +00:00
|
|
|
Tuple2<Decimal, double> getPrice(CryptoCurrency coin) => _cachedPrices[coin]!;
|
2022-08-26 08:11:35 +00:00
|
|
|
|
2023-02-28 16:36:24 +00:00
|
|
|
Tuple2<Decimal, double> getTokenPrice(String contractAddress) =>
|
|
|
|
_cachedTokenPrices[contractAddress.toLowerCase()] ??
|
|
|
|
Tuple2(Decimal.zero, 0);
|
|
|
|
|
2022-10-18 16:36:25 +00:00
|
|
|
PriceService(this.baseTicker);
|
2022-08-26 08:11:35 +00:00
|
|
|
|
|
|
|
Future<void> updatePrice() async {
|
|
|
|
final priceMap =
|
|
|
|
await _priceAPI.getPricesAnd24hChange(baseCurrency: baseTicker);
|
|
|
|
|
|
|
|
bool shouldNotify = false;
|
|
|
|
for (final map in priceMap.entries) {
|
|
|
|
if (_cachedPrices[map.key] != map.value) {
|
|
|
|
_cachedPrices[map.key] = map.value;
|
|
|
|
shouldNotify = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-16 19:08:28 +00:00
|
|
|
final _tokenContractAddressesToCheck = await tokenContractAddressesToCheck;
|
|
|
|
|
|
|
|
if (_tokenContractAddressesToCheck.isNotEmpty) {
|
2023-02-28 16:36:24 +00:00
|
|
|
final tokenPriceMap = await _priceAPI.getPricesAnd24hChangeForEthTokens(
|
2024-01-16 19:08:28 +00:00
|
|
|
contractAddresses: _tokenContractAddressesToCheck,
|
2023-02-28 16:36:24 +00:00
|
|
|
baseCurrency: baseTicker,
|
|
|
|
);
|
|
|
|
|
|
|
|
for (final map in tokenPriceMap.entries) {
|
|
|
|
if (_cachedTokenPrices[map.key] != map.value) {
|
|
|
|
_cachedTokenPrices[map.key] = map.value;
|
|
|
|
shouldNotify = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 08:11:35 +00:00
|
|
|
if (shouldNotify) {
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cancel() {
|
|
|
|
_timer?.cancel();
|
|
|
|
_timer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
void start(bool rightAway) {
|
|
|
|
if (rightAway) {
|
|
|
|
updatePrice();
|
|
|
|
}
|
|
|
|
_timer?.cancel();
|
|
|
|
_timer = Timer.periodic(updateInterval, (_) {
|
|
|
|
updatePrice();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
cancel();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
}
|