feat: can migrate identity to external address
This commit is contained in:
parent
20590a944c
commit
93c9b377ba
|
@ -229,5 +229,9 @@
|
||||||
"gotit": "Got it",
|
"gotit": "Got it",
|
||||||
"moreInfo": "More information",
|
"moreInfo": "More information",
|
||||||
"keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.",
|
"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",
|
"gotit": "Got it",
|
||||||
"moreInfo": "More information",
|
"moreInfo": "More information",
|
||||||
"keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.",
|
"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",
|
"gotit": "J'ai compris",
|
||||||
"moreInfo": "Plus d'info",
|
"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.",
|
"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": {
|
"identities": {
|
||||||
"test1": {
|
"test1": {
|
||||||
"index": 0,
|
"index": 0,
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
},
|
},
|
||||||
"owner_pubkey": "5LqbvutJtRTHvnforyndwPbkC4Kf5cJtdRQaDcHoMi8S"
|
"owner_pubkey": "5LqbvutJtRTHvnforyndwPbkC4Kf5cJtdRQaDcHoMi8S"
|
||||||
},
|
},
|
||||||
"testCesium1": {
|
"test5": {
|
||||||
"index": 4,
|
"index": 4,
|
||||||
"balance": 10000,
|
"balance": 10000,
|
||||||
"membership_expire_on": 1705509948,
|
"membership_expire_on": 1705509948,
|
||||||
|
@ -59,6 +59,18 @@
|
||||||
"test2": 1727758466,
|
"test2": 1727758466,
|
||||||
"test3": 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"
|
"owner_pubkey": "DCovzCEnQm9GUWe6mr8u42JR1JAuoj3HbQUGdCkfTzSr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,30 @@ import 'package:gecko/models/wallet_data.dart';
|
||||||
class MigrateWalletChecks {
|
class MigrateWalletChecks {
|
||||||
final Map balance;
|
final Map balance;
|
||||||
final IdtyStatus idtyStatus;
|
final IdtyStatus idtyStatus;
|
||||||
final bool isSmith;
|
|
||||||
final String validationStatus;
|
final String validationStatus;
|
||||||
final bool canValidate;
|
final bool canValidate;
|
||||||
|
|
||||||
const MigrateWalletChecks(
|
const MigrateWalletChecks({
|
||||||
{required this.balance,
|
required this.balance,
|
||||||
required this.idtyStatus,
|
required this.idtyStatus,
|
||||||
required this.isSmith,
|
required this.validationStatus,
|
||||||
required this.validationStatus,
|
required this.canValidate,
|
||||||
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/');
|
final avatarFolder = Directory('${directory.path}/avatars/');
|
||||||
if (await avatarFolder.exists()) {
|
if (await avatarFolder.exists()) {
|
||||||
await avatarFolder.delete(recursive: true);
|
await avatarFolder.delete(recursive: true);
|
||||||
|
await avatarFolder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
myWalletProvider.pinCode = '';
|
myWalletProvider.pinCode = '';
|
||||||
|
|
|
@ -12,7 +12,7 @@ class SearchProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<G1WalletsList>> searchAddress() async {
|
Future<List<G1WalletsList>> searchAddress() async {
|
||||||
if (isAddress(searchController.text)) {
|
if (await isAddress(searchController.text)) {
|
||||||
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
||||||
return [wallet];
|
return [wallet];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -38,7 +38,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
int blocNumber = 0;
|
int blocNumber = 0;
|
||||||
bool isLoadingEndpoint = false;
|
bool isLoadingEndpoint = false;
|
||||||
Map transactionStatus = {};
|
Map transactionStatus = {};
|
||||||
static const int initSs58 = 42;
|
final int initSs58 = 42;
|
||||||
Map<String, int> currencyParameters = {};
|
Map<String, int> currencyParameters = {};
|
||||||
final csSalt = TextEditingController();
|
final csSalt = TextEditingController();
|
||||||
final csPassword = TextEditingController();
|
final csPassword = TextEditingController();
|
||||||
|
@ -890,7 +890,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
|
|
||||||
Future<MigrateWalletChecks> getBalanceAndIdtyStatus(
|
Future<MigrateWalletChecks> getBalanceAndIdtyStatus(
|
||||||
String fromAddress, String toAddress) async {
|
String fromAddress, String toAddress) async {
|
||||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
|
||||||
bool canValidate = false;
|
bool canValidate = false;
|
||||||
String validationStatus = '';
|
String validationStatus = '';
|
||||||
|
|
||||||
|
@ -908,7 +907,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
final isSmithData = await isSmith(fromAddress);
|
final isSmithData = await isSmith(fromAddress);
|
||||||
|
|
||||||
// Check conditions to set 'canValidate' and 'validationStatus'
|
// Check conditions to set 'canValidate' and 'validationStatus'
|
||||||
if (transferableBalance != 0 && !fromHasConsumer) {
|
if (transferableBalance != 0 &&
|
||||||
|
!fromHasConsumer &&
|
||||||
|
await isAddress(toAddress)) {
|
||||||
canValidate = true;
|
canValidate = true;
|
||||||
} else if (toIdtyStatus != IdtyStatus.none &&
|
} else if (toIdtyStatus != IdtyStatus.none &&
|
||||||
fromIdtyStatus != IdtyStatus.none) {
|
fromIdtyStatus != IdtyStatus.none) {
|
||||||
|
@ -921,14 +922,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
validationStatus = 'thisAccountIsEmpty'.tr();
|
validationStatus = 'thisAccountIsEmpty'.tr();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sub.g1V1NewAddress == '') {
|
|
||||||
validationStatus = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return MigrateWalletChecks(
|
return MigrateWalletChecks(
|
||||||
balance: fromBalance,
|
balance: fromBalance,
|
||||||
idtyStatus: toIdtyStatus,
|
idtyStatus: toIdtyStatus,
|
||||||
isSmith: isSmithData,
|
|
||||||
validationStatus: validationStatus,
|
validationStatus: validationStatus,
|
||||||
canValidate: canValidate,
|
canValidate: canValidate,
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,10 +6,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/g1_wallets_list.dart';
|
import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
import 'package:gecko/models/scale_functions.dart';
|
import 'package:gecko/models/scale_functions.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
import 'package:jdenticon_dart/jdenticon_dart.dart';
|
import 'package:jdenticon_dart/jdenticon_dart.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:barcode_scan2/barcode_scan2.dart';
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class WalletsProfilesProvider with ChangeNotifier {
|
class WalletsProfilesProvider with ChangeNotifier {
|
||||||
WalletsProfilesProvider(this.address);
|
WalletsProfilesProvider(this.address);
|
||||||
|
@ -35,7 +37,7 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
log.e("BarcodeScanner ERR: $e");
|
log.e("BarcodeScanner ERR: $e");
|
||||||
return 'false';
|
return 'false';
|
||||||
}
|
}
|
||||||
if (isAddress(barcode.rawContent)) {
|
if (await isAddress(barcode.rawContent)) {
|
||||||
address = barcode.rawContent;
|
address = barcode.rawContent;
|
||||||
Navigator.popUntil(
|
Navigator.popUntil(
|
||||||
context,
|
context,
|
||||||
|
@ -93,20 +95,26 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAddress(address) {
|
// bool isAddress(address) {
|
||||||
final RegExp regExp = RegExp(
|
// final RegExp regExp = RegExp(
|
||||||
r'^[a-zA-Z0-9]+$',
|
// r'^[a-zA-Z0-9]+$',
|
||||||
caseSensitive: false,
|
// caseSensitive: false,
|
||||||
multiLine: false,
|
// multiLine: false,
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (regExp.hasMatch(address) == true &&
|
// if (regExp.hasMatch(address) == true &&
|
||||||
address.length > 45 &&
|
// address.length > 45 &&
|
||||||
address.length < 52) {
|
// address.length < 52) {
|
||||||
return true;
|
// return true;
|
||||||
} else {
|
// } else {
|
||||||
return false;
|
// 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,
|
snackMessage(context,
|
||||||
|
|
|
@ -91,9 +91,10 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
controller: sub.csSalt,
|
controller: sub.csSalt,
|
||||||
obscureText: !sub.isCesiumIDVisible,
|
obscureText: !sub.isCesiumIDVisible,
|
||||||
style: scaledTextStyle(fontSize: 16),
|
style: scaledTextStyle(fontSize: 14),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'enterCesiumId'.tr(),
|
hintText: 'enterCesiumId'.tr(),
|
||||||
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
key: keyCesiumIdVisible,
|
key: keyCesiumIdVisible,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
@ -132,9 +133,10 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
controller: sub.csPassword,
|
controller: sub.csPassword,
|
||||||
obscureText: !sub.isCesiumIDVisible,
|
obscureText: !sub.isCesiumIDVisible,
|
||||||
style: scaledTextStyle(fontSize: 16),
|
style: scaledTextStyle(fontSize: 14),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'enterCesiumPassword'.tr(),
|
hintText: 'enterCesiumPassword'.tr(),
|
||||||
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
sub.isCesiumIDVisible
|
sub.isCesiumIDVisible
|
||||||
|
@ -167,7 +169,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
'v1: ${getShortPubkey(sub.g1V1OldPubkey)}',
|
'v1: ${getShortPubkey(sub.g1V1OldPubkey)}',
|
||||||
style: scaledTextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 17,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
fontFamily: 'Monospace'),
|
fontFamily: 'Monospace'),
|
||||||
),
|
),
|
||||||
|
@ -183,7 +185,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
'v2: ${getShortPubkey(sub.g1V1NewAddress)}',
|
'v2: ${getShortPubkey(sub.g1V1NewAddress)}',
|
||||||
style: scaledTextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 17,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
fontFamily: 'Monospace'),
|
fontFamily: 'Monospace'),
|
||||||
),
|
),
|
||||||
|
@ -212,7 +214,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
ScaledSizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
'migrateToThisWallet'.tr(),
|
'migrateToThisWallet'.tr(),
|
||||||
style: scaledTextStyle(fontSize: 17),
|
style: scaledTextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
ScaledSizedBox(height: 5),
|
ScaledSizedBox(height: 5),
|
||||||
DropdownButtonHideUnderline(
|
DropdownButtonHideUnderline(
|
||||||
|
@ -226,7 +228,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
value: wallet,
|
value: wallet,
|
||||||
child: Text(
|
child: Text(
|
||||||
wallet.name!,
|
wallet.name!,
|
||||||
style: scaledTextStyle(fontSize: 17),
|
style: scaledTextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
@ -292,7 +294,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
'migrateAccount'.tr(),
|
'migrateAccount'.tr(),
|
||||||
style: scaledTextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20, fontWeight: FontWeight.w600),
|
fontSize: 19, fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -301,7 +303,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
statusData.validationStatus,
|
statusData.validationStatus,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: scaledTextStyle(
|
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/wallet_data.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.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/my_wallets.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/providers/wallet_options.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/myWallets/unlocking_wallet.dart';
|
||||||
import 'package:gecko/screens/transaction_in_progress.dart';
|
import 'package:gecko/screens/transaction_in_progress.dart';
|
||||||
import 'package:gecko/widgets/commons/top_appbar.dart';
|
import 'package:gecko/widgets/commons/top_appbar.dart';
|
||||||
|
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MigrateIdentityScreen extends StatelessWidget {
|
class MigrateIdentityScreen extends StatelessWidget {
|
||||||
|
@ -22,190 +25,251 @@ class MigrateIdentityScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// final _homeProvider = Provider.of<HomeProvider>(context);
|
|
||||||
final walletOptions =
|
final walletOptions =
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
final myWalletProvider =
|
final myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
|
final generatedWalletsProvider =
|
||||||
|
Provider.of<GenerateWalletsProvider>(context, listen: false);
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(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 fromAddress = walletOptions.address.text;
|
||||||
final defaultWallet = myWalletProvider.getDefaultWallet();
|
final newMnemonicSentence = TextEditingController();
|
||||||
final walletsList = myWalletProvider.listWallets.toList();
|
final newWalletAddress = TextEditingController();
|
||||||
late WalletData selectedWallet;
|
|
||||||
|
|
||||||
if (fromAddress == defaultWallet.address) {
|
|
||||||
selectedWallet =
|
|
||||||
walletsList[fromAddress == walletsList[0].address ? 1 : 0];
|
|
||||||
} else {
|
|
||||||
selectedWallet = defaultWallet;
|
|
||||||
}
|
|
||||||
|
|
||||||
final mdStyle = MarkdownStyleSheet(
|
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,
|
textAlign: WrapAlignment.center,
|
||||||
);
|
);
|
||||||
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
||||||
|
|
||||||
if (walletsList.length < 2) {
|
var statusData = const MigrateWalletChecks.defaultValues();
|
||||||
return Column(
|
var mnemonicIsValid = false;
|
||||||
children: [
|
int? matchDerivationNbr;
|
||||||
ScaledSizedBox(height: 80),
|
String matchInfo = '';
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
Future scanDerivations() async {
|
||||||
children: [
|
if (!await isAddress(newWalletAddress.text) ||
|
||||||
Text(
|
!await sub.isMnemonicValid(newMnemonicSentence.text) ||
|
||||||
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
|
!statusData.canValidate) {
|
||||||
style: scaledTextStyle(fontSize: 17),
|
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(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: GeckoAppBar('migrateIdentity'.tr()),
|
appBar: GeckoAppBar('migrateIdentity'.tr()),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
child: Column(children: <Widget>[
|
||||||
return FutureBuilder(
|
const Row(children: []),
|
||||||
future: sub.getBalanceAndIdtyStatus(
|
ScaledSizedBox(height: 18),
|
||||||
fromAddress, selectedWallet.address),
|
ScaledSizedBox(
|
||||||
builder: (BuildContext context,
|
width: 320,
|
||||||
AsyncSnapshot<MigrateWalletChecks> status) {
|
child: MarkdownBody(
|
||||||
if (status.data == null) {
|
data: 'areYouSureMigrateIdentity'.tr(args: [
|
||||||
return Column(children: [
|
duniterIndexer.walletNameIndexer[fromAddress] ?? '???',
|
||||||
ScaledSizedBox(height: 80),
|
'${walletOptions.balanceCache[fromAddress]} $unit'
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
]),
|
||||||
ScaledSizedBox(
|
styleSheet: mdStyle),
|
||||||
height: scaleSize(32),
|
),
|
||||||
width: scaleSize(32),
|
ScaledSizedBox(height: 55),
|
||||||
child: CircularProgressIndicator(
|
Text('migrateToThisWallet'.tr(),
|
||||||
color: orangeC,
|
style: scaledTextStyle(fontSize: 16)),
|
||||||
strokeWidth: scaleSize(4),
|
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!;
|
String? pin;
|
||||||
final walletsList = myWalletProvider.listWallets.toList();
|
if (myWalletProvider.pinCode == '') {
|
||||||
|
pin = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (homeContext) {
|
||||||
|
return UnlockingWallet(wallet: defaultWallet);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (myWalletProvider.pinCode == '') return;
|
||||||
|
|
||||||
walletsList
|
await sub.importAccount(
|
||||||
.removeWhere((element) => element.address == fromAddress);
|
mnemonic: newMnemonicSentence.text,
|
||||||
|
derivePath: matchDerivationNbr == -1
|
||||||
|
? ''
|
||||||
|
: "//$matchDerivationNbr",
|
||||||
|
password: 'password');
|
||||||
|
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
final transactionId = await sub.migrateIdentity(
|
||||||
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
fromAddress: fromAddress,
|
||||||
|
destAddress: newWalletAddress.text,
|
||||||
|
fromPassword: pin ?? myWalletProvider.pinCode,
|
||||||
|
destPassword: 'password',
|
||||||
|
withBalance: true,
|
||||||
|
fromBalance: statusData.balance);
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
sub.deleteAccounts([newWalletAddress.text]);
|
||||||
const Row(children: []),
|
Navigator.pop(context);
|
||||||
ScaledSizedBox(height: 18),
|
Navigator.push(
|
||||||
ScaledSizedBox(
|
context,
|
||||||
width: 320,
|
MaterialPageRoute(builder: (context) {
|
||||||
child: MarkdownBody(
|
return TransactionInProgress(
|
||||||
data: 'areYouSureMigrateIdentity'.tr(args: [
|
transactionId: transactionId,
|
||||||
duniterIndexer.walletNameIndexer[fromAddress] ??
|
transType: 'identityMigration',
|
||||||
'???',
|
fromAddress: getShortPubkey(fromAddress),
|
||||||
'${statusData.balance['transferableBalance']} $unit'
|
toAddress:
|
||||||
]),
|
getShortPubkey(newWalletAddress.text));
|
||||||
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),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}).toList(),
|
}
|
||||||
onChanged: (WalletData? newSelectedWallet) {
|
: null,
|
||||||
selectedWallet = newSelectedWallet!;
|
child: Text(
|
||||||
sub.reload();
|
'migrateIdentity'.tr(),
|
||||||
},
|
style: scaledTextStyle(
|
||||||
),
|
fontSize: 19,
|
||||||
),
|
fontWeight: FontWeight.w600,
|
||||||
const Spacer(flex: 2),
|
color: Colors.white),
|
||||||
ScaledSizedBox(
|
),
|
||||||
width: 320,
|
),
|
||||||
height: 55,
|
);
|
||||||
child: ElevatedButton(
|
}),
|
||||||
key: keyConfirm,
|
Consumer<WalletOptionsProvider>(builder: (context, _, __) {
|
||||||
style: ElevatedButton.styleFrom(
|
return ScaledSizedBox(
|
||||||
foregroundColor: Colors.white,
|
width: 320,
|
||||||
elevation: 4,
|
child: Column(
|
||||||
backgroundColor: orangeC,
|
children: [
|
||||||
),
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ScaledSizedBox(height: 10),
|
ScaledSizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
statusData.validationStatus,
|
statusData.validationStatus,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style:
|
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 searchProvider = Provider.of<SearchProvider>(context, listen: false);
|
||||||
final clipboard = await Clipboard.getData('text/plain');
|
final clipboard = await Clipboard.getData('text/plain');
|
||||||
pastedAddress = clipboard?.text ?? '';
|
pastedAddress = clipboard?.text ?? '';
|
||||||
canPasteAddress = isAddress(pastedAddress);
|
canPasteAddress = await isAddress(pastedAddress);
|
||||||
searchProvider.reload();
|
searchProvider.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
ScaledSizedBox(height: 30),
|
ScaledSizedBox(height: 30),
|
||||||
Text(
|
Text(
|
||||||
'networkSettings'.tr(),
|
'networkSettings'.tr(),
|
||||||
style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20),
|
style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 19),
|
||||||
),
|
),
|
||||||
ScaledSizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
duniterEndpointSelection(context),
|
duniterEndpointSelection(context),
|
||||||
|
@ -36,7 +36,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
ScaledSizedBox(height: 35),
|
ScaledSizedBox(height: 35),
|
||||||
Text(
|
Text(
|
||||||
'displaySettings'.tr(),
|
'displaySettings'.tr(),
|
||||||
style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20),
|
style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 19),
|
||||||
),
|
),
|
||||||
ScaledSizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
chooseCurrencyUnit(context),
|
chooseCurrencyUnit(context),
|
||||||
|
@ -56,7 +56,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
'forgetAllMyChests'.tr(),
|
'forgetAllMyChests'.tr(),
|
||||||
style: scaledTextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 18,
|
fontSize: 17,
|
||||||
color: const Color(0xffD80000),
|
color: const Color(0xffD80000),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
|
@ -83,14 +83,14 @@ class SettingsScreen extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
ScaledSizedBox(width: 12),
|
ScaledSizedBox(width: 12),
|
||||||
Text('showUdAmounts'.tr(), style: scaledTextStyle(fontSize: 16)),
|
Text('showUdAmounts'.tr(), style: scaledTextStyle(fontSize: 15)),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Consumer<HomeProvider>(builder: (context, homeProvider, _) {
|
Consumer<HomeProvider>(builder: (context, homeProvider, _) {
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
return Icon(
|
return Icon(
|
||||||
isUdUnit ? Icons.check_box : Icons.check_box_outline_blank,
|
isUdUnit ? Icons.check_box : Icons.check_box_outline_blank,
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
size: scaleSize(30),
|
size: scaleSize(27),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
ScaledSizedBox(width: 30),
|
ScaledSizedBox(width: 30),
|
||||||
|
@ -141,7 +141,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
width: 55,
|
width: 55,
|
||||||
child: Text(
|
child: Text(
|
||||||
'currencyNode'.tr(),
|
'currencyNode'.tr(),
|
||||||
style: scaledTextStyle(fontSize: 16),
|
style: scaledTextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
@ -161,7 +161,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
return DropdownButtonHideUnderline(
|
return DropdownButtonHideUnderline(
|
||||||
key: keySelectDuniterNodeDropDown,
|
key: keySelectDuniterNodeDropDown,
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
style: scaledTextStyle(fontSize: 16, color: Colors.black),
|
style: scaledTextStyle(fontSize: 15, color: Colors.black),
|
||||||
value: selectedDuniterEndpoint,
|
value: selectedDuniterEndpoint,
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
items: duniterBootstrapNodes
|
items: duniterBootstrapNodes
|
||||||
|
@ -229,7 +229,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
key: keyCustomDuniterEndpoint,
|
key: keyCustomDuniterEndpoint,
|
||||||
controller: endpointController,
|
controller: endpointController,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
style: scaledTextStyle(fontSize: 16),
|
style: scaledTextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -293,7 +293,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
ScaledSizedBox(width: 5),
|
ScaledSizedBox(width: 5),
|
||||||
ScaledSizedBox(
|
ScaledSizedBox(
|
||||||
width: 55,
|
width: 55,
|
||||||
child: Text('Indexer', style: scaledTextStyle(fontSize: 16)),
|
child: Text('Indexer', style: scaledTextStyle(fontSize: 15)),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Icon(indexerEndpoint != '' ? Icons.check : Icons.close),
|
Icon(indexerEndpoint != '' ? Icons.check : Icons.close),
|
||||||
|
@ -303,7 +303,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
child: Consumer<SettingsProvider>(builder: (context, set, _) {
|
child: Consumer<SettingsProvider>(builder: (context, set, _) {
|
||||||
return DropdownButtonHideUnderline(
|
return DropdownButtonHideUnderline(
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
style: scaledTextStyle(fontSize: 16, color: Colors.black),
|
style: scaledTextStyle(fontSize: 15, color: Colors.black),
|
||||||
value: selectedIndexerEndpoint,
|
value: selectedIndexerEndpoint,
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
items:
|
items:
|
||||||
|
@ -366,7 +366,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: indexerEndpointController,
|
controller: indexerEndpointController,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
style: scaledTextStyle(fontSize: 16),
|
style: scaledTextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue