CAKE-345 | merged release-4.2.4 branch into current and resolved problems

OleksandrSobol committed Jul 22, 2021 at 19:48 UTC c14d021f072f2c378aa6ac860b22895a36b36348
8 files changed +98 -96
lib/bitcoin/electrum_wallet.dart
+26 -45
@@ -176,9 +176,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
176 throw BitcoinTransactionNoInputsException();
177 }
178
179 - final allAmountFee =
180 - calculateEstimatedFee(transactionCredentials.priority, null);
181 - final allAmount = balance.confirmed - allAmountFee;
179 + final allAmountFee = feeAmountForPriority(
180 + transactionCredentials.priority, inputs.length, sendItemList.length);
181 + final allAmount = allInputsAmount - allAmountFee;
182 +
183 var credentialsAmount = 0;
184 var amount = 0;
185 var fee = 0;
@@ -187,7 +188,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
188 final sendAllItems = sendItemList.where((item) => item.sendAll).toList();
189
190 if (sendAllItems?.isNotEmpty ?? false) {
190 - throw BitcoinTransactionWrongBalanceException();
191 + throw BitcoinTransactionWrongBalanceException(currency);
192 }
193
194 final nullAmountItems = sendItemList.where((item) =>
@@ -195,29 +196,37 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
196 .toList();
197
198 if (nullAmountItems?.isNotEmpty ?? false) {
198 - throw BitcoinTransactionWrongBalanceException();
199 + throw BitcoinTransactionWrongBalanceException(currency);
200 }
201
202 credentialsAmount = sendItemList.fold(0, (previousValue, element) =>
202 - previousValue + stringDoubleToBitcoinAmount(
203 - element.cryptoAmount.replaceAll(',', '.')));
203 + previousValue + stringDoubleToBitcoinAmount(
204 + element.cryptoAmount.replaceAll(',', '.')));
205 +
206 + if (credentialsAmount > allAmount) {
207 + throw BitcoinTransactionWrongBalanceException(currency);
208 + }
209
210 amount = allAmount - credentialsAmount < minAmount
206 - ? allAmount
207 - : credentialsAmount;
211 + ? allAmount
212 + : credentialsAmount;
213
214 fee = amount == allAmount
210 - ? allAmountFee
211 - : calculateEstimatedFee(transactionCredentials.priority, amount,
212 - outputsCount: sendItemList.length + 1);
215 + ? allAmountFee
216 + : calculateEstimatedFee(transactionCredentials.priority, amount,
217 + outputsCount: sendItemList.length + 1);
218 } else {
219 final sendItem = sendItemList.first;
220
221 credentialsAmount = !sendItem.sendAll
222 ? stringDoubleToBitcoinAmount(
218 - sendItem.cryptoAmount.replaceAll(',', '.'))
223 + sendItem.cryptoAmount.replaceAll(',', '.'))
224 : 0;
225
226 + if (credentialsAmount > allAmount) {
227 + throw BitcoinTransactionWrongBalanceException(currency);
228 + }
229 +
230 amount = sendItem.sendAll || allAmount - credentialsAmount < minAmount
231 ? allAmount
232 : credentialsAmount;
@@ -227,35 +236,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
236 : calculateEstimatedFee(transactionCredentials.priority, amount);
237 }
238
230 - if (fee == 0) {
231 - throw BitcoinTransactionWrongBalanceException();
232 - }
233 -
234 - final totalAmount = amount + fee;
235 -
236 - if (totalAmount > balance.confirmed) {
237 - throw BitcoinTransactionWrongBalanceException();
238 - }
239 -
240 - feeAmountForPriority(transactionCredentials.priority, inputs.length, 1);
241 - final allAmount = allInputsAmount - allAmountFee;
242 -
243 - final credentialsAmount = transactionCredentials.amount != null
244 - ? stringDoubleToBitcoinAmount(transactionCredentials.amount)
245 - : 0;
246 - final amount = transactionCredentials.amount == null ||
247 - allAmount - credentialsAmount < minAmount
248 - ? allAmount
249 - : credentialsAmount;
250 - final fee = transactionCredentials.amount == null || amount == allAmount
251 - ? allAmountFee
252 - : calculateEstimatedFee(transactionCredentials.priority, amount);
253 -
239 if (fee == 0) {
240 throw BitcoinTransactionWrongBalanceException(currency);
241 }
242
258 - final totalAmount = amount + fee;
243 + final totalAmount = amount + fee;
244
245 if (totalAmount > balance.confirmed || totalAmount > allInputsAmount) {
246 throw BitcoinTransactionWrongBalanceException(currency);
@@ -264,8 +249,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
249 final txb = bitcoin.TransactionBuilder(network: networkType);
250 final changeAddress = walletAddresses.address;
251 var leftAmount = totalAmount;
267 - final changeAddress = address;
268 - var leftAmount = totalAmount;
252 var totalInputAmount = 0;
253
254 inputs.clear();
@@ -288,8 +271,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
271
272 if (amount <= 0 || totalInputAmount < totalAmount) {
273 throw BitcoinTransactionWrongBalanceException(currency);
291 - if (amount <= 0 || totalInputAmount < amount) {
292 - throw BitcoinTransactionWrongBalanceException();
274 }
275
276 txb.setVersion(1);
@@ -298,8 +279,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
279 if (input.isP2wpkh) {
280 final p2wpkh = bitcoin
281 .P2WPKH(
301 - data: generatePaymentData(hd: hd, index: input.address.index),
302 - network: networkType)
282 + data: generatePaymentData(hd: hd, index: input.address.index),
283 + network: networkType)
284 .data;
285
286 txb.addInput(input.hash, input.vout, null, p2wpkh.output);
@@ -313,7 +294,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
294 ? amount
295 : stringDoubleToBitcoinAmount(item.cryptoAmount.replaceAll(',', '.'));
296
316 - txb.addOutput(
297 + txb.addOutput(
298 addressToOutputScript(item.address, networkType),
299 _amount);
300 });
lib/src/screens/exchange/exchange_page.dart
+1 -16
@@ -784,22 +784,7 @@ class ExchangePage extends BasePage {
784 BuildContext context, String domain, String ticker) async {
785 final parsedAddress = await parseAddressFromDomain(domain, ticker);
786
787 - switch (parsedAddress.parseFrom) {
788 - case ParseFrom.unstoppableDomains:
789 - showAddressAlert(
790 - context,
791 - S.of(context).address_detected,
792 - S.of(context).address_from_domain(parsedAddress.name));
793 - break;
794 - case ParseFrom.openAlias:
795 - showAddressAlert(
796 - context,
797 - S.of(context).openalias_alert_title,
798 - S.of(context).openalias_alert_content(parsedAddress.name));
799 - break;
800 - case ParseFrom.notParsed:
801 - break;
802 - }
787 + showAddressAlert(context, parsedAddress);
788
789 return parsedAddress.address;
790 }
lib/src/screens/send/send_page.dart
+4 -15
@@ -1,8 +1,4 @@
1 import 'dart:ui';
2 -import 'package:cake_wallet/entities/parsed_address.dart';
3 -import 'package:cake_wallet/entities/transaction_priority.dart';
4 -import 'package:cake_wallet/entities/parse_address_from_domain.dart';
5 -import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
2 import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
3 import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
4 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
@@ -83,7 +79,7 @@ class SendPage extends BasePage {
79 content: Column(
80 children: <Widget>[
81 Container(
86 - height: 445,
82 + height: 470,
83 child: Observer(
84 builder: (_) {
85 return PageView.builder(
@@ -219,16 +215,9 @@ class SendPage extends BasePage {
215 item.address =
216 template.address;
217 item.setCryptoAmount(template.amount);
222 - final record =
223 - await item.getOpenaliasRecord();
224 -
225 - if (record != null) {
226 - showAddressAlert(
227 - context,
228 - S.current.openalias_alert_title,
229 - S.current
230 - .openalias_alert_content(record.name));
231 - }
218 + final parsedAddress = await item
219 + .applyOpenaliasOrUnstoppableDomains();
220 + showAddressAlert(context, parsedAddress);
221 },
222 onRemove: () {
223 showPopUp<void>(
lib/src/screens/send/send_template_page.dart
-1
@@ -146,7 +146,6 @@ class SendTemplatePage extends BasePage {
146 .primaryTextTheme
147 .headline
148 .decorationColor),
149 - validator: sendTemplateViewModel.addressValidator,
149 ),
150 ),
151 Padding(
lib/src/screens/send/widgets/parse_address_from_domain_alert.dart
+18 -1
@@ -1,9 +1,26 @@
1 +import 'package:cake_wallet/entities/parsed_address.dart';
2 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
3 import 'package:cake_wallet/utils/show_pop_up.dart';
4 import 'package:flutter/material.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
6
6 -void showAddressAlert(BuildContext context, String title, String content) async {
7 +void showAddressAlert(BuildContext context, ParsedAddress parsedAddress) async {
8 + var title = '';
9 + var content = '';
10 +
11 + switch (parsedAddress.parseFrom) {
12 + case ParseFrom.unstoppableDomains:
13 + title = S.of(context).address_detected;
14 + content = S.of(context).address_from_domain(parsedAddress.name);
15 + break;
16 + case ParseFrom.openAlias:
17 + title = S.of(context).openalias_alert_title;
18 + content = S.of(context).openalias_alert_content(parsedAddress.name);
19 + break;
20 + case ParseFrom.notParsed:
21 + return;
22 + }
23 +
24 await showPopUp<void>(
25 context: context,
26 builder: (BuildContext context) {
lib/src/screens/send/widgets/send_card.dart
+37 -10
@@ -1,5 +1,6 @@
1 import 'dart:ui';
2 import 'package:cake_wallet/entities/transaction_priority.dart';
3 +import 'package:cake_wallet/routes.dart';
4 import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
5 import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
6 import 'package:cake_wallet/src/widgets/picker.dart';
@@ -79,7 +80,7 @@ class SendCardState extends State<SendCard>
80 )
81 ]),
82 child: Container(
82 - height: 445,
83 + height: 470,
84 decoration: BoxDecoration(
85 borderRadius: BorderRadius.only(
86 bottomLeft: Radius.circular(24),
@@ -140,6 +141,11 @@ class SendCardState extends State<SendCard>
141 .primaryTextTheme
142 .headline
143 .decorationColor),
144 + onPushPasteButton: (context) async {
145 + final parsedAddress =
146 + await item.applyOpenaliasOrUnstoppableDomains();
147 + showAddressAlert(context, parsedAddress);
148 + },
149 validator: sendViewModel.addressValidator,
150 ),
151 Observer(
@@ -393,7 +399,34 @@ class SendCardState extends State<SendCard>
399 ],
400 ),
401 ),
396 - ))
402 + )),
403 + if (sendViewModel.isElectrumWallet) Padding(
404 + padding: EdgeInsets.only(top: 6),
405 + child: GestureDetector(
406 + onTap: () => Navigator.of(context)
407 + .pushNamed(Routes.unspentCoinsList),
408 + child: Container(
409 + color: Colors.transparent,
410 + child: Row(
411 + mainAxisAlignment:
412 + MainAxisAlignment.spaceBetween,
413 + children: [
414 + Text(
415 + S.of(context).coin_control,
416 + style: TextStyle(
417 + fontSize: 12,
418 + fontWeight: FontWeight.w600,
419 + color: Colors.white)),
420 + Icon(
421 + Icons.arrow_forward_ios,
422 + size: 12,
423 + color: Colors.white,
424 + )
425 + ],
426 + )
427 + )
428 + )
429 + )
430 ],
431 )
432 ),
@@ -485,14 +518,8 @@ class SendCardState extends State<SendCard>
518
519 addressFocusNode.addListener(() async {
520 if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) {
488 - final record = await item.getOpenaliasRecord();
489 -
490 - if (record != null) {
491 - showAddressAlert(
492 - context,
493 - S.current.openalias_alert_title,
494 - S.current.openalias_alert_content(record.name));
495 - }
521 + final parsedAddress = await item.applyOpenaliasOrUnstoppableDomains();
522 + showAddressAlert(context, parsedAddress);
523 }
524 });
525
lib/view_model/send/send_item.dart
+8 -8
@@ -2,6 +2,8 @@ import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
2 import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
3 import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
4 import 'package:cake_wallet/entities/openalias_record.dart';
5 +import 'package:cake_wallet/entities/parse_address_from_domain.dart';
6 +import 'package:cake_wallet/entities/parsed_address.dart';
7 import 'package:cake_wallet/monero/monero_amount_format.dart';
8 import 'package:flutter/material.dart';
9 import 'package:intl/intl.dart';
@@ -184,15 +186,13 @@ abstract class SendItemBase with Store {
186 _cryptoNumberFormat.maximumFractionDigits = maximumFractionDigits;
187 }
188
187 - Future<OpenaliasRecord> getOpenaliasRecord() async {
188 - final formattedName = OpenaliasRecord.formatDomainName(address);
189 - final record = await OpenaliasRecord.fetchAddressAndName(formattedName);
189 + Future<ParsedAddress> applyOpenaliasOrUnstoppableDomains() async {
190 + final domain = address;
191 + final ticker = _wallet.currency.title.toLowerCase();
192 + final parsedAddress = await parseAddressFromDomain(domain, ticker);
193
191 - if (record == null || record.address.contains(formattedName)) {
192 - return null;
193 - }
194 + address = parsedAddress.address;
195
195 - address = record.address;
196 - return record;
196 + return parsedAddress;
197 }
198 }
\ No newline at end of file
lib/view_model/send/send_view_model.dart
+4
@@ -44,6 +44,8 @@ abstract class SendViewModelBase with Store {
44
45 sendItemList = ObservableList<SendItem>()
46 ..add(SendItem(_wallet, _settingsStore, _fiatConversationStore));
47 +
48 + isElectrumWallet = _wallet is ElectrumWallet;
49 }
50
51 @observable
@@ -51,6 +53,8 @@ abstract class SendViewModelBase with Store {
53
54 ObservableList<SendItem> sendItemList;
55
56 + bool isElectrumWallet;
57 +
58 @action
59 void addSendItem() {
60 sendItemList.add(SendItem(_wallet, _settingsStore, _fiatConversationStore));