Cw 268 contact address validation (#905)

* feat: Proper Bitcoin address validation in exchange screen

* fix: use custom validation in addition to RegEx to make sure all address cases are validated

- for cases like P2SH addresses starting with a 3, which are not validated by bitcoin_flutter functions

* feat: add bitcoin_flutter to root project

* refactor: improve conditional isValid return chain

* feat: enhance contact page address validation

- only shows address box when a currency is selected, to prevent the selected value from being null
- changes TextValidator() for the new AddressValidator()

* fix: use -1 for initial selectedAtIndex, since there is no currency yet selected
This commit is contained in:
Rafael Saes 2023-05-15 09:43:52 -03:00 committed by GitHub
parent 0231298381
commit 40f3ccbe42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,13 +1,11 @@
import 'package:cake_wallet/core/validator.dart'; import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/currency.dart'; import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/contact_name_validator.dart'; import 'package:cake_wallet/core/contact_name_validator.dart';
import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
@ -33,8 +31,8 @@ class ContactPage extends BasePage {
_addressController _addressController
.addListener(() => contactViewModel.address = _addressController.text); .addListener(() => contactViewModel.address = _addressController.text);
autorun((_) => autorun((_) => _currencyTypeController.text =
_currencyTypeController.text = contactViewModel.currency?.toString()??''); contactViewModel.currency?.toString() ?? '');
} }
@override @override
@ -61,7 +59,8 @@ class ContactPage extends BasePage {
} }
}); });
return ScrollableWithBottomSection( return Observer(
builder: (_) => ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24), contentPadding: EdgeInsets.all(24),
content: Form( content: Form(
key: _formKey, key: _formKey,
@ -90,22 +89,25 @@ class ContactPage extends BasePage {
), ),
), ),
), ),
if (contactViewModel.currency != null)
Padding( Padding(
padding: EdgeInsets.only(top: 20), padding: EdgeInsets.only(top: 20),
child: Observer( child: AddressTextField(
builder: (_) => AddressTextField(
controller: _addressController, controller: _addressController,
options: [ options: [
AddressTextFieldOption.paste, AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode, AddressTextFieldOption.qrCode,
], ],
buttonColor: Theme.of(context).accentTextTheme!.headline3!.color!, buttonColor:
Theme.of(context).accentTextTheme!.headline3!.color!,
iconColor: PaletteDark.gray, iconColor: PaletteDark.gray,
borderColor: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!, borderColor: Theme.of(context)
validator: TextValidator() .primaryTextTheme!
// AddressValidator( .headline6!
// type: contactViewModel.currency), .backgroundColor!,
)), validator:
AddressValidator(type: contactViewModel.currency!),
),
) )
], ],
), ),
@ -130,27 +132,32 @@ class ContactPage extends BasePage {
child: Observer( child: Observer(
builder: (_) => PrimaryButton( builder: (_) => PrimaryButton(
onPressed: () async { onPressed: () async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) { if (_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return; return;
} }
await contactViewModel.save(); await contactViewModel.save();
}, },
text: S.of(context).save, text: S.of(context).save,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!, color: Theme.of(context)
.accentTextTheme!
.bodyText1!
.color!,
textColor: Colors.white, textColor: Colors.white,
isDisabled: !contactViewModel.isReady))) isDisabled: !contactViewModel.isReady)))
], ],
)); )),
);
} }
void _presentCurrencyPicker(BuildContext context) { void _presentCurrencyPicker(BuildContext context) {
showPopUp<void>( showPopUp<void>(
builder: (_) => CurrencyPicker( builder: (_) => CurrencyPicker(
selectedAtIndex: selectedAtIndex: contactViewModel.currency != null
contactViewModel.currency != null ? contactViewModel.currencies
? contactViewModel.currencies.indexOf(contactViewModel.currency!) .indexOf(contactViewModel.currency!)
: 0, : -1,
items: contactViewModel.currencies, items: contactViewModel.currencies,
title: S.of(context).please_select, title: S.of(context).please_select,
hintText: S.of(context).search_currency, hintText: S.of(context).search_currency,