Cw 598 fixes for electrum based wallets (#1344)

* fix: address book addresses, bch builder, exchange all fee estimation, bch coin control

* feat: new error framework for Electrum messages

* build: cw_bitcoin.dart

* feat: error improvements, localization, fix exchange amount mismatch

* chore: misc comment & print [skip ci]

* feat: refactor & simplify sendAll vs regular tx estimation and creation

- Since there were so many conditions inside a single function to alter its behavior if sendAll or not, it is easier and more readable to have separate sendAll and estimateTx functions that behave separately

* fix: wrong LTC dust

* feat: fee rate confirmation

* fix: wrong createTrade value when isSendAll is enabled

* fix bitcoin cash address parsing [skip ci]

* fix: form no amount validator, address book with multiple entries, exchange all below min error

* fix: improve string, fix sending with dust inputs at the top

* fix: two change outputs when re-estimating

* fix: sendAll with a little dust adds fees

* chore: sanity check [skip ci]

* fix: if the fee is higher than estimated

* Minor enhancement [skip ci]

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
Rafael
2024-03-29 20:51:34 +02:00
committed by GitHub
co-authored by OmarHatem
parent 78685b74f0
commit fd9018bcc4
60 changed files with 984 additions and 431 deletions
+8 -2
View File
@@ -186,7 +186,13 @@ class ExchangePage extends BasePage {
StandardCheckbox(
value: exchangeViewModel.isFixedRateMode,
caption: S.of(context).fixed_rate,
onChanged: (value) => exchangeViewModel.isFixedRateMode = value,
onChanged: (value) {
if (value) {
exchangeViewModel.enableFixedRateMode();
} else {
exchangeViewModel.isFixedRateMode = false;
}
},
),
],
)),
@@ -528,7 +534,7 @@ class ExchangePage extends BasePage {
_receiveAmountFocus.addListener(() {
if (_receiveAmountFocus.hasFocus) {
exchangeViewModel.isFixedRateMode = true;
exchangeViewModel.enableFixedRateMode();
}
// exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
});
@@ -262,6 +262,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
fee: S.of(popupContext).send_fee,
feeValue: widget.exchangeTradeViewModel.sendViewModel
.pendingTransaction!.feeFormatted,
feeRate: widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.feeRate,
rightButtonText: S.of(popupContext).send,
leftButtonText: S.of(popupContext).cancel,
actionRightButton: () async {
+1
View File
@@ -426,6 +426,7 @@ class SendPage extends BasePage {
fee: isEVMCompatibleChain(sendViewModel.walletType)
? S.of(_dialogContext).send_estimated_fee
: S.of(_dialogContext).send_fee,
feeRate: sendViewModel.pendingTransaction!.feeRate,
feeValue: sendViewModel.pendingTransaction!.feeFormatted,
feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
outputs: sendViewModel.outputs,
@@ -16,6 +16,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
required this.amountValue,
required this.fiatAmountValue,
required this.fee,
this.feeRate,
required this.feeValue,
required this.feeFiatAmount,
required this.outputs,
@@ -36,6 +37,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
final String amountValue;
final String fiatAmountValue;
final String fee;
final String? feeRate;
final String feeValue;
final String feeFiatAmount;
final List<Output> outputs;
@@ -90,6 +92,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
amountValue: amountValue,
fiatAmountValue: fiatAmountValue,
fee: fee,
feeRate: feeRate,
feeValue: feeValue,
feeFiatAmount: feeFiatAmount,
outputs: outputs);
@@ -103,6 +106,7 @@ class ConfirmSendingAlertContent extends StatefulWidget {
required this.amountValue,
required this.fiatAmountValue,
required this.fee,
this.feeRate,
required this.feeValue,
required this.feeFiatAmount,
required this.outputs});
@@ -113,6 +117,7 @@ class ConfirmSendingAlertContent extends StatefulWidget {
final String amountValue;
final String fiatAmountValue;
final String fee;
final String? feeRate;
final String feeValue;
final String feeFiatAmount;
final List<Output> outputs;
@@ -125,6 +130,7 @@ class ConfirmSendingAlertContent extends StatefulWidget {
amountValue: amountValue,
fiatAmountValue: fiatAmountValue,
fee: fee,
feeRate: feeRate,
feeValue: feeValue,
feeFiatAmount: feeFiatAmount,
outputs: outputs);
@@ -138,6 +144,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
required this.amountValue,
required this.fiatAmountValue,
required this.fee,
this.feeRate,
required this.feeValue,
required this.feeFiatAmount,
required this.outputs})
@@ -153,6 +160,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
final String amountValue;
final String fiatAmountValue;
final String fee;
final String? feeRate;
final String feeValue;
final String feeFiatAmount;
final List<Output> outputs;
@@ -183,7 +191,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
return Stack(alignment: Alignment.center, clipBehavior: Clip.none, children: [
Container(
height: 200,
height: feeRate != null ? 250 : 200,
child: SingleChildScrollView(
controller: controller,
child: Column(
@@ -311,6 +319,36 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
)
],
)),
if (feeRate != null && feeRate!.isNotEmpty)
Padding(
padding: EdgeInsets.only(top: 16),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
S.current.send_estimated_fee,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
),
Text(
"$feeRate sat/byte",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
)
],
)),
Padding(
padding: EdgeInsets.only(top: 16),
child: Column(
@@ -46,9 +46,6 @@ class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
itemBuilder: (_, int index) {
return Observer(builder: (_) {
final item = unspentCoinsListViewModel.items[index];
final address = unspentCoinsListViewModel.wallet.type == WalletType.bitcoinCash
? bitcoinCash!.getCashAddrFormat(item.address)
: item.address;
return GestureDetector(
onTap: () => Navigator.of(context).pushNamed(Routes.unspentCoinsDetails,
@@ -56,7 +53,7 @@ class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
child: UnspentCoinsListItem(
note: item.note,
amount: item.amount,
address: address,
address: item.address,
isSending: item.isSending,
isFrozen: item.isFrozen,
isChange: item.isChange,