mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-05-05 15:12:14 +00:00
CAKE-345 | merged release-4.2.4 branch into current and resolved problems
This commit is contained in:
parent
2a047e1f51
commit
c14d021f07
8 changed files with 98 additions and 96 deletions
lib
bitcoin
src/screens
exchange
send
view_model/send
|
@ -176,9 +176,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
throw BitcoinTransactionNoInputsException();
|
throw BitcoinTransactionNoInputsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final allAmountFee =
|
final allAmountFee = feeAmountForPriority(
|
||||||
calculateEstimatedFee(transactionCredentials.priority, null);
|
transactionCredentials.priority, inputs.length, sendItemList.length);
|
||||||
final allAmount = balance.confirmed - allAmountFee;
|
final allAmount = allInputsAmount - allAmountFee;
|
||||||
|
|
||||||
var credentialsAmount = 0;
|
var credentialsAmount = 0;
|
||||||
var amount = 0;
|
var amount = 0;
|
||||||
var fee = 0;
|
var fee = 0;
|
||||||
|
@ -187,7 +188,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
final sendAllItems = sendItemList.where((item) => item.sendAll).toList();
|
final sendAllItems = sendItemList.where((item) => item.sendAll).toList();
|
||||||
|
|
||||||
if (sendAllItems?.isNotEmpty ?? false) {
|
if (sendAllItems?.isNotEmpty ?? false) {
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
final nullAmountItems = sendItemList.where((item) =>
|
final nullAmountItems = sendItemList.where((item) =>
|
||||||
|
@ -195,29 +196,37 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (nullAmountItems?.isNotEmpty ?? false) {
|
if (nullAmountItems?.isNotEmpty ?? false) {
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
credentialsAmount = sendItemList.fold(0, (previousValue, element) =>
|
credentialsAmount = sendItemList.fold(0, (previousValue, element) =>
|
||||||
previousValue + stringDoubleToBitcoinAmount(
|
previousValue + stringDoubleToBitcoinAmount(
|
||||||
element.cryptoAmount.replaceAll(',', '.')));
|
element.cryptoAmount.replaceAll(',', '.')));
|
||||||
|
|
||||||
|
if (credentialsAmount > allAmount) {
|
||||||
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
|
}
|
||||||
|
|
||||||
amount = allAmount - credentialsAmount < minAmount
|
amount = allAmount - credentialsAmount < minAmount
|
||||||
? allAmount
|
? allAmount
|
||||||
: credentialsAmount;
|
: credentialsAmount;
|
||||||
|
|
||||||
fee = amount == allAmount
|
fee = amount == allAmount
|
||||||
? allAmountFee
|
? allAmountFee
|
||||||
: calculateEstimatedFee(transactionCredentials.priority, amount,
|
: calculateEstimatedFee(transactionCredentials.priority, amount,
|
||||||
outputsCount: sendItemList.length + 1);
|
outputsCount: sendItemList.length + 1);
|
||||||
} else {
|
} else {
|
||||||
final sendItem = sendItemList.first;
|
final sendItem = sendItemList.first;
|
||||||
|
|
||||||
credentialsAmount = !sendItem.sendAll
|
credentialsAmount = !sendItem.sendAll
|
||||||
? stringDoubleToBitcoinAmount(
|
? stringDoubleToBitcoinAmount(
|
||||||
sendItem.cryptoAmount.replaceAll(',', '.'))
|
sendItem.cryptoAmount.replaceAll(',', '.'))
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
|
if (credentialsAmount > allAmount) {
|
||||||
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
|
}
|
||||||
|
|
||||||
amount = sendItem.sendAll || allAmount - credentialsAmount < minAmount
|
amount = sendItem.sendAll || allAmount - credentialsAmount < minAmount
|
||||||
? allAmount
|
? allAmount
|
||||||
: credentialsAmount;
|
: credentialsAmount;
|
||||||
|
@ -227,35 +236,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
: calculateEstimatedFee(transactionCredentials.priority, amount);
|
: calculateEstimatedFee(transactionCredentials.priority, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fee == 0) {
|
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
|
||||||
}
|
|
||||||
|
|
||||||
final totalAmount = amount + fee;
|
|
||||||
|
|
||||||
if (totalAmount > balance.confirmed) {
|
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
|
||||||
}
|
|
||||||
|
|
||||||
feeAmountForPriority(transactionCredentials.priority, inputs.length, 1);
|
|
||||||
final allAmount = allInputsAmount - allAmountFee;
|
|
||||||
|
|
||||||
final credentialsAmount = transactionCredentials.amount != null
|
|
||||||
? stringDoubleToBitcoinAmount(transactionCredentials.amount)
|
|
||||||
: 0;
|
|
||||||
final amount = transactionCredentials.amount == null ||
|
|
||||||
allAmount - credentialsAmount < minAmount
|
|
||||||
? allAmount
|
|
||||||
: credentialsAmount;
|
|
||||||
final fee = transactionCredentials.amount == null || amount == allAmount
|
|
||||||
? allAmountFee
|
|
||||||
: calculateEstimatedFee(transactionCredentials.priority, amount);
|
|
||||||
|
|
||||||
if (fee == 0) {
|
if (fee == 0) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
final totalAmount = amount + fee;
|
final totalAmount = amount + fee;
|
||||||
|
|
||||||
if (totalAmount > balance.confirmed || totalAmount > allInputsAmount) {
|
if (totalAmount > balance.confirmed || totalAmount > allInputsAmount) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
|
@ -264,8 +249,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
final txb = bitcoin.TransactionBuilder(network: networkType);
|
final txb = bitcoin.TransactionBuilder(network: networkType);
|
||||||
final changeAddress = walletAddresses.address;
|
final changeAddress = walletAddresses.address;
|
||||||
var leftAmount = totalAmount;
|
var leftAmount = totalAmount;
|
||||||
final changeAddress = address;
|
|
||||||
var leftAmount = totalAmount;
|
|
||||||
var totalInputAmount = 0;
|
var totalInputAmount = 0;
|
||||||
|
|
||||||
inputs.clear();
|
inputs.clear();
|
||||||
|
@ -288,8 +271,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
|
|
||||||
if (amount <= 0 || totalInputAmount < totalAmount) {
|
if (amount <= 0 || totalInputAmount < totalAmount) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
if (amount <= 0 || totalInputAmount < amount) {
|
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txb.setVersion(1);
|
txb.setVersion(1);
|
||||||
|
@ -298,8 +279,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
if (input.isP2wpkh) {
|
if (input.isP2wpkh) {
|
||||||
final p2wpkh = bitcoin
|
final p2wpkh = bitcoin
|
||||||
.P2WPKH(
|
.P2WPKH(
|
||||||
data: generatePaymentData(hd: hd, index: input.address.index),
|
data: generatePaymentData(hd: hd, index: input.address.index),
|
||||||
network: networkType)
|
network: networkType)
|
||||||
.data;
|
.data;
|
||||||
|
|
||||||
txb.addInput(input.hash, input.vout, null, p2wpkh.output);
|
txb.addInput(input.hash, input.vout, null, p2wpkh.output);
|
||||||
|
@ -313,7 +294,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
? amount
|
? amount
|
||||||
: stringDoubleToBitcoinAmount(item.cryptoAmount.replaceAll(',', '.'));
|
: stringDoubleToBitcoinAmount(item.cryptoAmount.replaceAll(',', '.'));
|
||||||
|
|
||||||
txb.addOutput(
|
txb.addOutput(
|
||||||
addressToOutputScript(item.address, networkType),
|
addressToOutputScript(item.address, networkType),
|
||||||
_amount);
|
_amount);
|
||||||
});
|
});
|
||||||
|
|
|
@ -784,22 +784,7 @@ class ExchangePage extends BasePage {
|
||||||
BuildContext context, String domain, String ticker) async {
|
BuildContext context, String domain, String ticker) async {
|
||||||
final parsedAddress = await parseAddressFromDomain(domain, ticker);
|
final parsedAddress = await parseAddressFromDomain(domain, ticker);
|
||||||
|
|
||||||
switch (parsedAddress.parseFrom) {
|
showAddressAlert(context, parsedAddress);
|
||||||
case ParseFrom.unstoppableDomains:
|
|
||||||
showAddressAlert(
|
|
||||||
context,
|
|
||||||
S.of(context).address_detected,
|
|
||||||
S.of(context).address_from_domain(parsedAddress.name));
|
|
||||||
break;
|
|
||||||
case ParseFrom.openAlias:
|
|
||||||
showAddressAlert(
|
|
||||||
context,
|
|
||||||
S.of(context).openalias_alert_title,
|
|
||||||
S.of(context).openalias_alert_content(parsedAddress.name));
|
|
||||||
break;
|
|
||||||
case ParseFrom.notParsed:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsedAddress.address;
|
return parsedAddress.address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
|
||||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
||||||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
|
@ -83,7 +79,7 @@ class SendPage extends BasePage {
|
||||||
content: Column(
|
content: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: 445,
|
height: 470,
|
||||||
child: Observer(
|
child: Observer(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return PageView.builder(
|
return PageView.builder(
|
||||||
|
@ -219,16 +215,9 @@ class SendPage extends BasePage {
|
||||||
item.address =
|
item.address =
|
||||||
template.address;
|
template.address;
|
||||||
item.setCryptoAmount(template.amount);
|
item.setCryptoAmount(template.amount);
|
||||||
final record =
|
final parsedAddress = await item
|
||||||
await item.getOpenaliasRecord();
|
.applyOpenaliasOrUnstoppableDomains();
|
||||||
|
showAddressAlert(context, parsedAddress);
|
||||||
if (record != null) {
|
|
||||||
showAddressAlert(
|
|
||||||
context,
|
|
||||||
S.current.openalias_alert_title,
|
|
||||||
S.current
|
|
||||||
.openalias_alert_content(record.name));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onRemove: () {
|
onRemove: () {
|
||||||
showPopUp<void>(
|
showPopUp<void>(
|
||||||
|
|
|
@ -146,7 +146,6 @@ class SendTemplatePage extends BasePage {
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.headline
|
.headline
|
||||||
.decorationColor),
|
.decorationColor),
|
||||||
validator: sendTemplateViewModel.addressValidator,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
|
@ -1,9 +1,26 @@
|
||||||
|
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
|
||||||
void showAddressAlert(BuildContext context, String title, String content) async {
|
void showAddressAlert(BuildContext context, ParsedAddress parsedAddress) async {
|
||||||
|
var title = '';
|
||||||
|
var content = '';
|
||||||
|
|
||||||
|
switch (parsedAddress.parseFrom) {
|
||||||
|
case ParseFrom.unstoppableDomains:
|
||||||
|
title = S.of(context).address_detected;
|
||||||
|
content = S.of(context).address_from_domain(parsedAddress.name);
|
||||||
|
break;
|
||||||
|
case ParseFrom.openAlias:
|
||||||
|
title = S.of(context).openalias_alert_title;
|
||||||
|
content = S.of(context).openalias_alert_content(parsedAddress.name);
|
||||||
|
break;
|
||||||
|
case ParseFrom.notParsed:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await showPopUp<void>(
|
await showPopUp<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
||||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
|
@ -79,7 +80,7 @@ class SendCardState extends State<SendCard>
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 445,
|
height: 470,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(24),
|
bottomLeft: Radius.circular(24),
|
||||||
|
@ -140,6 +141,11 @@ class SendCardState extends State<SendCard>
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.headline
|
.headline
|
||||||
.decorationColor),
|
.decorationColor),
|
||||||
|
onPushPasteButton: (context) async {
|
||||||
|
final parsedAddress =
|
||||||
|
await item.applyOpenaliasOrUnstoppableDomains();
|
||||||
|
showAddressAlert(context, parsedAddress);
|
||||||
|
},
|
||||||
validator: sendViewModel.addressValidator,
|
validator: sendViewModel.addressValidator,
|
||||||
),
|
),
|
||||||
Observer(
|
Observer(
|
||||||
|
@ -393,7 +399,34 @@ class SendCardState extends State<SendCard>
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
))
|
)),
|
||||||
|
if (sendViewModel.isElectrumWallet) Padding(
|
||||||
|
padding: EdgeInsets.only(top: 6),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => Navigator.of(context)
|
||||||
|
.pushNamed(Routes.unspentCoinsList),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
S.of(context).coin_control,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white)),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -485,14 +518,8 @@ class SendCardState extends State<SendCard>
|
||||||
|
|
||||||
addressFocusNode.addListener(() async {
|
addressFocusNode.addListener(() async {
|
||||||
if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) {
|
if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) {
|
||||||
final record = await item.getOpenaliasRecord();
|
final parsedAddress = await item.applyOpenaliasOrUnstoppableDomains();
|
||||||
|
showAddressAlert(context, parsedAddress);
|
||||||
if (record != null) {
|
|
||||||
showAddressAlert(
|
|
||||||
context,
|
|
||||||
S.current.openalias_alert_title,
|
|
||||||
S.current.openalias_alert_content(record.name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
||||||
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
||||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||||
import 'package:cake_wallet/entities/openalias_record.dart';
|
import 'package:cake_wallet/entities/openalias_record.dart';
|
||||||
|
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||||
|
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||||
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
@ -184,15 +186,13 @@ abstract class SendItemBase with Store {
|
||||||
_cryptoNumberFormat.maximumFractionDigits = maximumFractionDigits;
|
_cryptoNumberFormat.maximumFractionDigits = maximumFractionDigits;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<OpenaliasRecord> getOpenaliasRecord() async {
|
Future<ParsedAddress> applyOpenaliasOrUnstoppableDomains() async {
|
||||||
final formattedName = OpenaliasRecord.formatDomainName(address);
|
final domain = address;
|
||||||
final record = await OpenaliasRecord.fetchAddressAndName(formattedName);
|
final ticker = _wallet.currency.title.toLowerCase();
|
||||||
|
final parsedAddress = await parseAddressFromDomain(domain, ticker);
|
||||||
|
|
||||||
if (record == null || record.address.contains(formattedName)) {
|
address = parsedAddress.address;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = record.address;
|
return parsedAddress;
|
||||||
return record;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -44,6 +44,8 @@ abstract class SendViewModelBase with Store {
|
||||||
|
|
||||||
sendItemList = ObservableList<SendItem>()
|
sendItemList = ObservableList<SendItem>()
|
||||||
..add(SendItem(_wallet, _settingsStore, _fiatConversationStore));
|
..add(SendItem(_wallet, _settingsStore, _fiatConversationStore));
|
||||||
|
|
||||||
|
isElectrumWallet = _wallet is ElectrumWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
|
@ -51,6 +53,8 @@ abstract class SendViewModelBase with Store {
|
||||||
|
|
||||||
ObservableList<SendItem> sendItemList;
|
ObservableList<SendItem> sendItemList;
|
||||||
|
|
||||||
|
bool isElectrumWallet;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void addSendItem() {
|
void addSendItem() {
|
||||||
sendItemList.add(SendItem(_wallet, _settingsStore, _fiatConversationStore));
|
sendItemList.add(SendItem(_wallet, _settingsStore, _fiatConversationStore));
|
||||||
|
|
Loading…
Reference in a new issue