add frozen balance to dashboard

This commit is contained in:
Serhii 2023-03-26 15:47:05 +03:00
parent 505e407229
commit 9f35c39f2d
34 changed files with 209 additions and 47 deletions

View file

@ -4,7 +4,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_core/balance.dart';
class ElectrumBalance extends Balance {
const ElectrumBalance({required this.confirmed, required this.unconfirmed})
const ElectrumBalance({required this.confirmed, required this.unconfirmed, required this.frozen})
: super(confirmed, unconfirmed);
static ElectrumBalance? fromJSON(String? jsonSource) {
@ -16,11 +16,13 @@ class ElectrumBalance extends Balance {
return ElectrumBalance(
confirmed: decoded['confirmed'] as int? ?? 0,
unconfirmed: decoded['unconfirmed'] as int? ?? 0);
unconfirmed: decoded['unconfirmed'] as int? ?? 0,
frozen: decoded['frozen'] as int? ?? 0);
}
final int confirmed;
final int unconfirmed;
final int frozen;
@override
String get formattedAvailableBalance =>
@ -30,6 +32,15 @@ class ElectrumBalance extends Balance {
String get formattedAdditionalBalance =>
bitcoinAmountToString(amount: unconfirmed);
String get formattedFrozenBalance {
final frozenFormatted = bitcoinAmountToString(amount: frozen);
return frozenFormatted == '0.0' ? '' : frozenFormatted;
}
@override
String get formattedTotalAvailableBalance =>
bitcoinAmountToString(amount: confirmed - frozen);
String toJSON() =>
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed});
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen});
}

View file

@ -63,7 +63,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
_scripthashesUpdateSubject = {},
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
currency != null
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0,
frozen: 0)}
: {}),
this.unspentCoinsInfo = unspentCoinsInfo,
super(walletInfo) {
@ -133,8 +134,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
await walletAddresses.discoverAddresses();
await updateTransactions();
_subscribeForUpdates();
await _updateBalance();
await updateUnspent();
await updateBalance();
_feeRates = await electrumClient.feeRates();
Timer.periodic(const Duration(minutes: 1),
@ -343,7 +344,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
electrumClient: electrumClient, amount: amount, fee: fee)
..addListener((transaction) async {
transactionHistory.addOne(transaction);
await _updateBalance();
await updateBalance();
});
}
@ -634,8 +635,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
_scripthashesUpdateSubject[sh] = electrumClient.scripthashUpdate(sh);
_scripthashesUpdateSubject[sh]?.listen((event) async {
try {
await _updateBalance();
await updateUnspent();
await updateBalance();
await updateTransactions();
} catch (e) {
print(e.toString());
@ -653,7 +654,16 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final sh = scriptHash(addressRecord.address, networkType: networkType);
final balanceFuture = electrumClient.getBalance(sh);
balanceFutures.add(balanceFuture);
}
}
var totalFrozen = 0;
unspentCoinsInfo.values.forEach((info) {
unspentCoins.forEach((element) {
if (element.hash == info.hash && info.isFrozen) {
totalFrozen += element.value;
}
});
});
final balances = await Future.wait(balanceFutures);
var totalConfirmed = 0;
@ -672,10 +682,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
}
}
return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed);
return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed,
frozen: totalFrozen);
}
Future<void> _updateBalance() async {
Future<void> updateBalance() async {
balance[currency] = await _fetchBalances();
await save();
}

View file

@ -37,7 +37,7 @@ class ElectrumWallletSnapshot {
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
.toList();
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
ElectrumBalance(confirmed: 0, unconfirmed: 0);
ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
var regularAddressIndex = 0;
var changeAddressIndex = 0;

View file

@ -8,4 +8,8 @@ abstract class Balance {
String get formattedAvailableBalance;
String get formattedAdditionalBalance;
String get formattedFrozenBalance;
String get formattedTotalAvailableBalance;
}

View file

@ -26,4 +26,10 @@ class MoneroBalance extends Balance {
@override
String get formattedAdditionalBalance => formattedFullBalance;
@override
String get formattedFrozenBalance => '';
@override
String get formattedTotalAvailableBalance => '';
}

View file

@ -71,4 +71,6 @@ abstract class WalletBase<
void close();
Future<void> changePassword(String password);
Future<void>? updateBalance();
}

View file

@ -104,6 +104,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
(_) async => await save());
}
@override
Future<void>? updateBalance() => null;
@override
void close() {
_listener?.stop();

View file

@ -118,6 +118,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
Duration(seconds: _autoSaveInterval),
(_) async => await save());
}
@override
Future<void>? updateBalance() => null;
@override
void close() {

View file

@ -75,6 +75,8 @@ class BalancePage extends StatelessWidget{
additionalBalanceLabel: '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
additionalBalance: balance.additionalBalance,
additionalFiatBalance: balance.fiatAdditionalBalance,
frozenBalance: balance.frozenBalance,
frozenFiatBalance: balance.fiatFrozenBalance,
currency: balance.formattedAssetTitle);
});
})
@ -88,6 +90,8 @@ class BalancePage extends StatelessWidget{
required String additionalBalanceLabel,
required String additionalBalance,
required String additionalFiatBalance,
required String frozenBalance,
required String frozenFiatBalance,
required String currency}) {
return Container(
margin: const EdgeInsets.only(left: 16, right: 16),
@ -153,7 +157,50 @@ class BalancePage extends StatelessWidget{
.headline2!
.backgroundColor!,
height: 1)),
SizedBox(height: 26),
SizedBox(height: 26),
if(frozenBalance.isNotEmpty)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(S.current.frozen_balance + ':',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline3!
.backgroundColor!,
height: 1)),
SizedBox(height: 8),
AutoSizeText(
frozenBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
SizedBox(height: 4),
Text(frozenFiatBalance,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
),
SizedBox(height: 12)]),
Text('${additionalBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(

View file

@ -1,5 +1,8 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/crypto_currency.dart';
@ -11,6 +14,7 @@ import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
part 'balance_view_model.g.dart';
@ -19,14 +23,18 @@ class BalanceRecord {
const BalanceRecord({
required this.availableBalance,
required this.additionalBalance,
required this.frozenBalance,
required this.fiatAvailableBalance,
required this.fiatAdditionalBalance,
required this.fiatFrozenBalance,
required this.asset,
required this.formattedAssetTitle});
final String fiatAdditionalBalance;
final String fiatAvailableBalance;
final String fiatFrozenBalance;
final String additionalBalance;
final String availableBalance;
final String frozenBalance;
final CryptoCurrency asset;
final String formattedAssetTitle;
}
@ -135,6 +143,32 @@ abstract class BalanceViewModelBase with Store {
return walletBalance.formattedAvailableBalance;
}
@computed
String get frozenBalance {
final walletBalance = _walletBalance;
if (displayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
return walletBalance.formattedFrozenBalance;
}
@computed
String get frozenFiatBalance {
final walletBalance = _walletBalance;
final fiatCurrency = settingsStore.fiatCurrency;
if (displayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
return _getFiatBalance(
price: price,
cryptoAmount: walletBalance.formattedFrozenBalance) + ' ' + fiatCurrency.toString();
}
@computed
String get additionalBalance {
final walletBalance = _walletBalance;
@ -158,7 +192,7 @@ abstract class BalanceViewModelBase with Store {
return _getFiatBalance(
price: price,
cryptoAmount: walletBalance.formattedAvailableBalance) + ' ' + fiatCurrency.toString();
}
@computed
@ -173,7 +207,7 @@ abstract class BalanceViewModelBase with Store {
return _getFiatBalance(
price: price,
cryptoAmount: walletBalance.formattedAdditionalBalance) + ' ' + fiatCurrency.toString();
}
@computed
@ -183,8 +217,10 @@ abstract class BalanceViewModelBase with Store {
return MapEntry(key, BalanceRecord(
availableBalance: '---',
additionalBalance: '---',
frozenBalance: '---',
fiatAdditionalBalance: isFiatDisabled ? '' : '---',
fiatAvailableBalance: isFiatDisabled ? '' : '---',
fiatFrozenBalance: isFiatDisabled ? '' : '---',
asset: key,
formattedAssetTitle: _formatterAsset(key)));
}
@ -205,15 +241,31 @@ abstract class BalanceViewModelBase with Store {
+ ' '
+ _getFiatBalance(
price: price,
cryptoAmount: value.formattedAvailableBalance));
cryptoAmount: value.formattedFrozenBalance.isEmpty
? value.formattedAvailableBalance
: value.formattedTotalAvailableBalance));
return MapEntry(key, BalanceRecord(
availableBalance: value.formattedAvailableBalance,
additionalBalance: value.formattedAdditionalBalance,
fiatAdditionalBalance: additionalFiatBalance,
fiatAvailableBalance: availableFiatBalance,
asset: key,
formattedAssetTitle: _formatterAsset(key)));
final frozenFiatBalance = isFiatDisabled ? '' : (fiatCurrency.toString()
+ ' '
+ _getFiatBalance(
price: price,
cryptoAmount: value.formattedFrozenBalance));
return MapEntry(
key,
BalanceRecord(
availableBalance: value.formattedFrozenBalance.isEmpty
? value.formattedAvailableBalance
: value.formattedTotalAvailableBalance,
additionalBalance: value.formattedAdditionalBalance,
frozenBalance: value.formattedFrozenBalance,
fiatAdditionalBalance: additionalFiatBalance,
fiatAvailableBalance: availableFiatBalance,
fiatFrozenBalance: frozenFiatBalance,
asset: key,
formattedAssetTitle: _formatterAsset(key)));
});
}
@ -290,7 +342,7 @@ abstract class BalanceViewModelBase with Store {
}
String _getFiatBalance({required double price, String? cryptoAmount}) {
if (cryptoAmount == null) {
if (cryptoAmount == null || cryptoAmount.isEmpty) {
return '0.00';
}
@ -306,7 +358,7 @@ abstract class BalanceViewModelBase with Store {
return assetStringified.replaceFirst('X', 'x');
}
return asset.toString();
return asset.toString();
default:
return asset.toString();
}

View file

@ -53,6 +53,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
await info.save();
bitcoin!.updateUnspents(wallet);
wallet.updateBalance();
} catch (e) {
print(e.toString());
}

View file

@ -684,5 +684,6 @@
"do_not_send": "لا ترسل",
"error_dialog_content": "عفوًا ، لقد حصلنا على بعض الخطأ.\n\nيرجى إرسال تقرير التعطل إلى فريق الدعم لدينا لتحسين التطبيق.",
"decimal_places_error": "عدد كبير جدًا من المنازل العشرية",
"edit_node": "تحرير العقدة"
"edit_node": "تحرير العقدة",
"frozen_balance": "الرصيد المجمد"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Не изпращай",
"error_dialog_content": "Получихме грешка.\n\nМоля, изпратете доклада до нашия отдел поддръжка, за да подобрим приложението.",
"decimal_places_error": "Твърде много знаци след десетичната запетая",
"edit_node": "Редактиране на възел"
"edit_node": "Редактиране на възел",
"frozen_balance": "Замразен баланс"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Neodesílat",
"error_dialog_content": "Nastala chyba.\n\nProsím odešlete zprávu o chybě naší podpoře, aby mohli zajistit opravu.",
"decimal_places_error": "Příliš mnoho desetinných míst",
"edit_node": "Upravit uzel"
"edit_node": "Upravit uzel",
"frozen_balance": "Zmrazená bilance"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Nicht senden",
"error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern.",
"decimal_places_error": "Zu viele Nachkommastellen",
"edit_node": "Knoten bearbeiten"
"edit_node": "Knoten bearbeiten",
"frozen_balance": "Gefrorenes Gleichgewicht"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Don't send",
"error_dialog_content": "Oops, we got some error.\n\nPlease send the crash report to our support team to make the application better.",
"decimal_places_error": "Too many decimal places",
"edit_node": "Edit Node"
"edit_node": "Edit Node",
"frozen_balance": "Frozen Balance"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "no enviar",
"error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación.",
"decimal_places_error": "Demasiados lugares decimales",
"edit_node": "Edit Node"
"edit_node": "Editar nodo",
"frozen_balance": "Balance congelado"
}

View file

@ -684,5 +684,6 @@
"do_not_send": "N'envoyez pas",
"error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer le rapport de plantage à notre équipe d'assistance pour améliorer l'application.",
"decimal_places_error": "Trop de décimales",
"edit_node": "Modifier le nœud"
"edit_node": "Modifier le nœud",
"frozen_balance": "Équilibre gelé"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "मत भेजो",
"error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।",
"decimal_places_error": "बहुत अधिक दशमलव स्थान",
"edit_node": "नोड संपादित करें"
"edit_node": "नोड संपादित करें",
"frozen_balance": "जमे हुए संतुलन"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Ne šalji",
"error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju.",
"decimal_places_error": "Previše decimalnih mjesta",
"edit_node": "Uredi čvor"
"edit_node": "Uredi čvor",
"frozen_balance": "Zamrznuti saldo"
}

View file

@ -668,5 +668,6 @@
"contact_list_contacts": "Kontak",
"contact_list_wallets": "Dompet Saya",
"decimal_places_error": "Terlalu banyak tempat desimal",
"edit_node": "Sunting Node"
"edit_node": "Sunting Node",
"frozen_balance": "Saldo Beku"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Non inviare",
"error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione.",
"decimal_places_error": "Troppe cifre decimali",
"edit_node": "Modifica nodo"
"edit_node": "Modifica nodo",
"frozen_balance": "Equilibrio congelato"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "送信しない",
"error_dialog_content": "エラーが発生しました。\n\nアプリケーションを改善するために、クラッシュ レポートをサポート チームに送信してください。",
"decimal_places_error": "小数点以下の桁数が多すぎる",
"edit_node": "ノードを編集"
"edit_node": "ノードを編集",
"frozen_balance": "冷凍残高"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "보내지 마세요",
"error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오.",
"decimal_places_error": "소수점 이하 자릿수가 너무 많습니다.",
"edit_node": "노드 편집"
"edit_node": "노드 편집",
"frozen_balance": "얼어붙은 균형"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "မပို့ပါနှင့်",
"error_dialog_content": "အိုး၊ ကျွန်ုပ်တို့တွင် အမှားအယွင်းအချို့ရှိသည်။\n\nအပလီကေးရှင်းကို ပိုမိုကောင်းမွန်စေရန်အတွက် ပျက်စီးမှုအစီရင်ခံစာကို ကျွန်ုပ်တို့၏ပံ့ပိုးကူညီရေးအဖွဲ့ထံ ပေးပို့ပါ။",
"decimal_places_error": "ဒဿမနေရာများ များလွန်းသည်။",
"edit_node": "Node ကို တည်းဖြတ်ပါ။"
"edit_node": "Node ကို တည်းဖြတ်ပါ။",
"frozen_balance": "ေးခဲမှူ"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Niet sturen",
"error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren.",
"decimal_places_error": "Te veel decimalen",
"edit_node": "Knooppunt bewerken"
"edit_node": "Knooppunt bewerken",
"frozen_balance": "Bevroren saldo"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Nie wysyłaj",
"error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację.",
"decimal_places_error": "Za dużo miejsc dziesiętnych",
"edit_node": "Edytuj węzeł"
"edit_node": "Edytuj węzeł",
"frozen_balance": "Zamrożona równowaga"
}

View file

@ -685,5 +685,6 @@
"do_not_send": "não envie",
"error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo.",
"decimal_places_error": "Muitas casas decimais",
"edit_node": "Editar nó"
"edit_node": "Editar nó",
"frozen_balance": "Saldo Congelado"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Не отправлять",
"error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше.",
"decimal_places_error": "Слишком много десятичных знаков",
"edit_node": "Редактировать узел"
"edit_node": "Редактировать узел",
"frozen_balance": "Замороженный баланс"
}

View file

@ -684,5 +684,6 @@
"do_not_send": "อย่าส่ง",
"error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น",
"decimal_places_error": "ทศนิยมมากเกินไป",
"edit_node": "แก้ไขโหนด"
"edit_node": "แก้ไขโหนด",
"frozen_balance": "ยอดคงเหลือแช่แข็ง"
}

View file

@ -686,5 +686,6 @@
"do_not_send": "Gönderme",
"error_dialog_content": "Hay aksi, bir hatamız var.\n\nUygulamayı daha iyi hale getirmek için lütfen kilitlenme raporunu destek ekibimize gönderin.",
"decimal_places_error": "Çok fazla ondalık basamak",
"edit_node": "Düğümü Düzenle"
"edit_node": "Düğümü Düzenle",
"frozen_balance": "Dondurulmuş Bakiye"
}

View file

@ -685,5 +685,6 @@
"do_not_send": "Не надсилайте",
"error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток.",
"decimal_places_error": "Забагато знаків після коми",
"edit_node": "Редагувати вузол"
"edit_node": "Редагувати вузол",
"frozen_balance": "Заморожений баланс"
}

View file

@ -687,5 +687,6 @@
"do_not_send" : "مت بھیجیں۔",
"error_dialog_content" : "افوہ، ہمیں کچھ خرابی ملی۔\n\nایپلی کیشن کو بہتر بنانے کے لیے براہ کرم کریش رپورٹ ہماری سپورٹ ٹیم کو بھیجیں۔",
"decimal_places_error": "بہت زیادہ اعشاریہ جگہیں۔",
"edit_node": "نوڈ میں ترمیم کریں۔"
"edit_node": "نوڈ میں ترمیم کریں۔",
"frozen_balance": "منجمد بیلنس"
}

View file

@ -684,5 +684,6 @@
"do_not_send": "不要发送",
"error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队以改进应用程序。",
"decimal_places_error": "小数位太多",
"edit_node": "编辑节点"
"edit_node": "编辑节点",
"frozen_balance": "冻结余额"
}