fix: chest change not consistent; feat: Can create custom derivation number, and root wallet
This commit is contained in:
parent
51182efe97
commit
8e49ac73ff
|
@ -74,6 +74,9 @@ Future<void> main() async {
|
|||
|
||||
await _homeProvider.getValidEndpoints();
|
||||
// await configBox.delete('isCacheChecked');
|
||||
if (configBox.get('isCacheChecked') == null) {
|
||||
configBox.put('isCacheChecked', false);
|
||||
}
|
||||
// log.d(await configBox.get('endpoint'));
|
||||
|
||||
HttpOverrides.global = MyHttpOverrides();
|
||||
|
|
|
@ -57,12 +57,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
|
||||
Future storeHDWChest(
|
||||
String address, String _name, BuildContext context) async {
|
||||
int chestNumber = 0;
|
||||
chestBox.toMap().forEach((key, value) {
|
||||
if (!value.isCesium!) {
|
||||
chestNumber++;
|
||||
}
|
||||
});
|
||||
int chestNumber = chestBox.isEmpty ? 0 : chestBox.keys.last + 1;
|
||||
|
||||
String chestName;
|
||||
if (chestNumber == 0) {
|
||||
|
|
|
@ -30,7 +30,8 @@ class MyWalletsProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
List<WalletData> readAllWallets(int? _chest) {
|
||||
List<WalletData> readAllWallets([int? _chest]) {
|
||||
_chest = _chest ?? configBox.get('currentChest') ?? 0;
|
||||
listWallets.clear();
|
||||
walletBox.toMap().forEach((key, value) {
|
||||
if (value.chest == _chest) {
|
||||
|
@ -108,28 +109,20 @@ class MyWalletsProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> generateNewDerivation(context, String _name) async {
|
||||
MyWalletsProvider _myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
||||
Future<void> generateNewDerivation(context, String _name,
|
||||
[int? number]) async {
|
||||
isNewDerivationLoading = true;
|
||||
notifyListeners();
|
||||
int _newDerivationNbr;
|
||||
int _newWalletNbr;
|
||||
|
||||
final List idList = getNextWalletNumberAndDerivation();
|
||||
int _newWalletNbr = idList[0];
|
||||
int _newDerivationNbr = number ?? idList[1];
|
||||
|
||||
int? _chest = getCurrentChest();
|
||||
|
||||
List<WalletData> _walletConfig = readAllWallets(_chest);
|
||||
|
||||
if (_walletConfig.isEmpty) {
|
||||
_newDerivationNbr = 2;
|
||||
_newWalletNbr = 0;
|
||||
} else {
|
||||
_newDerivationNbr = _walletConfig.last.derivation! + 2;
|
||||
_newWalletNbr = _walletConfig.last.number! + 1;
|
||||
}
|
||||
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
||||
WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
|
||||
WalletData defaultWallet = getDefaultWallet()!;
|
||||
|
||||
final address = await _sub.derive(
|
||||
context, defaultWallet.address!, _newDerivationNbr, pinCode);
|
||||
|
@ -149,6 +142,71 @@ class MyWalletsProvider with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> generateRootWallet(context, String _name) async {
|
||||
MyWalletsProvider _myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
||||
isNewDerivationLoading = true;
|
||||
notifyListeners();
|
||||
int _newWalletNbr;
|
||||
int? _chest = getCurrentChest();
|
||||
|
||||
List<WalletData> _walletConfig = readAllWallets(_chest);
|
||||
|
||||
if (_walletConfig.isEmpty) {
|
||||
_newWalletNbr = 0;
|
||||
} else {
|
||||
_newWalletNbr = _walletConfig.last.number! + 1;
|
||||
}
|
||||
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
||||
WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
|
||||
|
||||
final address =
|
||||
await _sub.generateRootKeypair(defaultWallet.address!, pinCode);
|
||||
|
||||
WalletData newWallet = WalletData(
|
||||
version: dataVersion,
|
||||
chest: _chest,
|
||||
address: address,
|
||||
number: _newWalletNbr,
|
||||
name: _name,
|
||||
derivation: -1,
|
||||
imageDefaultPath: '${_newWalletNbr % 4}.png');
|
||||
|
||||
await walletBox.add(newWallet);
|
||||
|
||||
isNewDerivationLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<int> getNextWalletNumberAndDerivation(
|
||||
{int? chestNumber, bool isOneshoot = false}) {
|
||||
int _newDerivationNbr = 0;
|
||||
int _newWalletNbr = 0;
|
||||
|
||||
chestNumber ??= getCurrentChest();
|
||||
|
||||
List<WalletData> _walletConfig = readAllWallets(chestNumber);
|
||||
|
||||
if (_walletConfig.isEmpty) {
|
||||
_newDerivationNbr = 2;
|
||||
} else {
|
||||
WalletData _lastWallet = _walletConfig.reduce(
|
||||
(curr, next) => curr.derivation! > next.derivation! ? curr : next);
|
||||
|
||||
if (_lastWallet.derivation == -1) {
|
||||
_newDerivationNbr = 2;
|
||||
} else {
|
||||
_newDerivationNbr = _lastWallet.derivation! + (isOneshoot ? 1 : 2);
|
||||
}
|
||||
|
||||
_newWalletNbr = _walletConfig.last.number! + 1;
|
||||
}
|
||||
|
||||
return [_newWalletNbr, _newDerivationNbr];
|
||||
}
|
||||
|
||||
int lockPin = 0;
|
||||
Future resetPinCode([int minutes = 15]) async {
|
||||
lockPin++;
|
||||
|
|
|
@ -230,6 +230,8 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
Future<bool> checkPassword(String address, String pass) async {
|
||||
final account = getKeypair(address);
|
||||
// log.d(account.address);
|
||||
|
||||
return await sdk.api.keyring.checkPassword(account, pass);
|
||||
}
|
||||
|
||||
|
@ -510,7 +512,23 @@ class SubstrateSdk with ChangeNotifier {
|
|||
generatedMnemonic = seedList[0];
|
||||
|
||||
return await importAccount(
|
||||
fromMnemonic: true, derivePath: '//$number', password: password);
|
||||
mnemonic: generatedMnemonic,
|
||||
fromMnemonic: true,
|
||||
derivePath: '//$number',
|
||||
password: password);
|
||||
}
|
||||
|
||||
Future<String> generateRootKeypair(String address, String password) async {
|
||||
final keypair = getKeypair(address);
|
||||
|
||||
final seedMap =
|
||||
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
|
||||
|
||||
if (seedMap?['type'] != 'mnemonic') return '';
|
||||
final List seedList = seedMap!['seed'].split('//');
|
||||
generatedMnemonic = seedList[0];
|
||||
|
||||
return await importAccount(fromMnemonic: true, password: password);
|
||||
}
|
||||
|
||||
Future<bool> isMnemonicValid(String mnemonic) async {
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:gecko/providers/chest_provider.dart';
|
|||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/screens/myWallets/change_pin.dart';
|
||||
import 'package:gecko/screens/myWallets/custom_derivations.dart';
|
||||
import 'package:gecko/screens/myWallets/show_seed.dart';
|
||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -123,7 +124,7 @@ class ChestOptions extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
height: 50,
|
||||
child: Row(children: <Widget>[
|
||||
const SizedBox(width: 28),
|
||||
const SizedBox(width: 26),
|
||||
Image.asset(
|
||||
'assets/chests/secret_code.png',
|
||||
height: 25,
|
||||
|
@ -136,6 +137,35 @@ class ChestOptions extends StatelessWidget {
|
|||
])),
|
||||
),
|
||||
SizedBox(height: 10 * ratio),
|
||||
InkWell(
|
||||
key: const Key('createRootDerivation'),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const CustomDerivation();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
child: Row(children: const <Widget>[
|
||||
SizedBox(width: 35),
|
||||
Icon(
|
||||
Icons.manage_accounts,
|
||||
size: 33,
|
||||
),
|
||||
SizedBox(width: 25),
|
||||
Text(
|
||||
'Créer une autre dérivation',
|
||||
style: TextStyle(fontSize: 20, color: Colors.black),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10 * ratio),
|
||||
InkWell(
|
||||
key: const Key('deleteChest'),
|
||||
onTap: () async {
|
||||
|
@ -144,7 +174,7 @@ class ChestOptions extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
height: 50,
|
||||
child: Row(children: <Widget>[
|
||||
const SizedBox(width: 30),
|
||||
const SizedBox(width: 28),
|
||||
Image.asset(
|
||||
'assets/walletOptions/trash.png',
|
||||
height: 45,
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CustomDerivation extends StatefulWidget {
|
||||
const CustomDerivation({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CustomDerivation> createState() => _CustomDerivationState();
|
||||
}
|
||||
|
||||
class _CustomDerivationState extends State<CustomDerivation> {
|
||||
String? dropdownValue;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
dropdownValue = 'root';
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
MyWalletsProvider _myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
||||
final derivationList = <String>[
|
||||
'root',
|
||||
for (var i = 0; i < 50; i += 1) i.toString()
|
||||
];
|
||||
|
||||
final listWallets = _myWalletProvider.readAllWallets();
|
||||
|
||||
for (WalletData _wallet in listWallets) {
|
||||
derivationList.remove(_wallet.derivation.toString());
|
||||
if (_wallet.derivation == -1) {
|
||||
derivationList.remove('root');
|
||||
}
|
||||
}
|
||||
|
||||
if (!derivationList.contains(dropdownValue)) {
|
||||
dropdownValue = derivationList.first;
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 60 * ratio,
|
||||
title: const SizedBox(
|
||||
height: 22,
|
||||
child: Text('Créer une dérivation personnalisé'),
|
||||
)),
|
||||
body: Center(
|
||||
child: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
const Spacer(),
|
||||
const Text(
|
||||
'Choisissez une dérivation:',
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: DropdownButton<String>(
|
||||
value: dropdownValue,
|
||||
menuMaxHeight: 300,
|
||||
icon: const Icon(Icons.arrow_downward),
|
||||
elevation: 16,
|
||||
style: TextStyle(color: orangeC),
|
||||
underline: Container(
|
||||
height: 2,
|
||||
color: orangeC,
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
dropdownValue = newValue!;
|
||||
});
|
||||
},
|
||||
items: derivationList
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: SizedBox(
|
||||
width: 75,
|
||||
child: Row(children: [
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontSize: 20, color: Colors.black),
|
||||
),
|
||||
const Spacer(),
|
||||
]),
|
||||
));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const Spacer(flex: 1),
|
||||
SizedBox(
|
||||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData? defaultWallet =
|
||||
_myWalletProvider.getDefaultWallet();
|
||||
String? _pin;
|
||||
if (_myWalletProvider.pinCode == '') {
|
||||
_pin = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
return UnlockingWallet(wallet: defaultWallet);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (_pin != null || _myWalletProvider.pinCode != '') {
|
||||
String _newDerivationName =
|
||||
'Portefeuille ${_myWalletProvider.listWallets.last.number! + 2}';
|
||||
if (dropdownValue == 'root') {
|
||||
await _myWalletProvider.generateRootWallet(
|
||||
context, 'Portefeuille racine');
|
||||
} else {
|
||||
await _myWalletProvider.generateNewDerivation(
|
||||
context,
|
||||
_newDerivationName,
|
||||
int.parse(dropdownValue!),
|
||||
);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(builder: (context) {
|
||||
// return const WalletsHome();
|
||||
// }),
|
||||
// );
|
||||
}
|
||||
},
|
||||
child: const Text(
|
||||
'Valider',
|
||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -37,10 +37,6 @@ class UnlockingWallet extends StatelessWidget {
|
|||
currentChestNumber = configBox.get('currentChest');
|
||||
currentChest = chestBox.get(currentChestNumber)!;
|
||||
|
||||
if (configBox.get('isCacheChecked') == null) {
|
||||
configBox.put('isCacheChecked', false);
|
||||
}
|
||||
|
||||
int _pinLenght = _walletOptions.getPinLenght(wallet!.number);
|
||||
errorController = StreamController<ErrorAnimationType>();
|
||||
|
||||
|
@ -222,7 +218,6 @@ class UnlockingWallet extends StatelessWidget {
|
|||
],
|
||||
onCompleted: (_pin) async {
|
||||
_myWalletProvider.pinCode = _pin.toUpperCase();
|
||||
|
||||
final isValid = await _sub.checkPassword(
|
||||
defaultWallet!.address!, _pin.toUpperCase());
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ description: Pay with G1.
|
|||
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 0.0.7+9
|
||||
version: 0.0.7+10
|
||||
|
||||
environment:
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
|
Loading…
Reference in New Issue