feat: can migrate identity to external address
This commit is contained in:
parent
20590a944c
commit
93c9b377ba
|
@ -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 !"
|
||||
}
|
|
@ -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 !"
|
||||
}
|
|
@ -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é !"
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = '';
|
||||
|
|
|
@ -12,7 +12,7 @@ class SearchProvider with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<List<G1WalletsList>> searchAddress() async {
|
||||
if (isAddress(searchController.text)) {
|
||||
if (await isAddress(searchController.text)) {
|
||||
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
||||
return [wallet];
|
||||
} else {
|
||||
|
|
|
@ -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<String, int> currencyParameters = {};
|
||||
final csSalt = TextEditingController();
|
||||
final csPassword = TextEditingController();
|
||||
|
@ -890,7 +890,6 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
Future<MigrateWalletChecks> getBalanceAndIdtyStatus(
|
||||
String fromAddress, String toAddress) async {
|
||||
final sub = Provider.of<SubstrateSdk>(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,
|
||||
);
|
||||
|
|
|
@ -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<bool> isAddress(String address) async {
|
||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||
return await sub.sdk.api.account.checkAddressFormat(address, sub.initSs58) ??
|
||||
false;
|
||||
}
|
||||
|
||||
snackMessage(context,
|
||||
|
|
|
@ -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]),
|
||||
)
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -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<HomeProvider>(context);
|
||||
final walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
final generatedWalletsProvider =
|
||||
Provider.of<GenerateWalletsProvider>(context, listen: false);
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||
final sub = Provider.of<SubstrateSdk>(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<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return FutureBuilder(
|
||||
future: sub.getBalanceAndIdtyStatus(
|
||||
fromAddress, selectedWallet.address),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<MigrateWalletChecks> 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: <Widget>[
|
||||
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<WalletOptionsProvider>(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: <Widget>[
|
||||
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<WalletOptionsProvider>(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(),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
final searchProvider = Provider.of<SearchProvider>(context, listen: false);
|
||||
final clipboard = await Clipboard.getData('text/plain');
|
||||
pastedAddress = clipboard?.text ?? '';
|
||||
canPasteAddress = isAddress(pastedAddress);
|
||||
canPasteAddress = await isAddress(pastedAddress);
|
||||
searchProvider.reload();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<HomeProvider>(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<SettingsProvider>(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),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue