Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #99 from MXCzkEVM/pre_main_qa
Browse files Browse the repository at this point in the history
Pre main qa
  • Loading branch information
reasje authored Oct 19, 2023
2 parents 7c7b819 + 69f29ae commit 5c2154a
Show file tree
Hide file tree
Showing 33 changed files with 810 additions and 161 deletions.
16 changes: 14 additions & 2 deletions assets/flutter_i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,25 @@
"checking_balance": "Checking balance...",
"no_balance": "You have no balance",
"no_balance_tip": "You currently have no MXC in your wallet.\nYou can either receive tokens or choose to claim a username later.",
"signature_request": "Signature request",
"signature_request": "Signature request",
"sign": "Sign",
"insufficient_balance": "Insufficient balance",
"unregistered_mns_notice": "Oops! Sending tokens to a username as elusive as a unicorn in a forest. Check if they're registered!",
"insufficient_balance_for_fee": "Insufficient balance for fee",
"send_&_receive": "Send & Receive",
"contract": "Contract",
"decimals": "Decimals",
"add_token_success_message" : "Hooray! The token has been successfully added to your AXS wallet! 🎉"
"add_token_success_message": "Hooray! The token has been successfully added to your AXS wallet! 🎉",
"import_account": "Import account",
"add_account": "Add account",
"private_key": "Private key",
"import_notice": "Imported accounts won’t be associated with your AXS wallet Secret Recovery Phrase.",
"imported": "Imported",
"view_private_key": "View private key",
"view_private_key_notice": "Warning: Never disclose this key. Anyone with your private keys can steal any assets held in your account.",
"removing_account": "Removing account",
"removing_account_warning": "Are you sure you want to remove this account?",
"remove": "Remove",
"duplicate_account_import_notice": "The account you are trying to import is a duplicate",
"unable_to_launch_email_app": "Unable to launch email app"
}
32 changes: 21 additions & 11 deletions lib/common/components/list/single_line_info_item.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import 'package:datadashwallet/features/dapps/subfeatures/open_dapp/open_dapp_presenter.dart';
import 'package:datadashwallet/common/common.dart';
import 'package:datadashwallet/core/src/providers/providers_use_cases.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mxc_ui/mxc_ui.dart';

class SingleLineInfoItem extends HookConsumerWidget {
const SingleLineInfoItem({
super.key,
required this.title,
required this.value,
this.hint,
});
const SingleLineInfoItem(
{super.key,
required this.title,
required this.value,
this.hint,
this.valueActionIcon});

final String title;
final String value;
final String? hint;
final Widget? valueActionIcon;

@override
Widget build(BuildContext context, WidgetRef ref) {
final presenter = ref.read(openDAppPageContainer.actions);
final isAddress = presenter.isAddress(value);
late final _chainConfigurationUseCase =
ref.read(chainConfigurationUseCaseProvider);

final isAddress = Validation.isAddress(value);
return Padding(
padding: const EdgeInsets.symmetric(vertical: Sizes.spaceXSmall),
child: Row(
Expand All @@ -34,7 +40,9 @@ class SingleLineInfoItem extends HookConsumerWidget {
),
Expanded(
child: InkWell(
onTap: isAddress ? () => presenter.launchAddress(value) : null,
onTap: isAddress
? () => _chainConfigurationUseCase.launchAddress(value)
: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expand All @@ -46,7 +54,9 @@ class SingleLineInfoItem extends HookConsumerWidget {
textAlign: TextAlign.end,
),
),
if (isAddress) ...[
if (valueActionIcon != null)
valueActionIcon!
else if (isAddress) ...[
const SizedBox(width: 8),
Icon(
MxcIcons.external_link,
Expand Down
2 changes: 2 additions & 0 deletions lib/common/urls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ class Urls {

static const String iOSUrl =
'https://apps.apple.com/us/app/axs-decentralized-wallet/id6460891587';

static const String emailApp = 'mailto:';
}
2 changes: 1 addition & 1 deletion lib/common/utils/formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Formatter {

static String convertWeiToEth(String inputString, int tokenDecimal) {
// 10^18 = 1000000000000000000 but we want to have up to 2 digits accuracy
if (double.parse(inputString).toDouble() < 10000000000000000) {
if (double.parse(inputString).toDouble() < 1000000000000000) {
return '0';
}
final valueDouble = double.parse(inputString).toDouble() / pow(10, 18);
Expand Down
21 changes: 21 additions & 0 deletions lib/common/utils/utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
import 'package:datadashwallet/common/common.dart';
import 'package:url_launcher/url_launcher.dart';

export 'formatter.dart';
export 'permission.dart';
export 'validation.dart';

class Utils {
static Future<bool> isEmailAppAvailable() async {
final url = Uri.parse(Urls.emailApp);

return await canLaunchUrl(url);
}

static Future<void> launchEmailApp() async {
final url = Uri.parse(Urls.emailApp);

if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
throw 'unable_to_launch_email_app';
}
}
}
32 changes: 32 additions & 0 deletions lib/common/utils/validation.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:datadashwallet/common/config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:web3dart/web3dart.dart';


class Validation {
static String? notEmpty(BuildContext context, String? value,
Expand Down Expand Up @@ -53,6 +55,17 @@ class Validation {
return null;
}

static String? checkEthereumPrivateKey(BuildContext context, String value) {
String ethereumPrivateKeyPattern = r'^[0-9a-fA-F]{64}$';

if (!RegExp(ethereumPrivateKeyPattern, caseSensitive: false)
.hasMatch(value)) {
return FlutterI18n.translate(context, 'invalid_format');
}

return null;
}

static String? checkMnsValidation(BuildContext context, String value) {
if (!((value.endsWith('.mxc') || value.endsWith('.MXC')) &&
value.length > 4)) {
Expand Down Expand Up @@ -118,4 +131,23 @@ class Validation {

return regex.hasMatch(value);
}


static bool isAddress(String address) {
try {
EthereumAddress.fromHex(address);
return true;
} catch (e) {
return false;
}
}

static bool isPrivateKey(String privateKey) {
try {
EthPrivateKey.fromHex(privateKey);
return true;
} catch (e) {
return false;
}
}
}
15 changes: 13 additions & 2 deletions lib/features/common/account/account_cache_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,19 @@ class AccountCacheRepository extends GlobalCacheRepository {
List<Account> get accountItems => accounts.value;
Account get accountItem => account.value!;

void addAccount(Account item) => accounts.value = [...accounts.value, item];
void addAccount(Account item, {int? index}) {
if (index == null) {
accounts.value = [...accounts.value, item];
} else {
final newList = accounts.value;
newList.insert(index, item);
accounts.value = newList;
}
}

void removeAccount(Account item) => accounts.value =
accounts.value.where((e) => e.name != item.name).toList();
accounts.value.where((e) => e.address != item.address).toList();

void updateAccount(Account item) => accounts.value = accounts.value.map((e) {
if (item.address == account.value!.address) {
account.value = item;
Expand All @@ -67,6 +77,7 @@ class AccountCacheRepository extends GlobalCacheRepository {
}
return e;
}).toList();

void resetAccounts() => accounts.value = [];

void setXsdConversionRate(double value) => xsdConversionRate.value = value;
Expand Down
27 changes: 25 additions & 2 deletions lib/features/common/account/account_use_case.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,41 @@ class AccountUseCase extends ReactiveUseCase {
update(account, item);
}

void addAccount(Account item) async {
_accountCacheRepository.addAccount(item);
void addAccount(Account item, {int? index}) async {
_accountCacheRepository.addAccount(item, index: index);
final items = _accountCacheRepository.accountItems;
update(account, item);
update(accounts, items);
getAccountsNames();
}

/// Deletes the given account, If the account is selected will select the index 0 account
/// This is only used to delete the imported accounts.
void removeAccount(Account item) async {
_accountCacheRepository.removeAccount(item);
final items = _accountCacheRepository.accountItems;
update(accounts, items);
}

bool isAccountSelected(Account item) {
return (item.address == account.value!.address);
}

void changeAccount(Account item) {
update(account, item);
}

int findAccountsLastIndex() {
int lastIndex = 0;
for (Account account in accounts.value.reversed) {
if (!account.isCustom) {
lastIndex = int.parse(account.name);
break;
}
}
return lastIndex;
}

void resetXsdConversionRate(double value) {
_accountCacheRepository.setXsdConversionRate(value);
update(xsdConversionRate, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,7 @@ class OpenDAppPresenter extends CompletePresenter<OpenDAppState> {
}

bool isAddress(String address) {
try {
EthereumAddress.fromHex(address);
return true;
} catch (e) {
return false;
}
return Validation.isAddress(address);
}

void addAsset(int id, Map<String, dynamic> data,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ class AddAssetInfo extends ConsumerWidget {
title: FlutterI18n.translate(context, 'contract'),
value: contractAddress ?? ''));
infoList.add(SingleLineInfoItem(
title: FlutterI18n.translate(context, 'symbol'), value: symbol ?? ''));
title: FlutterI18n.translate(context, 'symbol'),
value: symbol ?? '',
));
infoList.add(SingleLineInfoItem(
title: FlutterI18n.translate(context, 'decimals'),
value: decimalsString));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,25 @@ class SendCryptoPresenter extends CompletePresenter<SendCryptoState> {

double sumBalance = token.balance! - double.parse(amount);
estimatedGasFee = await _estimatedFee(recipientAddress);
sumBalance -= estimatedGasFee?.gasFee ?? 0.0;
final estimatedFee = estimatedGasFee == null
? '--'
: Validation.isExpoNumber(estimatedGasFee.gasFee.toString())
? '0.000'
: estimatedGasFee.gasFee.toString();

final result = await showTransactionDialog(context!,
amount: amount,
balance: sumBalance.toString(),
token: token,
network: state.network?.label ?? '--',
from: state.account!.address,
to: recipient,
estimatedFee: estimatedFee,
onTap: (transactionType) => _nextTransactionStep(transactionType),
networkSymbol: state.network?.symbol ?? '--');
if (estimatedGasFee != null) {
sumBalance -= estimatedGasFee.gasFee;
final estimatedFee = estimatedGasFee == null
? '--'
: Validation.isExpoNumber(estimatedGasFee.gasFee.toString())
? '0.000'
: estimatedGasFee.gasFee.toString();

final result = await showTransactionDialog(context!,
amount: amount,
balance: sumBalance.toString(),
token: token,
network: state.network?.label ?? '--',
from: state.account!.address,
to: recipient,
estimatedFee: estimatedFee,
onTap: (transactionType) => _nextTransactionStep(transactionType),
networkSymbol: state.network?.symbol ?? '--');
}
}

String? checkAmountCeiling() {
Expand Down Expand Up @@ -203,7 +205,11 @@ class SendCryptoPresenter extends CompletePresenter<SendCryptoState> {

return gasFee;
} catch (e, s) {
addError(e, s);
if (e is RPCError) {
String errorMessage = e.message;
errorMessage = changeErrorMessage(errorMessage);
addError(errorMessage);
}
} finally {
loading = false;
}
Expand All @@ -229,7 +235,7 @@ class SendCryptoPresenter extends CompletePresenter<SendCryptoState> {
hash: res,
status: TransactionStatus.pending,
type: TransactionType.sent,
value: amount.getValueInUnit(EtherUnit.wei).toString(),
value: amount.getValueInUnitBI(EtherUnit.wei).toString(),
token: token,
timeStamp: DateTime.now());

Expand All @@ -249,16 +255,21 @@ class SendCryptoPresenter extends CompletePresenter<SendCryptoState> {
BottomFlowDialog.of(context!).close();
}
String errorMessage = e.message;
if (e.message.contains('gas required exceeds allowance')) {
errorMessage = translate('insufficient_balance_for_fee') ?? e.message;
}
errorMessage = changeErrorMessage(errorMessage);
addError(errorMessage);
}
} finally {
loading = false;
}
}

String changeErrorMessage(String message) {
if (message.contains('gas required exceeds allowance')) {
return translate('insufficient_balance_for_fee') ?? message;
}
return message;
}

@override
Future<void> dispose() async {
super.dispose();
Expand Down
Loading

0 comments on commit 5c2154a

Please sign in to comment.