Merge branch 'mweb' of https://github.com/cake-tech/cake_wallet into mweb-bg-sync-2

This commit is contained in:
Matthew Fosse 2024-09-16 08:32:59 -07:00
commit e51d6ea8c0
39 changed files with 452 additions and 104 deletions

View file

@ -7,7 +7,14 @@ class ElectrumBalance extends Balance {
required this.confirmed, required this.confirmed,
required this.unconfirmed, required this.unconfirmed,
required this.frozen, required this.frozen,
}) : super(confirmed, unconfirmed); this.secondConfirmed = 0,
this.secondUnconfirmed = 0,
}) : super(
confirmed,
unconfirmed,
secondAvailable: secondConfirmed,
secondAdditional: secondUnconfirmed,
);
static ElectrumBalance? fromJSON(String? jsonSource) { static ElectrumBalance? fromJSON(String? jsonSource) {
if (jsonSource == null) { if (jsonSource == null) {
@ -25,6 +32,8 @@ class ElectrumBalance extends Balance {
int confirmed; int confirmed;
int unconfirmed; int unconfirmed;
final int frozen; final int frozen;
int secondConfirmed = 0;
int secondUnconfirmed = 0;
@override @override
String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen); String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen);
@ -38,6 +47,22 @@ class ElectrumBalance extends Balance {
return frozenFormatted == '0.0' ? '' : frozenFormatted; return frozenFormatted == '0.0' ? '' : frozenFormatted;
} }
String toJSON() => @override
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen}); 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
});
} }

View file

@ -884,7 +884,7 @@ abstract class ElectrumWalletBase
final totalAmount = amount + fee; final totalAmount = amount + fee;
if (totalAmount > balance[currency]!.confirmed) { if (totalAmount > (balance[currency]!.confirmed + balance[currency]!.secondConfirmed)) {
throw BitcoinTransactionWrongBalanceException(); throw BitcoinTransactionWrongBalanceException();
} }

View file

@ -244,9 +244,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
print("STARTING SYNC - MWEB ENABLED: $mwebEnabled"); print("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
syncStatus = SyncronizingSyncStatus(); syncStatus = SyncronizingSyncStatus();
await subscribeForUpdates(); await subscribeForUpdates();
await updateTransactions();
await updateFeeRates();
await updateFeeRates();
_feeRatesTimer?.cancel(); _feeRatesTimer?.cancel();
_feeRatesTimer = _feeRatesTimer =
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates()); Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
@ -265,14 +264,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
} }
await waitForMwebAddresses(); await waitForMwebAddresses();
await getStub(); await getStub();
await processMwebUtxos();
await updateTransactions();
await updateUnspent(); await updateUnspent();
await updateBalance(); await updateBalance();
_syncTimer?.cancel(); _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 { _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
if (syncStatus is FailedSyncStatus) return; if (syncStatus is FailedSyncStatus) return;
@ -319,7 +317,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
lastFewProgresses.add(syncStatus.progress()); lastFewProgresses.add(syncStatus.progress());
if (lastFewProgresses.length < 4) return; if (lastFewProgresses.length < 4) return;
// limit list size to 4: // limit list size to 4:
while(lastFewProgresses.length > 4) { while (lastFewProgresses.length > 4) {
lastFewProgresses.removeAt(0); lastFewProgresses.removeAt(0);
} }
// if the progress is the same over the last 40 seconds, restart the sync: // if the progress is the same over the last 40 seconds, restart the sync:
@ -330,9 +328,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
timer.cancel(); timer.cancel();
} }
}); });
});
// this runs in the background and processes new utxos as they come in:
processMwebUtxos();
} }
@action @action
@ -678,14 +673,19 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
int confirmed = balance.confirmed; int confirmed = balance.confirmed;
int unconfirmed = balance.unconfirmed; int unconfirmed = balance.unconfirmed;
int confirmedMweb = 0;
int unconfirmedMweb = 0;
try { try {
mwebUtxosBox.values.forEach((utxo) { mwebUtxosBox.values.forEach((utxo) {
if (utxo.height > 0) { if (utxo.height > 0) {
confirmed += utxo.value.toInt(); confirmedMweb += utxo.value.toInt();
} else { } else {
unconfirmed += utxo.value.toInt(); unconfirmedMweb += utxo.value.toInt();
} }
}); });
if (/*confirmedMweb > 0 &&*/ unconfirmedMweb > 0) {
unconfirmedMweb = -1 * (confirmedMweb - unconfirmedMweb);
}
} catch (_) {} } catch (_) {}
// update unspent balances: // 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 @override
@ -869,7 +875,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
final addresses = <String>{}; final addresses = <String>{};
transaction.inputAddresses?.forEach((id) async { transaction.inputAddresses?.forEach((id) async {
final utxo = mwebUtxosBox.get(id); final utxo = mwebUtxosBox.get(id);
await mwebUtxosBox.delete(id); // await mwebUtxosBox.delete(id);
if (utxo == null) return; if (utxo == null) return;
final addressRecord = walletAddresses.allAddresses final addressRecord = walletAddresses.allAddresses
.firstWhere((addressRecord) => addressRecord.address == utxo.address); .firstWhere((addressRecord) => addressRecord.address == utxo.address);

View file

@ -122,6 +122,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
Future<String> getChangeAddress({List<BitcoinOutput>? outputs, UtxoDetails? utxoDetails}) async { Future<String> getChangeAddress({List<BitcoinOutput>? outputs, UtxoDetails? utxoDetails}) async {
// use regular change address on peg in, otherwise use mweb for change address: // use regular change address on peg in, otherwise use mweb for change address:
if (!mwebEnabled) {
return super.getChangeAddress();
}
if (outputs != null && utxoDetails != null) { if (outputs != null && utxoDetails != null) {
// check if this is a PEGIN: // check if this is a PEGIN:
bool outputsToMweb = false; bool outputsToMweb = false;
@ -134,6 +138,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
outputsToMweb = true; outputsToMweb = true;
} }
} }
// TODO: this doesn't respect coin control because it doesn't know which available inputs are selected
utxoDetails.availableInputs.forEach((element) { utxoDetails.availableInputs.forEach((element) {
if (element.address.contains("mweb")) { if (element.address.contains("mweb")) {
comesFromMweb = true; comesFromMweb = true;
@ -144,6 +149,11 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
if (isPegIn && mwebEnabled) { if (isPegIn && mwebEnabled) {
return super.getChangeAddress(); return super.getChangeAddress();
} }
// use regular change address if it's not an mweb tx:
if (!comesFromMweb && !outputsToMweb) {
return super.getChangeAddress();
}
} }
if (mwebEnabled) { if (mwebEnabled) {

View file

@ -1,13 +1,18 @@
abstract class Balance { abstract class Balance {
const Balance(this.available, this.additional); const Balance(this.available, this.additional, {this.secondAvailable, this.secondAdditional});
final int available; final int available;
final int additional; final int additional;
final int? secondAvailable;
final int? secondAdditional;
String get formattedAvailableBalance; String get formattedAvailableBalance;
String get formattedAdditionalBalance; String get formattedAdditionalBalance;
String get formattedUnAvailableBalance => ''; String get formattedUnAvailableBalance => '';
String get formattedSecondAvailableBalance => '';
String get formattedSecondAdditionalBalance => '';
String get formattedFullAvailableBalance => '';
String get formattedFullUnAvailableBalance => '';
} }

View file

@ -123,7 +123,7 @@ void restoreWalletFromKeysSync(
int nettype = 0, int nettype = 0,
int restoreHeight = 0}) { int restoreHeight = 0}) {
txhistory = null; txhistory = null;
final newWptr = spendKey != "" var newWptr = (spendKey != "")
? monero.WalletManager_createDeterministicWalletFromSpendKey( ? monero.WalletManager_createDeterministicWalletFromSpendKey(
wmPtr, wmPtr,
path: path, path: path,
@ -149,6 +149,32 @@ void restoreWalletFromKeysSync(
message: monero.Wallet_errorString(newWptr)); 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; wptr = newWptr;
openedWalletsByPath[path] = wptr!; openedWalletsByPath[path] = wptr!;

View file

@ -140,7 +140,7 @@ void restoreWalletFromKeysSync(
int nettype = 0, int nettype = 0,
int restoreHeight = 0}) { int restoreHeight = 0}) {
txhistory = null; txhistory = null;
final newWptr = spendKey != "" var newWptr = (spendKey != "")
? wownero.WalletManager_createDeterministicWalletFromSpendKey( ? wownero.WalletManager_createDeterministicWalletFromSpendKey(
wmPtr, wmPtr,
path: path, path: path,
@ -165,7 +165,31 @@ void restoreWalletFromKeysSync(
throw WalletRestoreFromKeysException( throw WalletRestoreFromKeysException(
message: wownero.Wallet_errorString(newWptr)); 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; wptr = newWptr;
openedWalletsByPath[path] = wptr!; openedWalletsByPath[path] = wptr!;

View file

@ -131,7 +131,7 @@ class CryptoBalanceWidget extends StatelessWidget {
builder: (_) { builder: (_) {
if (dashboardViewModel.getMoneroError != null) { if (dashboardViewModel.getMoneroError != null) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16,0,16,16), padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
title: "Invalid monero bindings", title: "Invalid monero bindings",
subTitle: dashboardViewModel.getMoneroError.toString(), subTitle: dashboardViewModel.getMoneroError.toString(),
@ -146,13 +146,12 @@ class CryptoBalanceWidget extends StatelessWidget {
builder: (_) { builder: (_) {
if (dashboardViewModel.getWowneroError != null) { if (dashboardViewModel.getWowneroError != null) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16,0,16,16), padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
title: "Invalid wownero bindings", title: "Invalid wownero bindings",
subTitle: dashboardViewModel.getWowneroError.toString(), subTitle: dashboardViewModel.getWowneroError.toString(),
onTap: () {}, onTap: () {},
) ));
);
} }
return Container(); return Container();
}, },
@ -273,6 +272,18 @@ class CryptoBalanceWidget extends StatelessWidget {
currency: balance.asset, currency: balance.asset,
hasAdditionalBalance: hasAdditionalBalance:
dashboardViewModel.balanceViewModel.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, isTestnet: dashboardViewModel.isTestnet,
); );
}); });
@ -290,12 +301,11 @@ class CryptoBalanceWidget extends StatelessWidget {
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
customBorder: 30, customBorder: 30,
title: "This wallet has encountered an issue", title: "This wallet has encountered an issue",
subTitle: "Here are the things that you should note:\n - " subTitle: "Here are the things that you should note:\n - " +
+dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") +
+"\n\nPlease restart your wallet and if it doesn't help contact our support.", "\n\nPlease restart your wallet and if it doesn't help contact our support.",
onTap: () {}, onTap: () {},
) ))
)
], ],
if (dashboardViewModel.showSilentPaymentsCard) ...[ if (dashboardViewModel.showSilentPaymentsCard) ...[
SizedBox(height: 10), SizedBox(height: 10),
@ -494,10 +504,18 @@ class BalanceRowWidget extends StatelessWidget {
required this.additionalBalanceLabel, required this.additionalBalanceLabel,
required this.additionalBalance, required this.additionalBalance,
required this.additionalFiatBalance, 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.frozenBalance,
required this.frozenFiatBalance, required this.frozenFiatBalance,
required this.currency, required this.currency,
required this.hasAdditionalBalance, required this.hasAdditionalBalance,
required this.hasSecondAvailableBalance,
required this.hasSecondAdditionalBalance,
required this.isTestnet, required this.isTestnet,
super.key, super.key,
}); });
@ -508,10 +526,18 @@ class BalanceRowWidget extends StatelessWidget {
final String additionalBalanceLabel; final String additionalBalanceLabel;
final String additionalBalance; final String additionalBalance;
final String additionalFiatBalance; 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 frozenBalance;
final String frozenFiatBalance; final String frozenFiatBalance;
final CryptoCurrency currency; final CryptoCurrency currency;
final bool hasAdditionalBalance; final bool hasAdditionalBalance;
final bool hasSecondAvailableBalance;
final bool hasSecondAdditionalBalance;
final bool isTestnet; final bool isTestnet;
// void _showBalanceDescription(BuildContext context) { // 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<BalancePageTheme>()!.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
AutoSizeText(
secondAvailableBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.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<BalancePageTheme>()!.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<BalancePageTheme>()!.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
AutoSizeText(
secondAdditionalBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.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<BalancePageTheme>()!.textColor,
height: 1,
),
),
],
),
], ],
), ),
), ),

View file

@ -1,3 +1,6 @@
import 'dart:math';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -35,7 +38,7 @@ class AddressList extends StatelessWidget {
separatorBuilder: (context, _) => const HorizontalSectionDivider(), separatorBuilder: (context, _) => const HorizontalSectionDivider(),
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemCount: addressListViewModel.items.length, itemCount: min(addressListViewModel.items.length, 100),// TODO: don't show all 1000 mweb addresses
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = addressListViewModel.items[index]; final item = addressListViewModel.items[index];
Widget cell = Container(); Widget cell = Container();

View file

@ -21,10 +21,14 @@ class BalanceRecord {
const BalanceRecord( const BalanceRecord(
{required this.availableBalance, {required this.availableBalance,
required this.additionalBalance, required this.additionalBalance,
required this.secondAvailableBalance,
required this.secondAdditionalBalance,
required this.frozenBalance, required this.frozenBalance,
required this.fiatAvailableBalance, required this.fiatAvailableBalance,
required this.fiatAdditionalBalance, required this.fiatAdditionalBalance,
required this.fiatFrozenBalance, required this.fiatFrozenBalance,
required this.fiatSecondAvailableBalance,
required this.fiatSecondAdditionalBalance,
required this.asset, required this.asset,
required this.formattedAssetTitle}); required this.formattedAssetTitle});
final String fiatAdditionalBalance; final String fiatAdditionalBalance;
@ -33,6 +37,10 @@ class BalanceRecord {
final String additionalBalance; final String additionalBalance;
final String availableBalance; final String availableBalance;
final String frozenBalance; final String frozenBalance;
final String secondAvailableBalance;
final String secondAdditionalBalance;
final String fiatSecondAdditionalBalance;
final String fiatSecondAvailableBalance;
final CryptoCurrency asset; final CryptoCurrency asset;
final String formattedAssetTitle; 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 @computed
bool get hasMultiBalance => appStore.wallet!.type == WalletType.haven; bool get hasMultiBalance => appStore.wallet!.type == WalletType.haven;
@ -207,6 +235,17 @@ abstract class BalanceViewModelBase with Store {
return walletBalance.formattedAdditionalBalance; return walletBalance.formattedAdditionalBalance;
} }
@computed
String get secondAdditionalBalance {
final walletBalance = _walletBalance;
if (displayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
return walletBalance.formattedSecondAdditionalBalance;
}
@computed @computed
String get availableFiatBalance { String get availableFiatBalance {
final walletBalance = _walletBalance; final walletBalance = _walletBalance;
@ -243,9 +282,13 @@ abstract class BalanceViewModelBase with Store {
availableBalance: '---', availableBalance: '---',
additionalBalance: '---', additionalBalance: '---',
frozenBalance: '---', frozenBalance: '---',
secondAvailableBalance: '---',
secondAdditionalBalance: '---',
fiatAdditionalBalance: isFiatDisabled ? '' : '---', fiatAdditionalBalance: isFiatDisabled ? '' : '---',
fiatAvailableBalance: isFiatDisabled ? '' : '---', fiatAvailableBalance: isFiatDisabled ? '' : '---',
fiatFrozenBalance: isFiatDisabled ? '' : '---', fiatFrozenBalance: isFiatDisabled ? '' : '---',
fiatSecondAvailableBalance: isFiatDisabled ? '' : '---',
fiatSecondAdditionalBalance: isFiatDisabled ? '' : '---',
asset: key, asset: key,
formattedAssetTitle: _formatterAsset(key))); formattedAssetTitle: _formatterAsset(key)));
} }
@ -274,24 +317,46 @@ abstract class BalanceViewModelBase with Store {
' ' + ' ' +
_getFiatBalance(price: price, cryptoAmount: getFormattedFrozenBalance(value))); _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( return MapEntry(
key, key,
BalanceRecord( BalanceRecord(
availableBalance: value.formattedAvailableBalance, availableBalance: value.formattedAvailableBalance,
additionalBalance: value.formattedAdditionalBalance, additionalBalance: value.formattedAdditionalBalance,
frozenBalance: getFormattedFrozenBalance(value), frozenBalance: getFormattedFrozenBalance(value),
secondAvailableBalance: value.formattedSecondAvailableBalance,
secondAdditionalBalance: value.formattedSecondAdditionalBalance,
fiatAdditionalBalance: additionalFiatBalance, fiatAdditionalBalance: additionalFiatBalance,
fiatAvailableBalance: availableFiatBalance, fiatAvailableBalance: availableFiatBalance,
fiatFrozenBalance: frozenFiatBalance, fiatFrozenBalance: frozenFiatBalance,
fiatSecondAvailableBalance: secondAvailableFiatBalance,
fiatSecondAdditionalBalance: secondAdditionalFiatBalance,
asset: key, asset: key,
formattedAssetTitle: _formatterAsset(key))); formattedAssetTitle: _formatterAsset(key)));
}); });
} }
@computed @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) { switch (type) {
case WalletType.ethereum: case WalletType.ethereum:
case WalletType.polygon: 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 @computed
List<BalanceRecord> get formattedBalances { List<BalanceRecord> get formattedBalances {
final balance = balances.values.toList(); final balance = balances.values.toList();

View file

@ -217,7 +217,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
PendingTransaction? pendingTransaction; PendingTransaction? pendingTransaction;
@computed @computed
String get balance => wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance; String get balance => wallet.balance[selectedCryptoCurrency]!.formattedFullAvailableBalance;
@computed @computed
bool get isFiatDisabled => balanceViewModel.isFiatDisabled; bool get isFiatDisabled => balanceViewModel.isFiatDisabled;

View file

@ -396,6 +396,8 @@
"monero_light_theme": " ضوء مونيرو", "monero_light_theme": " ضوء مونيرو",
"moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}",
"more_options": "المزيد من الخيارات", "more_options": "المزيد من الخيارات",
"mweb_confirmed": "أكد MWEB",
"mweb_unconfirmed": "غير مؤكد MWEB",
"name": "ﻢﺳﺍ", "name": "ﻢﺳﺍ",
"nano_current_rep": "الممثل الحالي", "nano_current_rep": "الممثل الحالي",
"nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!", "nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Лека тема Monero", "monero_light_theme": "Лека тема Monero",
"moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}",
"more_options": "Още настройки", "more_options": "Още настройки",
"mweb_confirmed": "Потвърден MWeb",
"mweb_unconfirmed": "Непотвърден mweb",
"name": "Име", "name": "Име",
"nano_current_rep": "Настоящ представител", "nano_current_rep": "Настоящ представител",
"nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!", "nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Světlé téma Monero", "monero_light_theme": "Světlé téma Monero",
"moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}",
"more_options": "Více možností", "more_options": "Více možností",
"mweb_confirmed": "Potvrzený mweb",
"mweb_unconfirmed": "Nepotvrzené mWeb",
"name": "název", "name": "název",
"nano_current_rep": "Současný zástupce", "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!", "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!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Light-Thema", "monero_light_theme": "Monero Light-Thema",
"moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein", "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
"more_options": "Weitere Optionen", "more_options": "Weitere Optionen",
"mweb_confirmed": "Bestätigt MWeb",
"mweb_unconfirmed": "Unbestätigter MWeb",
"name": "Name", "name": "Name",
"nano_current_rep": "Aktueller Vertreter", "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!", "nano_gpt_thanks_message": "Danke, dass du Nanogpt benutzt hast! Denken Sie daran, nach Abschluss Ihrer Transaktion zurück zum Browser zu gehen!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Light Theme", "monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}",
"more_options": "More Options", "more_options": "More Options",
"mweb_confirmed": "Confirmed MWEB",
"mweb_unconfirmed": "Unconfirmed MWEB",
"name": "Name", "name": "Name",
"nano_current_rep": "Current Representative", "nano_current_rep": "Current Representative",
"nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!", "nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Tema ligero de Monero", "monero_light_theme": "Tema ligero de Monero",
"moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}",
"more_options": "Más Opciones", "more_options": "Más Opciones",
"mweb_confirmed": "Confirmado mweb",
"mweb_unconfirmed": "Mweb no confirmado",
"name": "Nombre", "name": "Nombre",
"nano_current_rep": "Representante actual", "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!", "nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Thème de lumière Monero", "monero_light_theme": "Thème de lumière Monero",
"moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}",
"more_options": "Plus d'options", "more_options": "Plus d'options",
"mweb_confirmed": "Confirmé MWEB",
"mweb_unconfirmed": "Mweb non confirmé",
"name": "Nom", "name": "Nom",
"nano_current_rep": "Représentant actuel", "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!", "nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Jigon Hasken Monero", "monero_light_theme": "Jigon Hasken Monero",
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
"more_options": "Ƙarin Zaɓuɓɓuka", "more_options": "Ƙarin Zaɓuɓɓuka",
"mweb_confirmed": "Tabbatar da Mweb",
"mweb_unconfirmed": "Myconfired",
"name": "Suna", "name": "Suna",
"nano_current_rep": "Wakilin Yanzu", "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!", "nano_gpt_thanks_message": "Na gode da amfani da Nanogpt! Ka tuna da komawa zuwa mai bincike bayan ma'amalar ka ta cika!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "मोनेरो लाइट थीम", "monero_light_theme": "मोनेरो लाइट थीम",
"moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}",
"more_options": "और विकल्प", "more_options": "और विकल्प",
"mweb_confirmed": "MWEB की पुष्टि की",
"mweb_unconfirmed": "अपुष्ट MWEB",
"name": "नाम", "name": "नाम",
"nano_current_rep": "वर्तमान प्रतिनिधि", "nano_current_rep": "वर्तमान प्रतिनिधि",
"nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!", "nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero lagana tema", "monero_light_theme": "Monero lagana tema",
"moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}",
"more_options": "Više opcija", "more_options": "Više opcija",
"mweb_confirmed": "Potvrđen MWeb",
"mweb_unconfirmed": "Nepotvrđeni mWeb",
"name": "Ime", "name": "Ime",
"nano_current_rep": "Trenutni predstavnik", "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!", "nano_gpt_thanks_message": "Hvala što ste koristili nanogpt! Ne zaboravite da se vratite u preglednik nakon što vam se transakcija završi!",

View file

@ -387,6 +387,8 @@
"monero_light_theme": "Monero պայծառ տեսք", "monero_light_theme": "Monero պայծառ տեսք",
"moonpay_alert_text": "Գումարի արժեքը պետք է լինի հավասար կամ ավելի քան ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Գումարի արժեքը պետք է լինի հավասար կամ ավելի քան ${minAmount} ${fiatCurrency}",
"more_options": "Այլ տարբերակներ", "more_options": "Այլ տարբերակներ",
"mweb_confirmed": "Հաստատված MWEB",
"mweb_unconfirmed": "Չկարգավորված Mweb",
"name": "Անուն", "name": "Անուն",
"nano_current_rep": "Ընթացիկ ներկայացուցիչ", "nano_current_rep": "Ընթացիկ ներկայացուցիչ",
"nano_gpt_thanks_message": "Շնորհակալություն NanoGPT-ն օգտագործելու համար: Հիշեք վերադառնալ դիտարկիչ ձեր փոխանցումն ավարտելուց հետո", "nano_gpt_thanks_message": "Շնորհակալություն NanoGPT-ն օգտագործելու համար: Հիշեք վերադառնալ դիտարկիչ ձեր փոխանցումն ավարտելուց հետո",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Tema Cahaya Monero", "monero_light_theme": "Tema Cahaya Monero",
"moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}",
"more_options": "Opsi Lainnya", "more_options": "Opsi Lainnya",
"mweb_confirmed": "Mengkonfirmasi mWeb",
"mweb_unconfirmed": "MWEB yang belum dikonfirmasi",
"name": "Nama", "name": "Nama",
"nano_current_rep": "Perwakilan saat ini", "nano_current_rep": "Perwakilan saat ini",
"nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!", "nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!",

View file

@ -397,6 +397,8 @@
"monero_light_theme": "Tema leggero Monero", "monero_light_theme": "Tema leggero Monero",
"moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}",
"more_options": "Altre opzioni", "more_options": "Altre opzioni",
"mweb_confirmed": "MWeb confermato",
"mweb_unconfirmed": "MWeb non confermato",
"name": "Nome", "name": "Nome",
"nano_current_rep": "Rappresentante attuale", "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!", "nano_gpt_thanks_message": "Grazie per aver usato il nanogpt! Ricorda di tornare al browser dopo il completamento della transazione!",

View file

@ -397,6 +397,8 @@
"monero_light_theme": "モネロ ライト テーマ", "monero_light_theme": "モネロ ライト テーマ",
"moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}",
"more_options": "その他のオプション", "more_options": "その他のオプション",
"mweb_confirmed": "確認されたMWEB",
"mweb_unconfirmed": "未確認のMWEB",
"name": "名前", "name": "名前",
"nano_current_rep": "現在の代表", "nano_current_rep": "現在の代表",
"nano_gpt_thanks_message": "NanoGptを使用してくれてありがとうトランザクションが完了したら、ブラウザに戻ることを忘れないでください", "nano_gpt_thanks_message": "NanoGptを使用してくれてありがとうトランザクションが完了したら、ブラウザに戻ることを忘れないでください",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "모네로 라이트 테마", "monero_light_theme": "모네로 라이트 테마",
"moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}",
"more_options": "추가 옵션", "more_options": "추가 옵션",
"mweb_confirmed": "확인 mweb",
"mweb_unconfirmed": "확인되지 않은 mweb",
"name": "이름", "name": "이름",
"nano_current_rep": "현재 대표", "nano_current_rep": "현재 대표",
"nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!", "nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Light အပြင်အဆင်", "monero_light_theme": "Monero Light အပြင်အဆင်",
"moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်", "moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်",
"more_options": "နောက်ထပ် ရွေးချယ်စရာများ", "more_options": "နောက်ထပ် ရွေးချယ်စရာများ",
"mweb_confirmed": "အတည်ပြုလိုက် mweb",
"mweb_unconfirmed": "အတည်မပြုနိုင်သော mweb",
"name": "နာမည်", "name": "နာမည်",
"nano_current_rep": "လက်ရှိကိုယ်စားလှယ်", "nano_current_rep": "လက်ရှိကိုယ်စားလှယ်",
"nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။", "nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Light-thema", "monero_light_theme": "Monero Light-thema",
"moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}",
"more_options": "Meer opties", "more_options": "Meer opties",
"mweb_confirmed": "Bevestigde MWEB",
"mweb_unconfirmed": "Onbevestigde MWEB",
"name": "Naam", "name": "Naam",
"nano_current_rep": "Huidige vertegenwoordiger", "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!", "nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat uw transactie is voltooid!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Lekki motyw Monero", "monero_light_theme": "Lekki motyw Monero",
"moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}",
"more_options": "Więcej opcji", "more_options": "Więcej opcji",
"mweb_confirmed": "Potwierdził MWEB",
"mweb_unconfirmed": "Niepotwierdzone MWEB",
"name": "Nazwa", "name": "Nazwa",
"nano_current_rep": "Obecny przedstawiciel", "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!", "nano_gpt_thanks_message": "Dzięki za użycie Nanogpt! Pamiętaj, aby wrócić do przeglądarki po zakończeniu transakcji!",

View file

@ -397,6 +397,8 @@
"monero_light_theme": "Monero Light Theme", "monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}",
"more_options": "Mais opções", "more_options": "Mais opções",
"mweb_confirmed": "MWEB confirmado",
"mweb_unconfirmed": "MWEB não confirmado",
"name": "Nome", "name": "Nome",
"nano_current_rep": "Representante atual", "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!", "nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Светлая тема Monero", "monero_light_theme": "Светлая тема Monero",
"moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}",
"more_options": "Дополнительные параметры", "more_options": "Дополнительные параметры",
"mweb_confirmed": "Подтверждено MWEB",
"mweb_unconfirmed": "Неподтвержденная MWEB",
"name": "Имя", "name": "Имя",
"nano_current_rep": "Нынешний представитель", "nano_current_rep": "Нынешний представитель",
"nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!", "nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "ธีมแสง Monero", "monero_light_theme": "ธีมแสง Monero",
"moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}",
"more_options": "ตัวเลือกเพิ่มเติม", "more_options": "ตัวเลือกเพิ่มเติม",
"mweb_confirmed": "MWEB ยืนยันแล้ว",
"mweb_unconfirmed": "mweb ที่ไม่ได้รับการยืนยัน",
"name": "ชื่อ", "name": "ชื่อ",
"nano_current_rep": "ตัวแทนปัจจุบัน", "nano_current_rep": "ตัวแทนปัจจุบัน",
"nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!", "nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Light Theme", "monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "Ang halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Ang halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
"more_options": "Higit pang mga Pagpipilian", "more_options": "Higit pang mga Pagpipilian",
"mweb_confirmed": "Nakumpirma na MWeb",
"mweb_unconfirmed": "Hindi nakumpirma si Mweb",
"name": "Pangalan", "name": "Pangalan",
"nano_current_rep": "Kasalukuyang Representative", "nano_current_rep": "Kasalukuyang Representative",
"nano_gpt_thanks_message": "Salamat sa paggamit ng NanoGPT! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!", "nano_gpt_thanks_message": "Salamat sa paggamit ng NanoGPT! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Monero Hafif Tema", "monero_light_theme": "Monero Hafif Tema",
"moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır", "moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır",
"more_options": "Daha Fazla Seçenek", "more_options": "Daha Fazla Seçenek",
"mweb_confirmed": "Onaylanmış mweb",
"mweb_unconfirmed": "Doğrulanmamış mweb",
"name": "İsim", "name": "İsim",
"nano_current_rep": "Mevcut temsilci", "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!", "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!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "Легка тема Monero", "monero_light_theme": "Легка тема Monero",
"moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}",
"more_options": "Більше параметрів", "more_options": "Більше параметрів",
"mweb_confirmed": "Підтвердив Mweb",
"mweb_unconfirmed": "Неперевірений MWEB",
"name": "Ім'я", "name": "Ім'я",
"nano_current_rep": "Поточний представник", "nano_current_rep": "Поточний представник",
"nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!", "nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "مونیرو لائٹ تھیم", "monero_light_theme": "مونیرو لائٹ تھیم",
"moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔", "moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔",
"more_options": "مزید زرائے", "more_options": "مزید زرائے",
"mweb_confirmed": "تصدیق شدہ MWEB",
"mweb_unconfirmed": "غیر مصدقہ MWEB",
"name": "ﻡﺎﻧ", "name": "ﻡﺎﻧ",
"nano_current_rep": "موجودہ نمائندہ", "nano_current_rep": "موجودہ نمائندہ",
"nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!", "nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!",

View file

@ -140,8 +140,8 @@
"confirm": "Xác nhận", "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_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_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_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_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", "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", "confirmations": "Xác nhận",
@ -386,6 +386,8 @@
"monero_light_theme": "Chủ đề sáng Monero", "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}", "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", "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", "name": "Tên",
"nano_current_rep": "Đại diện hiện tại", "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!", "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!",

View file

@ -397,6 +397,8 @@
"monero_light_theme": "Monero Light Akori", "monero_light_theme": "Monero Light Akori",
"moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}",
"more_options": "Ìyàn àfikún", "more_options": "Ìyàn àfikún",
"mweb_confirmed": "Jẹrisi Mweb",
"mweb_unconfirmed": "Ajopo Mweb",
"name": "Oruko", "name": "Oruko",
"nano_current_rep": "Aṣoju lọwọlọwọ", "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!", "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!",

View file

@ -396,6 +396,8 @@
"monero_light_theme": "门罗币浅色主题", "monero_light_theme": "门罗币浅色主题",
"moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}",
"more_options": "更多选项", "more_options": "更多选项",
"mweb_confirmed": "确认的MWEB",
"mweb_unconfirmed": "未经证实的MWEB",
"name": "姓名", "name": "姓名",
"nano_current_rep": "当前代表", "nano_current_rep": "当前代表",
"nano_gpt_thanks_message": "感谢您使用Nanogpt事务完成后请记住回到浏览器", "nano_gpt_thanks_message": "感谢您使用Nanogpt事务完成后请记住回到浏览器",