feat: Add warning before adding erc20 token via contract address (#1663)

* feat: Add warning before adding erc20 token via contract address

* fix: Update message on edit token page

* fix: Adjust polygon secrets variable name

* fix: Handle loading state, translate strings and fix other issues

* fix linux build [skip ci]

* fix: Modify warning text for contract address scam alert

* Update secret_key.dart

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
David Adegoke
2024-09-12 00:19:47 +03:00
committed by GitHub
co-authored by Omar Hatem
parent 0e106834bc
commit 7bf2fb9dce
34 changed files with 584 additions and 93 deletions
+94 -45
View File
@@ -2,16 +2,19 @@ import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/checkbox_widget.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class EditTokenPage extends BasePage {
EditTokenPage({
@@ -79,7 +82,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (widget.token != null) {
address = widget.homeSettingsViewModel.getTokenAddressBasedOnWallet(widget.token!);
_contractAddressController.text = address ?? '';
_tokenNameController.text = widget.token!.name;
_tokenSymbolController.text = widget.token!.title;
@@ -135,8 +138,8 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
S.of(context).warning,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).dialogTheme.backgroundColor,
fontWeight: FontWeight.bold,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
Padding(
@@ -145,7 +148,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
S.of(context).add_token_warning,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.extension<TransactionTradeTheme>()!
.detailsTitlesColor,
@@ -167,6 +170,15 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
bottomSection: Column(
children: [
if (_showDisclaimer) ...[
Text(
S.current.do_not_send_funds_to_contract_address_warning,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
SizedBox(height: 20),
CheckboxWidget(
value: _disclaimerChecked,
caption: S.of(context).add_token_disclaimer_check,
@@ -176,47 +188,84 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
),
SizedBox(height: 20),
],
Row(
children: <Widget>[
Expanded(
child: PrimaryButton(
onPressed: () async {
if (widget.token != null) {
await widget.homeSettingsViewModel.deleteToken(widget.token!);
}
Navigator.pop(context);
},
text: widget.token != null ? S.of(context).delete : S.of(context).cancel,
color: Colors.red,
textColor: Colors.white,
),
),
SizedBox(width: 20),
Expanded(
child: PrimaryButton(
onPressed: () async {
if (_formKey.currentState!.validate() &&
(!_showDisclaimer || _disclaimerChecked)) {
await widget.homeSettingsViewModel.addToken(
token: CryptoCurrency(
name: _tokenNameController.text,
title: _tokenSymbolController.text.toUpperCase(),
decimals: int.parse(_tokenDecimalController.text),
iconPath: _tokenIconPathController.text,
),
contractAddress: _contractAddressController.text,
);
if (mounted) {
Observer(
builder: (context) {
return Row(
children: <Widget>[
Expanded(
child: LoadingPrimaryButton(
isLoading: widget.homeSettingsViewModel.isDeletingToken,
onPressed: () async {
if (widget.token != null) {
await widget.homeSettingsViewModel.deleteToken(widget.token!);
}
Navigator.pop(context);
}
}
},
text: S.of(context).save,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
],
},
text: widget.token != null ? S.of(context).delete : S.of(context).cancel,
color: Colors.red,
textColor: Colors.white,
),
),
SizedBox(width: 20),
Expanded(
child: LoadingPrimaryButton(
isLoading: widget.homeSettingsViewModel.isAddingToken ||
widget.homeSettingsViewModel.isValidatingContractAddress,
onPressed: () async {
if (_formKey.currentState!.validate() &&
(!_showDisclaimer || _disclaimerChecked)) {
final hasPotentialError = await widget.homeSettingsViewModel
.checkIfERC20TokenContractAddressIsAPotentialScamAddress(
_contractAddressController.text,
);
final actionCall = () async {
await widget.homeSettingsViewModel.addToken(
token: CryptoCurrency(
name: _tokenNameController.text,
title: _tokenSymbolController.text.toUpperCase(),
decimals: int.parse(_tokenDecimalController.text),
iconPath: _tokenIconPathController.text,
),
contractAddress: _contractAddressController.text,
);
};
if (hasPotentialError) {
showPopUp<void>(
context: context,
builder: (dialogContext) {
return AlertWithTwoActions(
alertTitle: S.current.warning,
alertContent: S.current.contract_warning,
rightButtonText: S.of(context).continue_text,
leftButtonText: S.of(context).cancel,
actionRightButton: () async {
Navigator.of(dialogContext).pop();
await actionCall();
if (mounted) {
Navigator.pop(context);
}
},
actionLeftButton: () => Navigator.of(dialogContext).pop(),
);
},
);
} else {
await actionCall();
if (mounted) {
Navigator.pop(context);
}
}
}
},
text: S.of(context).save,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
],
);
},
),
],
),