can migrate identity from standart mnemonic derivation

This commit is contained in:
poka 2022-08-20 20:08:02 +02:00
parent c840753f4a
commit ad601be19c
10 changed files with 384 additions and 82 deletions

BIN
assets/skull_Icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -185,5 +185,8 @@
"importOldAccount": "Import your old account", "importOldAccount": "Import your old account",
"enterCesiumId": "Enter your Cesium ID", "enterCesiumId": "Enter your Cesium ID",
"enterCesiumPassword": "Enter your Cesium password", "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 **{}** ?"
} }

View File

@ -185,5 +185,8 @@
"importOldAccount": "Import your old account", "importOldAccount": "Import your old account",
"enterCesiumId": "Enter your Cesium ID", "enterCesiumId": "Enter your Cesium ID",
"enterCesiumPassword": "Enter your Cesium password", "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 **{}** ?"
} }

View File

@ -186,5 +186,8 @@
"importOldAccount": "Importer son ancien compte", "importOldAccount": "Importer son ancien compte",
"enterCesiumId": "Entrez votre identifiant Cesium", "enterCesiumId": "Entrez votre identifiant Cesium",
"enterCesiumPassword": "Entrez votre mot de passe 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 **{}** ?"
} }

View File

@ -2,7 +2,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:fast_base58/fast_base58.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
@ -88,16 +87,29 @@ class SubstrateSdk with ChangeNotifier {
); );
} }
Future<String> _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 ////////// ////////// 2: GET ONCHAIN STORAGE //////////
//////////////////////////////////////////// ////////////////////////////////////////////
Future<int> getIdentityIndexOf(String address) async { Future<int> _getIdentityIndexOf(String address) async {
return await _getStorage('identity.identityIndexOf("$address")') ?? 0; return await _getStorage('identity.identityIndexOf("$address")') ?? 0;
} }
Future<List<int>> getCerts(String address) async { Future<List<int>> getCerts(String address) async {
final idtyIndex = await getIdentityIndexOf(address); final idtyIndex = await _getIdentityIndexOf(address);
final certsReceiver = final certsReceiver =
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
@ -105,8 +117,8 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<int> getCertValidityPeriod(String from, String to) async { Future<int> getCertValidityPeriod(String from, String to) async {
final idtyIndexFrom = await getIdentityIndexOf(from); final idtyIndexFrom = await _getIdentityIndexOf(from);
final idtyIndexTo = await getIdentityIndexOf(to); final idtyIndexTo = await _getIdentityIndexOf(to);
if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0;
@ -246,7 +258,7 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<Map> getCertMeta(String address) async { Future<Map> getCertMeta(String address) async {
var idtyIndex = await getIdentityIndexOf(address); var idtyIndex = await _getIdentityIndexOf(address);
final certMeta = final certMeta =
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? ''; await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
@ -255,7 +267,7 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<String> idtyStatus(String address) async { Future<String> idtyStatus(String address) async {
var idtyIndex = await getIdentityIndexOf(address); var idtyIndex = await _getIdentityIndexOf(address);
if (idtyIndex == 0) { if (idtyIndex == 0) {
return 'noid'; return 'noid';
@ -287,8 +299,7 @@ class SubstrateSdk with ChangeNotifier {
final pubkey = await sdk.api.account.decodeAddress([address]); final pubkey = await sdk.api.account.decodeAddress([address]);
final String pubkeyHex = pubkey!.keys.first; final String pubkeyHex = pubkey!.keys.first;
final pubkeyByte = HEX.decode(pubkeyHex.substring(2)) as Uint8List; final pubkeyByte = HEX.decode(pubkeyHex.substring(2)) as Uint8List;
final pubkey58 = Base58Encode(pubkeyByte); // final pubkey58 = Base58Encode(pubkeyByte);
log.d('tatatatata: $pubkey58');
return pubkeyByte; return pubkeyByte;
} }
@ -624,22 +635,18 @@ class SubstrateSdk with ChangeNotifier {
return g1V1NewAddress; return g1V1NewAddress;
} }
Future<List> getBalanceAndIdtyStatus(String address, String myAddress) async { Future<List> getBalanceAndIdtyStatus(
final balance = String fromAddress, String toAddress) async {
address == '' ? {'transferableBalance': 0} : await getBalance(address); final fromBalance = fromAddress == ''
final thisIdtyStatus = address == '' ? 'noid' : await idtyStatus(address); ? {'transferableBalance': 0}
final thisHasConsumer = : await getBalance(fromAddress);
address == '' ? false : await hasAccountConsumers(address); final fromIdtyStatus =
final myIdtyStatus = await idtyStatus(myAddress); fromAddress == '' ? 'noid' : await idtyStatus(fromAddress);
final fromHasConsumer =
fromAddress == '' ? false : await hasAccountConsumers(fromAddress);
final toIdtyStatus = await idtyStatus(toAddress);
log.d('tatata: $myIdtyStatus'); return [fromBalance, fromIdtyStatus, toIdtyStatus, fromHasConsumer];
return [
balance['transferableBalance'],
thisIdtyStatus,
myIdtyStatus,
thisHasConsumer
];
} }
////////////////////////////////////// //////////////////////////////////////
@ -694,8 +701,8 @@ class SubstrateSdk with ChangeNotifier {
final myIdtyStatus = await idtyStatus(fromAddress); final myIdtyStatus = await idtyStatus(fromAddress);
final toIdtyStatus = await idtyStatus(toAddress); final toIdtyStatus = await idtyStatus(toAddress);
final fromIndex = await getIdentityIndexOf(fromAddress); final fromIndex = await _getIdentityIndexOf(fromAddress);
final toIndex = await getIdentityIndexOf(toAddress); final toIndex = await _getIdentityIndexOf(toAddress);
if (myIdtyStatus != 'Validated') { if (myIdtyStatus != 'Validated') {
transactionStatus = 'notMember'; transactionStatus = 'notMember';
@ -785,24 +792,12 @@ class SubstrateSdk with ChangeNotifier {
return await _executeCall(txInfo, txOptions, password); return await _executeCall(txInfo, txOptions, password);
} }
Future<String> 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<String> migrateIdentity( Future<String> migrateIdentity(
{required String fromAddress, {required String fromAddress,
required String destAddress, required String destAddress,
required String formPassword, required String fromPassword,
required String destPassword, required String destPassword,
required Map fromBalance,
bool withBalance = false}) async { bool withBalance = false}) async {
transactionStatus = ''; transactionStatus = '';
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
@ -818,13 +813,13 @@ class SubstrateSdk with ChangeNotifier {
final prefix = 'icok'.codeUnits; final prefix = 'icok'.codeUnits;
final genesisHashString = await getGenesisHash(); final genesisHashString = await getGenesisHash();
final genesisHash = HEX.decode(genesisHashString.substring(2)) as Uint8List; 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 oldPubkey = await addressToPubkey(fromAddress);
final messageToSign = final messageToSign =
Uint8List.fromList(prefix + genesisHash + idtyIndex + oldPubkey); Uint8List.fromList(prefix + genesisHash + idtyIndex + oldPubkey);
final messageToSignHex = HEX.encode(messageToSign); final messageToSignHex = HEX.encode(messageToSign);
final newKeySig = 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] // 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()'; const tx1 = 'api.tx.universalDividend.claimUds()';
final tx2 = final tx2 =
'api.tx.identity.changeOwnerKey("$destAddress", "$newKeySig")'; '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 { } else {
txInfo = TxInfoData( txInfo = TxInfoData(
'identity', 'identity',
@ -865,11 +861,11 @@ newKeySig: $newKeySig""");
txOptions = [destAddress, 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 { Future revokeIdentity(String address, String password) async {
final idtyIndex = await getIdentityIndexOf(address); final idtyIndex = await _getIdentityIndexOf(address);
final sender = TxSenderData( final sender = TxSenderData(
keyring.current.address, keyring.current.address,
@ -892,7 +888,7 @@ newKeySig: $newKeySig""");
Future migrateCsToV2(String salt, String password, String destAddress, Future migrateCsToV2(String salt, String password, String destAddress,
{required destPassword, {required destPassword,
required double balance, required Map balance,
String idtyStatus = 'noid'}) async { String idtyStatus = 'noid'}) async {
final scrypt = pc.KeyDerivator('scrypt'); final scrypt = pc.KeyDerivator('scrypt');
@ -928,10 +924,11 @@ newKeySig: $newKeySig""");
await migrateIdentity( await migrateIdentity(
fromAddress: keypair.address!, fromAddress: keypair.address!,
destAddress: destAddress, destAddress: destAddress,
formPassword: 'password', fromPassword: 'password',
destPassword: destPassword, destPassword: destPassword,
withBalance: true); withBalance: true,
} else if (balance != 0) { fromBalance: balance);
} else if (balance['transferableBalance'] != 0) {
await pay( await pay(
fromAddress: keypair.address!, fromAddress: keypair.address!,
destAddress: destAddress, destAddress: destAddress,
@ -994,5 +991,5 @@ class PasswordException implements Exception {
PasswordException(this.cause); PasswordException(this.cause);
} }
Uint8List int32bytes(int value) => Uint8List _int32bytes(int value) =>
Uint8List(4)..buffer.asInt32List()[0] = value; Uint8List(4)..buffer.asInt32List()[0] = value;

View File

@ -302,8 +302,11 @@ class WalletOptionsProvider with ChangeNotifier {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return const TransactionInProgress( return TransactionInProgress(
transType: 'comfirmIdty'); transType: 'comfirmIdty',
fromAddress: wallet.address,
toAddress: wallet.address,
);
}), }),
); );
} }

View File

@ -60,14 +60,14 @@ class ImportG1v1 extends StatelessWidget {
builder: (BuildContext context, AsyncSnapshot<List> status) { builder: (BuildContext context, AsyncSnapshot<List> status) {
// log.d(_certs.data); // log.d(_certs.data);
final balance = status.data?[0] ?? 0; final Map balance = status.data?[0] ?? 0;
final idtyStatus = status.data?[1]; final String idtyStatus = status.data?[1];
final myIdtyStatus = status.data?[2]; final String myIdtyStatus = status.data?[2];
final hasConsumer = status.data?[3] ?? false; final bool hasConsumer = status.data?[3] ?? false;
// log.d('hasconsumer: $hasConsumer'); // log.d('hasconsumer: $hasConsumer');
if (balance != 0 && !hasConsumer) { if (balance['transferableBalance'] != 0 && !hasConsumer) {
canValidate = true; canValidate = true;
validationStatus = ''; validationStatus = '';
} else { } else {
@ -87,9 +87,6 @@ class ImportG1v1 extends StatelessWidget {
validationStatus = ''; validationStatus = '';
} }
log.d(
'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus');
return Column(children: <Widget>[ return Column(children: <Widget>[
const SizedBox(height: 20), const SizedBox(height: 20),
TextFormField( TextFormField(
@ -234,13 +231,17 @@ class ImportG1v1 extends StatelessWidget {
sub.csSalt.text, sub.csSalt.text,
sub.csPassword.text, sub.csPassword.text,
selectedWallet.address!, selectedWallet.address!,
destPassword: pin ?? myWalletProvider.pinCode, destPassword:
pin ?? myWalletProvider.pinCode,
balance: balance, balance: balance,
idtyStatus: idtyStatus); idtyStatus: idtyStatus);
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return const TransactionInProgress(); return TransactionInProgress(
transType: 'identityMigration',
fromAddress: sub.g1V1NewAddress,
toAddress: selectedWallet.address);
}), }),
); );
resetScreen(context); resetScreen(context);

View File

@ -1,6 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/migrate_identity.dart';
// import 'package:gecko/models/wallet_data.dart'; // import 'package:gecko/models/wallet_data.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';
@ -22,19 +24,44 @@ class ManageMembership extends StatelessWidget {
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
title: const SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text('manageMembership'), child: const Text('manageMembership').tr(),
)), )),
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
const SizedBox(height: 20), const SizedBox(height: 20),
revokeMyIdentity(context), migrateIdentity(context),
const SizedBox(height: 10),
revokeMyIdentity(context)
// const SizedBox(height: 20), // 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 <Widget>[
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) { Widget revokeMyIdentity(BuildContext context) {
return InkWell( return InkWell(
key: const Key('revokeIdty'), key: const Key('revokeIdty'),
@ -79,14 +106,15 @@ class ManageMembership extends StatelessWidget {
// } // }
}, },
child: SizedBox( child: SizedBox(
height: 40, height: 60,
child: Row(children: const <Widget>[ child: Row(children: <Widget>[
SizedBox(width: 32), const SizedBox(width: 20),
// Image.asset( Image.asset(
// 'assets/medal.png', 'assets/skull_Icon.png',
// height: 45, height: 30,
// ), ),
Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)), const SizedBox(width: 16),
const Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)),
]), ]),
), ),
); );

View File

@ -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<HomeProvider>(context);
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(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<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.getBalanceAndIdtyStatus(
fromAddress, selectedWallet.address!),
builder: (BuildContext context, AsyncSnapshot<List> 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: <Widget>[
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]),
)
]);
});
}),
),
);
}
}

View File

@ -11,9 +11,12 @@ import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class TransactionInProgress extends StatelessWidget { 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); : super(key: key);
final String transType; final String transType;
final String? fromAddress;
final String? toAddress;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -32,8 +35,8 @@ class TransactionInProgress extends StatelessWidget {
log.d(walletViewProvider.address!); log.d(walletViewProvider.address!);
final from = myWalletProvider.getDefaultWallet().name!; final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!;
final to = getShortPubkey(walletViewProvider.address!); final to = toAddress ?? getShortPubkey(walletViewProvider.address!);
final amount = walletViewProvider.payAmount.text; final amount = walletViewProvider.payAmount.text;
String actionName = ''; String actionName = '';
@ -58,6 +61,11 @@ class TransactionInProgress extends StatelessWidget {
actionName = "revokeAdhesion".tr(); actionName = "revokeAdhesion".tr();
} }
break; break;
case 'identityMigration':
{
actionName = "identityMigration".tr();
}
break;
default: default:
{ {
actionName = 'strangeTransaction'.tr(); actionName = 'strangeTransaction'.tr();
@ -148,7 +156,9 @@ class TransactionInProgress extends StatelessWidget {
onWillPop: () { onWillPop: () {
sub.transactionStatus = ''; sub.transactionStatus = '';
Navigator.pop(context); Navigator.pop(context);
if (transType == 'pay') Navigator.pop(context); if (transType == 'pay' || transType == 'identityMigration') {
Navigator.pop(context);
}
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -261,7 +271,10 @@ class TransactionInProgress extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
sub.transactionStatus = ''; sub.transactionStatus = '';
if (transType == 'pay') Navigator.pop(context); if (transType == 'pay' ||
transType == 'identityMigration') {
Navigator.pop(context);
}
}, },
child: Text( child: Text(
'close'.tr(), 'close'.tr(),