CW-325-Coin-Control-enhancements (#846)

* fix checkbox * save the output state * add note as a header * Allow copy the Amount and Address * add frozen balance to dashboard * add block explorer * fix url launcher * code formatting * minor fixes * Revert "minor fixes" This reverts commit d230b6a07bc3855407251991926ab0f257c55a5a. * fix missing implementations error * [skip ci] update localization * fix unspent with same txid * add amount check * add vout check * remove formattedTotalAvailableBalance * remove unrelated mac os files

Serhii committed Apr 20, 2023 at 16:46 UTC 315c4c911c1c6af214ac3e7a59a1acbb04a19ed5
37 files changed +525 -339
cw_bitcoin/lib/electrum_balance.dart
+12 -7
@@ -4,7 +4,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
4 import 'package:cw_core/balance.dart';
5
6 class ElectrumBalance extends Balance {
7 - const ElectrumBalance({required this.confirmed, required this.unconfirmed})
7 + const ElectrumBalance({required this.confirmed, required this.unconfirmed, required this.frozen})
8 : super(confirmed, unconfirmed);
9
10 static ElectrumBalance? fromJSON(String? jsonSource) {
@@ -16,20 +16,25 @@ class ElectrumBalance extends Balance {
16
17 return ElectrumBalance(
18 confirmed: decoded['confirmed'] as int? ?? 0,
19 - unconfirmed: decoded['unconfirmed'] as int? ?? 0);
19 + unconfirmed: decoded['unconfirmed'] as int? ?? 0,
20 + frozen: decoded['frozen'] as int? ?? 0);
21 }
22
23 final int confirmed;
24 final int unconfirmed;
25 + final int frozen;
26
27 @override
26 - String get formattedAvailableBalance =>
27 - bitcoinAmountToString(amount: confirmed);
28 + String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen);
29
30 @override
30 - String get formattedAdditionalBalance =>
31 - bitcoinAmountToString(amount: unconfirmed);
31 + String get formattedAdditionalBalance => bitcoinAmountToString(amount: unconfirmed);
32 +
33 + String get formattedFrozenBalance {
34 + final frozenFormatted = bitcoinAmountToString(amount: frozen);
35 + return frozenFormatted == '0.0' ? '' : frozenFormatted;
36 + }
37
38 String toJSON() =>
34 - json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed});
39 + json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen});
40 }
cw_bitcoin/lib/electrum_wallet.dart
+23 -8
@@ -63,7 +63,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
63 _scripthashesUpdateSubject = {},
64 balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
65 currency != null
66 - ? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
66 + ? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0,
67 + frozen: 0)}
68 : {}),
69 this.unspentCoinsInfo = unspentCoinsInfo,
70 super(walletInfo) {
@@ -133,8 +134,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
134 await walletAddresses.discoverAddresses();
135 await updateTransactions();
136 _subscribeForUpdates();
136 - await _updateBalance();
137 await updateUnspent();
138 + await updateBalance();
139 _feeRates = await electrumClient.feeRates();
140
141 Timer.periodic(const Duration(minutes: 1),
@@ -343,7 +344,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
344 electrumClient: electrumClient, amount: amount, fee: fee)
345 ..addListener((transaction) async {
346 transactionHistory.addOne(transaction);
346 - await _updateBalance();
347 + await updateBalance();
348 });
349 }
350
@@ -497,7 +498,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
498 hash: coin.hash,
499 isFrozen: coin.isFrozen,
500 isSending: coin.isSending,
500 - noteRaw: coin.note
501 + noteRaw: coin.note,
502 + address: coin.address.address,
503 + value: coin.value,
504 + vout: coin.vout,
505 );
506
507 await unspentCoinsInfo.add(newInfo);
@@ -634,8 +638,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
638 _scripthashesUpdateSubject[sh] = electrumClient.scripthashUpdate(sh);
639 _scripthashesUpdateSubject[sh]?.listen((event) async {
640 try {
637 - await _updateBalance();
641 await updateUnspent();
642 + await updateBalance();
643 await updateTransactions();
644 } catch (e) {
645 print(e.toString());
@@ -653,7 +657,17 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
657 final sh = scriptHash(addressRecord.address, networkType: networkType);
658 final balanceFuture = electrumClient.getBalance(sh);
659 balanceFutures.add(balanceFuture);
656 - }
660 + }
661 +
662 + var totalFrozen = 0;
663 + unspentCoinsInfo.values.forEach((info) {
664 + unspentCoins.forEach((element) {
665 + if (element.hash == info.hash && info.isFrozen && element.address.address == info.address
666 + && element.value == info.value) {
667 + totalFrozen += element.value;
668 + }
669 + });
670 + });
671
672 final balances = await Future.wait(balanceFutures);
673 var totalConfirmed = 0;
@@ -672,10 +686,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
686 }
687 }
688
675 - return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed);
689 + return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed,
690 + frozen: totalFrozen);
691 }
692
678 - Future<void> _updateBalance() async {
693 + Future<void> updateBalance() async {
694 balance[currency] = await _fetchBalances();
695 await save();
696 }
cw_bitcoin/lib/electrum_wallet_snapshot.dart
+1 -1
@@ -37,7 +37,7 @@ class ElectrumWallletSnapshot {
37 .map((addr) => BitcoinAddressRecord.fromJSON(addr))
38 .toList();
39 final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
40 - ElectrumBalance(confirmed: 0, unconfirmed: 0);
40 + ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
41 var regularAddressIndex = 0;
42 var changeAddressIndex = 0;
43
cw_core/lib/unspent_coins_info.dart
+13 -1
@@ -9,7 +9,10 @@ class UnspentCoinsInfo extends HiveObject {
9 required this.hash,
10 required this.isFrozen,
11 required this.isSending,
12 - required this.noteRaw});
12 + required this.noteRaw,
13 + required this.address,
14 + required this.vout,
15 + required this.value});
16
17 static const typeId = 9;
18 static const boxName = 'Unspent';
@@ -30,6 +33,15 @@ class UnspentCoinsInfo extends HiveObject {
33 @HiveField(4)
34 String? noteRaw;
35
36 + @HiveField(5, defaultValue: '')
37 + String address;
38 +
39 + @HiveField(6, defaultValue: 0)
40 + int value;
41 +
42 + @HiveField(7, defaultValue: 0)
43 + int vout;
44 +
45 String get note => noteRaw ?? '';
46
47 set note(String value) => noteRaw = value;
cw_core/lib/wallet_base.dart
+2
@@ -71,4 +71,6 @@ abstract class WalletBase<
71 void close();
72
73 Future<void> changePassword(String password);
74 +
75 + Future<void>? updateBalance();
76 }
cw_haven/lib/haven_wallet.dart
+3
@@ -104,6 +104,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
104 (_) async => await save());
105 }
106
107 + @override
108 + Future<void>? updateBalance() => null;
109 +
110 @override
111 void close() {
112 _listener?.stop();
cw_monero/lib/monero_wallet.dart
+2
@@ -118,6 +118,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
118 Duration(seconds: _autoSaveInterval),
119 (_) async => await save());
120 }
121 + @override
122 + Future<void>? updateBalance() => null;
123
124 @override
125 void close() {
lib/src/screens/dashboard/widgets/balance_page.dart
+146 -126
@@ -8,187 +8,207 @@ import 'package:auto_size_text/auto_size_text.dart';
8 import 'package:cake_wallet/src/widgets/introducing_card.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10
11 -
12 -class BalancePage extends StatelessWidget{
11 +class BalancePage extends StatelessWidget {
12 BalancePage({required this.dashboardViewModel, required this.settingsStore});
13
14 final DashboardViewModel dashboardViewModel;
15 final SettingsStore settingsStore;
16
17 + Color get backgroundLightColor =>
18 + settingsStore.currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
19 +
20 @override
21 Widget build(BuildContext context) {
22 return GestureDetector(
21 - onLongPress: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
22 - onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
23 - child: SingleChildScrollView(
24 - child: Column(
25 - crossAxisAlignment: CrossAxisAlignment.start,
26 - children: [
27 - SizedBox(height: ResponsiveLayoutUtil.instance.isMobile(context) ? 56 : 16),
23 + onLongPress: () => dashboardViewModel.balanceViewModel.isReversing =
24 + !dashboardViewModel.balanceViewModel.isReversing,
25 + onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
26 + !dashboardViewModel.balanceViewModel.isReversing,
27 + child: SingleChildScrollView(
28 + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
29 + SizedBox(height: 56),
30 Container(
29 - margin: const EdgeInsets.only(left: 24, bottom: 16),
30 - child: Observer(builder: (_) {
31 - return Text(
32 - dashboardViewModel.balanceViewModel.asset,
33 - style: TextStyle(
34 - fontSize: 24,
35 - fontFamily: 'Lato',
36 - fontWeight: FontWeight.w600,
37 - color: Theme.of(context)
38 - .accentTextTheme!
39 - .headline2!
40 - .backgroundColor!,
41 - height: 1),
42 - maxLines: 1,
43 - textAlign: TextAlign.center);
44 - })),
31 + margin: const EdgeInsets.only(left: 24, bottom: 16),
32 + child: Observer(builder: (_) {
33 + return Text(dashboardViewModel.balanceViewModel.asset,
34 + style: TextStyle(
35 + fontSize: 24,
36 + fontFamily: 'Lato',
37 + fontWeight: FontWeight.w600,
38 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
39 + height: 1),
40 + maxLines: 1,
41 + textAlign: TextAlign.center);
42 + })),
43 Observer(builder: (_) {
46 - if (dashboardViewModel.balanceViewModel.isShowCard){
44 + if (dashboardViewModel.balanceViewModel.isShowCard) {
45 return IntroducingCard(
48 - title: S.of(context).introducing_cake_pay,
46 + title: S.of(context).introducing_cake_pay,
47 subTitle: S.of(context).cake_pay_learn_more,
48 borderColor: settingsStore.currentTheme.type == ThemeType.bright
49 ? Color.fromRGBO(255, 255, 255, 0.2)
50 : Colors.transparent,
53 - closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard
54 - );
51 + closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
52 }
56 - return Container ();
53 + return Container();
54 }),
55 Observer(builder: (_) {
56 return ListView.separated(
60 - physics: NeverScrollableScrollPhysics(),
61 - shrinkWrap: true,
62 - separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
63 - itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
64 - itemBuilder: (__, index) {
65 - final balance = dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
66 - return buildBalanceRow(context,
67 - availableBalanceLabel: '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
57 + physics: NeverScrollableScrollPhysics(),
58 + shrinkWrap: true,
59 + separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
60 + itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
61 + itemBuilder: (__, index) {
62 + final balance =
63 + dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
64 + return buildBalanceRow(context,
65 + availableBalanceLabel:
66 + '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
67 availableBalance: balance.availableBalance,
68 availableFiatBalance: balance.fiatAvailableBalance,
70 - additionalBalanceLabel: '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
69 + additionalBalanceLabel:
70 + '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
71 additionalBalance: balance.additionalBalance,
72 additionalFiatBalance: balance.fiatAdditionalBalance,
73 + frozenBalance: balance.frozenBalance,
74 + frozenFiatBalance: balance.fiatFrozenBalance,
75 currency: balance.formattedAssetTitle);
74 - });
75 - })
76 - ])));
76 + });
77 + })
78 + ])));
79 }
80
81 Widget buildBalanceRow(BuildContext context,
80 - {required String availableBalanceLabel,
82 + {required String availableBalanceLabel,
83 required String availableBalance,
84 required String availableFiatBalance,
85 required String additionalBalanceLabel,
86 required String additionalBalance,
87 required String additionalFiatBalance,
88 + required String frozenBalance,
89 + required String frozenFiatBalance,
90 required String currency}) {
87 - return Container(
91 + return Container(
92 margin: const EdgeInsets.only(left: 16, right: 16),
93 decoration: BoxDecoration(
90 - borderRadius: BorderRadius.circular(30.0),
91 - border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
92 - color:Theme.of(context).textTheme!.headline6!.backgroundColor!
93 - ),
94 + borderRadius: BorderRadius.circular(30.0),
95 + border: Border.all(
96 + color: settingsStore.currentTheme.type == ThemeType.bright
97 + ? Color.fromRGBO(255, 255, 255, 0.2)
98 + : Colors.transparent,
99 + width: 1,
100 + ),
101 + color: Theme.of(context).textTheme!.headline6!.backgroundColor!),
102 child: Container(
95 - margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
96 - child: Column(
97 - crossAxisAlignment: CrossAxisAlignment.start,
98 - children: [
99 - SizedBox(height: 4,),
100 - Text('${availableBalanceLabel}',
101 - textAlign: TextAlign.center,
102 - style: TextStyle(
103 + margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
104 + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
105 + SizedBox(
106 + height: 4,
107 + ),
108 + Text('${availableBalanceLabel}',
109 + textAlign: TextAlign.center,
110 + style: TextStyle(
111 fontSize: 12,
112 fontFamily: 'Lato',
113 fontWeight: FontWeight.w400,
106 - color: Theme.of(context)
107 - .accentTextTheme!
108 - .headline3!
109 - .backgroundColor!,
114 + color: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
115 height: 1)),
111 - SizedBox(height: 5),
112 - Row(
113 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
114 - children: [
115 - AutoSizeText(
116 - availableBalance,
117 - style: TextStyle(
118 - fontSize: 24,
119 - fontFamily: 'Lato',
120 - fontWeight: FontWeight.w900,
121 - color: Theme.of(context)
122 - .accentTextTheme!
123 - .headline2!
124 - .backgroundColor!,
125 - height: 1),
126 - maxLines: 1,
127 - textAlign: TextAlign.center),
128 - Text(currency,
116 + SizedBox(height: 5),
117 + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
118 + AutoSizeText(availableBalance,
119 + style: TextStyle(
120 + fontSize: 24,
121 + fontFamily: 'Lato',
122 + fontWeight: FontWeight.w900,
123 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
124 + height: 1),
125 + maxLines: 1,
126 + textAlign: TextAlign.center),
127 + Text(currency,
128 + style: TextStyle(
129 + fontSize: 28,
130 + fontFamily: 'Lato',
131 + fontWeight: FontWeight.w800,
132 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
133 + height: 1)),
134 + ]),
135 + SizedBox(
136 + height: 4,
137 + ),
138 + Text('${availableFiatBalance}',
139 + textAlign: TextAlign.center,
140 + style: TextStyle(
141 + fontSize: 16,
142 + fontFamily: 'Lato',
143 + fontWeight: FontWeight.w500,
144 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
145 + height: 1)),
146 + SizedBox(height: 26),
147 + if (frozenBalance.isNotEmpty)
148 + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
149 + Text(S.current.frozen_balance,
150 + textAlign: TextAlign.center,
151 style: TextStyle(
130 - fontSize: 28,
152 + fontSize: 12,
153 fontFamily: 'Lato',
132 - fontWeight: FontWeight.w800,
133 - color: Theme.of(context)
134 - .accentTextTheme!
135 - .headline2!
136 - .backgroundColor!,
154 + fontWeight: FontWeight.w400,
155 + color: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
156 height: 1)),
138 - ]),
139 - SizedBox(height: 4,),
140 - Text('${availableFiatBalance}',
141 - textAlign: TextAlign.center,
142 - style: TextStyle(
143 - fontSize: 16,
144 - fontFamily: 'Lato',
145 - fontWeight: FontWeight.w500,
146 - color: Theme.of(context)
147 - .accentTextTheme!
148 - .headline2!
149 - .backgroundColor!,
150 - height: 1)),
151 - SizedBox(height: 26),
152 - Text('${additionalBalanceLabel}',
153 - textAlign: TextAlign.center,
154 - style: TextStyle(
155 - fontSize: 12,
156 - fontFamily: 'Lato',
157 - fontWeight: FontWeight.w400,
158 - color: Theme.of(context)
159 - .accentTextTheme!
160 - .headline3!
161 - .backgroundColor!,
162 - height: 1)),
163 - SizedBox(height: 8),
164 - AutoSizeText(
165 - additionalBalance,
157 + SizedBox(height: 8),
158 + AutoSizeText(frozenBalance,
159 style: TextStyle(
167 - fontSize: 20,
160 + fontSize: 20,
161 fontFamily: 'Lato',
162 fontWeight: FontWeight.w400,
170 - color: Theme.of(context)
171 - .accentTextTheme!
172 - .headline2!
173 - .backgroundColor!,
163 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
164 height: 1),
165 maxLines: 1,
166 textAlign: TextAlign.center),
177 - SizedBox(height: 4,),
178 - Text('${additionalFiatBalance}',
167 + SizedBox(height: 4),
168 + Text(
169 + frozenFiatBalance,
170 + textAlign: TextAlign.center,
171 + style: TextStyle(
172 + fontSize: 12,
173 + fontFamily: 'Lato',
174 + fontWeight: FontWeight.w400,
175 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
176 + height: 1),
177 + ),
178 + SizedBox(height: 24)
179 + ]),
180 + Text('${additionalBalanceLabel}',
181 textAlign: TextAlign.center,
182 style: TextStyle(
183 + fontSize: 12,
184 + fontFamily: 'Lato',
185 + fontWeight: FontWeight.w400,
186 + color: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
187 + height: 1)),
188 + SizedBox(height: 8),
189 + AutoSizeText(additionalBalance,
190 + style: TextStyle(
191 + fontSize: 20,
192 + fontFamily: 'Lato',
193 + fontWeight: FontWeight.w400,
194 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
195 + height: 1),
196 + maxLines: 1,
197 + textAlign: TextAlign.center),
198 + SizedBox(
199 + height: 4,
200 + ),
201 + Text(
202 + '${additionalFiatBalance}',
203 + textAlign: TextAlign.center,
204 + style: TextStyle(
205 fontSize: 12,
206 fontFamily: 'Lato',
207 fontWeight: FontWeight.w400,
184 - color: Theme.of(context)
185 - .accentTextTheme!
186 - .headline2!
187 - .backgroundColor!,
208 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
209 height: 1),
189 - )
190 - ])),
210 + )
211 + ])),
212 );
213 }
214 }
194 -
lib/src/screens/unspent_coins/unspent_coins_details_page.dart
+23 -9
@@ -1,13 +1,16 @@
1 +import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart';
2 import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
3 import 'package:cake_wallet/src/screens/transaction_details/widgets/textfield_list_row.dart';
4 import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_switch_row.dart';
5 import 'package:cake_wallet/src/widgets/standard_list.dart';
6 +import 'package:cake_wallet/utils/show_bar.dart';
7 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_details_view_model.dart';
8 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_switch_item.dart';
9 import 'package:flutter/material.dart';
10 import 'package:cake_wallet/src/widgets/list_row.dart';
11 import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
12 import 'package:cake_wallet/src/screens/base_page.dart';
13 +import 'package:flutter/services.dart';
14 import 'package:flutter_mobx/flutter_mobx.dart';
15 import 'package:cake_wallet/generated/i18n.dart';
16
@@ -30,9 +33,13 @@ class UnspentCoinsDetailsPage extends BasePage {
33 final item = unspentCoinsDetailsViewModel.items[index];
34
35 if (item is StandartListItem) {
33 - return ListRow(
34 - title: '${item.title}:',
35 - value: item.value);
36 + return GestureDetector(
37 + onTap: () {
38 + Clipboard.setData(ClipboardData(text: item.value));
39 + showBar<void>(context, S.of(context).transaction_details_copied(item.title));
40 + },
41 + child: ListRow(title: '${item.title}:', value: item.value),
42 + );
43 }
44
45 if (item is TextFieldListItem) {
@@ -44,14 +51,21 @@ class UnspentCoinsDetailsPage extends BasePage {
51 }
52
53 if (item is UnspentCoinsSwitchItem) {
47 - return Observer(builder: (_) => UnspentCoinsSwitchRow(
48 - title: item.title,
49 - switchValue: item.switchValue(),
50 - onSwitchValueChange: item.onSwitchValueChange
51 - ));
54 + return Observer(
55 + builder: (_) => UnspentCoinsSwitchRow(
56 + title: item.title,
57 + switchValue: item.switchValue(),
58 + onSwitchValueChange: item.onSwitchValueChange));
59 + }
60 +
61 + if (item is BlockExplorerListItem) {
62 + return GestureDetector(
63 + onTap: item.onTap,
64 + child: ListRow(title: '${item.title}:', value: item.value),
65 + );
66 }
67
68 return Container();
69 });
70 }
57 -}
\ No newline at end of file
71 +}
lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+55 -76
@@ -1,5 +1,6 @@
1 import 'package:auto_size_text/auto_size_text.dart';
2 import 'package:cake_wallet/palette.dart';
3 +import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
4 import 'package:flutter/material.dart';
5 import 'package:flutter/cupertino.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
@@ -28,99 +29,77 @@ class UnspentCoinsListItem extends StatelessWidget {
29
30 @override
31 Widget build(BuildContext context) {
31 - final itemColor = isSending? selectedItemColor : unselectedItemColor;
32 - final _note = (note?.isNotEmpty ?? false) ? note : address;
33 -
32 + final itemColor = isSending ? selectedItemColor : unselectedItemColor;
33 return Container(
35 - height: 62,
36 - padding: EdgeInsets.all(12),
37 - decoration: BoxDecoration(
38 - borderRadius: BorderRadius.all(Radius.circular(12)),
39 - color: itemColor),
34 + height: 70,
35 + padding: EdgeInsets.symmetric(vertical: 6, horizontal: 12),
36 + decoration:
37 + BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(12)), color: itemColor),
38 child: Row(
41 - mainAxisSize: MainAxisSize.max,
39 crossAxisAlignment: CrossAxisAlignment.center,
40 children: [
41 Padding(
42 padding: EdgeInsets.only(right: 12),
46 - child: GestureDetector(
47 - onTap: () => onCheckBoxTap?.call(),
48 - child: Container(
49 - height: 24.0,
50 - width: 24.0,
51 - decoration: BoxDecoration(
52 - border: Border.all(
53 - color: Theme.of(context)
54 - .primaryTextTheme!
55 - .caption!
56 - .color!,
57 - width: 1.0),
58 - borderRadius: BorderRadius.all(
59 - Radius.circular(8.0)),
60 - color: itemColor),
61 - child: isSending
62 - ? Icon(
63 - Icons.check,
64 - color: Colors.blue,
65 - size: 20.0,
66 - )
67 - : Offstage(),
68 - )
69 - )
70 - ),
43 + child: StandardCheckbox(
44 + value: isSending, onChanged: (value) => onCheckBoxTap?.call())),
45 Expanded(
46 child: Column(
47 mainAxisAlignment: MainAxisAlignment.spaceBetween,
48 crossAxisAlignment: CrossAxisAlignment.start,
49 children: [
76 - Row(
77 - mainAxisSize: MainAxisSize.max,
78 - mainAxisAlignment: MainAxisAlignment.start,
79 - crossAxisAlignment: CrossAxisAlignment.center,
80 - children: [
81 - Expanded(
82 - child: AutoSizeText(
83 - amount,
84 - style: TextStyle(
85 - color: amountColor,
86 - fontSize: 16,
87 - fontWeight: FontWeight.w600
88 - ),
89 - maxLines: 1,
90 - ),
50 + Row(
51 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
52 + crossAxisAlignment: CrossAxisAlignment.start,
53 + children: [
54 + Column(
55 + crossAxisAlignment: CrossAxisAlignment.start,
56 + children: [
57 + if (note.isNotEmpty)
58 + AutoSizeText(
59 + note,
60 + style: TextStyle(
61 + color: amountColor, fontSize: 15, fontWeight: FontWeight.w600),
62 + maxLines: 1,
63 ),
92 - if (isFrozen) Container(
64 + AutoSizeText(
65 + amount,
66 + style:
67 + TextStyle(color: amountColor, fontSize: 15, fontWeight: FontWeight.w600),
68 + maxLines: 1,
69 + )
70 + ]),
71 + if (isFrozen)
72 + Container(
73 height: 17,
74 padding: EdgeInsets.only(left: 6, right: 6),
75 decoration: BoxDecoration(
96 - borderRadius: BorderRadius.all(Radius.circular(8.5)),
97 - color: Colors.white),
76 + borderRadius: BorderRadius.all(Radius.circular(8.5)),
77 + color: Colors.white),
78 alignment: Alignment.center,
79 child: Text(
100 - S.of(context).frozen,
101 - style: TextStyle(
102 - color: amountColor,
103 - fontSize: 7,
104 - fontWeight: FontWeight.w600
105 - ),
106 - )
107 - )
108 - ],
109 - ),
110 - Text(
111 - _note,
112 - style: TextStyle(
113 - color: addressColor,
114 - fontSize: 12,
80 + S.of(context).frozen,
81 + style:
82 + TextStyle(color: amountColor, fontSize: 7, fontWeight: FontWeight.w600),
83 + ))
84 + ],
85 + ),
86 + Expanded(
87 + child: Row(
88 + crossAxisAlignment: CrossAxisAlignment.center,
89 + children: [
90 + AutoSizeText(
91 + address,
92 + style: TextStyle(
93 + color: addressColor,
94 + fontSize: 12,
95 + ),
96 + maxLines: 1,
97 ),
116 - maxLines: 1,
117 - overflow: TextOverflow.ellipsis
118 - )
119 - ]
120 - )
121 - )
98 + ],
99 + ),
100 + ),
101 + ])),
102 ],
123 - )
124 - );
103 + ));
104 }
126 -}
\ No newline at end of file
105 +}
lib/view_model/dashboard/balance_view_model.dart
+65 -11
@@ -1,5 +1,9 @@
1 +import 'package:cake_wallet/bitcoin/bitcoin.dart';
2 import 'package:cake_wallet/entities/fiat_api_mode.dart';
3 +import 'package:cw_bitcoin/bitcoin_amount_format.dart';
4 +import 'package:cw_bitcoin/electrum_balance.dart';
5 import 'package:cw_core/transaction_history.dart';
6 +import 'package:cw_core/unspent_coins_info.dart';
7 import 'package:cw_core/wallet_base.dart';
8 import 'package:cw_core/balance.dart';
9 import 'package:cw_core/crypto_currency.dart';
@@ -11,6 +15,7 @@ import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
15 import 'package:cake_wallet/store/app_store.dart';
16 import 'package:cake_wallet/store/settings_store.dart';
17 import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
18 +import 'package:hive/hive.dart';
19 import 'package:mobx/mobx.dart';
20
21 part 'balance_view_model.g.dart';
@@ -19,14 +24,18 @@ class BalanceRecord {
24 const BalanceRecord({
25 required this.availableBalance,
26 required this.additionalBalance,
27 + required this.frozenBalance,
28 required this.fiatAvailableBalance,
29 required this.fiatAdditionalBalance,
30 + required this.fiatFrozenBalance,
31 required this.asset,
32 required this.formattedAssetTitle});
33 final String fiatAdditionalBalance;
34 final String fiatAvailableBalance;
35 + final String fiatFrozenBalance;
36 final String additionalBalance;
37 final String availableBalance;
38 + final String frozenBalance;
39 final CryptoCurrency asset;
40 final String formattedAssetTitle;
41 }
@@ -135,6 +144,32 @@ abstract class BalanceViewModelBase with Store {
144 return walletBalance.formattedAvailableBalance;
145 }
146
147 + @computed
148 + String get frozenBalance {
149 + final walletBalance = _walletBalance;
150 +
151 + if (displayMode == BalanceDisplayMode.hiddenBalance) {
152 + return '---';
153 + }
154 +
155 + return getFormattedFrozenBalance(walletBalance);
156 + }
157 +
158 + @computed
159 + String get frozenFiatBalance {
160 + final walletBalance = _walletBalance;
161 + final fiatCurrency = settingsStore.fiatCurrency;
162 +
163 + if (displayMode == BalanceDisplayMode.hiddenBalance) {
164 + return '---';
165 + }
166 +
167 + return _getFiatBalance(
168 + price: price,
169 + cryptoAmount: getFormattedFrozenBalance(walletBalance)) + ' ' + fiatCurrency.toString();
170 +
171 + }
172 +
173 @computed
174 String get additionalBalance {
175 final walletBalance = _walletBalance;
@@ -158,7 +193,7 @@ abstract class BalanceViewModelBase with Store {
193 return _getFiatBalance(
194 price: price,
195 cryptoAmount: walletBalance.formattedAvailableBalance) + ' ' + fiatCurrency.toString();
161 -
196 +
197 }
198
199 @computed
@@ -173,7 +208,7 @@ abstract class BalanceViewModelBase with Store {
208 return _getFiatBalance(
209 price: price,
210 cryptoAmount: walletBalance.formattedAdditionalBalance) + ' ' + fiatCurrency.toString();
176 -
211 +
212 }
213
214 @computed
@@ -183,8 +218,10 @@ abstract class BalanceViewModelBase with Store {
218 return MapEntry(key, BalanceRecord(
219 availableBalance: '---',
220 additionalBalance: '---',
221 + frozenBalance: '---',
222 fiatAdditionalBalance: isFiatDisabled ? '' : '---',
223 fiatAvailableBalance: isFiatDisabled ? '' : '---',
224 + fiatFrozenBalance: isFiatDisabled ? '' : '---',
225 asset: key,
226 formattedAssetTitle: _formatterAsset(key)));
227 }
@@ -207,13 +244,25 @@ abstract class BalanceViewModelBase with Store {
244 price: price,
245 cryptoAmount: value.formattedAvailableBalance));
246
210 - return MapEntry(key, BalanceRecord(
211 - availableBalance: value.formattedAvailableBalance,
212 - additionalBalance: value.formattedAdditionalBalance,
213 - fiatAdditionalBalance: additionalFiatBalance,
214 - fiatAvailableBalance: availableFiatBalance,
215 - asset: key,
216 - formattedAssetTitle: _formatterAsset(key)));
247 +
248 + final frozenFiatBalance = isFiatDisabled ? '' : (fiatCurrency.toString()
249 + + ' '
250 + + _getFiatBalance(
251 + price: price,
252 + cryptoAmount: getFormattedFrozenBalance(value)));
253 +
254 +
255 + return MapEntry(
256 + key,
257 + BalanceRecord(
258 + availableBalance: value.formattedAvailableBalance,
259 + additionalBalance: value.formattedAdditionalBalance,
260 + frozenBalance: getFormattedFrozenBalance(value),
261 + fiatAdditionalBalance: additionalFiatBalance,
262 + fiatAvailableBalance: availableFiatBalance,
263 + fiatFrozenBalance: frozenFiatBalance,
264 + asset: key,
265 + formattedAssetTitle: _formatterAsset(key)));
266 });
267 }
268
@@ -290,7 +339,7 @@ abstract class BalanceViewModelBase with Store {
339 }
340
341 String _getFiatBalance({required double price, String? cryptoAmount}) {
293 - if (cryptoAmount == null) {
342 + if (cryptoAmount == null || cryptoAmount.isEmpty) {
343 return '0.00';
344 }
345
@@ -306,10 +355,15 @@ abstract class BalanceViewModelBase with Store {
355 return assetStringified.replaceFirst('X', 'x');
356 }
357
309 - return asset.toString();
358 + return asset.toString();
359 default:
360 return asset.toString();
361 }
362 }
363 +
364 +
365 + String getFormattedFrozenBalance(Balance walletBalance) =>
366 + walletBalance is ElectrumBalance ? walletBalance.formattedFrozenBalance : '';
367 +
368 }
369
lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
+52 -24
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart';
2 import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
3 import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
4 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
@@ -5,7 +6,9 @@ import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
7 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
8 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_switch_item.dart';
9 +import 'package:cw_core/wallet_type.dart';
10 import 'package:mobx/mobx.dart';
11 +import 'package:url_launcher/url_launcher.dart';
12
13 part 'unspent_coins_details_view_model.g.dart';
14
@@ -13,21 +16,14 @@ class UnspentCoinsDetailsViewModel = UnspentCoinsDetailsViewModelBase
16 with _$UnspentCoinsDetailsViewModel;
17
18 abstract class UnspentCoinsDetailsViewModelBase with Store {
16 - UnspentCoinsDetailsViewModelBase({
17 - required this.unspentCoinsItem,
18 - required this.unspentCoinsListViewModel})
19 + UnspentCoinsDetailsViewModelBase(
20 + {required this.unspentCoinsItem, required this.unspentCoinsListViewModel})
21 : items = <TransactionDetailsListItem>[],
22 isFrozen = unspentCoinsItem.isFrozen,
23 note = unspentCoinsItem.note {
24 items = [
23 - StandartListItem(
24 - title: S.current.transaction_details_amount,
25 - value: unspentCoinsItem.amount
26 - ),
27 - StandartListItem(
28 - title: S.current.widgets_address,
29 - value: unspentCoinsItem.address
30 - ),
25 + StandartListItem(title: S.current.transaction_details_amount, value: unspentCoinsItem.amount),
26 + StandartListItem(title: S.current.widgets_address, value: unspentCoinsItem.address),
27 TextFieldListItem(
28 title: S.current.note_tap_to_change,
29 value: note,
@@ -36,21 +32,53 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
32 unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
33 }),
34 UnspentCoinsSwitchItem(
39 - title: S.current.freeze,
40 - value: '',
41 - switchValue: () => isFrozen,
42 - onSwitchValueChange: (value) async {
43 - isFrozen = value;
44 - unspentCoinsItem.isFrozen = value;
45 - if (value) {
46 - unspentCoinsItem.isSending = !value;
47 - }
48 - await unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
49 - }
50 - )
35 + title: S.current.freeze,
36 + value: '',
37 + switchValue: () => isFrozen,
38 + onSwitchValueChange: (value) async {
39 + isFrozen = value;
40 + unspentCoinsItem.isFrozen = value;
41 + if (value) {
42 + unspentCoinsItem.isSending = !value;
43 + }
44 + await unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
45 + }),
46 + BlockExplorerListItem(
47 + title: S.current.view_in_block_explorer,
48 + value: _explorerDescription(unspentCoinsListViewModel.wallet.type),
49 + onTap: () {
50 + try {
51 + final url = Uri.parse(
52 + _explorerUrl(unspentCoinsListViewModel.wallet.type, unspentCoinsItem.hash));
53 + return launchUrl(url);
54 + } catch (e) {}
55 +
56 + })
57 ];
58 }
59
60 + String _explorerUrl(WalletType type, String txId) {
61 + switch (type) {
62 + case WalletType.bitcoin:
63 + return 'https://ordinals.com/tx/${txId}';
64 + case WalletType.litecoin:
65 + return 'https://litecoin.earlyordies.com/tx/${txId}';
66 + default:
67 + return '';
68 + }
69 + }
70 +
71 + String _explorerDescription(WalletType type) {
72 + switch (type) {
73 + case WalletType.bitcoin:
74 + return S.current.view_transaction_on + 'Ordinals.com';
75 + case WalletType.litecoin:
76 + return S.current.view_transaction_on + 'Earlyordies.com';
77 + default:
78 + return '';
79 + }
80 + }
81 +
82 @observable
83 bool isFrozen;
84
@@ -60,4 +88,4 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
88 final UnspentCoinsItem unspentCoinsItem;
89 final UnspentCoinsListViewModel unspentCoinsListViewModel;
90 List<TransactionDetailsListItem> items;
63 -}
\ No newline at end of file
91 +}
lib/view_model/unspent_coins/unspent_coins_item.dart
+9 -1
@@ -11,7 +11,9 @@ abstract class UnspentCoinsItemBase with Store {
11 required this.hash,
12 required this.isFrozen,
13 required this.note,
14 - required this.isSending});
14 + required this.isSending,
15 + required this.amountRaw,
16 + required this.vout});
17
18 @observable
19 String address;
@@ -30,4 +32,10 @@ abstract class UnspentCoinsItemBase with Store {
32
33 @observable
34 bool isSending;
35 +
36 + @observable
37 + int amountRaw;
38 +
39 + @observable
40 + int vout;
41 }
\ No newline at end of file
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+49 -28
@@ -1,60 +1,81 @@
1 -//import 'package:cw_bitcoin/bitcoin_amount_format.dart';
2 -//import 'package:cw_bitcoin/electrum_wallet.dart';
1 import 'package:cw_core/unspent_coins_info.dart';
2 import 'package:cake_wallet/bitcoin/bitcoin.dart';
3 import 'package:cw_core/wallet_base.dart';
4 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
7 -import 'package:flutter/foundation.dart';
5 import 'package:hive/hive.dart';
6 import 'package:mobx/mobx.dart';
7 +import 'package:collection/collection.dart';
8
9 part 'unspent_coins_list_view_model.g.dart';
10
11 class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel;
12
13 abstract class UnspentCoinsListViewModelBase with Store {
16 - UnspentCoinsListViewModelBase({
17 - required this.wallet,
18 - required Box<UnspentCoinsInfo> unspentCoinsInfo})
19 - : _unspentCoinsInfo = unspentCoinsInfo {
14 + UnspentCoinsListViewModelBase(
15 + {required this.wallet, required Box<UnspentCoinsInfo> unspentCoinsInfo})
16 + : _unspentCoinsInfo = unspentCoinsInfo {
17 bitcoin!.updateUnspents(wallet);
18 }
19
20 WalletBase wallet;
24 - Box<UnspentCoinsInfo> _unspentCoinsInfo;
21 + final Box<UnspentCoinsInfo> _unspentCoinsInfo;
22
23 @computed
27 - ObservableList<UnspentCoinsItem> get items => ObservableList.of(bitcoin!.getUnspents(wallet).map((elem) {
28 - final amount = bitcoin!.formatterBitcoinAmountToString(amount: elem.value) +
29 - ' ${wallet.currency.title}';
30 -
31 - final info = _unspentCoinsInfo.values
32 - .firstWhere((element) => element.walletId == wallet.id && element.hash == elem.hash);
33 -
34 - return UnspentCoinsItem(
35 - address: elem.address,
36 - amount: amount,
37 - hash: elem.hash,
38 - isFrozen: elem.isFrozen,
39 - note: info.note,
40 - isSending: elem.isSending
41 - );
42 - }));
24 + ObservableList<UnspentCoinsItem> get items =>
25 + ObservableList.of(bitcoin!.getUnspents(wallet).map((elem) {
26 + final amount = bitcoin!.formatterBitcoinAmountToString(amount: elem.value) +
27 + ' ${wallet.currency.title}';
28 +
29 + final info = getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout);
30 +
31 + return UnspentCoinsItem(
32 + address: elem.address,
33 + amount: amount,
34 + hash: elem.hash,
35 + isFrozen: info?.isFrozen ?? false,
36 + note: info?.note ?? '',
37 + isSending: info?.isSending ?? true,
38 + amountRaw: elem.value,
39 + vout: elem.vout);
40 + }));
41
42 Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
43 try {
46 - final info = _unspentCoinsInfo.values
47 - .firstWhere((element) => element.walletId.contains(wallet.id) &&
48 - element.hash.contains(item.hash));
44 + final info = getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout);
45 + if (info == null) {
46 + final newInfo = UnspentCoinsInfo(
47 + walletId: wallet.id,
48 + hash: item.hash,
49 + address: item.address,
50 + value: item.amountRaw,
51 + vout: item.vout,
52 + isFrozen: item.isFrozen,
53 + isSending: item.isSending,
54 + noteRaw: item.note);
55
56 + await _unspentCoinsInfo.add(newInfo);
57 + bitcoin!.updateUnspents(wallet);
58 + wallet.updateBalance();
59 + return;
60 + }
61 info.isFrozen = item.isFrozen;
62 info.isSending = item.isSending;
63 info.note = item.note;
64
65 await info.save();
66 bitcoin!.updateUnspents(wallet);
67 + wallet.updateBalance();
68 } catch (e) {
69 print(e.toString());
70 }
71 }
60 -}
\ No newline at end of file
72 +
73 + UnspentCoinsInfo? getUnspentCoinInfo(String hash, String address, int value, int vout) {
74 + return _unspentCoinsInfo.values.firstWhereOrNull((element) =>
75 + element.walletId == wallet.id &&
76 + element.hash == hash &&
77 + element.address == address &&
78 + element.value == value &&
79 + element.vout == vout);
80 + }
81 +}
res/values/strings_ar.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info":"من فضلك لا تنس تحديد علامة الوجهة أثناء إرسال معاملة XRP للتبادل",
480
481 "exchange_incorrect_current_wallet_for_xmr":"إذا كنت ترغب في استبدال XMR من رصيد Cake Wallet Monero ، فيرجى التبديل إلى محفظة Monero أولاً.",
482 - "confirmed":"مؤكد",
483 - "unconfirmed":"غير مؤكد",
482 + "confirmed":"رصيد مؤكد",
483 + "unconfirmed":"رصيد غير مؤكد",
484 "displayable":"قابل للعرض",
485
486 "submit_request":"تقديم طلب",
@@ -685,6 +685,7 @@
685 "error_dialog_content": "عفوًا ، لقد حصلنا على بعض الخطأ.\n\nيرجى إرسال تقرير التعطل إلى فريق الدعم لدينا لتحسين التطبيق.",
686 "decimal_places_error": "عدد كبير جدًا من المنازل العشرية",
687 "edit_node": "تحرير العقدة",
688 + "frozen_balance": "الرصيد المجمد",
689 "invoice_details": "تفاصيل الفاتورة",
690 "donation_link_details": "تفاصيل رابط التبرع",
691 "anonpay_description": "توليد ${type}. يمكن للمستلم ${method} بأي عملة مشفرة مدعومة ، وستتلقى أموالاً في هذه",
res/values/strings_bg.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Не забравяйте да дадете Destination Tag-а, когато изпращате XRP транзакцията за обмена",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Ако искате да обмените XMR от своя Cake Wallet Monero баланс, първо изберете своя Monero портфейл.",
482 - "confirmed" : "Потвърдено",
483 - "unconfirmed" : "Непотвърдено",
482 + "confirmed" : "Потвърден баланс",
483 + "unconfirmed" : "Непотвърден баланс",
484 "displayable" : "Възможност за показване",
485
486 "submit_request" : "изпращане на заявка",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Получихме грешка.\n\nМоля, изпратете доклада до нашия отдел поддръжка, за да подобрим приложението.",
688 "decimal_places_error": "Твърде много знаци след десетичната запетая",
689 "edit_node": "Редактиране на възел",
690 + "frozen_balance": "Замразен баланс",
691 "invoice_details": "IДанни за фактура",
692 "donation_link_details": "Подробности за връзката за дарение",
693 "anonpay_description": "Генерирайте ${type}. Получателят може да ${method} с всяка поддържана криптовалута и вие ще получите средства в този портфейл.",
res/values/strings_cs.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Prosím nezapomeňte zadat Destination Tag, když posíláte XRP transakce ke směně",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Pokud chcete směnit XMR z Monero částky v Cake Wallet, prosím přepněte se nejprve do své Monero peněženky.",
482 - "confirmed" : "Potvrzeno",
483 - "unconfirmed" : "Nepotvrzeno",
482 + "confirmed" : "Potvrzený zůstatek",
483 + "unconfirmed" : "Nepotvrzený zůstatek",
484 "displayable" : "Zobrazitelné",
485
486 "submit_request" : "odeslat požadavek",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Nastala chyba.\n\nProsím odešlete zprávu o chybě naší podpoře, aby mohli zajistit opravu.",
688 "decimal_places_error": "Příliš mnoho desetinných míst",
689 "edit_node": "Upravit uzel",
690 + "frozen_balance": "Zmrazená bilance",
691 "invoice_details": "detaily faktury",
692 "donation_link_details": "Podrobnosti odkazu na darování",
693 "anonpay_description": "Vygenerujte ${type}. Příjemce může ${method} s jakoukoli podporovanou kryptoměnou a vy obdržíte prostředky v této peněžence.",
res/values/strings_de.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Wenn Sie XMR von Ihrem Cake Wallet Monero-Guthaben umtauschen möchten, wechseln Sie bitte zuerst zu Ihrer Monero-Wallet.",
482 - "confirmed" : "Bestätigt",
483 - "unconfirmed" : "Unbestätigt",
482 + "confirmed" : "Bestätigter Saldo",
483 + "unconfirmed" : "Unbestätigter Saldo",
484 "displayable" : "Anzeigebar",
485
486 "submit_request" : "Eine Anfrage stellen",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern.",
688 "decimal_places_error": "Zu viele Nachkommastellen",
689 "edit_node": "Knoten bearbeiten",
690 + "frozen_balance": "Gefrorenes Gleichgewicht",
691 "invoice_details": "Rechnungs-Details",
692 "donation_link_details": "Details zum Spendenlink",
693 "anonpay_description": "Generieren Sie ${type}. Der Empfänger kann ${method} mit jeder unterstützten Kryptowährung verwenden, und Sie erhalten Geld in dieser Brieftasche.",
res/values/strings_en.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Please don’t forget to specify the Destination Tag while sending the XRP transaction for the exchange",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "If you want to exchange XMR from your Cake Wallet Monero balance, please switch to your Monero wallet first.",
482 - "confirmed" : "Confirmed",
483 - "unconfirmed" : "Unconfirmed",
482 + "confirmed" : "Confirmed Balance",
483 + "unconfirmed" : "Unconfirmed Balance",
484 "displayable" : "Displayable",
485
486 "submit_request" : "submit a request",
@@ -697,6 +697,7 @@
697 "onion_link": "Onion link",
698 "decimal_places_error": "Too many decimal places",
699 "edit_node": "Edit Node",
700 + "frozen_balance": "Frozen Balance",
701 "settings": "Settings",
702 "sell_monero_com_alert_content": "Selling Monero is not supported yet",
703 "error_text_input_below_minimum_limit" : "Amount is less than the minimum",
res/values/strings_es.arb
+4 -3
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "No olvide especificar la etiqueta de destino al enviar la transacción XRP para el intercambio",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Si desea intercambiar XMR de su saldo de Cake Wallet Monero, primero cambie a su billetera Monero.",
482 - "confirmed" : "Confirmada",
483 - "unconfirmed" : "Inconfirmado",
482 + "confirmed" : "Saldo confirmado",
483 + "unconfirmed" : "Saldo no confirmado",
484 "displayable" : "Visualizable",
485
486 "submit_request" : "presentar una solicitud",
@@ -686,7 +686,8 @@
686 "do_not_send": "no enviar",
687 "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación.",
688 "decimal_places_error": "Demasiados lugares decimales",
689 - "edit_node": "Edit Node",
689 + "edit_node": "Editar nodo",
690 + "frozen_balance": "Balance congelado",
691 "invoice_details": "Detalles de la factura",
692 "donation_link_details": "Detalles del enlace de donación",
693 "anonpay_description": "Genera ${type}. El destinatario puede ${method} con cualquier criptomoneda admitida, y recibirá fondos en esta billetera.",
res/values/strings_fr.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Merci de ne pas oublier de spécifier le tag de destination lors de l'envoi de la transaction XRP de l'échange",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Si vous souhaitez échanger des XMR du solde Monero de votre Cake Wallet, merci de sélectionner votre portefeuille (wallet) Monero au préalable.",
482 - "confirmed" : "Confirmé",
483 - "unconfirmed" : "Non confirmé",
482 + "confirmed" : "Solde confirmé",
483 + "unconfirmed" : "Solde non confirmé",
484 "displayable" : "Visible",
485
486 "submit_request" : "soumettre une requête",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Oups, nous avons rencontré une erreur.\n\nMerci d'envoyer le rapport d'erreur à notre équipe d'assistance afin de nous permettre d'améliorer l'application.",
688 "decimal_places_error": "Trop de décimales",
689 "edit_node": "Modifier le nœud",
690 + "frozen_balance": "Équilibre gelé",
691 "invoice_details": "Détails de la facture",
692 "donation_link_details": "Détails du lien de don",
693 "anonpay_description": "Générez ${type}. Le destinataire peut ${method} avec n'importe quelle crypto-monnaie prise en charge, et vous recevrez des fonds dans ce portefeuille (wallet).",
res/values/strings_hi.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "एक्सचेंज के लिए एक्सआरपी लेनदेन भेजते समय कृपया गंतव्य टैग निर्दिष्ट करना न भूलें",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "यदि आप अपने केक वॉलेट मोनेरो बैलेंस से एक्सएमआर का आदान-प्रदान करना चाहते हैं, तो कृपया अपने मोनेरो वॉलेट में जाएं।",
482 - "confirmed" : "की पुष्टि की",
483 - "unconfirmed" : "अपुष्ट",
482 + "confirmed" : "पुष्टि की गई शेष राशिी",
483 + "unconfirmed" : "अपुष्ट शेष राशि",
484 "displayable" : "प्रदर्शन योग्य",
485
486 "submit_request" : "एक अनुरोध सबमिट करें",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।",
688 "decimal_places_error": "बहुत अधिक दशमलव स्थान",
689 "edit_node": "नोड संपादित करें",
690 + "frozen_balance": "जमे हुए संतुलन",
691 "invoice_details": "चालान विवरण",
692 "donation_link_details": "दान लिंक विवरण",
693 "anonpay_description": "${type} उत्पन्न करें। प्राप्तकर्ता किसी भी समर्थित क्रिप्टोकरेंसी के साथ ${method} कर सकता है, और आपको इस वॉलेट में धन प्राप्त होगा।",
res/values/strings_hr.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Molimo ne zaboravite navesti odredišnu oznaku prilikom slanja XRP transakcije na razmjenu",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Ako želite razmijeniti XMR s vlastitog Monero računa na Cake Wallet novčaniku, molimo prvo se prebacite na svoj Monero novčanik.",
482 - "confirmed" : "Potvrđeno",
483 - "unconfirmed" : "Nepotvrđeno",
482 + "confirmed" : "Potvrđeno stanje",
483 + "unconfirmed" : "Nepotvrđeno stanje",
484 "displayable" : "Dostupno za prikaz",
485
486 "submit_request" : "podnesi zahtjev",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju.",
688 "decimal_places_error": "Previše decimalnih mjesta",
689 "edit_node": "Uredi čvor",
690 + "frozen_balance": "Zamrznuti saldo",
691 "invoice_details": "Podaci o fakturi",
692 "donation_link_details": "Detalji veza za donacije",
693 "anonpay_description": "Generiraj ${type}. Primatelj može ${method} s bilo kojom podržanom kriptovalutom, a vi ćete primiti sredstva u ovaj novčanik.",
res/values/strings_id.arb
+3 -2
@@ -466,8 +466,8 @@
466 "xrp_extra_info" : "Jangan lupa untuk menentukan Tag Tujuan saat mengirim transaksi XRP untuk pertukaran",
467
468 "exchange_incorrect_current_wallet_for_xmr" : "Jika Anda ingin menukar XMR dari saldo Monero Cake Wallet Anda, silakan beralih ke dompet Monero Anda terlebih dahulu.",
469 - "confirmed" : "Dikonfirmasi",
470 - "unconfirmed" : "Tidak dikonfirmasi",
469 + "confirmed" : "Saldo Terkonfirmasi",
470 + "unconfirmed" : "Saldo Belum Dikonfirmasi",
471 "displayable" : "Dapat ditampilkan",
472
473 "submit_request" : "kirim permintaan",
@@ -669,6 +669,7 @@
669 "contact_list_wallets": "Dompet Saya",
670 "decimal_places_error": "Terlalu banyak tempat desimal",
671 "edit_node": "Sunting Node",
672 + "frozen_balance": "Saldo Beku",
673 "invoice_details": "Detail faktur",
674 "donation_link_details": "Detail tautan donasi",
675 "anonpay_description": "Hasilkan ${type}. Penerima dapat ${method} dengan cryptocurrency apa pun yang didukung, dan Anda akan menerima dana di dompet ini.",
res/values/strings_it.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Gentilmente ricorda di indicare il Tag di Destinazione quando invii una transazione XRP per lo scambio",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Se vuoi scambiare XMR dal tuo saldo Cake Wallet Monero, gentilmente passa al tuo portafoglio Monero.",
482 - "confirmed" : "Confermato",
483 - "unconfirmed" : "Non confermato",
482 + "confirmed" : "Saldo confermato",
483 + "unconfirmed" : "Saldo non confermato",
484 "displayable" : "Visualizzabile",
485
486 "submit_request" : "invia una richiesta",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione.",
688 "decimal_places_error": "Troppe cifre decimali",
689 "edit_node": "Modifica nodo",
690 + "frozen_balance": "Equilibrio congelato",
691 "invoice_details": "Dettagli della fattura",
692 "donation_link_details": "Dettagli del collegamento alla donazione",
693 "anonpay_description": "Genera ${type}. Il destinatario può ${method} con qualsiasi criptovaluta supportata e riceverai fondi in questo portafoglio.",
res/values/strings_ja.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "取引所のXRPトランザクションを送信するときに、宛先タグを指定することを忘れないでください",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Cake Wallet Moneroの残高からXMRを交換する場合は、最初にMoneroウォレットに切り替えてください。",
482 - "confirmed" : "確認済み",
483 - "unconfirmed" : "未確認",
482 + "confirmed" : "確認済み残高",
483 + "unconfirmed" : "残高未確認",
484 "displayable" : "表示可能",
485
486 "submit_request" : "リクエストを送信する",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "エラーが発生しました。\n\nアプリケーションを改善するために、クラッシュ レポートをサポート チームに送信してください。",
688 "decimal_places_error": "小数点以下の桁数が多すぎる",
689 "edit_node": "ノードを編集",
690 + "frozen_balance": "冷凍残高",
691 "invoice_details": "請求の詳細",
692 "donation_link_details": "寄付リンクの詳細",
693 "anonpay_description": "${type} を生成します。受取人はサポートされている任意の暗号通貨で ${method} でき、あなたはこのウォレットで資金を受け取ります。",
res/values/strings_ko.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "교환을 위해 XRP 트랜잭션을 보내는 동안 대상 태그를 지정하는 것을 잊지 마십시오",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Cake Wallet Monero 잔액에서 XMR을 교환하려면 먼저 Monero 지갑으로 전환하십시오.",
482 - "confirmed" : "확인",
483 - "unconfirmed" : "미확인",
482 + "confirmed" : "확인된 잔액",
483 + "unconfirmed" : "확인되지 않은 잔액",
484 "displayable" : "표시 가능",
485
486 "submit_request" : "요청을 제출",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오.",
688 "decimal_places_error": "소수점 이하 자릿수가 너무 많습니다.",
689 "edit_node": "노드 편집",
690 + "frozen_balance": "얼어붙은 균형",
691 "invoice_details": "인보이스 세부정보",
692 "donation_link_details": "기부 링크 세부정보",
693 "anonpay_description": "${type} 생성. 수신자는 지원되는 모든 암호화폐로 ${method}할 수 있으며 이 지갑에서 자금을 받게 됩니다.",
res/values/strings_my.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "လဲလှယ်မှုအတွက် XRP ငွေလွှဲပို့နေစဉ် Destination Tag ကို သတ်မှတ်ရန် မမေ့ပါနှင့်",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "သင်၏ Cake Wallet Monero လက်ကျန်မှ XMR ကိုလဲလှယ်လိုပါက၊ သင်၏ Monero ပိုက်ဆံအိတ်သို့ ဦးစွာပြောင်းပါ။",
482 - "confirmed" : "အတည်ပြုခဲ့သည်။",
483 - "unconfirmed" : "အတည်မပြုနိုင်ပါ။",
482 + "confirmed" : "အတည်ပြုထားသော လက်ကျန်ငွေ",
483 + "unconfirmed" : "အတည်မပြုနိုင်သော လက်ကျန်ငွေ",
484 "displayable" : "ပြသနိုင်သည်။",
485
486 "submit_request" : "တောင်းဆိုချက်တစ်ခုတင်ပြပါ။",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "အိုး၊ ကျွန်ုပ်တို့တွင် အမှားအယွင်းအချို့ရှိသည်။\n\nအပလီကေးရှင်းကို ပိုမိုကောင်းမွန်စေရန်အတွက် ပျက်စီးမှုအစီရင်ခံစာကို ကျွန်ုပ်တို့၏ပံ့ပိုးကူညီရေးအဖွဲ့ထံ ပေးပို့ပါ။",
688 "decimal_places_error": "ဒဿမနေရာများ များလွန်းသည်။",
689 "edit_node": "Node ကို တည်းဖြတ်ပါ။",
690 + "frozen_balance": "ေးခဲမှူ",
691 "invoice_details": "ပြေစာအသေးစိတ်",
692 "donation_link_details": "လှူဒါန်းရန်လင့်ခ်အသေးစိတ်",
693 "anonpay_description": "${type} ကို ဖန်တီးပါ။ လက်ခံသူက ${method} ကို ပံ့ပိုးပေးထားသည့် cryptocurrency တစ်ခုခုဖြင့် လုပ်ဆောင်နိုင်ပြီး၊ သင်သည် ဤပိုက်ဆံအိတ်တွင် ရံပုံငွေများ ရရှိမည်ဖြစ်သည်။",
res/values/strings_nl.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Vergeet niet om de Destination Tag op te geven tijdens het verzenden van de XRP-transactie voor de uitwisseling",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Als u XMR wilt omwisselen van uw Cake Wallet Monero-saldo, moet u eerst overschakelen naar uw Monero-portemonnee.",
482 - "confirmed" : "Bevestigd",
483 - "unconfirmed" : "Niet bevestigd",
482 + "confirmed" : "Bevestigd saldo",
483 + "unconfirmed" : "Onbevestigd saldo",
484 "displayable" : "Weer te geven",
485
486 "submit_request" : "een verzoek indienen",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren.",
688 "decimal_places_error": "Te veel decimalen",
689 "edit_node": "Knooppunt bewerken",
690 + "frozen_balance": "Bevroren saldo",
691 "invoice_details": "Factuurgegevens",
692 "donation_link_details": "Details van de donatielink",
693 "anonpay_description": "Genereer ${type}. De ontvanger kan ${method} gebruiken met elke ondersteunde cryptocurrency en u ontvangt geld in deze portemonnee",
res/values/strings_pl.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Jeśli chcesz wymienić XMR z salda Cake Wallet Monero, najpierw przełącz się na portfel Monero.",
482 - "confirmed" : "Potwierdzony",
483 - "unconfirmed" : "Niepotwierdzony",
482 + "confirmed" : "Potwierdzone saldo",
483 + "unconfirmed" : "Niepotwierdzone saldo",
484 "displayable" : "Wyświetlane",
485
486 "submit_request" : "Złóż wniosek",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację.",
688 "decimal_places_error": "Za dużo miejsc dziesiętnych",
689 "edit_node": "Edytuj węzeł",
690 + "frozen_balance": "Zamrożona równowaga",
691 "invoice_details": "Dane do faktury",
692 "donation_link_details": "Szczegóły linku darowizny",
693 "anonpay_description": "Wygeneruj ${type}. Odbiorca może ${method} z dowolną obsługiwaną kryptowalutą, a Ty otrzymasz środki w tym portfelu.",
res/values/strings_pt.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Não se esqueça de especificar a etiqueta de destino ao enviar a transação XRP para a troca",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Se você deseja trocar o XMR de seu saldo da Carteira Monero Cake, troque primeiro para sua carteira Monero.",
482 - "confirmed" : "Confirmada",
483 - "unconfirmed" : "Não confirmado",
482 + "confirmed" : "Saldo Confirmado",
483 + "unconfirmed" : "Saldo não confirmado",
484 "displayable" : "Exibível",
485
486 "submit_request" : "enviar um pedido",
@@ -686,6 +686,7 @@
686 "error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo.",
687 "decimal_places_error": "Muitas casas decimais",
688 "edit_node": "Editar nó",
689 + "frozen_balance": "Saldo Congelado",
690 "invoice_details": "Detalhes da fatura",
691 "donation_link_details": "Detalhes do link de doação",
692 "anonpay_description": "Gere ${type}. O destinatário pode ${method} com qualquer criptomoeda suportada e você receberá fundos nesta carteira.",
res/values/strings_ru.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Не забудьте указать целевой тег при отправке транзакции XRP для обмена",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Если вы хотите обменять XMR со своего баланса Monero в Cake Wallet, сначала переключитесь на свой кошелек Monero.",
482 - "confirmed" : "Подтверждено",
483 - "unconfirmed" : "Неподтвержденный",
482 + "confirmed" : "Подтвержденный баланс",
483 + "unconfirmed" : "Неподтвержденный баланс",
484 "displayable" : "Отображаемый",
485
486 "submit_request" : "отправить запрос",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше.",
688 "decimal_places_error": "Слишком много десятичных знаков",
689 "edit_node": "Редактировать узел",
690 + "frozen_balance": "Замороженный баланс",
691 "invoice_details": "Детали счета",
692 "donation_link_details": "Информация о ссылке для пожертвований",
693 "anonpay_description": "Создайте ${type}. Получатель может использовать ${method} с любой поддерживаемой криптовалютой, и вы получите средства на этот кошелек.",
res/values/strings_th.arb
+3 -2
@@ -477,8 +477,8 @@
477 "xrp_extra_info": "โปรดอย่าลืมระบุ Destination Tag ในขณะที่ส่งธุรกรรม XRP สำหรับการแลกเปลี่ยน",
478
479 "exchange_incorrect_current_wallet_for_xmr" : "หากคุณต้องการแลกเปลี่ยน XMR จากยอดคงเหลือ Monero ใน Cake Wallet ของคุณ กรุณาเปลี่ยนเป็นกระเป๋า Monero ก่อน",
480 - "confirmed" : "ได้รับการยืนยัน",
481 - "unconfirmed" : "ยังไม่ได้รับการยืนยัน",
480 + "confirmed" : "ยอดคงเหลือที่ยืนยันแล้ว",
481 + "unconfirmed" : "ยอดคงเหลือที่ไม่ได้รับการยืนยัน",
482 "displayable" : "สามารถแสดงได้",
483
484 "submit_request" : "ส่งคำขอ",
@@ -685,6 +685,7 @@
685 "error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น",
686 "decimal_places_error": "ทศนิยมมากเกินไป",
687 "edit_node": "แก้ไขโหนด",
688 + "frozen_balance": "ยอดคงเหลือแช่แข็ง",
689 "invoice_details": "รายละเอียดใบแจ้งหนี้",
690 "donation_link_details": "รายละเอียดลิงค์บริจาค",
691 "anonpay_description": "สร้าง ${type} ผู้รับสามารถ ${method} ด้วยสกุลเงินดิจิทัลที่รองรับ และคุณจะได้รับเงินในกระเป๋าสตางค์นี้",
res/values/strings_tr.arb
+3 -2
@@ -479,8 +479,8 @@
479 "xrp_extra_info" : "Lütfen takas için XRP işlemi gönderirken Hedef Etiketi (Destination Tag) belirtmeyi unutmayın",
480
481 "exchange_incorrect_current_wallet_for_xmr" : "Cake Wallet'daki Monero bakiyenizi kullanarak takas yapmak istiyorsan, lütfen önce Monero cüzdanına geç.",
482 - "confirmed" : "Onaylı",
483 - "unconfirmed" : "Onaylanmamış",
482 + "confirmed" : "Onaylanmış Bakiye",
483 + "unconfirmed" : "Onaylanmamış Bakiye",
484 "displayable" : "Gösterilebilir",
485
486 "submit_request" : "talep gönder",
@@ -687,6 +687,7 @@
687 "error_dialog_content": "Hay aksi, bir hatamız var.\n\nUygulamayı daha iyi hale getirmek için lütfen kilitlenme raporunu destek ekibimize gönderin.",
688 "decimal_places_error": "Çok fazla ondalık basamak",
689 "edit_node": "Düğümü Düzenle",
690 + "frozen_balance": "Dondurulmuş Bakiye",
691 "invoice_details": "fatura detayları",
692 "donation_link_details": "Bağış bağlantısı ayrıntıları",
693 "anonpay_description": "${type} oluşturun. Alıcı, desteklenen herhangi bir kripto para birimi ile ${method} yapabilir ve bu cüzdanda para alırsınız.",
res/values/strings_uk.arb
+3 -2
@@ -478,8 +478,8 @@
478 "xrp_extra_info" : "Будь ласка, не забудьте вказати тег призначення під час надсилання XRP-транзакції для обміну",
479
480 "exchange_incorrect_current_wallet_for_xmr" : "Якщо ви хочете обміняти XMR із вашого балансу Cake Wallet Monero, спочатку перейдіть на свій гаманець Monero.",
481 - "confirmed" : "Підтверджено",
482 - "unconfirmed" : "Непідтверджений",
481 + "confirmed" : "Підтверджений баланс",
482 + "unconfirmed" : "Непідтверджений баланс",
483 "displayable" : "Відображуваний",
484
485 "submit_request" : "надіслати запит",
@@ -686,6 +686,7 @@
686 "error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток.",
687 "decimal_places_error": "Забагато знаків після коми",
688 "edit_node": "Редагувати вузол",
689 + "frozen_balance": "Заморожений баланс",
690 "invoice_details": "Реквізити рахунку-фактури",
691 "donation_link_details": "Деталі посилання для пожертв",
692 "anonpay_description": "Згенерувати ${type}. Одержувач може ${method} будь-якою підтримуваною криптовалютою, і ви отримаєте кошти на цей гаманець.",
res/values/strings_ur.arb
+3 -2
@@ -481,8 +481,8 @@
481 "xrp_extra_info" : "ایکسچینج کے لیے XRP ٹرانزیکشن بھیجتے وقت ڈیسٹینیشن ٹیگ بتانا نہ بھولیں۔",
482
483 "exchange_incorrect_current_wallet_for_xmr" : "اگر آپ اپنے Cake والیٹ Monero بیلنس سے XMR کا تبادلہ کرنا چاہتے ہیں، تو براہ کرم پہلے اپنے Monero والیٹ پر جائیں۔",
484 - "confirmed" : "تصدیق شدہ",
485 - "unconfirmed" : "غیر تصدیق شدہ",
484 + "confirmed" : "تصدیق شدہ بیلنس",
485 + "unconfirmed" : "غیر تصدیق شدہ بیلنس",
486 "displayable" : "قابل نمائش",
487
488 "submit_request" : "درخواست بھیج دو",
@@ -688,6 +688,7 @@
688 "error_dialog_content" : "افوہ، ہمیں کچھ خرابی ملی۔\n\nایپلی کیشن کو بہتر بنانے کے لیے براہ کرم کریش رپورٹ ہماری سپورٹ ٹیم کو بھیجیں۔",
689 "decimal_places_error": "بہت زیادہ اعشاریہ جگہیں۔",
690 "edit_node": "نوڈ میں ترمیم کریں۔",
691 + "frozen_balance": "منجمد بیلنس",
692 "invoice_details": "رسید کی تفصیلات",
693 "donation_link_details": "عطیہ کے لنک کی تفصیلات",
694 "anonpay_description": "${type} بنائیں۔ وصول کنندہ کسی بھی تعاون یافتہ کرپٹو کرنسی کے ساتھ ${method} کرسکتا ہے، اور آپ کو اس بٹوے میں فنڈز موصول ہوں گے۔",
res/values/strings_zh.arb
+3 -2
@@ -478,8 +478,8 @@
478 "xrp_extra_info" : "发送用于交换的XRP交易时,请不要忘记指定目标Tag",
479
480 "exchange_incorrect_current_wallet_for_xmr" : "如果要从Cake Wallet Monero余额中兑换XMR,请先切换到Monero钱包。",
481 - "confirmed" : "已确认",
482 - "unconfirmed" : "未经证实",
481 + "confirmed" : "确认余额",
482 + "unconfirmed" : "未确认余额",
483 "displayable" : "可显示",
484
485 "submit_request" : "提交请求",
@@ -686,6 +686,7 @@
686 "error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队,以改进应用程序。",
687 "decimal_places_error": "小数位太多",
688 "edit_node": "编辑节点",
689 + "frozen_balance": "冻结余额",
690 "invoice_details": "发票明细",
691 "donation_link_details": "捐赠链接详情",
692 "anonpay_description": "生成 ${type}。收款人可以使用任何受支持的加密货币 ${method},您将在此钱包中收到资金。",