Merge branch 'derivationsDetection'
This commit is contained in:
commit
86467c06f3
|
@ -10,6 +10,7 @@ import 'package:gecko/models/wallet_data.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:pdf/pdf.dart';
|
import 'package:pdf/pdf.dart';
|
||||||
import 'package:pdf/widgets.dart' as pw;
|
import 'package:pdf/widgets.dart' as pw;
|
||||||
|
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import "package:unorm_dart/unorm_dart.dart" as unorm;
|
import "package:unorm_dart/unorm_dart.dart" as unorm;
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
FocusNode walletNameFocus = FocusNode();
|
FocusNode walletNameFocus = FocusNode();
|
||||||
Color? askedWordColor = Colors.black;
|
Color? askedWordColor = Colors.black;
|
||||||
bool isAskedWordValid = false;
|
bool isAskedWordValid = false;
|
||||||
|
int scanedWalletNumber = -1;
|
||||||
|
|
||||||
late int nbrWord;
|
late int nbrWord;
|
||||||
String? nbrWordAlpha;
|
String? nbrWordAlpha;
|
||||||
|
@ -55,8 +57,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
TextEditingController cellController11 = TextEditingController();
|
TextEditingController cellController11 = TextEditingController();
|
||||||
bool isFirstTimeSentenceComplete = true;
|
bool isFirstTimeSentenceComplete = true;
|
||||||
|
|
||||||
Future storeHDWChest(
|
Future storeHDWChest(BuildContext context) async {
|
||||||
String address, String _name, BuildContext context) async {
|
|
||||||
int chestNumber = chestBox.isEmpty ? 0 : chestBox.keys.last + 1;
|
int chestNumber = chestBox.isEmpty ? 0 : chestBox.keys.last + 1;
|
||||||
|
|
||||||
String chestName;
|
String chestName;
|
||||||
|
@ -75,16 +76,6 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
await chestBox.add(thisChest);
|
await chestBox.add(thisChest);
|
||||||
int? chestKey = chestBox.keys.last;
|
int? chestKey = chestBox.keys.last;
|
||||||
|
|
||||||
WalletData myWallet = WalletData(
|
|
||||||
version: dataVersion,
|
|
||||||
chest: chestKey,
|
|
||||||
address: address,
|
|
||||||
number: 0,
|
|
||||||
name: _name,
|
|
||||||
derivation: 2,
|
|
||||||
imageDefaultPath: '0.png');
|
|
||||||
await walletBox.add(myWallet);
|
|
||||||
|
|
||||||
await configBox.put('currentChest', chestKey);
|
await configBox.put('currentChest', chestKey);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -271,13 +262,25 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
return _wordsList;
|
return _wordsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBipWord(String word) {
|
bool isBipWord(String word, [bool checkRedondance = true]) {
|
||||||
|
bool isValid = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
// Needed for bad encoding of UTF-8
|
// Needed for bad encoding of UTF-8
|
||||||
word = word.replaceAll('é', 'é');
|
word = word.replaceAll('é', 'é');
|
||||||
word = word.replaceAll('è', 'è');
|
word = word.replaceAll('è', 'è');
|
||||||
return bip39Words(appLang).contains(word.toLowerCase());
|
|
||||||
|
int nbrMatch = 0;
|
||||||
|
if (bip39Words(appLang).contains(word.toLowerCase())) {
|
||||||
|
for (var bipWord in bip39Words(appLang)) {
|
||||||
|
if (bipWord.startsWith(word)) {
|
||||||
|
isValid = nbrMatch == 0 ? true : false;
|
||||||
|
if (checkRedondance) nbrMatch = nbrMatch + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBipWordsList(List<String> words) {
|
bool isBipWordsList(List<String> words) {
|
||||||
|
@ -349,7 +352,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
cellController11
|
cellController11
|
||||||
];
|
];
|
||||||
for (var word in sentence!.text!.split(' ')) {
|
for (var word in sentence!.text!.split(' ')) {
|
||||||
bool isValid = isBipWord(word);
|
bool isValid = isBipWord(word, false);
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
cells[nbr].text = word;
|
cells[nbr].text = word;
|
||||||
|
@ -361,4 +364,84 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
void reloadBuild() {
|
void reloadBuild() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> scanDerivations(BuildContext context,
|
||||||
|
{int numberScan = 20}) async {
|
||||||
|
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
|
final ss58 = _sub.ss58;
|
||||||
|
final currentChestNumber = configBox.get('currentChest');
|
||||||
|
bool isAlive = false;
|
||||||
|
scanedWalletNumber = 0;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final hasRoot = await scanRootBalance(_sub, currentChestNumber);
|
||||||
|
if (hasRoot) {
|
||||||
|
scanedWalletNumber = 1;
|
||||||
|
isAlive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
|
||||||
|
final addressData = await _sub.sdk.api.keyring.addressFromMnemonic(ss58,
|
||||||
|
cryptoType: CryptoType.sr25519,
|
||||||
|
mnemonic: generatedMnemonic!,
|
||||||
|
derivePath: '//$derivationNbr');
|
||||||
|
|
||||||
|
final balance = await _sub.getBalance(addressData.address!);
|
||||||
|
|
||||||
|
log.d(balance);
|
||||||
|
if (balance != 0) {
|
||||||
|
isAlive = true;
|
||||||
|
String walletName = scanedWalletNumber == 0
|
||||||
|
? 'Mon portefeuille courant'
|
||||||
|
: 'Portefeuille ${scanedWalletNumber + 1}';
|
||||||
|
await _sub.importAccount(
|
||||||
|
mnemonic: '',
|
||||||
|
fromMnemonic: true,
|
||||||
|
derivePath: '//$derivationNbr',
|
||||||
|
password: pin.text);
|
||||||
|
|
||||||
|
WalletData myWallet = WalletData(
|
||||||
|
version: dataVersion,
|
||||||
|
chest: currentChestNumber,
|
||||||
|
address: addressData.address!,
|
||||||
|
number: scanedWalletNumber,
|
||||||
|
name: walletName,
|
||||||
|
derivation: derivationNbr,
|
||||||
|
imageDefaultPath: '${scanedWalletNumber % 4}.png');
|
||||||
|
await walletBox.add(myWallet);
|
||||||
|
scanedWalletNumber = scanedWalletNumber + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanedWalletNumber = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return isAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> scanRootBalance(
|
||||||
|
SubstrateSdk _sub, int currentChestNumber) async {
|
||||||
|
final addressData = await _sub.sdk.api.keyring.addressFromMnemonic(ss58,
|
||||||
|
cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!);
|
||||||
|
|
||||||
|
final balance = await _sub.getBalance(addressData.address!);
|
||||||
|
|
||||||
|
log.d(balance);
|
||||||
|
if (balance != 0) {
|
||||||
|
String walletName = 'Mon portefeuille racine';
|
||||||
|
await _sub.importAccount(
|
||||||
|
mnemonic: '', fromMnemonic: true, password: pin.text);
|
||||||
|
|
||||||
|
WalletData myWallet = WalletData(
|
||||||
|
version: dataVersion,
|
||||||
|
chest: currentChestNumber,
|
||||||
|
address: addressData.address!,
|
||||||
|
number: 0,
|
||||||
|
name: walletName,
|
||||||
|
derivation: -1,
|
||||||
|
imageDefaultPath: '0.png');
|
||||||
|
await walletBox.add(myWallet);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,10 @@ class RestoreChest extends StatelessWidget {
|
||||||
context,
|
context,
|
||||||
FaderTransition(
|
FaderTransition(
|
||||||
page: skipIntro
|
page: skipIntro
|
||||||
? const OnboardingStepNine()
|
? const OnboardingStepNine(
|
||||||
: const OnboardingStepSeven(),
|
scanDerivation: true)
|
||||||
|
: const OnboardingStepSeven(
|
||||||
|
scanDerivation: true),
|
||||||
isFast: true),
|
isFast: true),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -123,24 +125,32 @@ class RestoreChest extends StatelessWidget {
|
||||||
Column(children: [
|
Column(children: [
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 150,
|
width: 190,
|
||||||
height: 50,
|
height: 60,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
elevation: 4,
|
elevation: 4,
|
||||||
primary: yellowC, // background
|
primary: yellowC, // background
|
||||||
onPrimary: Colors.black, // foreground
|
onPrimary: Colors.black, // foreground
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
genW.pasteMnemonic(context);
|
genW.pasteMnemonic(context);
|
||||||
},
|
},
|
||||||
child: const Text(
|
child: Row(
|
||||||
'Coller depuis le\npresse-papier',
|
children: const [
|
||||||
textAlign: TextAlign.center,
|
Icon(
|
||||||
style:
|
Icons.content_paste_go,
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
|
size: 25,
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 10),
|
||||||
|
Text(
|
||||||
|
'Coller depuis le\npresse-papier',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17, fontWeight: FontWeight.w400),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:async';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.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/wallet_data.dart';
|
||||||
import 'package:gecko/providers/generate_wallets.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';
|
||||||
|
@ -15,10 +16,10 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class OnboardingStepTen extends StatelessWidget {
|
class OnboardingStepTen extends StatelessWidget {
|
||||||
OnboardingStepTen({
|
OnboardingStepTen({Key? validationKey, this.scanDerivation = false})
|
||||||
Key? validationKey,
|
: super(key: validationKey);
|
||||||
}) : super(key: validationKey);
|
|
||||||
|
|
||||||
|
final bool scanDerivation;
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
Color? pinColor = const Color(0xFFA4B600);
|
Color? pinColor = const Color(0xFFA4B600);
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
@ -58,6 +59,20 @@ class OnboardingStepTen extends StatelessWidget {
|
||||||
style: TextStyle(fontSize: 16 * ratio))
|
style: TextStyle(fontSize: 16 * ratio))
|
||||||
]),
|
]),
|
||||||
SizedBox(height: isTall ? 80 : 20),
|
SizedBox(height: isTall ? 80 : 20),
|
||||||
|
Visibility(
|
||||||
|
visible: _generateWalletProvider.scanedWalletNumber != -1,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 15),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 22,
|
||||||
|
width: 22,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: orangeC,
|
||||||
|
strokeWidth: 3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
pinForm(context, _walletOptions, _pinLenght, 1, 2),
|
pinForm(context, _walletOptions, _pinLenght, 1, 2),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -153,18 +168,32 @@ class OnboardingStepTen extends StatelessWidget {
|
||||||
log.d(_pin + ' || ' + _generateWalletProvider.pin.text);
|
log.d(_pin + ' || ' + _generateWalletProvider.pin.text);
|
||||||
if (_pin.toUpperCase() == _generateWalletProvider.pin.text) {
|
if (_pin.toUpperCase() == _generateWalletProvider.pin.text) {
|
||||||
pinColor = Colors.green[500];
|
pinColor = Colors.green[500];
|
||||||
final address = await _sub.importAccount(
|
|
||||||
fromMnemonic: true,
|
await _generateWalletProvider.storeHDWChest(context);
|
||||||
mnemonic: _generateWalletProvider.generatedMnemonic!,
|
bool isAlive = false;
|
||||||
derivePath: '//2',
|
if (scanDerivation) {
|
||||||
password: _generateWalletProvider.pin.text);
|
isAlive = await _generateWalletProvider
|
||||||
await _generateWalletProvider.storeHDWChest(
|
.scanDerivations(context, numberScan: 20);
|
||||||
address, 'Mon portefeuille courant', context);
|
}
|
||||||
|
if (!isAlive) {
|
||||||
|
final address = await _sub.importAccount(
|
||||||
|
fromMnemonic: true,
|
||||||
|
mnemonic: _generateWalletProvider.generatedMnemonic!,
|
||||||
|
derivePath: '//2',
|
||||||
|
password: _generateWalletProvider.pin.text);
|
||||||
|
WalletData myWallet = WalletData(
|
||||||
|
version: dataVersion,
|
||||||
|
chest: configBox.get('currentChest'),
|
||||||
|
address: address,
|
||||||
|
number: 0,
|
||||||
|
name: 'Mon portefeuille courant',
|
||||||
|
derivation: 2,
|
||||||
|
imageDefaultPath: '0.png');
|
||||||
|
await walletBox.add(myWallet);
|
||||||
|
}
|
||||||
_myWalletProvider.readAllWallets(_currentChest);
|
_myWalletProvider.readAllWallets(_currentChest);
|
||||||
// scheduleMicrotask(() {
|
|
||||||
// _walletOptions.reloadBuild();
|
|
||||||
_myWalletProvider.rebuildWidget();
|
_myWalletProvider.rebuildWidget();
|
||||||
// });
|
|
||||||
_generateWalletProvider.generatedMnemonic = '';
|
_generateWalletProvider.generatedMnemonic = '';
|
||||||
_myWalletProvider.resetPinCode();
|
_myWalletProvider.resetPinCode();
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|
|
@ -6,7 +6,8 @@ import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/onBoarding/8.dart';
|
import 'package:gecko/screens/onBoarding/8.dart';
|
||||||
|
|
||||||
class OnboardingStepSeven extends StatelessWidget {
|
class OnboardingStepSeven extends StatelessWidget {
|
||||||
const OnboardingStepSeven({Key? key}) : super(key: key);
|
const OnboardingStepSeven({Key? key, this.scanDerivation = false}) : super(key: key);
|
||||||
|
final bool scanDerivation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -35,7 +36,7 @@ class OnboardingStepSeven extends StatelessWidget {
|
||||||
],
|
],
|
||||||
'coffre-fort-code-secret-dans-telephone.png',
|
'coffre-fort-code-secret-dans-telephone.png',
|
||||||
'>',
|
'>',
|
||||||
const OnboardingStepEight(),
|
OnboardingStepEight(scanDerivation: scanDerivation),
|
||||||
6,
|
6,
|
||||||
boxHeight: 400),
|
boxHeight: 400),
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,7 +6,9 @@ import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/onBoarding/9.dart';
|
import 'package:gecko/screens/onBoarding/9.dart';
|
||||||
|
|
||||||
class OnboardingStepEight extends StatelessWidget {
|
class OnboardingStepEight extends StatelessWidget {
|
||||||
const OnboardingStepEight({Key? key}) : super(key: key);
|
const OnboardingStepEight({Key? key, this.scanDerivation = false})
|
||||||
|
: super(key: key);
|
||||||
|
final bool scanDerivation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -41,7 +43,7 @@ class OnboardingStepEight extends StatelessWidget {
|
||||||
],
|
],
|
||||||
'coffre-fort-protege-les-portefeuilles.png',
|
'coffre-fort-protege-les-portefeuilles.png',
|
||||||
'>',
|
'>',
|
||||||
const OnboardingStepNine(),
|
OnboardingStepNine(scanDerivation: scanDerivation),
|
||||||
7),
|
7),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,7 +9,9 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class OnboardingStepNine extends StatelessWidget {
|
class OnboardingStepNine extends StatelessWidget {
|
||||||
const OnboardingStepNine({Key? key}) : super(key: key);
|
const OnboardingStepNine({Key? key, this.scanDerivation = false})
|
||||||
|
: super(key: key);
|
||||||
|
final bool scanDerivation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -103,7 +105,7 @@ class OnboardingStepNine extends StatelessWidget {
|
||||||
))),
|
))),
|
||||||
SizedBox(height: 22 * ratio),
|
SizedBox(height: 22 * ratio),
|
||||||
common.nextButton(context, "J'ai noté mon code secret",
|
common.nextButton(context, "J'ai noté mon code secret",
|
||||||
OnboardingStepTen(), false),
|
OnboardingStepTen(scanDerivation: scanDerivation), false),
|
||||||
SizedBox(height: 35 * ratio),
|
SizedBox(height: 35 * ratio),
|
||||||
]),
|
]),
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in New Issue