/* * 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 * */ import 'dart:async'; import 'package:decimal/decimal.dart'; import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/networking/http.dart'; import 'package:stackwallet/services/price.dart'; import 'package:stackwallet/supported_coins.dart'; import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart'; import 'package:tuple/tuple.dart'; class PriceService extends ChangeNotifier { late final String baseTicker; Future> get tokenContractAddressesToCheck async => (await MainDB.instance.getEthContracts().addressProperty().findAll()) .toSet(); final Duration updateInterval = const Duration(seconds: 60); Timer? _timer; final Map> _cachedPrices = { for (final coin in Coins.enabled) coin: Tuple2(Decimal.zero, 0.0), }; final Map> _cachedTokenPrices = {}; final _priceAPI = PriceAPI(HTTP()); Tuple2 getPrice(CryptoCurrency coin) => _cachedPrices[coin]!; Tuple2 getTokenPrice(String contractAddress) => _cachedTokenPrices[contractAddress.toLowerCase()] ?? Tuple2(Decimal.zero, 0); PriceService(this.baseTicker); Future 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; } } final _tokenContractAddressesToCheck = await tokenContractAddressesToCheck; 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(); } } 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(); } }