diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart index 15d6843d8..fb0f059d8 100644 --- a/cw_bitcoin/lib/electrum_balance.dart +++ b/cw_bitcoin/lib/electrum_balance.dart @@ -7,7 +7,14 @@ class ElectrumBalance extends Balance { required this.confirmed, required this.unconfirmed, required this.frozen, - }) : super(confirmed, unconfirmed); + this.secondConfirmed = 0, + this.secondUnconfirmed = 0, + }) : super( + confirmed, + unconfirmed, + secondAvailable: secondConfirmed, + secondAdditional: secondUnconfirmed, + ); static ElectrumBalance? fromJSON(String? jsonSource) { if (jsonSource == null) { @@ -25,6 +32,8 @@ class ElectrumBalance extends Balance { int confirmed; int unconfirmed; final int frozen; + int secondConfirmed = 0; + int secondUnconfirmed = 0; @override String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen); @@ -38,6 +47,22 @@ class ElectrumBalance extends Balance { return frozenFormatted == '0.0' ? '' : frozenFormatted; } - String toJSON() => - json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen}); + @override + String get formattedSecondAvailableBalance => bitcoinAmountToString(amount: secondConfirmed ?? 0); + + @override + String get formattedSecondAdditionalBalance => + bitcoinAmountToString(amount: secondUnconfirmed ?? 0); + + @override + String get formattedFullAvailableBalance => + bitcoinAmountToString(amount: confirmed + (secondConfirmed ?? 0) - frozen); + + String toJSON() => json.encode({ + 'confirmed': confirmed, + 'unconfirmed': unconfirmed, + 'frozen': frozen, + 'secondConfirmed': secondConfirmed, + 'secondUnconfirmed': secondUnconfirmed + }); } diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 3096b80eb..87885cebe 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -884,7 +884,7 @@ abstract class ElectrumWalletBase final totalAmount = amount + fee; - if (totalAmount > balance[currency]!.confirmed) { + if (totalAmount > (balance[currency]!.confirmed + balance[currency]!.secondConfirmed)) { throw BitcoinTransactionWrongBalanceException(); } diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index f33bfc701..993e55b04 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -244,9 +244,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { print("STARTING SYNC - MWEB ENABLED: $mwebEnabled"); syncStatus = SyncronizingSyncStatus(); await subscribeForUpdates(); - await updateTransactions(); - await updateFeeRates(); + await updateFeeRates(); _feeRatesTimer?.cancel(); _feeRatesTimer = Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates()); @@ -265,74 +264,70 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } await waitForMwebAddresses(); - await getStub(); + await processMwebUtxos(); + await updateTransactions(); await updateUnspent(); await updateBalance(); _syncTimer?.cancel(); - // delay the timer by a second so we don't overrride the restoreheight if one is set - Timer(const Duration(seconds: 2), () async { - _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async { - if (syncStatus is FailedSyncStatus) return; + _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async { + if (syncStatus is FailedSyncStatus) return; - final nodeHeight = - await electrumClient.getCurrentBlockChainTip() ?? 0; // current block height of our node - final resp = await _stub.status(StatusRequest()); + final nodeHeight = + await electrumClient.getCurrentBlockChainTip() ?? 0; // current block height of our node + final resp = await _stub.status(StatusRequest()); - if (resp.blockHeaderHeight < nodeHeight) { - int h = resp.blockHeaderHeight; - syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight); - } else if (resp.mwebHeaderHeight < nodeHeight) { - int h = resp.mwebHeaderHeight; - syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight); - } else if (resp.mwebUtxosHeight < nodeHeight) { - syncStatus = SyncingSyncStatus(1, 0.999); - } else { - // prevent unnecessary reaction triggers: - if (syncStatus is! SyncedSyncStatus) { - syncStatus = SyncedSyncStatus(); - } - - if (resp.mwebUtxosHeight > walletInfo.restoreHeight) { - await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight); - await checkMwebUtxosSpent(); - // update the confirmations for each transaction: - for (final transaction in transactionHistory.transactions.values) { - if (transaction.isPending) continue; - int txHeight = transaction.height ?? resp.mwebUtxosHeight; - final confirmations = (resp.mwebUtxosHeight - txHeight) + 1; - if (transaction.confirmations == confirmations) continue; - transaction.confirmations = confirmations; - transactionHistory.addOne(transaction); - } - await transactionHistory.save(); + if (resp.blockHeaderHeight < nodeHeight) { + int h = resp.blockHeaderHeight; + syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight); + } else if (resp.mwebHeaderHeight < nodeHeight) { + int h = resp.mwebHeaderHeight; + syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight); + } else if (resp.mwebUtxosHeight < nodeHeight) { + syncStatus = SyncingSyncStatus(1, 0.999); + } else { + // prevent unnecessary reaction triggers: + if (syncStatus is! SyncedSyncStatus) { + syncStatus = SyncedSyncStatus(); + } + + if (resp.mwebUtxosHeight > walletInfo.restoreHeight) { + await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight); + await checkMwebUtxosSpent(); + // update the confirmations for each transaction: + for (final transaction in transactionHistory.transactions.values) { + if (transaction.isPending) continue; + int txHeight = transaction.height ?? resp.mwebUtxosHeight; + final confirmations = (resp.mwebUtxosHeight - txHeight) + 1; + if (transaction.confirmations == confirmations) continue; + transaction.confirmations = confirmations; + transactionHistory.addOne(transaction); } + await transactionHistory.save(); } - }); - - // setup a watch dog to restart the sync process if it gets stuck: - List lastFewProgresses = []; - Timer.periodic(const Duration(seconds: 10), (timer) async { - if (syncStatus is! SyncingSyncStatus) return; - if (syncStatus.progress() > 0.98) return; - lastFewProgresses.add(syncStatus.progress()); - if (lastFewProgresses.length < 4) return; - // limit list size to 4: - while(lastFewProgresses.length > 4) { - lastFewProgresses.removeAt(0); - } - // if the progress is the same over the last 40 seconds, restart the sync: - if (lastFewProgresses.every((p) => p == lastFewProgresses.first)) { - print("mweb syncing is stuck, restarting..."); - await stopSync(); - startSync(); - timer.cancel(); - } - }); + } + }); + + // setup a watch dog to restart the sync process if it gets stuck: + List lastFewProgresses = []; + Timer.periodic(const Duration(seconds: 10), (timer) async { + if (syncStatus is! SyncingSyncStatus) return; + if (syncStatus.progress() > 0.98) return; + lastFewProgresses.add(syncStatus.progress()); + if (lastFewProgresses.length < 4) return; + // limit list size to 4: + while (lastFewProgresses.length > 4) { + lastFewProgresses.removeAt(0); + } + // if the progress is the same over the last 40 seconds, restart the sync: + if (lastFewProgresses.every((p) => p == lastFewProgresses.first)) { + print("mweb syncing is stuck, restarting..."); + await stopSync(); + startSync(); + timer.cancel(); + } }); - // this runs in the background and processes new utxos as they come in: - processMwebUtxos(); } @action @@ -678,14 +673,19 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { int confirmed = balance.confirmed; int unconfirmed = balance.unconfirmed; + int confirmedMweb = 0; + int unconfirmedMweb = 0; try { mwebUtxosBox.values.forEach((utxo) { if (utxo.height > 0) { - confirmed += utxo.value.toInt(); + confirmedMweb += utxo.value.toInt(); } else { - unconfirmed += utxo.value.toInt(); + unconfirmedMweb += utxo.value.toInt(); } }); + if (/*confirmedMweb > 0 &&*/ unconfirmedMweb > 0) { + unconfirmedMweb = -1 * (confirmedMweb - unconfirmedMweb); + } } catch (_) {} // update unspent balances: @@ -735,7 +735,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } } - return ElectrumBalance(confirmed: confirmed, unconfirmed: unconfirmed, frozen: balance.frozen); + return ElectrumBalance( + confirmed: confirmed, + unconfirmed: unconfirmed, + frozen: balance.frozen, + secondConfirmed: confirmedMweb, + secondUnconfirmed: unconfirmedMweb, + ); } @override @@ -869,7 +875,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { final addresses = {}; transaction.inputAddresses?.forEach((id) async { final utxo = mwebUtxosBox.get(id); - await mwebUtxosBox.delete(id); + // await mwebUtxosBox.delete(id); if (utxo == null) return; final addressRecord = walletAddresses.allAddresses .firstWhere((addressRecord) => addressRecord.address == utxo.address); diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index dd590f124..3a7856516 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -122,6 +122,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with Future getChangeAddress({List? outputs, UtxoDetails? utxoDetails}) async { // use regular change address on peg in, otherwise use mweb for change address: + if (!mwebEnabled) { + return super.getChangeAddress(); + } + if (outputs != null && utxoDetails != null) { // check if this is a PEGIN: bool outputsToMweb = false; @@ -134,6 +138,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with outputsToMweb = true; } } + // TODO: this doesn't respect coin control because it doesn't know which available inputs are selected utxoDetails.availableInputs.forEach((element) { if (element.address.contains("mweb")) { comesFromMweb = true; @@ -144,6 +149,11 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with if (isPegIn && mwebEnabled) { return super.getChangeAddress(); } + + // use regular change address if it's not an mweb tx: + if (!comesFromMweb && !outputsToMweb) { + return super.getChangeAddress(); + } } if (mwebEnabled) { diff --git a/cw_core/lib/balance.dart b/cw_core/lib/balance.dart index 431aff515..09ca8efbb 100644 --- a/cw_core/lib/balance.dart +++ b/cw_core/lib/balance.dart @@ -1,13 +1,18 @@ abstract class Balance { - const Balance(this.available, this.additional); + const Balance(this.available, this.additional, {this.secondAvailable, this.secondAdditional}); final int available; final int additional; + final int? secondAvailable; + final int? secondAdditional; + String get formattedAvailableBalance; - String get formattedAdditionalBalance; - String get formattedUnAvailableBalance => ''; + String get formattedSecondAvailableBalance => ''; + String get formattedSecondAdditionalBalance => ''; + String get formattedFullAvailableBalance => ''; + String get formattedFullUnAvailableBalance => ''; } diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index f06fe3e66..dca7586fb 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -123,7 +123,7 @@ void restoreWalletFromKeysSync( int nettype = 0, int restoreHeight = 0}) { txhistory = null; - final newWptr = spendKey != "" + var newWptr = (spendKey != "") ? monero.WalletManager_createDeterministicWalletFromSpendKey( wmPtr, path: path, @@ -149,6 +149,32 @@ void restoreWalletFromKeysSync( message: monero.Wallet_errorString(newWptr)); } + // CW-712 - Try to restore deterministic wallet first, if the view key doesn't + // match the view key provided + if (spendKey != "") { + final viewKeyRestored = monero.Wallet_secretViewKey(newWptr); + if (viewKey != viewKeyRestored && viewKey != "") { + monero.WalletManager_closeWallet(wmPtr, newWptr, false); + File(path).deleteSync(); + File(path+".keys").deleteSync(); + newWptr = monero.WalletManager_createWalletFromKeys( + wmPtr, + path: path, + password: password, + restoreHeight: restoreHeight, + addressString: address, + viewKeyString: viewKey, + spendKeyString: spendKey, + nettype: 0, + ); + final status = monero.Wallet_status(newWptr); + if (status != 0) { + throw WalletRestoreFromKeysException( + message: monero.Wallet_errorString(newWptr)); + } + } + } + wptr = newWptr; openedWalletsByPath[path] = wptr!; diff --git a/cw_wownero/lib/api/wallet_manager.dart b/cw_wownero/lib/api/wallet_manager.dart index 660433ba6..ed6d86823 100644 --- a/cw_wownero/lib/api/wallet_manager.dart +++ b/cw_wownero/lib/api/wallet_manager.dart @@ -140,7 +140,7 @@ void restoreWalletFromKeysSync( int nettype = 0, int restoreHeight = 0}) { txhistory = null; - final newWptr = spendKey != "" + var newWptr = (spendKey != "") ? wownero.WalletManager_createDeterministicWalletFromSpendKey( wmPtr, path: path, @@ -165,7 +165,31 @@ void restoreWalletFromKeysSync( throw WalletRestoreFromKeysException( message: wownero.Wallet_errorString(newWptr)); } - + // CW-712 - Try to restore deterministic wallet first, if the view key doesn't + // match the view key provided + if (spendKey != "") { + final viewKeyRestored = wownero.Wallet_secretViewKey(newWptr); + if (viewKey != viewKeyRestored && viewKey != "") { + wownero.WalletManager_closeWallet(wmPtr, newWptr, false); + File(path).deleteSync(); + File(path+".keys").deleteSync(); + newWptr = wownero.WalletManager_createWalletFromKeys( + wmPtr, + path: path, + password: password, + restoreHeight: restoreHeight, + addressString: address, + viewKeyString: viewKey, + spendKeyString: spendKey, + nettype: 0, + ); + final status = wownero.Wallet_status(newWptr); + if (status != 0) { + throw WalletRestoreFromKeysException( + message: wownero.Wallet_errorString(newWptr)); + } + } + } wptr = newWptr; openedWalletsByPath[path] = wptr!; diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart index 7847c92e2..a7b2a99fa 100644 --- a/lib/src/screens/dashboard/pages/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance_page.dart @@ -131,7 +131,7 @@ class CryptoBalanceWidget extends StatelessWidget { builder: (_) { if (dashboardViewModel.getMoneroError != null) { return Padding( - padding: const EdgeInsets.fromLTRB(16,0,16,16), + padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), child: DashBoardRoundedCardWidget( title: "Invalid monero bindings", subTitle: dashboardViewModel.getMoneroError.toString(), @@ -146,13 +146,12 @@ class CryptoBalanceWidget extends StatelessWidget { builder: (_) { if (dashboardViewModel.getWowneroError != null) { return Padding( - padding: const EdgeInsets.fromLTRB(16,0,16,16), - child: DashBoardRoundedCardWidget( - title: "Invalid wownero bindings", - subTitle: dashboardViewModel.getWowneroError.toString(), - onTap: () {}, - ) - ); + padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), + child: DashBoardRoundedCardWidget( + title: "Invalid wownero bindings", + subTitle: dashboardViewModel.getWowneroError.toString(), + onTap: () {}, + )); } return Container(); }, @@ -273,6 +272,18 @@ class CryptoBalanceWidget extends StatelessWidget { currency: balance.asset, hasAdditionalBalance: dashboardViewModel.balanceViewModel.hasAdditionalBalance, + hasSecondAdditionalBalance: + dashboardViewModel.balanceViewModel.hasSecondAdditionalBalance, + hasSecondAvailableBalance: + dashboardViewModel.balanceViewModel.hasSecondAvailableBalance, + secondAdditionalBalance: balance.secondAdditionalBalance, + secondAdditionalFiatBalance: balance.fiatSecondAdditionalBalance, + secondAvailableBalance: balance.secondAvailableBalance, + secondAvailableFiatBalance: balance.fiatSecondAvailableBalance, + secondAdditionalBalanceLabel: + '${dashboardViewModel.balanceViewModel.secondAdditionalBalanceLabel}', + secondAvailableBalanceLabel: + '${dashboardViewModel.balanceViewModel.secondAvailableBalanceLabel}', isTestnet: dashboardViewModel.isTestnet, ); }); @@ -286,16 +297,15 @@ class CryptoBalanceWidget extends StatelessWidget { if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[ SizedBox(height: 10), Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: DashBoardRoundedCardWidget( - customBorder: 30, - title: "This wallet has encountered an issue", - subTitle: "Here are the things that you should note:\n - " - +dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") - +"\n\nPlease restart your wallet and if it doesn't help contact our support.", - onTap: () {}, - ) - ) + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: DashBoardRoundedCardWidget( + customBorder: 30, + title: "This wallet has encountered an issue", + subTitle: "Here are the things that you should note:\n - " + + dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") + + "\n\nPlease restart your wallet and if it doesn't help contact our support.", + onTap: () {}, + )) ], if (dashboardViewModel.showSilentPaymentsCard) ...[ SizedBox(height: 10), @@ -494,10 +504,18 @@ class BalanceRowWidget extends StatelessWidget { required this.additionalBalanceLabel, required this.additionalBalance, required this.additionalFiatBalance, + required this.secondAvailableBalanceLabel, + required this.secondAvailableBalance, + required this.secondAvailableFiatBalance, + required this.secondAdditionalBalanceLabel, + required this.secondAdditionalBalance, + required this.secondAdditionalFiatBalance, required this.frozenBalance, required this.frozenFiatBalance, required this.currency, required this.hasAdditionalBalance, + required this.hasSecondAvailableBalance, + required this.hasSecondAdditionalBalance, required this.isTestnet, super.key, }); @@ -508,10 +526,18 @@ class BalanceRowWidget extends StatelessWidget { final String additionalBalanceLabel; final String additionalBalance; final String additionalFiatBalance; + final String secondAvailableBalanceLabel; + final String secondAvailableBalance; + final String secondAvailableFiatBalance; + final String secondAdditionalBalanceLabel; + final String secondAdditionalBalance; + final String secondAdditionalFiatBalance; final String frozenBalance; final String frozenFiatBalance; final CryptoCurrency currency; final bool hasAdditionalBalance; + final bool hasSecondAvailableBalance; + final bool hasSecondAdditionalBalance; final bool isTestnet; // void _showBalanceDescription(BuildContext context) { @@ -759,6 +785,94 @@ class BalanceRowWidget extends StatelessWidget { ), ], ), + if (hasSecondAvailableBalance) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24), + Text( + '${secondAvailableBalanceLabel}', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.labelTextColor, + height: 1, + ), + ), + SizedBox(height: 8), + AutoSizeText( + secondAvailableBalance, + style: TextStyle( + fontSize: 20, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.assetTitleColor, + height: 1, + ), + maxLines: 1, + textAlign: TextAlign.center, + ), + SizedBox(height: 4), + if (!isTestnet) + Text( + '${secondAvailableFiatBalance}', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.textColor, + height: 1, + ), + ), + ], + ), + if (hasSecondAdditionalBalance) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24), + Text( + '${secondAdditionalBalanceLabel}', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.labelTextColor, + height: 1, + ), + ), + SizedBox(height: 8), + AutoSizeText( + secondAdditionalBalance, + style: TextStyle( + fontSize: 20, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.assetTitleColor, + height: 1, + ), + maxLines: 1, + textAlign: TextAlign.center, + ), + SizedBox(height: 4), + if (!isTestnet) + Text( + '${secondAdditionalFiatBalance}', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontFamily: 'Lato', + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.textColor, + height: 1, + ), + ), + ], + ), ], ), ), diff --git a/lib/src/screens/receive/widgets/address_list.dart b/lib/src/screens/receive/widgets/address_list.dart index 8dfbedec1..de01f6879 100644 --- a/lib/src/screens/receive/widgets/address_list.dart +++ b/lib/src/screens/receive/widgets/address_list.dart @@ -1,3 +1,6 @@ + +import 'dart:math'; + import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; @@ -35,7 +38,7 @@ class AddressList extends StatelessWidget { separatorBuilder: (context, _) => const HorizontalSectionDivider(), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), - itemCount: addressListViewModel.items.length, + itemCount: min(addressListViewModel.items.length, 100),// TODO: don't show all 1000 mweb addresses itemBuilder: (context, index) { final item = addressListViewModel.items[index]; Widget cell = Container(); diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 045b55261..2d917c820 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -21,10 +21,14 @@ class BalanceRecord { const BalanceRecord( {required this.availableBalance, required this.additionalBalance, + required this.secondAvailableBalance, + required this.secondAdditionalBalance, required this.frozenBalance, required this.fiatAvailableBalance, required this.fiatAdditionalBalance, required this.fiatFrozenBalance, + required this.fiatSecondAvailableBalance, + required this.fiatSecondAdditionalBalance, required this.asset, required this.formattedAssetTitle}); final String fiatAdditionalBalance; @@ -33,6 +37,10 @@ class BalanceRecord { final String additionalBalance; final String availableBalance; final String frozenBalance; + final String secondAvailableBalance; + final String secondAdditionalBalance; + final String fiatSecondAdditionalBalance; + final String fiatSecondAvailableBalance; final CryptoCurrency asset; final String formattedAssetTitle; } @@ -158,6 +166,26 @@ abstract class BalanceViewModelBase with Store { } } + @computed + String get secondAvailableBalanceLabel { + switch (wallet.type) { + case WalletType.litecoin: + return S.current.mweb_confirmed; + default: + return S.current.confirmed; + } + } + + @computed + String get secondAdditionalBalanceLabel { + switch (wallet.type) { + case WalletType.litecoin: + return S.current.mweb_unconfirmed; + default: + return S.current.unconfirmed; + } + } + @computed bool get hasMultiBalance => appStore.wallet!.type == WalletType.haven; @@ -207,6 +235,17 @@ abstract class BalanceViewModelBase with Store { return walletBalance.formattedAdditionalBalance; } + @computed + String get secondAdditionalBalance { + final walletBalance = _walletBalance; + + if (displayMode == BalanceDisplayMode.hiddenBalance) { + return '---'; + } + + return walletBalance.formattedSecondAdditionalBalance; + } + @computed String get availableFiatBalance { final walletBalance = _walletBalance; @@ -243,9 +282,13 @@ abstract class BalanceViewModelBase with Store { availableBalance: '---', additionalBalance: '---', frozenBalance: '---', + secondAvailableBalance: '---', + secondAdditionalBalance: '---', fiatAdditionalBalance: isFiatDisabled ? '' : '---', fiatAvailableBalance: isFiatDisabled ? '' : '---', fiatFrozenBalance: isFiatDisabled ? '' : '---', + fiatSecondAvailableBalance: isFiatDisabled ? '' : '---', + fiatSecondAdditionalBalance: isFiatDisabled ? '' : '---', asset: key, formattedAssetTitle: _formatterAsset(key))); } @@ -274,24 +317,46 @@ abstract class BalanceViewModelBase with Store { ' ' + _getFiatBalance(price: price, cryptoAmount: getFormattedFrozenBalance(value))); + final secondAdditionalFiatBalance = isFiatDisabled + ? '' + : (fiatCurrency.toString() + + ' ' + + _getFiatBalance(price: price, cryptoAmount: value.formattedSecondAdditionalBalance)); + + final secondAvailableFiatBalance = isFiatDisabled + ? '' + : (fiatCurrency.toString() + + ' ' + + _getFiatBalance(price: price, cryptoAmount: value.formattedSecondAvailableBalance)); + return MapEntry( key, BalanceRecord( availableBalance: value.formattedAvailableBalance, additionalBalance: value.formattedAdditionalBalance, frozenBalance: getFormattedFrozenBalance(value), + secondAvailableBalance: value.formattedSecondAvailableBalance, + secondAdditionalBalance: value.formattedSecondAdditionalBalance, fiatAdditionalBalance: additionalFiatBalance, fiatAvailableBalance: availableFiatBalance, fiatFrozenBalance: frozenFiatBalance, + fiatSecondAvailableBalance: secondAvailableFiatBalance, + fiatSecondAdditionalBalance: secondAdditionalFiatBalance, asset: key, formattedAssetTitle: _formatterAsset(key))); }); } @computed - bool get hasAdditionalBalance => _hasAdditionBalanceForWalletType(wallet.type); + bool get hasAdditionalBalance => _hasAdditionalBalanceForWalletType(wallet.type); - bool _hasAdditionBalanceForWalletType(WalletType type) { + @computed + bool get hasSecondAdditionalBalance => _hasSecondAdditionalBalanceForWalletType(wallet.type); + + @computed + bool get hasSecondAvailableBalance => _hasSecondAvailableBalanceForWalletType(wallet.type); + + bool _hasAdditionalBalanceForWalletType(WalletType type) { switch (type) { case WalletType.ethereum: case WalletType.polygon: @@ -303,6 +368,20 @@ abstract class BalanceViewModelBase with Store { } } + bool _hasSecondAdditionalBalanceForWalletType(WalletType type) { + if (wallet.type == WalletType.litecoin /*&& settingsStore.mwebEnabled*/) { + return true; + } + return false; + } + + bool _hasSecondAvailableBalanceForWalletType(WalletType type) { + if (wallet.type == WalletType.litecoin /*&& settingsStore.mwebEnabled*/) { + return true; + } + return false; + } + @computed List get formattedBalances { final balance = balances.values.toList(); diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 22c083455..04a914a84 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -217,7 +217,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor PendingTransaction? pendingTransaction; @computed - String get balance => wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance; + String get balance => wallet.balance[selectedCryptoCurrency]!.formattedFullAvailableBalance; @computed bool get isFiatDisabled => balanceViewModel.isFiatDisabled; diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index ae4344222..d9c810c7f 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -396,6 +396,8 @@ "monero_light_theme": " ضوء مونيرو", "moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}", "more_options": "المزيد من الخيارات", + "mweb_confirmed": "أكد MWEB", + "mweb_unconfirmed": "غير مؤكد MWEB", "name": "ﻢﺳﺍ", "nano_current_rep": "الممثل الحالي", "nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 5a4fe8d6d..955fb71cd 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Лека тема Monero", "moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}", "more_options": "Още настройки", + "mweb_confirmed": "Потвърден MWeb", + "mweb_unconfirmed": "Непотвърден mweb", "name": "Име", "nano_current_rep": "Настоящ представител", "nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 7469233f1..b6cf8b6ec 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Světlé téma Monero", "moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}", "more_options": "Více možností", + "mweb_confirmed": "Potvrzený mweb", + "mweb_unconfirmed": "Nepotvrzené mWeb", "name": "název", "nano_current_rep": "Současný zástupce", "nano_gpt_thanks_message": "Děkujeme za používání Nanogpt! Nezapomeňte se po dokončení transakce vydat zpět do prohlížeče!", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 558e2ccf8..bd861cc14 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Light-Thema", "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein", "more_options": "Weitere Optionen", + "mweb_confirmed": "Bestätigt MWeb", + "mweb_unconfirmed": "Unbestätigter MWeb", "name": "Name", "nano_current_rep": "Aktueller Vertreter", "nano_gpt_thanks_message": "Danke, dass du Nanogpt benutzt hast! Denken Sie daran, nach Abschluss Ihrer Transaktion zurück zum Browser zu gehen!", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 0fc657cbd..0f5a0dec1 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Light Theme", "moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}", "more_options": "More Options", + "mweb_confirmed": "Confirmed MWEB", + "mweb_unconfirmed": "Unconfirmed MWEB", "name": "Name", "nano_current_rep": "Current Representative", "nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 4eba22456..3663e536f 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Tema ligero de Monero", "moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}", "more_options": "Más Opciones", + "mweb_confirmed": "Confirmado mweb", + "mweb_unconfirmed": "Mweb no confirmado", "name": "Nombre", "nano_current_rep": "Representante actual", "nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index e01a97ea2..e54eede31 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Thème de lumière Monero", "moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}", "more_options": "Plus d'options", + "mweb_confirmed": "Confirmé MWEB", + "mweb_unconfirmed": "Mweb non confirmé", "name": "Nom", "nano_current_rep": "Représentant actuel", "nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 0a5192803..0c5235162 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Jigon Hasken Monero", "moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}", "more_options": "Ƙarin Zaɓuɓɓuka", + "mweb_confirmed": "Tabbatar da Mweb", + "mweb_unconfirmed": "Myconfired", "name": "Suna", "nano_current_rep": "Wakilin Yanzu", "nano_gpt_thanks_message": "Na gode da amfani da Nanogpt! Ka tuna da komawa zuwa mai bincike bayan ma'amalar ka ta cika!", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index f56c11b20..60e01f226 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -396,6 +396,8 @@ "monero_light_theme": "मोनेरो लाइट थीम", "moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}", "more_options": "और विकल्प", + "mweb_confirmed": "MWEB की पुष्टि की", + "mweb_unconfirmed": "अपुष्ट MWEB", "name": "नाम", "nano_current_rep": "वर्तमान प्रतिनिधि", "nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index fd78fcc6a..1a46552d3 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero lagana tema", "moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}", "more_options": "Više opcija", + "mweb_confirmed": "Potvrđen MWeb", + "mweb_unconfirmed": "Nepotvrđeni mWeb", "name": "Ime", "nano_current_rep": "Trenutni predstavnik", "nano_gpt_thanks_message": "Hvala što ste koristili nanogpt! Ne zaboravite da se vratite u preglednik nakon što vam se transakcija završi!", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 21b940a63..f4b60272b 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -387,6 +387,8 @@ "monero_light_theme": "Monero պայծառ տեսք", "moonpay_alert_text": "Գումարի արժեքը պետք է լինի հավասար կամ ավելի քան ${minAmount} ${fiatCurrency}", "more_options": "Այլ տարբերակներ", + "mweb_confirmed": "Հաստատված MWEB", + "mweb_unconfirmed": "Չկարգավորված Mweb", "name": "Անուն", "nano_current_rep": "Ընթացիկ ներկայացուցիչ", "nano_gpt_thanks_message": "Շնորհակալություն NanoGPT-ն օգտագործելու համար: Հիշեք վերադառնալ դիտարկիչ ձեր փոխանցումն ավարտելուց հետո", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 97265a641..2b7eed1df 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Tema Cahaya Monero", "moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}", "more_options": "Opsi Lainnya", + "mweb_confirmed": "Mengkonfirmasi mWeb", + "mweb_unconfirmed": "MWEB yang belum dikonfirmasi", "name": "Nama", "nano_current_rep": "Perwakilan saat ini", "nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 268a1c748..163895973 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -397,6 +397,8 @@ "monero_light_theme": "Tema leggero Monero", "moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}", "more_options": "Altre opzioni", + "mweb_confirmed": "MWeb confermato", + "mweb_unconfirmed": "MWeb non confermato", "name": "Nome", "nano_current_rep": "Rappresentante attuale", "nano_gpt_thanks_message": "Grazie per aver usato il nanogpt! Ricorda di tornare al browser dopo il completamento della transazione!", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index be1b822be..9d4ce29a2 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -397,6 +397,8 @@ "monero_light_theme": "モネロ ライト テーマ", "moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}", "more_options": "その他のオプション", + "mweb_confirmed": "確認されたMWEB", + "mweb_unconfirmed": "未確認のMWEB", "name": "名前", "nano_current_rep": "現在の代表", "nano_gpt_thanks_message": "NanoGptを使用してくれてありがとう!トランザクションが完了したら、ブラウザに戻ることを忘れないでください!", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index bf0229ed2..1d605e160 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -396,6 +396,8 @@ "monero_light_theme": "모네로 라이트 테마", "moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}", "more_options": "추가 옵션", + "mweb_confirmed": "확인 mweb", + "mweb_unconfirmed": "확인되지 않은 mweb", "name": "이름", "nano_current_rep": "현재 대표", "nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index cfd6569c1..a7db770c9 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Light အပြင်အဆင်", "moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်", "more_options": "နောက်ထပ် ရွေးချယ်စရာများ", + "mweb_confirmed": "အတည်ပြုလိုက် mweb", + "mweb_unconfirmed": "အတည်မပြုနိုင်သော mweb", "name": "နာမည်", "nano_current_rep": "လက်ရှိကိုယ်စားလှယ်", "nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index b244f4017..a1749f89b 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Light-thema", "moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}", "more_options": "Meer opties", + "mweb_confirmed": "Bevestigde MWEB", + "mweb_unconfirmed": "Onbevestigde MWEB", "name": "Naam", "nano_current_rep": "Huidige vertegenwoordiger", "nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat uw transactie is voltooid!", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 8763afe9c..553a4c972 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Lekki motyw Monero", "moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}", "more_options": "Więcej opcji", + "mweb_confirmed": "Potwierdził MWEB", + "mweb_unconfirmed": "Niepotwierdzone MWEB", "name": "Nazwa", "nano_current_rep": "Obecny przedstawiciel", "nano_gpt_thanks_message": "Dzięki za użycie Nanogpt! Pamiętaj, aby wrócić do przeglądarki po zakończeniu transakcji!", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index e470e66de..0b772fa7e 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -397,6 +397,8 @@ "monero_light_theme": "Monero Light Theme", "moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}", "more_options": "Mais opções", + "mweb_confirmed": "MWEB confirmado", + "mweb_unconfirmed": "MWEB não confirmado", "name": "Nome", "nano_current_rep": "Representante atual", "nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 6453d012f..171dfde24 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Светлая тема Monero", "moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}", "more_options": "Дополнительные параметры", + "mweb_confirmed": "Подтверждено MWEB", + "mweb_unconfirmed": "Неподтвержденная MWEB", "name": "Имя", "nano_current_rep": "Нынешний представитель", "nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index cde37e3b2..494320ce5 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -396,6 +396,8 @@ "monero_light_theme": "ธีมแสง Monero", "moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}", "more_options": "ตัวเลือกเพิ่มเติม", + "mweb_confirmed": "MWEB ยืนยันแล้ว", + "mweb_unconfirmed": "mweb ที่ไม่ได้รับการยืนยัน", "name": "ชื่อ", "nano_current_rep": "ตัวแทนปัจจุบัน", "nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index c8d4262ce..3f6bf5e41 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Light Theme", "moonpay_alert_text": "Ang halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}", "more_options": "Higit pang mga Pagpipilian", + "mweb_confirmed": "Nakumpirma na MWeb", + "mweb_unconfirmed": "Hindi nakumpirma si Mweb", "name": "Pangalan", "nano_current_rep": "Kasalukuyang Representative", "nano_gpt_thanks_message": "Salamat sa paggamit ng NanoGPT! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 3fe0a91be..e4194e62e 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Monero Hafif Tema", "moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır", "more_options": "Daha Fazla Seçenek", + "mweb_confirmed": "Onaylanmış mweb", + "mweb_unconfirmed": "Doğrulanmamış mweb", "name": "İsim", "nano_current_rep": "Mevcut temsilci", "nano_gpt_thanks_message": "Nanogpt kullandığınız için teşekkürler! İşleminiz tamamlandıktan sonra tarayıcıya geri dönmeyi unutmayın!", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 4c7d7b1e0..8f7387a1f 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -396,6 +396,8 @@ "monero_light_theme": "Легка тема Monero", "moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}", "more_options": "Більше параметрів", + "mweb_confirmed": "Підтвердив Mweb", + "mweb_unconfirmed": "Неперевірений MWEB", "name": "Ім'я", "nano_current_rep": "Поточний представник", "nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 50f191d82..af021737d 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -396,6 +396,8 @@ "monero_light_theme": "مونیرو لائٹ تھیم", "moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔", "more_options": "مزید زرائے", + "mweb_confirmed": "تصدیق شدہ MWEB", + "mweb_unconfirmed": "غیر مصدقہ MWEB", "name": "ﻡﺎﻧ", "nano_current_rep": "موجودہ نمائندہ", "nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index d2c98fe2b..e0f4a6664 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -140,8 +140,8 @@ "confirm": "Xác nhận", "confirm_delete_template": "Thao tác này sẽ xóa mẫu này. Bạn có muốn tiếp tục không?", "confirm_delete_wallet": "Thao tác này sẽ xóa ví này. Bạn có muốn tiếp tục không?", - "confirm_fee_deduction": "Xác nhận Khấu trừ Phí", "confirm_fee_dedction_content": "Bạn có đồng ý trừ phí từ đầu ra không?", + "confirm_fee_deduction": "Xác nhận Khấu trừ Phí", "confirm_sending": "Xác nhận gửi", "confirm_silent_payments_switch_node": "Nút hiện tại của bạn không hỗ trợ thanh toán im lặng\\nCake Wallet sẽ chuyển sang một nút tương thích chỉ để quét", "confirmations": "Xác nhận", @@ -298,7 +298,7 @@ "fiat_balance": "Số dư Fiat", "field_required": "Trường này là bắt buộc", "fill_code": "Vui lòng điền mã xác minh được gửi đến email của bạn", - "filter_by": "Lọc theo", + "filter_by": "Lọc theo", "first_wallet_text": "Ví tuyệt vời cho Monero, Bitcoin, Ethereum, Litecoin, và Haven", "fixed_pair_not_supported": "Cặp tỷ giá cố định này không được hỗ trợ với các sàn giao dịch đã chọn", "fixed_rate": "Tỷ giá cố định", @@ -386,6 +386,8 @@ "monero_light_theme": "Chủ đề sáng Monero", "moonpay_alert_text": "Giá trị số tiền phải lớn hơn hoặc bằng ${minAmount} ${fiatCurrency}", "more_options": "Thêm tùy chọn", + "mweb_confirmed": "Xác nhận MWEB", + "mweb_unconfirmed": "MWEB chưa được xác nhận", "name": "Tên", "nano_current_rep": "Đại diện hiện tại", "nano_gpt_thanks_message": "Cảm ơn bạn đã sử dụng NanoGPT! Hãy nhớ quay lại trình duyệt sau khi giao dịch của bạn hoàn tất!", @@ -398,7 +400,7 @@ "new_subaddress_label_name": "Tên nhãn", "new_subaddress_title": "Địa chỉ mới", "new_template": "Mẫu mới", - "new_wallet": "Ví mới", + "new_wallet": "Ví mới", "newConnection": "Kết nối mới", "no_cards_found": "Không tìm thấy thẻ", "no_id_needed": "Không cần ID!", @@ -498,7 +500,7 @@ "red_dark_theme": "Chủ đề tối đỏ", "red_light_theme": "Chủ đề sáng đỏ", "redeemed": "Đã đổi", - "refund_address": "Địa chỉ hoàn tiền", + "refund_address": "Địa chỉ hoàn tiền", "reject": "Từ chối", "remaining": "còn lại", "remove": "Gỡ bỏ", @@ -598,7 +600,7 @@ "seedtype": "Loại hạt giống", "seedtype_legacy": "Di sản (25 từ)", "seedtype_polyseed": "Polyseed (16 từ)", - "seedtype_wownero": "Wownero (14 từ)", + "seedtype_wownero": "Wownero (14 từ)", "select_backup_file": "Chọn tệp sao lưu", "select_buy_provider_notice": "Chọn nhà cung cấp mua ở trên. Bạn có thể bỏ qua màn hình này bằng cách thiết lập nhà cung cấp mua mặc định trong cài đặt ứng dụng.", "select_destination": "Vui lòng chọn đích cho tệp sao lưu.", @@ -698,7 +700,7 @@ "support_description_guides": "Tài liệu và hỗ trợ cho các vấn đề phổ biến", "support_description_live_chat": "Miễn phí và nhanh chóng! Các đại diện hỗ trợ được đào tạo sẵn sàng hỗ trợ", "support_description_other_links": "Tham gia cộng đồng của chúng tôi hoặc liên hệ với chúng tôi hoặc các đối tác của chúng tôi qua các phương pháp khác", - "support_title_guides": "Hướng dẫn Cake Wallet", + "support_title_guides": "Hướng dẫn Cake Wallet", "support_title_live_chat": "Hỗ trợ trực tiếp", "support_title_other_links": "Liên kết hỗ trợ khác", "sweeping_wallet": "Quét ví", @@ -798,7 +800,7 @@ "trongrid_history": "Lịch sử TronGrid", "trusted": "Đã tin cậy", "tx_commit_exception_no_dust_on_change": "Giao dịch bị từ chối với số tiền này. Với số tiền này bạn có thể gửi ${min} mà không cần đổi tiền lẻ hoặc ${max} trả lại tiền lẻ.", - "tx_commit_failed": "Giao dịch không thành công. Vui lòng liên hệ với hỗ trợ.", + "tx_commit_failed": "Giao dịch không thành công. Vui lòng liên hệ với hỗ trợ.", "tx_invalid_input": "Bạn đang sử dụng loại đầu vào sai cho loại thanh toán này", "tx_no_dust_exception": "Giao dịch bị từ chối vì gửi một số tiền quá nhỏ. Vui lòng thử tăng số tiền.", "tx_not_enough_inputs_exception": "Không đủ đầu vào có sẵn. Vui lòng chọn thêm dưới Coin Control", @@ -897,4 +899,4 @@ "you_will_get": "Chuyển đổi thành", "you_will_send": "Chuyển đổi từ", "yy": "YY" -} +} \ No newline at end of file diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 2da577e8c..96307465f 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -397,6 +397,8 @@ "monero_light_theme": "Monero Light Akori", "moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}", "more_options": "Ìyàn àfikún", + "mweb_confirmed": "Jẹrisi Mweb", + "mweb_unconfirmed": "Ajopo Mweb", "name": "Oruko", "nano_current_rep": "Aṣoju lọwọlọwọ", "nano_gpt_thanks_message": "O ṣeun fun lilo Nonnogt! Ranti lati tẹle pada si ẹrọ lilọ kiri ayelujara lẹhin iṣowo rẹ pari!", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 837d4162f..fa74a52ec 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -396,6 +396,8 @@ "monero_light_theme": "门罗币浅色主题", "moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}", "more_options": "更多选项", + "mweb_confirmed": "确认的MWEB", + "mweb_unconfirmed": "未经证实的MWEB", "name": "姓名", "nano_current_rep": "当前代表", "nano_gpt_thanks_message": "感谢您使用Nanogpt!事务完成后,请记住回到浏览器!",