From ad601be19ce9e40ef9b137828187c63d9bf5d22a Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 20 Aug 2022 20:08:02 +0200 Subject: [PATCH] can migrate identity from standart mnemonic derivation --- assets/skull_Icon.png | Bin 0 -> 2280 bytes assets/translations/en.json | 5 +- assets/translations/es.json | 5 +- assets/translations/fr.json | 5 +- lib/providers/substrate_sdk.dart | 99 ++++---- lib/providers/wallet_options.dart | 7 +- lib/screens/myWallets/import_g1_v1.dart | 21 +- lib/screens/myWallets/manage_membership.dart | 50 +++- lib/screens/myWallets/migrate_identity.dart | 251 +++++++++++++++++++ lib/screens/transaction_in_progress.dart | 23 +- 10 files changed, 384 insertions(+), 82 deletions(-) create mode 100755 assets/skull_Icon.png create mode 100644 lib/screens/myWallets/migrate_identity.dart diff --git a/assets/skull_Icon.png b/assets/skull_Icon.png new file mode 100755 index 0000000000000000000000000000000000000000..3a789faff538ef15afac47e1a7651b99daf2c05c GIT binary patch literal 2280 zcmeH|`&$x*8plCF&A`hUI%P<56fdRA3u@?51iT?$2wQ2UDXF0*nls8=k$NP>ENxyA zI|x{aW)AU2rlz%3UP?^oa;Ov0g&r$QE5n&{KkPr)vtQ2nJkR(2KJW9qzr5e~hqs6l z76{dc>jMA)C@IK~y6uOym7u4+UB6#H5(5Be{f82Az<;~_KYvLAT7L_`{~5NnwuEE< zKyTk>I*S?>0RU=ggTOkvdOP%YLZAkQM#i7POiVvFGlzeHus~X({%K{6wzae0?cliA z$=Ssf7FM9Xu3yIQmFT>`~gWgrwv22~vXEz;Juj!xN~uDjj6_xk$pfB(b7M*~B{Po9p*N1u(2|2Xk{@@K`=^vo}_$~o2i z!mlsXi%b7qe);P4%A2>VYwzBFSpTTm_-*r(^vhfLo8s>{=4 z+U)}>r>}Y!`<32MykSg^vBrTVd4#OThi6)CmO+1c*0eUlGg_C-kXYvwJGm}q7qpY; zk#ljDz3i@PrjCtvO2FnL0QOhGEue>)q_Rvs=LMgw@=?#nz-hYO&@>SWF*dsZfM&YF z^an7*o@drHCG2Fl-ee|RO_o(RkNUm`1yPg5h@h}BN@!U|i#*OeV?fm3NR$gW0X3lh zRm@bqQNptf79pejVJkous7lltanTFDPz}k8_O;3HGcWOmuwe+AQxgH4kJ|ad43aHQ zaDu5Y`AX|SGsyA%emHD;#R4O`me=e2Vk6annF+6zw08BRCY7AojZp8xon%b3=q@+* zyj2y&ub4@d#y#c7&^?=6xK{cx9~NQn2iIEs@duxTROhSeL{@s1o8*#yjuoFq@G|Ko zw0*08T0;zdo;G;7nxC@E#2xUHSOQ;?+SNc$eMgB0mWE&H2ojTpCjjHsj8PTZvIJQ# zK=Byv^hr{6yN6L?{Rt}!L>RrZts5VO1|7E}v)RVw{=^4ygG_=XSE`gdRY>2+sezq~ zM%^JEfp(ZC!3oE<>vcD7<3OUE@^K>BInhK;4IVI;eM2N!VAj%Z4EuoK9Q%PhG8}Cv zi1#s(3IwHBtz~|bc4t9Q+lCCB*3x;t7z-1+a1iknx9V6Xej3XOwv56Tfm6;Nz45ss zQrs0bN)6(5L|_b4IwHmy_3Ec_Vs&a=u{WGyYd6T|m>6`mp+hCqtOabATahrLv?p{l zJF9($v>&(vM!&OH(_H<{OABy<;#F+cv(7>Wsqah|mRWGW=A)^K3iDUnXw1kntrf*D9|LuK%U<7h?^j#vOLg~?TPgy-6jEc~XHY<{$+oj$p5 z=sICfMTaldAFNPbYFj&JsCG2@(tepu2;w%>x9>Wl!9*POv34B)TK_6_NdX-2UYZ0A zcrHbQNZ@xNxd{%Zuov;t3Qz8aFO9+H1a74MUMyMq=WJrDUv literal 0 HcmV?d00001 diff --git a/assets/translations/en.json b/assets/translations/en.json index 3bdb47f..d3d510a 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -185,5 +185,8 @@ "importOldAccount": "Import your old account", "enterCesiumId": "Enter your Cesium ID", "enterCesiumPassword": "Enter your Cesium password", - "migrateAccount": "Migrate account" + "migrateAccount": "Migrate account", + "migrateIdentity": "Migrate identity", + "identityMigration": "Identity migration", + "areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?" } \ No newline at end of file diff --git a/assets/translations/es.json b/assets/translations/es.json index a081ff7..8994665 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -185,5 +185,8 @@ "importOldAccount": "Import your old account", "enterCesiumId": "Enter your Cesium ID", "enterCesiumPassword": "Enter your Cesium password", - "migrateAccount": "Migrate account" + "migrateAccount": "Migrate account", + "migrateIdentity": "Migrate identity", + "identityMigration": "Identity migration", + "areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?" } \ No newline at end of file diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 43c01b4..26b93ad 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -186,5 +186,8 @@ "importOldAccount": "Importer son ancien compte", "enterCesiumId": "Entrez votre identifiant Cesium", "enterCesiumPassword": "Entrez votre mot de passe Cesium", - "migrateAccount": "Migrer le compte" + "migrateAccount": "Migrer le compte", + "migrateIdentity": "Migrer l'identité", + "identityMigration": "Migration de l'identité", + "areYouSureMigrateIdentity": "Êtes-vous certain de vouloir migrer définitivement l'identité **{}** et son solde de **{}** ?" } \ No newline at end of file diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 6f43a5c..377dc21 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -2,7 +2,6 @@ import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; -import 'package:fast_base58/fast_base58.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; @@ -88,16 +87,29 @@ class SubstrateSdk with ChangeNotifier { ); } + Future _signMessage( + Uint8List message, String address, String password) async { + final params = SignAsExtensionParam(); + params.msgType = "pub(bytes.sign)"; + params.request = { + "address": address, + "data": message, + }; + + final res = await sdk.api.keyring.signAsExtension(password, params); + return res?.signature ?? ''; + } + //////////////////////////////////////////// ////////// 2: GET ONCHAIN STORAGE ////////// //////////////////////////////////////////// - Future getIdentityIndexOf(String address) async { + Future _getIdentityIndexOf(String address) async { return await _getStorage('identity.identityIndexOf("$address")') ?? 0; } Future> getCerts(String address) async { - final idtyIndex = await getIdentityIndexOf(address); + final idtyIndex = await _getIdentityIndexOf(address); final certsReceiver = await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; @@ -105,8 +117,8 @@ class SubstrateSdk with ChangeNotifier { } Future getCertValidityPeriod(String from, String to) async { - final idtyIndexFrom = await getIdentityIndexOf(from); - final idtyIndexTo = await getIdentityIndexOf(to); + final idtyIndexFrom = await _getIdentityIndexOf(from); + final idtyIndexTo = await _getIdentityIndexOf(to); if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; @@ -246,7 +258,7 @@ class SubstrateSdk with ChangeNotifier { } Future getCertMeta(String address) async { - var idtyIndex = await getIdentityIndexOf(address); + var idtyIndex = await _getIdentityIndexOf(address); final certMeta = await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? ''; @@ -255,7 +267,7 @@ class SubstrateSdk with ChangeNotifier { } Future idtyStatus(String address) async { - var idtyIndex = await getIdentityIndexOf(address); + var idtyIndex = await _getIdentityIndexOf(address); if (idtyIndex == 0) { return 'noid'; @@ -287,8 +299,7 @@ class SubstrateSdk with ChangeNotifier { final pubkey = await sdk.api.account.decodeAddress([address]); final String pubkeyHex = pubkey!.keys.first; final pubkeyByte = HEX.decode(pubkeyHex.substring(2)) as Uint8List; - final pubkey58 = Base58Encode(pubkeyByte); - log.d('tatatatata: $pubkey58'); + // final pubkey58 = Base58Encode(pubkeyByte); return pubkeyByte; } @@ -624,22 +635,18 @@ class SubstrateSdk with ChangeNotifier { return g1V1NewAddress; } - Future getBalanceAndIdtyStatus(String address, String myAddress) async { - final balance = - address == '' ? {'transferableBalance': 0} : await getBalance(address); - final thisIdtyStatus = address == '' ? 'noid' : await idtyStatus(address); - final thisHasConsumer = - address == '' ? false : await hasAccountConsumers(address); - final myIdtyStatus = await idtyStatus(myAddress); + Future getBalanceAndIdtyStatus( + String fromAddress, String toAddress) async { + final fromBalance = fromAddress == '' + ? {'transferableBalance': 0} + : await getBalance(fromAddress); + final fromIdtyStatus = + fromAddress == '' ? 'noid' : await idtyStatus(fromAddress); + final fromHasConsumer = + fromAddress == '' ? false : await hasAccountConsumers(fromAddress); + final toIdtyStatus = await idtyStatus(toAddress); - log.d('tatata: $myIdtyStatus'); - - return [ - balance['transferableBalance'], - thisIdtyStatus, - myIdtyStatus, - thisHasConsumer - ]; + return [fromBalance, fromIdtyStatus, toIdtyStatus, fromHasConsumer]; } ////////////////////////////////////// @@ -694,8 +701,8 @@ class SubstrateSdk with ChangeNotifier { final myIdtyStatus = await idtyStatus(fromAddress); final toIdtyStatus = await idtyStatus(toAddress); - final fromIndex = await getIdentityIndexOf(fromAddress); - final toIndex = await getIdentityIndexOf(toAddress); + final fromIndex = await _getIdentityIndexOf(fromAddress); + final toIndex = await _getIdentityIndexOf(toAddress); if (myIdtyStatus != 'Validated') { transactionStatus = 'notMember'; @@ -785,24 +792,12 @@ class SubstrateSdk with ChangeNotifier { return await _executeCall(txInfo, txOptions, password); } - Future signMessage( - Uint8List message, String address, String password) async { - final params = SignAsExtensionParam(); - params.msgType = "pub(bytes.sign)"; - params.request = { - "address": address, - "data": message, - }; - - final res = await sdk.api.keyring.signAsExtension(password, params); - return res?.signature ?? ''; - } - Future migrateIdentity( {required String fromAddress, required String destAddress, - required String formPassword, + required String fromPassword, required String destPassword, + required Map fromBalance, bool withBalance = false}) async { transactionStatus = ''; final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); @@ -818,13 +813,13 @@ class SubstrateSdk with ChangeNotifier { final prefix = 'icok'.codeUnits; final genesisHashString = await getGenesisHash(); final genesisHash = HEX.decode(genesisHashString.substring(2)) as Uint8List; - final idtyIndex = int32bytes(await getIdentityIndexOf(fromAddress)); + final idtyIndex = _int32bytes(await _getIdentityIndexOf(fromAddress)); final oldPubkey = await addressToPubkey(fromAddress); final messageToSign = Uint8List.fromList(prefix + genesisHash + idtyIndex + oldPubkey); final messageToSignHex = HEX.encode(messageToSign); final newKeySig = - await signMessage(messageToSign, destAddress, destPassword); + await _signMessage(messageToSign, destAddress, destPassword); // messageToSign: [105, 99, 111, 107, 7, 193, 18, 255, 106, 185, 215, 208, 213, 49, 235, 229, 159, 152, 179, 83, 24, 178, 129, 59, 22, 85, 87, 115, 128, 129, 157, 56, 214, 24, 45, 153, 21, 0, 0, 0, 181, 82, 178, 99, 198, 4, 156, 190, 78, 35, 102, 137, 255, 7, 162, 31, 16, 79, 255, 132, 130, 237, 230, 222, 176, 88, 245, 217, 237, 78, 196, 239] @@ -852,9 +847,10 @@ newKeySig: $newKeySig"""); const tx1 = 'api.tx.universalDividend.claimUds()'; final tx2 = 'api.tx.identity.changeOwnerKey("$destAddress", "$newKeySig")'; - const tx3 = 'api.tx.balances.transferAll(false)'; + // const tx3 = 'api.tx.balances.transferAll(false)'; - rawParams = '[[$tx1, $tx2, $tx3]]'; + rawParams = + fromBalance['unclaimedUds'] == 0 ? '[[$tx2]]' : '[[$tx1, $tx2]]'; } else { txInfo = TxInfoData( 'identity', @@ -865,11 +861,11 @@ newKeySig: $newKeySig"""); txOptions = [destAddress, newKeySig]; } - return await _executeCall(txInfo, txOptions, formPassword, rawParams); + return await _executeCall(txInfo, txOptions, fromPassword, rawParams); } Future revokeIdentity(String address, String password) async { - final idtyIndex = await getIdentityIndexOf(address); + final idtyIndex = await _getIdentityIndexOf(address); final sender = TxSenderData( keyring.current.address, @@ -892,7 +888,7 @@ newKeySig: $newKeySig"""); Future migrateCsToV2(String salt, String password, String destAddress, {required destPassword, - required double balance, + required Map balance, String idtyStatus = 'noid'}) async { final scrypt = pc.KeyDerivator('scrypt'); @@ -928,10 +924,11 @@ newKeySig: $newKeySig"""); await migrateIdentity( fromAddress: keypair.address!, destAddress: destAddress, - formPassword: 'password', + fromPassword: 'password', destPassword: destPassword, - withBalance: true); - } else if (balance != 0) { + withBalance: true, + fromBalance: balance); + } else if (balance['transferableBalance'] != 0) { await pay( fromAddress: keypair.address!, destAddress: destAddress, @@ -994,5 +991,5 @@ class PasswordException implements Exception { PasswordException(this.cause); } -Uint8List int32bytes(int value) => +Uint8List _int32bytes(int value) => Uint8List(4)..buffer.asInt32List()[0] = value; diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 63a4a2d..bb8a6ea 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -302,8 +302,11 @@ class WalletOptionsProvider with ChangeNotifier { Navigator.push( context, MaterialPageRoute(builder: (context) { - return const TransactionInProgress( - transType: 'comfirmIdty'); + return TransactionInProgress( + transType: 'comfirmIdty', + fromAddress: wallet.address, + toAddress: wallet.address, + ); }), ); } diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index a9fbc21..3833be9 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -60,14 +60,14 @@ class ImportG1v1 extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot status) { // log.d(_certs.data); - final balance = status.data?[0] ?? 0; - final idtyStatus = status.data?[1]; - final myIdtyStatus = status.data?[2]; - final hasConsumer = status.data?[3] ?? false; + final Map balance = status.data?[0] ?? 0; + final String idtyStatus = status.data?[1]; + final String myIdtyStatus = status.data?[2]; + final bool hasConsumer = status.data?[3] ?? false; // log.d('hasconsumer: $hasConsumer'); - if (balance != 0 && !hasConsumer) { + if (balance['transferableBalance'] != 0 && !hasConsumer) { canValidate = true; validationStatus = ''; } else { @@ -87,9 +87,6 @@ class ImportG1v1 extends StatelessWidget { validationStatus = ''; } - log.d( - 'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus'); - return Column(children: [ const SizedBox(height: 20), TextFormField( @@ -234,13 +231,17 @@ class ImportG1v1 extends StatelessWidget { sub.csSalt.text, sub.csPassword.text, selectedWallet.address!, - destPassword: pin ?? myWalletProvider.pinCode, + destPassword: + pin ?? myWalletProvider.pinCode, balance: balance, idtyStatus: idtyStatus); Navigator.push( context, MaterialPageRoute(builder: (context) { - return const TransactionInProgress(); + return TransactionInProgress( + transType: 'identityMigration', + fromAddress: sub.g1V1NewAddress, + toAddress: selectedWallet.address); }), ); resetScreen(context); diff --git a/lib/screens/myWallets/manage_membership.dart b/lib/screens/myWallets/manage_membership.dart index 5f4759f..4a05ec0 100644 --- a/lib/screens/myWallets/manage_membership.dart +++ b/lib/screens/myWallets/manage_membership.dart @@ -1,6 +1,8 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/screens/myWallets/migrate_identity.dart'; // import 'package:gecko/models/wallet_data.dart'; // import 'package:gecko/providers/my_wallets.dart'; // import 'package:gecko/providers/substrate_sdk.dart'; @@ -22,19 +24,44 @@ class ManageMembership extends StatelessWidget { backgroundColor: backgroundColor, appBar: AppBar( toolbarHeight: 60 * ratio, - title: const SizedBox( + title: SizedBox( height: 22, - child: Text('manageMembership'), + child: const Text('manageMembership').tr(), )), body: SafeArea( child: Column(children: [ const SizedBox(height: 20), - revokeMyIdentity(context), + migrateIdentity(context), + const SizedBox(height: 10), + revokeMyIdentity(context) // const SizedBox(height: 20), ]), )); } + Widget migrateIdentity(BuildContext context) { + return InkWell( + key: const Key('migrateIdentity'), + onTap: () async { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const MigrateIdentityScreen(); + }), + ); + }, + child: SizedBox( + height: 60, + child: Row(children: const [ + SizedBox(width: 16), + Icon(Icons.change_circle_outlined, size: 35), + SizedBox(width: 11.5), + Text('Migrer mon identité', style: TextStyle(fontSize: 20)), + ]), + ), + ); + } + Widget revokeMyIdentity(BuildContext context) { return InkWell( key: const Key('revokeIdty'), @@ -79,14 +106,15 @@ class ManageMembership extends StatelessWidget { // } }, child: SizedBox( - height: 40, - child: Row(children: const [ - SizedBox(width: 32), - // Image.asset( - // 'assets/medal.png', - // height: 45, - // ), - Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)), + height: 60, + child: Row(children: [ + const SizedBox(width: 20), + Image.asset( + 'assets/skull_Icon.png', + height: 30, + ), + const SizedBox(width: 16), + const Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)), ]), ), ); diff --git a/lib/screens/myWallets/migrate_identity.dart b/lib/screens/myWallets/migrate_identity.dart new file mode 100644 index 0000000..2bb0624 --- /dev/null +++ b/lib/screens/myWallets/migrate_identity.dart @@ -0,0 +1,251 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:gecko/globals.dart'; +import 'package:flutter/material.dart'; +import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/providers/duniter_indexer.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/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/screens/transaction_in_progress.dart'; +import 'package:provider/provider.dart'; + +class MigrateIdentityScreen extends StatelessWidget { + const MigrateIdentityScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + // HomeProvider _homeProvider = Provider.of(context); + WalletOptionsProvider walletOptions = + Provider.of(context, listen: false); + MyWalletsProvider myWalletProvider = + Provider.of(context, listen: false); + DuniterIndexer duniterIndexer = + 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; + } + bool canValidate = false; + String validationStatus = ''; + + final mdStyle = MarkdownStyleSheet( + p: const TextStyle(fontSize: 18, color: Colors.black, letterSpacing: 0.3), + textAlign: WrapAlignment.center, + ); + + if (walletsList.length < 2) { + return Column( + children: [ + const SizedBox(height: 80), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Text( + 'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération', + style: TextStyle(fontSize: 20), + ) + ], + ) + ], + ); + } + + return Scaffold( + backgroundColor: backgroundColor, + appBar: AppBar( + toolbarHeight: 60 * ratio, + title: SizedBox( + height: 22, + child: Text('importOldAccount'.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: [ + const SizedBox(height: 80), + Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + SizedBox( + height: 35, + width: 35, + child: CircularProgressIndicator( + color: orangeC, + strokeWidth: 4, + ), + ), + ]), + ]); + } + + // log.d('statusData: ${status.data}'); + + final Map balance = status.data?[0] ?? {}; + final String idtyStatus = status.data?[1]; + final String myIdtyStatus = status.data?[2]; + final bool hasConsumer = status.data?[3] ?? false; + + // log.d('hasconsumer: $hasConsumer'); + + if (balance['transferableBalance'] != 0 && !hasConsumer) { + canValidate = true; + validationStatus = ''; + } else { + canValidate = false; + validationStatus = hasConsumer + ? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X']) + : 'thisAccountIsEmpty'.tr(); + } + + if (idtyStatus != 'noid' && myIdtyStatus != 'noid') { + canValidate = false; + validationStatus = + 'youCannotMigrateIdentityToExistingIdentity'.tr(); + } + + log.d( + 'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus'); + + final walletsList = myWalletProvider.listWallets.toList(); + + walletsList + .removeWhere((element) => element.address == fromAddress); + // walletsList.add(WalletData(address: 'custom', name: 'custom')); + + return Column(children: [ + Row(children: const []), + const SizedBox(height: 20), + + SizedBox( + width: 350, + child: MarkdownBody( + data: 'areYouSureMigrateIdentity'.tr(args: [ + duniterIndexer.walletNameIndexer[fromAddress] ?? + '???', + '${balance['transferableBalance']} $currencyName' + ]), + styleSheet: mdStyle), + ), + // Text( + // 'areYouSureMigrateIdentity'.tr(args: [ + // duniterIndexer + // .walletNameIndexer[fromAddress]!, + // '$balance $currencyName' + // ]), + // textAlign: TextAlign.center, + // ), + const SizedBox(height: 20), + Text( + sub.g1V1NewAddress, + style: const TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold, + fontFamily: 'Monospace'), + ), + const SizedBox(height: 30), + Text('selectDestWallet'.tr()), + const SizedBox(height: 5), + DropdownButtonHideUnderline( + child: DropdownButton( + // alignment: AlignmentDirectional.topStart, + value: selectedWallet, + icon: const Icon(Icons.keyboard_arrow_down), + items: walletsList.map((wallet) { + return DropdownMenuItem( + value: wallet, + child: Text( + wallet.name!, + style: const TextStyle(fontSize: 18), + ), + ); + }).toList(), + onChanged: (WalletData? newSelectedWallet) { + selectedWallet = newSelectedWallet!; + sub.reload(); + }, + ), + ), + const SizedBox(height: 30), + SizedBox( + width: 380 * ratio, + height: 60 * ratio, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + elevation: 4, + primary: orangeC, // background + onPrimary: Colors.white, // foreground + ), + onPressed: canValidate + ? () async { + log.d('GOOO'); + WalletData? defaultWallet = + myWalletProvider.getDefaultWallet(); + + String? pin; + if (myWalletProvider.pinCode == '') { + pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + + sub.migrateIdentity( + fromAddress: fromAddress, + destAddress: selectedWallet.address!, + fromPassword: pin ?? myWalletProvider.pinCode, + destPassword: pin ?? myWalletProvider.pinCode, + withBalance: true, + fromBalance: balance); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transType: 'identityMigration', + fromAddress: fromAddress, + toAddress: selectedWallet.address); + }), + ); + } + : null, + child: Text( + 'migrateIdentity'.tr(), + style: TextStyle( + fontSize: 23 * ratio, fontWeight: FontWeight.w600), + ), + ), + ), + const SizedBox(height: 10), + Text( + validationStatus, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 15, color: Colors.grey[600]), + ) + ]); + }); + }), + ), + ); + } +} diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 6ab820b..dafd381 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -11,9 +11,12 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class TransactionInProgress extends StatelessWidget { - const TransactionInProgress({Key? key, this.transType = 'pay'}) + const TransactionInProgress( + {Key? key, this.transType = 'pay', this.fromAddress, this.toAddress}) : super(key: key); final String transType; + final String? fromAddress; + final String? toAddress; @override Widget build(BuildContext context) { @@ -32,8 +35,8 @@ class TransactionInProgress extends StatelessWidget { log.d(walletViewProvider.address!); - final from = myWalletProvider.getDefaultWallet().name!; - final to = getShortPubkey(walletViewProvider.address!); + final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!; + final to = toAddress ?? getShortPubkey(walletViewProvider.address!); final amount = walletViewProvider.payAmount.text; String actionName = ''; @@ -58,6 +61,11 @@ class TransactionInProgress extends StatelessWidget { actionName = "revokeAdhesion".tr(); } break; + case 'identityMigration': + { + actionName = "identityMigration".tr(); + } + break; default: { actionName = 'strangeTransaction'.tr(); @@ -148,7 +156,9 @@ class TransactionInProgress extends StatelessWidget { onWillPop: () { sub.transactionStatus = ''; Navigator.pop(context); - if (transType == 'pay') Navigator.pop(context); + if (transType == 'pay' || transType == 'identityMigration') { + Navigator.pop(context); + } return Future.value(true); }, child: Scaffold( @@ -261,7 +271,10 @@ class TransactionInProgress extends StatelessWidget { onPressed: () { Navigator.pop(context); sub.transactionStatus = ''; - if (transType == 'pay') Navigator.pop(context); + if (transType == 'pay' || + transType == 'identityMigration') { + Navigator.pop(context); + } }, child: Text( 'close'.tr(),