mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
fetch fiat rate from dashboard page
This commit is contained in:
parent
3eb297f953
commit
2d4a6824bb
5 changed files with 147 additions and 113 deletions
|
@ -50,7 +50,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future<double> _fetchHistoricalPrice(Map<String, dynamic> args) async {
|
||||
Future<double?> _fetchHistoricalPrice(Map<String, dynamic> args) async {
|
||||
final crypto = args['crypto'] as CryptoCurrency;
|
||||
final fiat = args['fiat'] as FiatCurrency;
|
||||
final torOnly = args['torOnly'] as bool;
|
||||
|
@ -77,35 +77,28 @@ Future<double> _fetchHistoricalPrice(Map<String, dynamic> args) async {
|
|||
|
||||
final response = await get(uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return 0.0;
|
||||
}
|
||||
if (response.statusCode != 200) return null;
|
||||
|
||||
final data = json.decode(response.body) as Map<String, dynamic>;
|
||||
final errors = data['errors'] as Map<String, dynamic>;
|
||||
|
||||
if (errors.isNotEmpty) {
|
||||
return 0.0;
|
||||
}
|
||||
if (errors.isNotEmpty) return 0.0;
|
||||
|
||||
final results = data['results'] as Map<String, dynamic>;
|
||||
|
||||
if (results.isNotEmpty) {
|
||||
price = results.values.first as double;
|
||||
}
|
||||
print('results.key: ${results.keys.first} results.value: ${results.values.first}');
|
||||
if (results.isNotEmpty) price = results.values.first as double;
|
||||
|
||||
return price;
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
return 0.0;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<double> _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat, bool torOnly) async =>
|
||||
compute(_fetchPrice, {'fiat': fiat, 'crypto': crypto, 'torOnly': torOnly});
|
||||
|
||||
Future<double> _fetchHistoricalAsync(
|
||||
Future<double?> _fetchHistoricalAsync(
|
||||
CryptoCurrency crypto, FiatCurrency fiat, bool torOnly, DateTime date) async =>
|
||||
compute(
|
||||
_fetchHistoricalPrice, {'fiat': fiat, 'crypto': crypto, 'torOnly': torOnly, 'date': date});
|
||||
|
@ -118,7 +111,7 @@ class FiatConversionService {
|
|||
}) async =>
|
||||
await _fetchPriceAsync(crypto, fiat, torOnly);
|
||||
|
||||
static Future<double> fetchHistoricalPrice({
|
||||
static Future<double?> fetchHistoricalPrice({
|
||||
required CryptoCurrency crypto,
|
||||
required FiatCurrency fiat,
|
||||
required bool torOnly,
|
||||
|
|
|
@ -349,7 +349,9 @@ Future setup(
|
|||
settingsStore: settingsStore,
|
||||
yatStore: getIt.get<YatStore>(),
|
||||
ordersStore: getIt.get<OrdersStore>(),
|
||||
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>())
|
||||
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
|
||||
transactionDescriptionBox: _transactionDescriptionBox,
|
||||
)
|
||||
);
|
||||
|
||||
getIt.registerFactory<AuthService>(() => AuthService(
|
||||
|
|
|
@ -4,7 +4,12 @@ part 'transaction_description.g.dart';
|
|||
|
||||
@HiveType(typeId: TransactionDescription.typeId)
|
||||
class TransactionDescription extends HiveObject {
|
||||
TransactionDescription({required this.id, this.recipientAddress, this.transactionNote});
|
||||
TransactionDescription(
|
||||
{required this.id,
|
||||
this.recipientAddress,
|
||||
this.transactionNote,
|
||||
this.historicalFiatRaw,
|
||||
this.historicalFiatRate});
|
||||
|
||||
static const typeId = 2;
|
||||
static const boxName = 'TransactionDescriptions';
|
||||
|
@ -19,5 +24,13 @@ class TransactionDescription extends HiveObject {
|
|||
@HiveField(2)
|
||||
String? transactionNote;
|
||||
|
||||
@HiveField(3)
|
||||
String? historicalFiatRaw;
|
||||
|
||||
@HiveField(4)
|
||||
double? historicalFiatRate;
|
||||
|
||||
String get note => transactionNote ?? '';
|
||||
|
||||
String get historicalFiat => historicalFiatRaw ?? '';
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import 'package:cake_wallet/core/fiat_conversion_service.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
|
@ -17,6 +23,7 @@ import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
|
|||
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
|
@ -43,6 +50,7 @@ abstract class DashboardViewModelBase with Store {
|
|||
required this.settingsStore,
|
||||
required this.yatStore,
|
||||
required this.ordersStore,
|
||||
required this.transactionDescriptionBox,
|
||||
required this.anonpayTransactionsStore})
|
||||
: isOutdatedElectrumWallet = false,
|
||||
hasSellAction = false,
|
||||
|
@ -116,6 +124,15 @@ abstract class DashboardViewModelBase with Store {
|
|||
|
||||
final _wallet = wallet;
|
||||
|
||||
|
||||
reaction((_) => settingsStore.fiatCurrency,
|
||||
(FiatCurrency fiatCurrency) {
|
||||
_wallet.transactionHistory.transactions.values.forEach((tx) {
|
||||
_getHistoricalFiatRate(tx);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
subname = monero!.getCurrentAccount(_wallet).label;
|
||||
|
||||
|
@ -130,11 +147,16 @@ abstract class DashboardViewModelBase with Store {
|
|||
.where((tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
|
||||
.toList();
|
||||
|
||||
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
|
||||
TransactionListItem(
|
||||
transaction: transaction,
|
||||
balanceViewModel: balanceViewModel,
|
||||
settingsStore: appStore.settingsStore)));
|
||||
transactions = ObservableList.of(_accountTransactions.map((transaction) {
|
||||
|
||||
|
||||
_getHistoricalFiatRate(transaction);
|
||||
|
||||
return TransactionListItem(
|
||||
transaction: transaction,
|
||||
balanceViewModel: balanceViewModel,
|
||||
settingsStore: appStore.settingsStore);
|
||||
}));
|
||||
} else {
|
||||
transactions = ObservableList.of(wallet
|
||||
.transactionHistory.transactions.values
|
||||
|
@ -154,6 +176,11 @@ abstract class DashboardViewModelBase with Store {
|
|||
balanceViewModel: balanceViewModel,
|
||||
settingsStore: appStore.settingsStore),
|
||||
filter: (TransactionInfo? transaction) {
|
||||
|
||||
_wallet.transactionHistory.transactions.values.forEach((tx) {
|
||||
_getHistoricalFiatRate(tx);
|
||||
});
|
||||
|
||||
if (transaction == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -273,6 +300,8 @@ abstract class DashboardViewModelBase with Store {
|
|||
|
||||
Map<String, List<FilterItem>> filterItems;
|
||||
|
||||
final Box<TransactionDescription> transactionDescriptionBox;
|
||||
|
||||
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
|
||||
|
||||
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
|
||||
|
@ -327,6 +356,11 @@ abstract class DashboardViewModelBase with Store {
|
|||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
||||
updateActions();
|
||||
|
||||
wallet.transactionHistory.transactions.values.forEach((tx) {
|
||||
_getHistoricalFiatRate(tx);
|
||||
});
|
||||
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
subname = monero!.getCurrentAccount(wallet).label;
|
||||
|
||||
|
@ -383,6 +417,7 @@ abstract class DashboardViewModelBase with Store {
|
|||
|
||||
@action
|
||||
void _onMoneroTransactionsUpdate(WalletBase wallet) {
|
||||
|
||||
transactions.clear();
|
||||
|
||||
final _accountTransactions = monero!.getTransactionHistory(wallet).transactions.values
|
||||
|
@ -405,4 +440,49 @@ abstract class DashboardViewModelBase with Store {
|
|||
&& wallet.type != WalletType.litecoin;
|
||||
hasSellAction = !isHaven;
|
||||
}
|
||||
|
||||
Future<void> _getHistoricalFiatRate(TransactionInfo transactionInfo) async {
|
||||
final description = transactionDescriptionBox.values.firstWhere(
|
||||
(val) => val.id == transactionInfo.id,
|
||||
orElse: () => TransactionDescription(id: transactionInfo.id));
|
||||
|
||||
if (description.historicalFiat != settingsStore.fiatCurrency.toString()
|
||||
|| description.historicalFiatRate == null) {
|
||||
if (description.key == 0) description.delete();
|
||||
description.historicalFiatRate = null;
|
||||
transactionDescriptionBox.put(description.id, description);
|
||||
final fiat = settingsStore.fiatCurrency;
|
||||
|
||||
final historicalFiatRate = await FiatConversionService.fetchHistoricalPrice(
|
||||
crypto: wallet.currency,
|
||||
fiat: fiat,
|
||||
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly,
|
||||
date: transactionInfo.date);
|
||||
var formattedFiatAmount = 0.0;
|
||||
switch (wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
formattedFiatAmount = bitcoinAmountToDouble(amount: transactionInfo.amount);
|
||||
break;
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
formattedFiatAmount = moneroAmountToDouble(amount: transactionInfo.amount);
|
||||
break;
|
||||
default:
|
||||
formattedFiatAmount;
|
||||
}
|
||||
description.historicalFiatRaw = settingsStore.fiatCurrency.toString();
|
||||
|
||||
if (historicalFiatRate != null) {
|
||||
final historicalFiatAmountFormatted = formattedFiatAmount * historicalFiatRate;
|
||||
if (description.key == 0) description.delete();
|
||||
description.historicalFiatRate = historicalFiatAmountFormatted;
|
||||
transactionDescriptionBox.put(description.id, description);
|
||||
} else {
|
||||
if (description.key == 0) description.delete();
|
||||
description.historicalFiatRate = null;
|
||||
transactionDescriptionBox.put(description.id, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
required this.wallet,
|
||||
required this.settingsStore})
|
||||
: items = ObservableList<TransactionDetailsListItem>(),
|
||||
isRecipientAddressShown = false,
|
||||
showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
|
||||
isRecipientAddressShown = false,
|
||||
showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
|
||||
final dateFormat = DateFormatter.withCurrentLocal();
|
||||
final tx = transactionInfo;
|
||||
|
||||
|
@ -42,19 +42,13 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
final addressIndex = tx.additionalInfo['addressIndex'] as int;
|
||||
final feeFormatted = tx.feeFormatted();
|
||||
final _items = [
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (feeFormatted != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee, value: feeFormatted),
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: feeFormatted),
|
||||
if (key?.isNotEmpty ?? false)
|
||||
StandartListItem(title: S.current.transaction_key, value: key!)
|
||||
];
|
||||
|
@ -68,18 +62,12 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
|
||||
if (address?.isNotEmpty ?? false) {
|
||||
isRecipientAddressShown = true;
|
||||
_items.add(
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: address));
|
||||
_items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address, value: address));
|
||||
}
|
||||
|
||||
if (label?.isNotEmpty ?? false) {
|
||||
_items.add(
|
||||
StandartListItem(
|
||||
title: S.current.address_label,
|
||||
value: label)
|
||||
);
|
||||
_items.add(StandartListItem(title: S.current.address_label, value: label));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
|
@ -89,26 +77,16 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
items.addAll(_items);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.bitcoin
|
||||
|| wallet.type == WalletType.litecoin) {
|
||||
if (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) {
|
||||
final _items = [
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.confirmations,
|
||||
value: tx.confirmations.toString()),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee,
|
||||
value: tx.feeFormatted()!)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!)
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
|
@ -116,19 +94,13 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
items.addAll([
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee, value: tx.feeFormatted()!)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!)
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -140,10 +112,9 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
|
||||
if (recipientAddress?.isNotEmpty ?? false) {
|
||||
items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: recipientAddress!));
|
||||
title: S.current.transaction_details_recipient_address, value: recipientAddress!));
|
||||
}
|
||||
} catch(_) {
|
||||
} catch (_) {
|
||||
// FIX-ME: Unhandled exception
|
||||
}
|
||||
}
|
||||
|
@ -175,8 +146,20 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
transactionDescriptionBox.add(description);
|
||||
}
|
||||
}));
|
||||
if (settingsStore.showHistoricalFiatRate) {
|
||||
getHistoricalFiatRate();
|
||||
|
||||
if (settingsStore.showHistoricalFiatRate &&
|
||||
description.historicalFiatRate != null &&
|
||||
description.historicalFiatRate! > 0) {
|
||||
final index =
|
||||
items.indexWhere((element) => element.title == S.current.transaction_details_fee);
|
||||
|
||||
items.insert(
|
||||
index + 1,
|
||||
StandartListItem(
|
||||
title: S.current.historical_fiat_rate,
|
||||
value: description.historicalFiatRate!.toStringAsFixed(2) +
|
||||
' ' +
|
||||
settingsStore.fiatCurrency.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,43 +172,6 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
bool showRecipientAddress;
|
||||
bool isRecipientAddressShown;
|
||||
|
||||
@action
|
||||
Future<void> getHistoricalFiatRate() async {
|
||||
if (settingsStore.fiatApiMode != FiatApiMode.disabled && settingsStore.showHistoricalFiatRate) {
|
||||
var fiatRateItemIndex =
|
||||
items.indexWhere((element) => element.title == S.current.transaction_details_fee);
|
||||
fiatRateItemIndex = fiatRateItemIndex == -1 ? items.length - 3 : fiatRateItemIndex;
|
||||
|
||||
final fiat = settingsStore.fiatCurrency;
|
||||
|
||||
final historicalFiatRate = await FiatConversionService.fetchHistoricalPrice(
|
||||
crypto: wallet.currency,
|
||||
fiat: fiat,
|
||||
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly,
|
||||
date: transactionInfo.date);
|
||||
var formattedFiatAmount = 0.0;
|
||||
switch (wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
formattedFiatAmount = bitcoinAmountToDouble(amount: transactionInfo.amount);
|
||||
break;
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
formattedFiatAmount = moneroAmountToDouble(amount: transactionInfo.amount);
|
||||
break;
|
||||
default:
|
||||
formattedFiatAmount;
|
||||
}
|
||||
final historicalFiatAmountFormatted = formattedFiatAmount * historicalFiatRate;
|
||||
if (historicalFiatAmountFormatted > 0.0)
|
||||
items.insert(
|
||||
fiatRateItemIndex + 1,
|
||||
StandartListItem(
|
||||
title: S.current.historical_fiat_rate,
|
||||
value: historicalFiatAmountFormatted.toStringAsFixed(2) + ' ${fiat}'));
|
||||
}
|
||||
}
|
||||
|
||||
String _explorerUrl(WalletType type, String txId) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
|
|
Loading…
Reference in a new issue