diff --git a/assets/translations/en.json b/assets/translations/en.json index cbecb40..9eaf364 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -229,5 +229,9 @@ "gotit": "Got it", "moreInfo": "More information", "keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.", - "fundsUnavailable": "Insufficient funds" + "fundsUnavailable": "Insufficient funds", + "addressNotBelongToMnemonic": "The address you provided does not belong to this recovery sentence", + "enterYourNewMnemonic": "Enter your new recovery sentence", + "enterYourNewAddress": "Enter your new address {}", + "youCanMigrateThisIdentity": "You can migrate this identity !" } \ No newline at end of file diff --git a/assets/translations/es.json b/assets/translations/es.json index 466a36a..0688c59 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -230,5 +230,9 @@ "gotit": "Got it", "moreInfo": "More information", "keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.", - "fundsUnavailable": "Insufficient funds" + "fundsUnavailable": "Insufficient funds", + "addressNotBelongToMnemonic": "The address you provided does not belong to this recovery sentence", + "enterYourNewMnemonic": "Enter your new recovery sentence", + "enterYourNewAddress": "Enter your new address {}", + "youCanMigrateThisIdentity": "You can migrate this identity !" } \ No newline at end of file diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 3286cce..af02869 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -229,5 +229,9 @@ "gotit": "J'ai compris", "moreInfo": "Plus d'info", "keepThisPaperSafe": "Gardez cette feuille précieusement, à l’abri des lézards indiscrets.\nElle vous permettra de restaurer tous vos portefeuilles à tout moment.", - "fundsUnavailable": "Fonds insuffisants" + "fundsUnavailable": "Fonds insuffisants", + "addressNotBelongToMnemonic": "L'adresse que vous avez fournit n'appartient pas à cette phrase de restauration", + "enterYourNewMnemonic": "Entrez votre nouvelle phrase de restauration", + "enterYourNewAddress": "Entrez votre nouvelle adresse {}", + "youCanMigrateThisIdentity": "Vous pouvez migrer vers cette identité !" } \ No newline at end of file diff --git a/integration_test/duniter/data/gecko_data.json b/integration_test/duniter/data/gecko_data.json index a034777..088753c 100644 --- a/integration_test/duniter/data/gecko_data.json +++ b/integration_test/duniter/data/gecko_data.json @@ -1,5 +1,5 @@ { - "initial_monetary_mass": 50100, + "initial_monetary_mass": 60100, "identities": { "test1": { "index": 0, @@ -49,7 +49,7 @@ }, "owner_pubkey": "5LqbvutJtRTHvnforyndwPbkC4Kf5cJtdRQaDcHoMi8S" }, - "testCesium1": { + "test5": { "index": 4, "balance": 10000, "membership_expire_on": 1705509948, @@ -59,6 +59,18 @@ "test2": 1727758466, "test3": 1727758466 }, + "owner_pubkey": "6FgzG8NwatTWHo7rM7sPP6P4Q95R2ZQNqYiHCs38RT21" + }, + "testCesium1": { + "index": 5, + "balance": 10000, + "membership_expire_on": 1705509948, + "next_cert_issuable_on": 1668347505, + "certs_received": { + "test1": 1727758466, + "test2": 1727758466, + "test3": 1727758466 + }, "owner_pubkey": "DCovzCEnQm9GUWe6mr8u42JR1JAuoj3HbQUGdCkfTzSr" } } diff --git a/lib/models/migrate_wallet_checks.dart b/lib/models/migrate_wallet_checks.dart index 4b491fc..c9f070a 100644 --- a/lib/models/migrate_wallet_checks.dart +++ b/lib/models/migrate_wallet_checks.dart @@ -3,14 +3,30 @@ import 'package:gecko/models/wallet_data.dart'; class MigrateWalletChecks { final Map balance; final IdtyStatus idtyStatus; - final bool isSmith; final String validationStatus; final bool canValidate; - const MigrateWalletChecks( - {required this.balance, - required this.idtyStatus, - required this.isSmith, - required this.validationStatus, - required this.canValidate}); + const MigrateWalletChecks({ + required this.balance, + required this.idtyStatus, + required this.validationStatus, + required this.canValidate, + }); + + const MigrateWalletChecks.defaultValues({ + this.balance = const {'transferableBalance': 0}, + this.idtyStatus = IdtyStatus.none, + this.validationStatus = '', + this.canValidate = false, + }); + + @override + String toString() { + return { + 'balance': balance, + 'idtyStatus': idtyStatus, + 'validationStatus': validationStatus, + 'canValidate': canValidate, + }.toString(); + } } diff --git a/lib/providers/my_wallets.dart b/lib/providers/my_wallets.dart index 28469e0..367f80f 100644 --- a/lib/providers/my_wallets.dart +++ b/lib/providers/my_wallets.dart @@ -119,6 +119,7 @@ class MyWalletsProvider with ChangeNotifier { final avatarFolder = Directory('${directory.path}/avatars/'); if (await avatarFolder.exists()) { await avatarFolder.delete(recursive: true); + await avatarFolder.create(); } myWalletProvider.pinCode = ''; diff --git a/lib/providers/search.dart b/lib/providers/search.dart index 7f914dc..38360b4 100644 --- a/lib/providers/search.dart +++ b/lib/providers/search.dart @@ -12,7 +12,7 @@ class SearchProvider with ChangeNotifier { } Future> searchAddress() async { - if (isAddress(searchController.text)) { + if (await isAddress(searchController.text)) { G1WalletsList wallet = G1WalletsList(address: searchController.text); return [wallet]; } else { diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 05bd7f6..2750e98 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -38,7 +38,7 @@ class SubstrateSdk with ChangeNotifier { int blocNumber = 0; bool isLoadingEndpoint = false; Map transactionStatus = {}; - static const int initSs58 = 42; + final int initSs58 = 42; Map currencyParameters = {}; final csSalt = TextEditingController(); final csPassword = TextEditingController(); @@ -890,7 +890,6 @@ class SubstrateSdk with ChangeNotifier { Future getBalanceAndIdtyStatus( String fromAddress, String toAddress) async { - final sub = Provider.of(homeContext, listen: false); bool canValidate = false; String validationStatus = ''; @@ -908,7 +907,9 @@ class SubstrateSdk with ChangeNotifier { final isSmithData = await isSmith(fromAddress); // Check conditions to set 'canValidate' and 'validationStatus' - if (transferableBalance != 0 && !fromHasConsumer) { + if (transferableBalance != 0 && + !fromHasConsumer && + await isAddress(toAddress)) { canValidate = true; } else if (toIdtyStatus != IdtyStatus.none && fromIdtyStatus != IdtyStatus.none) { @@ -921,14 +922,9 @@ class SubstrateSdk with ChangeNotifier { validationStatus = 'thisAccountIsEmpty'.tr(); } - if (sub.g1V1NewAddress == '') { - validationStatus = ''; - } - return MigrateWalletChecks( balance: fromBalance, idtyStatus: toIdtyStatus, - isSmith: isSmithData, validationStatus: validationStatus, canValidate: canValidate, ); diff --git a/lib/providers/wallets_profiles.dart b/lib/providers/wallets_profiles.dart index d134b46..a26c789 100644 --- a/lib/providers/wallets_profiles.dart +++ b/lib/providers/wallets_profiles.dart @@ -6,10 +6,12 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:provider/provider.dart'; class WalletsProfilesProvider with ChangeNotifier { WalletsProfilesProvider(this.address); @@ -35,7 +37,7 @@ class WalletsProfilesProvider with ChangeNotifier { log.e("BarcodeScanner ERR: $e"); return 'false'; } - if (isAddress(barcode.rawContent)) { + if (await isAddress(barcode.rawContent)) { address = barcode.rawContent; Navigator.popUntil( context, @@ -93,20 +95,26 @@ class WalletsProfilesProvider with ChangeNotifier { } } -bool isAddress(address) { - final RegExp regExp = RegExp( - r'^[a-zA-Z0-9]+$', - caseSensitive: false, - multiLine: false, - ); +// bool isAddress(address) { +// final RegExp regExp = RegExp( +// r'^[a-zA-Z0-9]+$', +// caseSensitive: false, +// multiLine: false, +// ); - if (regExp.hasMatch(address) == true && - address.length > 45 && - address.length < 52) { - return true; - } else { - return false; - } +// if (regExp.hasMatch(address) == true && +// address.length > 45 && +// address.length < 52) { +// return true; +// } else { +// return false; +// } +// } + +Future isAddress(String address) async { + final sub = Provider.of(homeContext, listen: false); + return await sub.sdk.api.account.checkAddressFormat(address, sub.initSs58) ?? + false; } snackMessage(context, diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index f6b5f0a..80ed6c1 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -91,9 +91,10 @@ class ImportG1v1 extends StatelessWidget { keyboardType: TextInputType.text, controller: sub.csSalt, obscureText: !sub.isCesiumIDVisible, - style: scaledTextStyle(fontSize: 16), + style: scaledTextStyle(fontSize: 14), decoration: InputDecoration( hintText: 'enterCesiumId'.tr(), + hintStyle: scaledTextStyle(fontSize: 14), suffixIcon: IconButton( key: keyCesiumIdVisible, icon: Icon( @@ -132,9 +133,10 @@ class ImportG1v1 extends StatelessWidget { keyboardType: TextInputType.text, controller: sub.csPassword, obscureText: !sub.isCesiumIDVisible, - style: scaledTextStyle(fontSize: 16), + style: scaledTextStyle(fontSize: 14), decoration: InputDecoration( hintText: 'enterCesiumPassword'.tr(), + hintStyle: scaledTextStyle(fontSize: 14), suffixIcon: IconButton( icon: Icon( sub.isCesiumIDVisible @@ -167,7 +169,7 @@ class ImportG1v1 extends StatelessWidget { child: Text( 'v1: ${getShortPubkey(sub.g1V1OldPubkey)}', style: scaledTextStyle( - fontSize: 17, + fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Monospace'), ), @@ -183,7 +185,7 @@ class ImportG1v1 extends StatelessWidget { child: Text( 'v2: ${getShortPubkey(sub.g1V1NewAddress)}', style: scaledTextStyle( - fontSize: 17, + fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Monospace'), ), @@ -212,7 +214,7 @@ class ImportG1v1 extends StatelessWidget { ScaledSizedBox(height: 20), Text( 'migrateToThisWallet'.tr(), - style: scaledTextStyle(fontSize: 17), + style: scaledTextStyle(fontSize: 16), ), ScaledSizedBox(height: 5), DropdownButtonHideUnderline( @@ -226,7 +228,7 @@ class ImportG1v1 extends StatelessWidget { value: wallet, child: Text( wallet.name!, - style: scaledTextStyle(fontSize: 17), + style: scaledTextStyle(fontSize: 16), ), ); }).toList(), @@ -292,7 +294,7 @@ class ImportG1v1 extends StatelessWidget { child: Text( 'migrateAccount'.tr(), style: scaledTextStyle( - fontSize: 20, fontWeight: FontWeight.w600), + fontSize: 19, fontWeight: FontWeight.w600), ), ), ), @@ -301,7 +303,7 @@ class ImportG1v1 extends StatelessWidget { statusData.validationStatus, textAlign: TextAlign.center, style: scaledTextStyle( - fontSize: 14, color: Colors.grey[600]), + fontSize: 12, color: Colors.grey[600]), ) ]); }); diff --git a/lib/screens/myWallets/migrate_identity.dart b/lib/screens/myWallets/migrate_identity.dart index ced07f1..dc44cc3 100644 --- a/lib/screens/myWallets/migrate_identity.dart +++ b/lib/screens/myWallets/migrate_identity.dart @@ -9,12 +9,15 @@ import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; +import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; +import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/widgets/commons/top_appbar.dart'; +import 'package:polkawallet_sdk/api/apiKeyring.dart'; import 'package:provider/provider.dart'; class MigrateIdentityScreen extends StatelessWidget { @@ -22,190 +25,251 @@ class MigrateIdentityScreen extends StatelessWidget { @override Widget build(BuildContext context) { - // final _homeProvider = Provider.of(context); final walletOptions = Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); + final generatedWalletsProvider = + Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); + final sub = Provider.of(context, listen: false); final fromAddress = walletOptions.address.text; - final defaultWallet = myWalletProvider.getDefaultWallet(); - final walletsList = myWalletProvider.listWallets.toList(); - late WalletData selectedWallet; - - if (fromAddress == defaultWallet.address) { - selectedWallet = - walletsList[fromAddress == walletsList[0].address ? 1 : 0]; - } else { - selectedWallet = defaultWallet; - } + final newMnemonicSentence = TextEditingController(); + final newWalletAddress = TextEditingController(); final mdStyle = MarkdownStyleSheet( - p: scaledTextStyle(fontSize: 17, color: Colors.black, letterSpacing: 0.3), + p: scaledTextStyle(fontSize: 16, color: Colors.black, letterSpacing: 0.3), textAlign: WrapAlignment.center, ); + final bool isUdUnit = configBox.get('isUdUnit') ?? false; + final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName; - if (walletsList.length < 2) { - return Column( - children: [ - ScaledSizedBox(height: 80), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération', - style: scaledTextStyle(fontSize: 17), - ) - ], - ) - ], + var statusData = const MigrateWalletChecks.defaultValues(); + var mnemonicIsValid = false; + int? matchDerivationNbr; + String matchInfo = ''; + + Future scanDerivations() async { + if (!await isAddress(newWalletAddress.text) || + !await sub.isMnemonicValid(newMnemonicSentence.text) || + !statusData.canValidate) { + mnemonicIsValid = false; + matchInfo = ''; + walletOptions.reload(); + return; + } + log.d('Scan derivations to find a match'); + + //Scan root wallet + final addressData = await sub.sdk.api.keyring.addressFromMnemonic( + sub.currencyParameters['ss58']!, + cryptoType: CryptoType.sr25519, + mnemonic: newMnemonicSentence.text, ); + + if (addressData.address == newWalletAddress.text) { + matchDerivationNbr = -1; + mnemonicIsValid = true; + walletOptions.reload(); + return; + } + + //Scan derivations + for (int derivationNbr in [ + for (var i = 0; i < generatedWalletsProvider.numberScan; i += 1) i + ]) { + final addressData = await sub.sdk.api.keyring.addressFromMnemonic( + sub.currencyParameters['ss58']!, + cryptoType: CryptoType.sr25519, + mnemonic: newMnemonicSentence.text, + derivePath: '//$derivationNbr'); + + if (addressData.address == newWalletAddress.text) { + matchDerivationNbr = derivationNbr; + mnemonicIsValid = true; + matchInfo = "youCanMigrateThisIdentity".tr(); + break; + } else { + mnemonicIsValid = false; + } + } + + if (!mnemonicIsValid) { + matchInfo = "addressNotBelongToMnemonic".tr(); + } + walletOptions.reload(); } return Scaffold( backgroundColor: backgroundColor, appBar: GeckoAppBar('migrateIdentity'.tr()), body: SafeArea( - child: Consumer(builder: (context, sub, _) { - return FutureBuilder( - future: sub.getBalanceAndIdtyStatus( - fromAddress, selectedWallet.address), - builder: (BuildContext context, - AsyncSnapshot status) { - if (status.data == null) { - return Column(children: [ - ScaledSizedBox(height: 80), - Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - ScaledSizedBox( - height: scaleSize(32), - width: scaleSize(32), - child: CircularProgressIndicator( - color: orangeC, - strokeWidth: scaleSize(4), - ), - ), - ]), - ]); + child: Column(children: [ + const Row(children: []), + ScaledSizedBox(height: 18), + ScaledSizedBox( + width: 320, + child: MarkdownBody( + data: 'areYouSureMigrateIdentity'.tr(args: [ + duniterIndexer.walletNameIndexer[fromAddress] ?? '???', + '${walletOptions.balanceCache[fromAddress]} $unit' + ]), + styleSheet: mdStyle), + ), + ScaledSizedBox(height: 55), + Text('migrateToThisWallet'.tr(), + style: scaledTextStyle(fontSize: 16)), + ScaledSizedBox(height: 5), + ScaledSizedBox( + width: 320, + child: TextField( + controller: newMnemonicSentence, + autofocus: true, + minLines: 2, + maxLines: 2, + style: scaledTextStyle(fontSize: 14), + decoration: InputDecoration( + icon: Image.asset( + 'assets/onBoarding/phrase_de_restauration_flou.png', + width: scaleSize(30), + ), + hintText: 'enterYourNewMnemonic'.tr(), + hintStyle: scaledTextStyle(fontSize: 14), + focusedBorder: const UnderlineInputBorder( + borderSide: BorderSide(color: orangeC), + ), + ), + onChanged: (newMnemonic) async { + await scanDerivations(); + }, + ), + ), + ScaledSizedBox(height: 5), + ScaledSizedBox( + width: 320, + child: TextField( + controller: newWalletAddress, + style: scaledTextStyle(fontSize: 14), + decoration: InputDecoration( + icon: Image.asset( + 'assets/walletOptions/key.png', + height: scaleSize(30), + ), + hintText: 'enterYourNewAddress'.tr(args: [currencyName]), + hintStyle: scaledTextStyle(fontSize: 14), + focusedBorder: const UnderlineInputBorder( + borderSide: BorderSide(color: orangeC), + ), + ), + onChanged: (newAddress) async { + if (await isAddress(newAddress)) { + statusData = await sub.getBalanceAndIdtyStatus( + fromAddress, newAddress); + await scanDerivations(); + } else { + statusData = const MigrateWalletChecks.defaultValues(); + matchInfo = ''; + walletOptions.reload(); } + }, + ), + ), + const Spacer(flex: 2), + Consumer(builder: (context, _, __) { + return ScaledSizedBox( + width: 320, + height: 55, + child: ElevatedButton( + key: keyConfirm, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, + ), + onPressed: statusData.canValidate && mnemonicIsValid + ? () async { + WalletData? defaultWallet = + myWalletProvider.getDefaultWallet(); - final statusData = status.data!; - final walletsList = myWalletProvider.listWallets.toList(); + String? pin; + if (myWalletProvider.pinCode == '') { + pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + if (myWalletProvider.pinCode == '') return; - walletsList - .removeWhere((element) => element.address == fromAddress); + await sub.importAccount( + mnemonic: newMnemonicSentence.text, + derivePath: matchDerivationNbr == -1 + ? '' + : "//$matchDerivationNbr", + password: 'password'); - final bool isUdUnit = configBox.get('isUdUnit') ?? false; - final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName; + final transactionId = await sub.migrateIdentity( + fromAddress: fromAddress, + destAddress: newWalletAddress.text, + fromPassword: pin ?? myWalletProvider.pinCode, + destPassword: 'password', + withBalance: true, + fromBalance: statusData.balance); - return Column(children: [ - const Row(children: []), - ScaledSizedBox(height: 18), - ScaledSizedBox( - width: 320, - child: MarkdownBody( - data: 'areYouSureMigrateIdentity'.tr(args: [ - duniterIndexer.walletNameIndexer[fromAddress] ?? - '???', - '${statusData.balance['transferableBalance']} $unit' - ]), - styleSheet: mdStyle), - ), - ScaledSizedBox(height: 55), - Text('migrateToThisWallet'.tr(), - style: scaledTextStyle(fontSize: 17)), - ScaledSizedBox(height: 5), - DropdownButtonHideUnderline( - key: keySelectWallet, - child: DropdownButton( - value: selectedWallet, - icon: const Icon(Icons.keyboard_arrow_down), - items: walletsList.map((wallet) { - return DropdownMenuItem( - key: keySelectThisWallet(wallet.address), - value: wallet, - child: Text( - wallet.name!, - style: scaledTextStyle(fontSize: 17), - ), + sub.deleteAccounts([newWalletAddress.text]); + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transactionId: transactionId, + transType: 'identityMigration', + fromAddress: getShortPubkey(fromAddress), + toAddress: + getShortPubkey(newWalletAddress.text)); + }), ); - }).toList(), - onChanged: (WalletData? newSelectedWallet) { - selectedWallet = newSelectedWallet!; - sub.reload(); - }, - ), - ), - const Spacer(flex: 2), - ScaledSizedBox( - width: 320, - height: 55, - child: ElevatedButton( - key: keyConfirm, - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - elevation: 4, - backgroundColor: orangeC, - ), - onPressed: statusData.canValidate - ? () async { - WalletData? defaultWallet = - myWalletProvider.getDefaultWallet(); - - String? pin; - if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( - context, - MaterialPageRoute( - builder: (homeContext) { - return UnlockingWallet( - wallet: defaultWallet); - }, - ), - ); - } - - if (myWalletProvider.pinCode == '') return; - final transactionId = await sub.migrateIdentity( - fromAddress: fromAddress, - destAddress: selectedWallet.address, - fromPassword: pin ?? myWalletProvider.pinCode, - destPassword: pin ?? myWalletProvider.pinCode, - withBalance: true, - fromBalance: statusData.balance); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return TransactionInProgress( - transactionId: transactionId, - transType: 'identityMigration', - fromAddress: getShortPubkey(fromAddress), - toAddress: getShortPubkey( - selectedWallet.address)); - }), - ); - } - : null, - child: Text( - 'migrateIdentity'.tr(), - style: scaledTextStyle( - fontSize: 20, - fontWeight: FontWeight.w600, - color: Colors.white), - ), - ), - ), + } + : null, + child: Text( + 'migrateIdentity'.tr(), + style: scaledTextStyle( + fontSize: 19, + fontWeight: FontWeight.w600, + color: Colors.white), + ), + ), + ); + }), + Consumer(builder: (context, _, __) { + return ScaledSizedBox( + width: 320, + child: Column( + children: [ ScaledSizedBox(height: 10), Text( statusData.validationStatus, textAlign: TextAlign.center, style: - scaledTextStyle(fontSize: 15, color: Colors.grey[600]), + scaledTextStyle(fontSize: 12, color: Colors.grey[600]), ), - const Spacer(), - ]); - }); - }), + ScaledSizedBox(height: 5), + Text( + matchInfo, + textAlign: TextAlign.center, + style: + scaledTextStyle(fontSize: 12, color: Colors.grey[600]), + ), + ], + ), + ); + }), + const Spacer(), + ]), ), ); } diff --git a/lib/screens/search.dart b/lib/screens/search.dart index cc984c0..4bf41f7 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -32,7 +32,7 @@ class _SearchScreenState extends State { final searchProvider = Provider.of(context, listen: false); final clipboard = await Clipboard.getData('text/plain'); pastedAddress = clipboard?.text ?? ''; - canPasteAddress = isAddress(pastedAddress); + canPasteAddress = await isAddress(pastedAddress); searchProvider.reload(); } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 2cd16a6..691b064 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -27,7 +27,7 @@ class SettingsScreen extends StatelessWidget { ScaledSizedBox(height: 30), Text( 'networkSettings'.tr(), - style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20), + style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 19), ), ScaledSizedBox(height: 20), duniterEndpointSelection(context), @@ -36,7 +36,7 @@ class SettingsScreen extends StatelessWidget { ScaledSizedBox(height: 35), Text( 'displaySettings'.tr(), - style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20), + style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 19), ), ScaledSizedBox(height: 20), chooseCurrencyUnit(context), @@ -56,7 +56,7 @@ class SettingsScreen extends StatelessWidget { child: Text( 'forgetAllMyChests'.tr(), style: scaledTextStyle( - fontSize: 18, + fontSize: 17, color: const Color(0xffD80000), fontWeight: FontWeight.w600, ), @@ -83,14 +83,14 @@ class SettingsScreen extends StatelessWidget { child: Row( children: [ ScaledSizedBox(width: 12), - Text('showUdAmounts'.tr(), style: scaledTextStyle(fontSize: 16)), + Text('showUdAmounts'.tr(), style: scaledTextStyle(fontSize: 15)), const Spacer(), Consumer(builder: (context, homeProvider, _) { final bool isUdUnit = configBox.get('isUdUnit') ?? false; return Icon( isUdUnit ? Icons.check_box : Icons.check_box_outline_blank, color: orangeC, - size: scaleSize(30), + size: scaleSize(27), ); }), ScaledSizedBox(width: 30), @@ -141,7 +141,7 @@ class SettingsScreen extends StatelessWidget { width: 55, child: Text( 'currencyNode'.tr(), - style: scaledTextStyle(fontSize: 16), + style: scaledTextStyle(fontSize: 15), ), ), const Spacer(), @@ -161,7 +161,7 @@ class SettingsScreen extends StatelessWidget { return DropdownButtonHideUnderline( key: keySelectDuniterNodeDropDown, child: DropdownButton( - style: scaledTextStyle(fontSize: 16, color: Colors.black), + style: scaledTextStyle(fontSize: 15, color: Colors.black), value: selectedDuniterEndpoint, icon: const Icon(Icons.keyboard_arrow_down), items: duniterBootstrapNodes @@ -229,7 +229,7 @@ class SettingsScreen extends StatelessWidget { key: keyCustomDuniterEndpoint, controller: endpointController, autocorrect: false, - style: scaledTextStyle(fontSize: 16), + style: scaledTextStyle(fontSize: 15), ), ), ); @@ -293,7 +293,7 @@ class SettingsScreen extends StatelessWidget { ScaledSizedBox(width: 5), ScaledSizedBox( width: 55, - child: Text('Indexer', style: scaledTextStyle(fontSize: 16)), + child: Text('Indexer', style: scaledTextStyle(fontSize: 15)), ), const Spacer(), Icon(indexerEndpoint != '' ? Icons.check : Icons.close), @@ -303,7 +303,7 @@ class SettingsScreen extends StatelessWidget { child: Consumer(builder: (context, set, _) { return DropdownButtonHideUnderline( child: DropdownButton( - style: scaledTextStyle(fontSize: 16, color: Colors.black), + style: scaledTextStyle(fontSize: 15, color: Colors.black), value: selectedIndexerEndpoint, icon: const Icon(Icons.keyboard_arrow_down), items: @@ -366,7 +366,7 @@ class SettingsScreen extends StatelessWidget { child: TextField( controller: indexerEndpointController, autocorrect: false, - style: scaledTextStyle(fontSize: 16), + style: scaledTextStyle(fontSize: 15), ), ), );