Merge branch 'end2EndTests' into 'master'
End2end tests See merge request clients/gecko!28
This commit is contained in:
commit
549996578b
|
@ -55,4 +55,5 @@ scripts/private/
|
|||
AppDir/
|
||||
appimage-builder-cache/
|
||||
AppImageBuilder.yml
|
||||
android/app/build.gradle
|
||||
android/app/build.gradle
|
||||
integration_test/duniter/data/chains/
|
|
@ -5,7 +5,7 @@ stages:
|
|||
- package
|
||||
|
||||
.env:
|
||||
image: axiomteam/gecko-ci:v0.0.9
|
||||
image: axiomteam/gecko-ci:v0.0.11
|
||||
tags:
|
||||
- redshift
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
"seeAWallet": "Voir un portefeuille",
|
||||
"mustWaitXBeforeCertify": "Vous devez attendre\n{} avant\nde pouvoir certifier",
|
||||
"mustConfirmHisIdentity": "Cette personne doit confirmer\nson identité avant de pouvoir\nêtre certifié",
|
||||
"canRenewCertInX": "Vous pourrez renouveller\ncette certification\ndans {}",
|
||||
"canRenewCertInX": "Vous pourrez renouveler\ncette certification\ndans {}",
|
||||
"executeATransfer": "Effectuer un virement",
|
||||
"executeTheTransfer": "Effectuer le virement",
|
||||
"doATransfer": "Faire un\nvirement",
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
# Context des tests
|
||||
|
||||
Chaque test est précédé par le lancement d'un noeud Duniter v2s en docker [dont voici le compose](https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/docker-compose.yml).
|
||||
|
||||
Voici le yaml de configuration de la monnaie de test éphémère: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/data/gecko_tests.json
|
||||
|
||||
|
||||
Voici le mnemonic de test utilisé:
|
||||
`pipe paddle ketchup filter life ice feel embody glide quantum ride usage`
|
||||
|
||||
Et les 5 premiers portefeuilles Gecko associés:
|
||||
```
|
||||
test1: 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa
|
||||
test2: 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb
|
||||
test3: 5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p
|
||||
test4: 5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5
|
||||
test5: 5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R
|
||||
```
|
||||
|
||||
Seul les 4 premiers sont membres au démarrage.
|
||||
|
||||
Voici le scénario de test principal que j'ai réalisé pour le moment
|
||||
|
||||
Scénario 1
|
||||
- Changer le noeud Duniter pour se connecter au nœud local (l'ip local est récupéré automatiquement, car le nœud est sur le host (votre pc), alors que l'app est dans son émulateur)
|
||||
- Importer le coffre de test
|
||||
- Effectuer une transaction du Portefeuille 1 (test1) vers le portefeuille 5 (test5)
|
||||
- Vérifier que les frais de créations de compte ont bien été prélevés
|
||||
- Certifier test5 avec test1, test2 et test3 et vérifier qu'il deviens bien membre
|
||||
- Créer 10 blocs, puis encore 10, puis 30 de plus et vérifier à chaque fois si le compte génère bien ses DU à la bonne valeur, réévaluation comprise au bloc 50.
|
||||
|
||||
Des vérifications sur l'état du texte affiché à l'écran ou des widgets affichés ou non sont fait entre chaque étapes pour vérifier que tout ce passe toujours bien.
|
||||
Si la moindre erreur intervient, le test s'arrête et vous informe de l'erreur en question.
|
||||
|
||||
Voici le code du test contenant ce scénario: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/gecko_complete.dart
|
||||
|
||||
Ce test dur environ 1 minutes et 15 seconds, compilation et lancement de nœud au démarrage inclus.
|
||||
|
||||
Voici le rendu (attention ça va assez vite ^^) :
|
||||
|
||||
|
||||
https://tube.p2p.legal/w/kMc5c8KnLi9BpwJrM4EnKX
|
||||
|
||||
On remarque notamment que des blocs sont créés uniquement et directement après un extrinsic lancé depuis l'app
|
||||
|
||||
---
|
||||
|
||||
# Tuto contributeurs
|
||||
|
||||
**Il n'est nécessaire ni de connaître le code de Ğecko, ni de connaître Dart/flutter pour écrire un nouveau scénario de test !**
|
||||
|
||||
Il vous suffit de comprendre par exemple cet extrait de code:
|
||||
|
||||
```
|
||||
// Copy test mnemonic in clipboard
|
||||
await clipCopy(testMnemonic);
|
||||
|
||||
// Open screen import chest
|
||||
await goKey(keyRestoreChest, duration: 0);
|
||||
|
||||
// Tap on button to paste mnemonic
|
||||
await goKey(keyPastMnemonic);
|
||||
|
||||
// Tap on next button 4 times to skip 3 screen
|
||||
await goKey(keyGoNext);
|
||||
await goKey(keyGoNext);
|
||||
await goKey(keyGoNext);
|
||||
await goKey(keyGoNext);
|
||||
|
||||
// Check if cached password checkbox is checked
|
||||
final isCached = await isIconPresent(Icons.check_box);
|
||||
|
||||
// If not, tap on to cache password
|
||||
if (!isCached) await goKey(keyCachePassword, duration: 0);
|
||||
|
||||
// Enter password
|
||||
await enterText(keyPinForm, 'AAAAA', 0);
|
||||
|
||||
// Check if string "Accéder à mon coffre" is present in screen
|
||||
await waitFor('Accéder à mon coffre');
|
||||
|
||||
// Go to wallets home
|
||||
await goKey(keyGoWalletsHome, duration: 0);
|
||||
|
||||
// Check if string "ĞD" is present in screen
|
||||
await waitFor('ĞD');
|
||||
|
||||
// Tap on add a new derivation button
|
||||
await addDerivation();
|
||||
|
||||
// Tap on Wallet 5
|
||||
await goKey(keyOpenWallet(test5.address));
|
||||
|
||||
// Copy address of Wallet 5
|
||||
await goKey(keyCopyAddress);
|
||||
|
||||
// Check if string "Cette adresse a été copié" is present in screen
|
||||
await waitFor('Cette adresse a été copié');
|
||||
|
||||
// Pop screen 2 time to go back home
|
||||
await goBack();
|
||||
await goBack();
|
||||
|
||||
// Create a new bloc (useless here, just to show you the method)
|
||||
await spawnBlock();
|
||||
|
||||
// Check if string "y'a pas de lézard" is present in screen
|
||||
await waitFor("y'a pas de lézard");
|
||||
```
|
||||
|
||||
Vous avez dans ce bout de code commenté tous ce dont vous avez besoin pour effectuer un test d'intégration dans Ğecko :slight_smile:
|
||||
|
||||
Vous trouverez toutes les clés de widgets disponibles dans l'app dans ce fichier: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/lib/models/widgets_keys.dart
|
||||
|
||||
Ce sont ces clés qui vous permette d’interagir avec les widgets de l'app depuis votre test.
|
||||
|
||||
Pour créer un nouveau test **à partir de zero**, voici la marche à suivre:
|
||||
- Suivez [le readme](https://git.duniter.org/clients/gecko/-/blob/master/README.md) pour configurer votre environnement de développement et ainsi pouvoir lancer Ğecko en mode debug dans un émulateur.
|
||||
- Créer un nouveau fichier pour votre test dans le dossier `integration_test` (ici nous l’appellerons `mon_test.dart`)
|
||||
- Prenez exemple sur le fichier `gecko_complete.dart` pour écrire votre test
|
||||
- Lancer un émulateur android (1 seul)
|
||||
- Exécutez votre test ainsi: `./integration_test/launch_test.sh mon_test`
|
||||
|
||||
Créer toute sorte de tests imaginable dans Ğecko est très utile pour éviter un maximum les régressions de bugs entre les différentes versions.
|
||||
|
||||
Si vous avez envie de nous aider, que vous ne savez presque pas coder mais que vous êtes prêt à mettre un peu les mains dans la sauce, et que vous avez une idée de scénario à tester, alors n'hésitez pas, je répondrais à toutes vos questions :slight_smile:
|
||||
|
||||
A noter que ces tests permettent de tester Gecko mais aussi partiellement Duniter et l'indexer d'une même pierre.
|
|
@ -1,447 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'dart:io';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'package:gecko/main.dart' as app;
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
int globalTimeout = 2;
|
||||
group(
|
||||
'Gecko end-to-end tests',
|
||||
() {
|
||||
// First, define the Finders and use them to locate widgets from the
|
||||
// test suite. Note: the Strings provided to the `byValueKey` method must
|
||||
// be the same as the Strings we used for the Keys in step 1.
|
||||
// final manageWalletsFinder = find.byKey(Key('manageWallets'));
|
||||
// final buttonFinder = find.byValueKey('increment');
|
||||
|
||||
// FlutterDriver driver;
|
||||
WidgetTester tester;
|
||||
String pinCode;
|
||||
|
||||
// *** Global functions *** //
|
||||
|
||||
// Easy get text
|
||||
Future<String> getText(String text) async {
|
||||
Text resultText = tester.firstWidget(find.byKey(Key(text)));
|
||||
// Text pinCodeText = generatedPinFinder.evaluate().single.widget as Text;
|
||||
|
||||
return resultText.data;
|
||||
}
|
||||
|
||||
// Function to tap the widget by key
|
||||
Future tapOn(String key) async {
|
||||
await tester.tap(find.byKey(Key(key)));
|
||||
}
|
||||
|
||||
// Function to go back to previous screen
|
||||
Future goBack() async {
|
||||
await Process.run(
|
||||
'adb',
|
||||
<String>['shell', 'input', 'keyevent', 'KEYCODE_BACK'],
|
||||
runInShell: true,
|
||||
);
|
||||
}
|
||||
|
||||
// Easy sleep
|
||||
Future sleep(int _time) async {
|
||||
await Future.delayed(Duration(milliseconds: _time));
|
||||
}
|
||||
|
||||
// Test if widget exist on screen, return a boolean
|
||||
Future<bool> isPresent(String text,
|
||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
||||
try {
|
||||
expect(text, findsOneWidget);
|
||||
return true;
|
||||
} catch (exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a derivation
|
||||
Future createDerivation(String _name) async {
|
||||
await tapOn('addDerivation');
|
||||
await sleep(100);
|
||||
|
||||
await tester.enterText(find.byKey(Key('DerivationNameKey')), _name);
|
||||
|
||||
await tapOn('validDerivation');
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Delete a derivation
|
||||
Future deleteWallet(bool _confirm) async {
|
||||
await tapOn('deleteWallet');
|
||||
await sleep(100);
|
||||
_confirm
|
||||
? await tapOn('confirmDeleting')
|
||||
: await tapOn('cancelDeleting');
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Delete all wallets
|
||||
Future deleteAllWallets() async {
|
||||
await tester.tap(find.byKey(Key('drawerMenu')));
|
||||
await sleep(300);
|
||||
await tester.tap(find.byKey(Key('parameters')));
|
||||
await sleep(300);
|
||||
await tester.tap(find.byKey(Key('deleteAllWallets')));
|
||||
await sleep(300);
|
||||
await tester.tap(find.byKey(Key('confirmDeletingAllWallets')));
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Fast creation of new Keychain
|
||||
Future<String> createNewKeychain(String name) async {
|
||||
await tapOn('drawerMenu');
|
||||
await sleep(300);
|
||||
await tapOn('parameters');
|
||||
await sleep(300);
|
||||
await tapOn('generateKeychain');
|
||||
expect(find.text(''), findsOneWidget);
|
||||
|
||||
pinCode = await getText('generatedPin');
|
||||
|
||||
await tapOn('storeKeychain');
|
||||
await sleep(100);
|
||||
await tester.enterText(find.byKey(Key('askedWord')), 'triche');
|
||||
await tapOn('walletName');
|
||||
await tester.enterText(find.byKey(Key('walletName')), 'name');
|
||||
await tapOn('confirmStorage');
|
||||
await sleep(300);
|
||||
return pinCode;
|
||||
}
|
||||
|
||||
// *** Begin of tests *** //
|
||||
|
||||
testWidgets('OnBoarding - Open wallets management', (
|
||||
WidgetTester tester, {
|
||||
timeout: Timeout.none,
|
||||
}) async {
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// expect("y'a pas de lézard !", findsOneWidget);
|
||||
await tester.tap(find.byKey(Key('manageWallets')));
|
||||
|
||||
print(
|
||||
'####################################################################');
|
||||
|
||||
// If a wallet exist, go to delete theme all
|
||||
await tester.pumpAndSettle();
|
||||
if (!await isPresent(
|
||||
"Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.")) {
|
||||
await tester.pumpAndSettle();
|
||||
// await tester.pageBack();
|
||||
await goBack();
|
||||
|
||||
await sleep(500);
|
||||
await deleteAllWallets();
|
||||
|
||||
await sleep(300);
|
||||
await tester.tap(find.byKey(Key('manageWallets')));
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify onboarding is starting, with text
|
||||
expect(
|
||||
"Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.",
|
||||
findsOneWidget);
|
||||
});
|
||||
|
||||
// test('OnBoarding - Go to create restore sentance', (
|
||||
// {timeout: Timeout.none}) async {
|
||||
// await tapOn('goStep1');
|
||||
// await tapOn('goStep2');
|
||||
// await tapOn('goStep3');
|
||||
// await tapOn('goStep4');
|
||||
// await tapOn('goStep5');
|
||||
// await tapOn('goStep6');
|
||||
|
||||
// expect(
|
||||
// "J’ai généré votre phrase de restauration !\nTâchez de la garder bien secrète, car elle permet à quiconque la connaît d’accéder à tous vos portefeuilles.",
|
||||
// findsOneWidget);
|
||||
// });
|
||||
|
||||
// test('OnBoarding - Generate sentance and confirme it', (
|
||||
// {timeout: Timeout.none}) async {
|
||||
// await tapOn('goStep7');
|
||||
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// Future selectWord() async {
|
||||
// List words = [for (var i = 1; i <= 13; i += 1) i];
|
||||
|
||||
// for (var j = 1; j < 13; j++) {
|
||||
// words[j] = await getText('word$j');
|
||||
// }
|
||||
// expect(await getText('step7'),
|
||||
// "C'est le moment de noter votre phrase !");
|
||||
|
||||
// await tapOn('goStep8');
|
||||
// await sleep(200);
|
||||
|
||||
// String goodWord = words[int.parse(
|
||||
// await getText('askedWord'),
|
||||
// )];
|
||||
|
||||
// // Enter the expected word
|
||||
// await tester.enterText(find.byKey(Key('inputWord')), goodWord);
|
||||
|
||||
// // Check if word is valid
|
||||
// expect(find.text("C'est le bon mot !"), findsOneWidget);
|
||||
|
||||
// // Continue onboarding workflow
|
||||
// await tapOn('goStep9');
|
||||
// }
|
||||
|
||||
// await selectWord();
|
||||
|
||||
// //Go back 2 times to mnemonic generation screen
|
||||
// await goBack();
|
||||
// await goBack();
|
||||
// await sleep(100);
|
||||
|
||||
// // Generate 3 times mnemonic
|
||||
// await tapOn('generateMnemonic');
|
||||
// await tapOn('generateMnemonic');
|
||||
// await tapOn('generateMnemonic');
|
||||
// await sleep(500);
|
||||
|
||||
// await selectWord();
|
||||
// });
|
||||
// test('OnBoarding - Generate secret code and confirm it', (
|
||||
// {timeout: Timeout.none}) async {
|
||||
// expect(await getText('step9'),
|
||||
// "Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre trousseau de clefs, ce qui le rend inutilisable par d’autres, par exemple si vous perdez votre téléphone ou si on vous le vole.");
|
||||
|
||||
// await tapOn('goStep10');
|
||||
// await tapOn('goStep11');
|
||||
|
||||
// while (await getText('generatedPin') == '') {
|
||||
// print('Waiting for pin code generation...');
|
||||
// await sleep(100);
|
||||
// }
|
||||
|
||||
// // Change secret code 4 times
|
||||
// for (int i = 0; i < 4; i++) await tapOn('changeSecretCode');
|
||||
|
||||
// await sleep(500);
|
||||
// pinCode = await getText('generatedPin');
|
||||
|
||||
// await tapOn('goStep12');
|
||||
// await sleep(300);
|
||||
|
||||
// // //Enter bad secret code
|
||||
// // await tester.enterText('abcde');
|
||||
// // await tapOn('formKey');
|
||||
// // await sleep(1500);
|
||||
// // await tapOn('formKey2');
|
||||
|
||||
// //Enter good secret code
|
||||
// await tester.enterText(find.byKey(Key('formKey2')), pinCode);
|
||||
|
||||
// expect(await getText('step13'),
|
||||
// "Top !\n\nVotre trousseau de clef et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !");
|
||||
// });
|
||||
|
||||
// test('My wallets - Rename first derivation', (
|
||||
// {timeout: const Duration(seconds: 2)}) async {
|
||||
// await tapOn('goWalletHome');
|
||||
|
||||
// expect(await getText('myWallets'), "Mes portefeuilles");
|
||||
// await sleep(300);
|
||||
|
||||
// // Go to first derivation and rename it
|
||||
// await tester.tap(find.text('Mon portefeuille courant'));
|
||||
// await sleep(300);
|
||||
// await tapOn('renameWallet');
|
||||
// await sleep(100);
|
||||
// await tapOn('walletName');
|
||||
// await sleep(100);
|
||||
// await tester.enterText(
|
||||
// find.byKey(Key('walletName')), 'Renommage wallet 1');
|
||||
// await sleep(300);
|
||||
// await tapOn('renameWallet');
|
||||
// await sleep(400);
|
||||
// expect('Renommage wallet 1', findsOneWidget);
|
||||
// await goBack();
|
||||
// });
|
||||
|
||||
// test('My wallets - Create a derivations, open thems, tap all buttons', (
|
||||
// {timeout: const Duration(seconds: 2)}) async {
|
||||
// expect('Renommage wallet 1', findsOneWidget);
|
||||
|
||||
// // Add a second derivation
|
||||
// await createDerivation('Derivation 2');
|
||||
|
||||
// // Go to second derivation options
|
||||
// await tester.tap(find.text('Derivation 2'));
|
||||
// await sleep(100);
|
||||
|
||||
// // Test options
|
||||
// await tapOn('displayBalance');
|
||||
// await tapOn('displayHistory');
|
||||
// await sleep(300);
|
||||
// await goBack();
|
||||
// await tapOn('displayBalance');
|
||||
// await sleep(100);
|
||||
// await tapOn('displayBalance');
|
||||
// await sleep(100);
|
||||
// await tapOn('displayBalance');
|
||||
// await tapOn('setDefaultWallet');
|
||||
// await sleep(50);
|
||||
// await tapOn('copyPubkey');
|
||||
// expect('Cette clé publique a été copié dans votre presse-papier.',
|
||||
// findsOneWidget);
|
||||
// await goBack();
|
||||
|
||||
// // Add a third derivation
|
||||
// await createDerivation('Derivation 3');
|
||||
|
||||
// // Add a fourth derivation
|
||||
// await createDerivation('Derivation 4');
|
||||
// await sleep(50);
|
||||
|
||||
// // Go to third derivation options
|
||||
// await tester.tap(find.text('Derivation 3'));
|
||||
// await sleep(100);
|
||||
// await tapOn('displayBalance');
|
||||
|
||||
// // Delete third derivation
|
||||
// await deleteWallet(true);
|
||||
// });
|
||||
|
||||
// test('My wallets - Extra tests', (
|
||||
// {timeout: const Duration(seconds: 2)}) async {
|
||||
// // Add derivation 5,6 and 7
|
||||
// expect('Derivation 4', findsOneWidget);
|
||||
// await createDerivation('Derivation 5');
|
||||
// await createDerivation('Derivation 6');
|
||||
// await createDerivation('Derivation 7');
|
||||
|
||||
// // Go home and come back to my wallets view
|
||||
// await goBack();
|
||||
// await sleep(100);
|
||||
// await tapOn('manageWallets');
|
||||
// await sleep(200);
|
||||
// //Enter secret code
|
||||
// await tester.enterText(find.byKey(Key('formKey')), pinCode);
|
||||
// await sleep(200);
|
||||
|
||||
// // Go to derivation 6 and delete it
|
||||
// await tester.tap(find.text('Derivation 6'));
|
||||
// await sleep(100);
|
||||
// await deleteWallet(true);
|
||||
|
||||
// // Go to 2nd derivation and check if it's de default
|
||||
// await tester.tap(find.text('Derivation 2'));
|
||||
// expect('Ce portefeuille est celui par defaut', findsOneWidget);
|
||||
// await tapOn('setDefaultWallet');
|
||||
// await sleep(100);
|
||||
// expect('Ce portefeuille est celui par defaut', findsOneWidget);
|
||||
// await sleep(300);
|
||||
|
||||
// // Display history, copy pubkey, go back and rename wallet name
|
||||
// await tapOn('displayHistory');
|
||||
// await sleep(400);
|
||||
// await tapOn('copyPubkey');
|
||||
// expect('Cette clé publique a été copié dans votre presse-papier.',
|
||||
// findsOneWidget);
|
||||
// await sleep(800);
|
||||
// await goBack();
|
||||
// await sleep(300);
|
||||
// await tapOn('renameWallet');
|
||||
// await sleep(100);
|
||||
// await tapOn('walletName');
|
||||
// await sleep(100);
|
||||
// await tester.enterText(
|
||||
// find.byKey(Key('walletName')), 'Renommage wallet 2');
|
||||
// await sleep(300);
|
||||
// await tapOn('renameWallet');
|
||||
// await sleep(400);
|
||||
// await goBack();
|
||||
// expect('Renommage wallet 2', findsOneWidget);
|
||||
// await createDerivation('Derivation 8');
|
||||
// await createDerivation('Derivation 9');
|
||||
// await createDerivation('Derivation 10');
|
||||
// await createDerivation('Derivation 11');
|
||||
// await createDerivation('Derivation 12');
|
||||
// await createDerivation('Derivation 13');
|
||||
// await createDerivation('Derivation 14');
|
||||
// await createDerivation('Derivation 15');
|
||||
// await createDerivation('Derivation 16');
|
||||
// await createDerivation('Derivation 17');
|
||||
// await createDerivation('Derivation 18');
|
||||
// await createDerivation('Derivation 19');
|
||||
// await createDerivation('Derivation 20');
|
||||
// await sleep(400);
|
||||
|
||||
// // Scroll the wallet screen until Derivation 20 and open it
|
||||
// await tester.scrollUntilVisible(find.byKey(Key('listWallets')), -300.0);
|
||||
|
||||
// expect('Derivation 20', findsOneWidget);
|
||||
// await sleep(400);
|
||||
// await tester.tap(find.text('Derivation 20'));
|
||||
// await tapOn('copyPubkey');
|
||||
// });
|
||||
|
||||
// test('Search - Search Pi profile, navigate in history transactions', (
|
||||
// {timeout: const Duration(seconds: 2)}) async {
|
||||
// expect('Derivation 20', findsOneWidget);
|
||||
// await goBack();
|
||||
// await goBack();
|
||||
// await sleep(200);
|
||||
// await tapOn('searchIcon');
|
||||
// await sleep(400);
|
||||
// await tester.enterText(find.byKey(Key('searchInput')),
|
||||
// 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU');
|
||||
// await sleep(100);
|
||||
// await tapOn('copyPubkey');
|
||||
// await sleep(500);
|
||||
// await tapOn('switchPayHistory');
|
||||
// await sleep(1200);
|
||||
// // await tester.scrollIntoView(find.byValueKey('listTransactions'));
|
||||
// await tester.scrollUntilVisible(
|
||||
// find.byKey(Key('listTransactions')),
|
||||
// -600.0,
|
||||
// );
|
||||
// await sleep(100);
|
||||
// await tapOn('transaction33');
|
||||
// expect('Commentaire:', findsOneWidget);
|
||||
|
||||
// // Want to paste pubkey copied, but doesn't work actualy with flutter driver: https://github.com/flutter/flutter/issues/47448
|
||||
// // final ClipboardData pubkeyCopied =
|
||||
// // await Clipboard.getData(Clipboard.kTextPlain);
|
||||
// // await tester.enterText(pubkeyCopied.text);
|
||||
|
||||
// await sleep(300);
|
||||
// }, timeout: Timeout(Duration(minutes: globalTimeout)));
|
||||
|
||||
// test('Wallet generation - Fast wallets generations', (
|
||||
// {timeout: const Duration(seconds: 2)}) async {
|
||||
// expect('Commentaire:', findsOneWidget);
|
||||
// await goBack();
|
||||
// await goBack();
|
||||
// await deleteAllWallets();
|
||||
// await sleep(100);
|
||||
// final String pincode = await createNewKeychain('Fast wallet');
|
||||
// await sleep(100);
|
||||
// await tapOn('manageWallets');
|
||||
// await sleep(200);
|
||||
// await tester.enterText(find.byKey(Key('formKey')), pinCode);
|
||||
// await sleep(100);
|
||||
// await createDerivation('Derivation 2');
|
||||
// await sleep(100);
|
||||
// await tester.tap(find.text('Fast wallet'));
|
||||
// expect('Fast wallet', findsOneWidget);
|
||||
// // Wait 3 seconds at the end
|
||||
// await sleep(3000);
|
||||
// });
|
||||
},
|
||||
);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'general_actions.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
void main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
await dotenv.load();
|
||||
|
||||
testWidgets('Certifications state', (testerLoc) async {
|
||||
tester = testerLoc;
|
||||
// Connect local node and import test chest in background
|
||||
await bkFastStart();
|
||||
|
||||
// Open chest
|
||||
await firstOpenChest();
|
||||
await goBack();
|
||||
|
||||
// Go wallet 5 view
|
||||
await tapKey(keyOpenSearch);
|
||||
await enterText(keySearchField, test5.address);
|
||||
await tapKey(keyConfirmSearch);
|
||||
await waitFor(test5.shortAddress());
|
||||
await tapKey(keySearchResult(test5.address));
|
||||
await waitFor('Certifier');
|
||||
await waitFor('Vous devez ', reverse: true);
|
||||
await waitFor('Vous pourrez renouveler ', reverse: true);
|
||||
|
||||
// Background pay 25
|
||||
await bkPay(
|
||||
fromAddress: test1.address, destAddress: test5.address, amount: 25);
|
||||
await waitFor('25.0 $currencyName');
|
||||
await spawnBlock();
|
||||
await waitFor('22.0 $currencyName');
|
||||
await bkCertify(fromAddress: test1.address, destAddress: test5.address);
|
||||
await waitFor('1', exactMatch: true);
|
||||
await bkConfirmIdentity(fromAddress: test5.address, name: test5.name);
|
||||
await bkCertify(fromAddress: test2.address, destAddress: test5.address);
|
||||
await waitFor('2', exactMatch: true);
|
||||
await bkCertify(fromAddress: test3.address, destAddress: test5.address);
|
||||
await waitFor('3', exactMatch: true);
|
||||
await bkCertify(fromAddress: test4.address, destAddress: test5.address);
|
||||
await waitFor('4', exactMatch: true);
|
||||
await bkPay(
|
||||
fromAddress: test2.address, destAddress: test5.address, amount: 40);
|
||||
await waitFor('61.99 $currencyName');
|
||||
await spawnBlock(until: 10);
|
||||
await waitFor('161.99 $currencyName');
|
||||
await spawnBlock(until: 20);
|
||||
await waitFor('261.99 $currencyName');
|
||||
}, timeout: testTimeout());
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"first_ud": 10000,
|
||||
"first_ud_reeval": 50,
|
||||
"genesis_parameters": {
|
||||
"genesis_certs_expire_on": 500,
|
||||
"genesis_certs_min_received": 3,
|
||||
"genesis_memberships_expire_on": 1051200,
|
||||
"genesis_smith_certs_expire_on": 2102400,
|
||||
"genesis_smith_certs_min_received": 3,
|
||||
"genesis_smith_memberships_expire_on": 1051200
|
||||
},
|
||||
"identities": {
|
||||
"test1": {
|
||||
"balance": 10000,
|
||||
"certs": ["test2", "test3", "test4"],
|
||||
"pubkey": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa"
|
||||
},
|
||||
"test2": {
|
||||
"balance": 10000,
|
||||
"certs": ["test1", "test3", "test4"],
|
||||
"pubkey": "5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb"
|
||||
},
|
||||
"test3": {
|
||||
"balance": 10000,
|
||||
"certs": ["test1", "test2", "test4"],
|
||||
"pubkey": "5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p"
|
||||
},
|
||||
"test4": {
|
||||
"balance": 10000,
|
||||
"certs": ["test1", "test2", "test3"],
|
||||
"pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5"
|
||||
},
|
||||
"testCesium1": {
|
||||
"balance": 10000,
|
||||
"certs": ["test1", "test2", "test3"],
|
||||
"pubkey": "5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"babe_epoch_duration": 30,
|
||||
"cert_period": 15,
|
||||
"cert_max_by_issuer": 10,
|
||||
"cert_min_received_cert_to_issue_cert": 2,
|
||||
"cert_validity_period": 1000,
|
||||
"idty_confirm_period": 40,
|
||||
"idty_creation_period": 50,
|
||||
"membership_period": 1000,
|
||||
"pending_membership_period": 500,
|
||||
"ud_creation_period": 10,
|
||||
"ud_reeval_period": 50,
|
||||
"smith_cert_period": 15,
|
||||
"smith_cert_max_by_issuer": 8,
|
||||
"smith_cert_min_received_cert_to_issue_cert": 2,
|
||||
"smith_cert_validity_period": 1000,
|
||||
"smith_membership_period": 1000,
|
||||
"smith_pending_membership_period": 500,
|
||||
"smiths_wot_first_cert_issuable_on": 20,
|
||||
"smiths_wot_min_cert_for_membership": 3,
|
||||
"wot_first_cert_issuable_on": 0,
|
||||
"wot_min_cert_for_create_idty_right": 3,
|
||||
"wot_min_cert_for_membership": 3
|
||||
},
|
||||
"smiths": {
|
||||
"test1": {
|
||||
"certs": ["test2", "test3", "test4"]
|
||||
},
|
||||
"test2": {
|
||||
"certs": ["test1", "test3", "test4"]
|
||||
},
|
||||
"test3": {
|
||||
"certs": ["test1", "test2", "test4"]
|
||||
},
|
||||
"test4": {
|
||||
"certs": ["test1", "test2", "test3"]
|
||||
}
|
||||
},
|
||||
"sudo_key": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa",
|
||||
"technical_committee": ["test1", "test2", "test3"]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
duniter-v2s-gecko-tests:
|
||||
container_name: duniter-v2s-gecko-tests
|
||||
image: duniter/duniter-v2s:debug-latest
|
||||
command: --sealing=manual
|
||||
ports:
|
||||
- "127.0.0.1:9615:9615"
|
||||
- "127.0.0.1:9933:9933"
|
||||
- "0.0.0.0:9944:9944"
|
||||
- "30333:30333"
|
||||
environment:
|
||||
DUNITER_INSTANCE_NAME: "gecko_tests"
|
||||
DUNITER_CHAIN_NAME: "dev"
|
||||
DUNITER_GENESIS_CONFIG: "/var/lib/duniter/gecko_tests.json"
|
||||
volumes:
|
||||
- ./data:/var/lib/duniter
|
|
@ -0,0 +1,139 @@
|
|||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'general_actions.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
void main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
await dotenv.load();
|
||||
|
||||
testWidgets('Gecko complete', (testerLoc) async {
|
||||
// Share WidgetTester to test provider
|
||||
tester = testerLoc;
|
||||
|
||||
// Start app and wait finish starting
|
||||
await startWait();
|
||||
|
||||
// Change Duniter endpoint to local
|
||||
await changeNode();
|
||||
|
||||
// Delete all existing chests is exists
|
||||
await deleteAllWallets();
|
||||
|
||||
// Restore the test chest
|
||||
await restoreChest();
|
||||
|
||||
// Execute a transaction to test5
|
||||
await payTest2();
|
||||
|
||||
// Certify test5 account with 3 accounts to become member
|
||||
await certifyTest5();
|
||||
}, timeout: testTimeout());
|
||||
}
|
||||
|
||||
Future payTest2() async {
|
||||
await waitFor('Rechercher');
|
||||
await tapKey(keyOpenSearch);
|
||||
final addressToSearch = await clipPaste();
|
||||
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
||||
expect(addressToSearch, test5.address);
|
||||
await enterText(keySearchField, addressToSearch);
|
||||
await tapKey(keyConfirmSearch);
|
||||
await waitFor(endAddress);
|
||||
await tapKey(keySearchResult(addressToSearch));
|
||||
await waitFor(endAddress);
|
||||
await waitFor('0.0 ĞD');
|
||||
await tapKey(keyPay);
|
||||
await enterText(keyAmountField, '12.14');
|
||||
await tapKey(keyConfirmPayment);
|
||||
spawnBlock(duration: 500);
|
||||
|
||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||
await waitFor('12.14');
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('9.14');
|
||||
humanRead(2);
|
||||
}
|
||||
|
||||
Future certifyTest5() async {
|
||||
// Create identity with Test1 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('Identité créée');
|
||||
|
||||
// Confirm Identity Test5
|
||||
await tapKey(keyAppBarChest, duration: 300);
|
||||
await tapKey(keyOpenWallet(test5.address));
|
||||
await tapKey(keyCopyAddress);
|
||||
humanRead(3);
|
||||
await tapKey(keyConfirmIdentity);
|
||||
await enterText(keyEnterIdentityUsername, test5.name);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('Identité confirmée');
|
||||
humanRead(2);
|
||||
// Set wallet 2 as default wallet
|
||||
await goBack();
|
||||
await tapKey(keyOpenWallet(test2.address));
|
||||
await tapKey(keySetDefaultWallet);
|
||||
await waitFor('Ce portefeuille est celui par defaut');
|
||||
|
||||
// Search Wallet 5 again
|
||||
await tapKey(keyAppBarSearch);
|
||||
final addressToSearch = await clipPaste();
|
||||
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
||||
expect(addressToSearch, test5.address);
|
||||
await enterText(keySearchField, addressToSearch);
|
||||
await tapKey(keyConfirmSearch);
|
||||
await waitFor(endAddress);
|
||||
await tapKey(keySearchResult(addressToSearch));
|
||||
await waitFor(endAddress);
|
||||
await waitFor('1');
|
||||
|
||||
// Certify with test2 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('2');
|
||||
|
||||
// Change default wallet to test3
|
||||
await tapKey(keyPay);
|
||||
await tapKey(keyChangeChest);
|
||||
await tapKey(keySelectThisWallet(test3.address));
|
||||
await tapKey(keyConfirm);
|
||||
await sleep();
|
||||
|
||||
// Certify with test3 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('Vous devez attendre');
|
||||
|
||||
// Check if test5 is member
|
||||
await tapKey(keyAppBarChest, duration: 300);
|
||||
await tapKey(keyOpenWallet(test5.address));
|
||||
await waitFor('Membre validé !');
|
||||
|
||||
// spawn 20 blocs and check if ud is creating
|
||||
await spawnBlock(until: 10);
|
||||
await waitFor('109.13');
|
||||
await spawnBlock(until: 20);
|
||||
await waitFor('209.13');
|
||||
|
||||
// Check UD reval
|
||||
await spawnBlock(until: 50);
|
||||
await waitFor('509.36');
|
||||
humanRead(5);
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
// GENERAL ACTIONS
|
||||
|
||||
Future changeNode() async {
|
||||
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
|
||||
log.d('ip address: $ipAddress');
|
||||
|
||||
await tapKey(keyDrawerMenu);
|
||||
await tapKey(keyParameters);
|
||||
await tapKey(keySelectDuniterNodeDropDown, duration: 5);
|
||||
await tapKey(keySelectDuniterNode('Personnalisé'), selectLast: true);
|
||||
await enterText(keyCustomDuniterEndpoint, 'ws://$ipAddress:9944');
|
||||
await tapKey(keyConnectToEndpoint);
|
||||
await isIconPresent(Icons.add_card_sharp,
|
||||
timeout: const Duration(seconds: 8));
|
||||
await goBack();
|
||||
}
|
||||
|
||||
Future deleteAllWallets() async {
|
||||
if (await isPresent('Rechercher')) {
|
||||
await tapKey(keyDrawerMenu);
|
||||
await tapKey(keyParameters);
|
||||
await tapKey(keyDeleteAllWallets);
|
||||
await tapKey(keyConfirm);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
}
|
||||
|
||||
Future restoreChest() async {
|
||||
// Copy test mnemonic in clipboard
|
||||
await clipCopy(testMnemonic);
|
||||
|
||||
// Open screen import chest
|
||||
await tapKey(keyRestoreChest, duration: 0);
|
||||
|
||||
// Tap on button to paste mnemonic
|
||||
await tapKey(keyPastMnemonic);
|
||||
|
||||
// Tap on next button 4 times to skip 3 screen
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
|
||||
// Check if cached password checkbox is checked
|
||||
final isCached = await isIconPresent(Icons.check_box);
|
||||
|
||||
// If not, tap on to cache password
|
||||
if (!isCached) await tapKey(keyCachePassword, duration: 0);
|
||||
|
||||
// Enter password
|
||||
await enterText(keyPinForm, 'AAAAA', 0);
|
||||
|
||||
// Check if string "Accéder à mon coffre" is present in screen
|
||||
await waitFor('Accéder à mon coffre');
|
||||
|
||||
// Go to wallets home
|
||||
await tapKey(keyGoWalletsHome, duration: 0);
|
||||
|
||||
// Check if string "ĞD" is present in screen
|
||||
await waitFor('ĞD');
|
||||
|
||||
// Tap on add a new derivation button
|
||||
await addDerivation();
|
||||
|
||||
// Tap on Wallet 5
|
||||
await tapKey(keyOpenWallet(test5.address));
|
||||
|
||||
// Copy address of Wallet 5
|
||||
await tapKey(keyCopyAddress);
|
||||
|
||||
// Check if string "Cette adresse a été copié" is present in screen
|
||||
await waitFor('Cette adresse a été copié');
|
||||
|
||||
// Pop screen 2 time to go back home
|
||||
await goBack();
|
||||
await goBack();
|
||||
}
|
||||
|
||||
Future onboardingNewChest() async {
|
||||
final generateWalletProvider =
|
||||
Provider.of<GenerateWalletsProvider>(homeContext, listen: false);
|
||||
// Open screen create new wallet
|
||||
await tapKey(keyOnboardingNewChest);
|
||||
|
||||
// Tap on next button 4 times to skip 3 screen
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await waitFor('7', exactMatch: true);
|
||||
|
||||
final word41 = getWidgetText(keyMnemonicWord('4'));
|
||||
|
||||
// Change 2 times mnemonic
|
||||
await tapKey(keyGenerateMnemonic);
|
||||
await tester.pumpAndSettle();
|
||||
final word42 = getWidgetText(keyMnemonicWord('4'));
|
||||
expect(word41, isNot(word42));
|
||||
await tapKey(keyGenerateMnemonic, duration: 500);
|
||||
await tester.pumpAndSettle();
|
||||
final word43 = getWidgetText(keyMnemonicWord('4'));
|
||||
expect(word42, isNot(word43));
|
||||
|
||||
// Go next screen
|
||||
await tapKey(keyGoNext);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Enter asked word
|
||||
final askedWordNumber = int.parse(getWidgetText(keyAskedWord));
|
||||
List mnemonic = generateWalletProvider.generatedMnemonic!.split(' ');
|
||||
|
||||
final askedWord = mnemonic[askedWordNumber - 1];
|
||||
await enterText(keyInputWord, askedWord);
|
||||
await waitFor('Continuer', exactMatch: true);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await tapKey(keyGoNext);
|
||||
await waitFor('AAAAA', exactMatch: true);
|
||||
await tapKey(keyGoNext);
|
||||
|
||||
// Check if cached password checkbox is checked
|
||||
final isCached = await isIconPresent(Icons.check_box);
|
||||
|
||||
// If not, tap on to cache password
|
||||
if (!isCached) await tapKey(keyCachePassword, duration: 0);
|
||||
|
||||
// Enter password
|
||||
await enterText(keyPinForm, 'AAAAA', 0);
|
||||
|
||||
// Check if string "Accéder à mon coffre" is present in screen
|
||||
await waitFor('Accéder à mon coffre');
|
||||
|
||||
// Go to wallets home
|
||||
await tapKey(keyGoWalletsHome, duration: 0);
|
||||
|
||||
// Check if string "ĞD" is present in screen
|
||||
await waitFor('Mon portefeuille co');
|
||||
await waitFor('0.0 $currencyName');
|
||||
// await waitFor('Scanner un');
|
||||
}
|
||||
|
||||
Future addDerivation() async {
|
||||
await tapKey(keyAddDerivation);
|
||||
await waitFor('Portefeuille 5');
|
||||
}
|
||||
|
||||
Future firstOpenChest() async {
|
||||
await tapKey(keyOpenWalletsHomme);
|
||||
sleep(300);
|
||||
final isCached = await isIconPresent(Icons.check_box);
|
||||
if (!isCached) await tapKey(keyCachePassword, duration: 0);
|
||||
await enterText(keyPinForm, 'AAAAA', 0);
|
||||
await waitFor('100.0 $currencyName');
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
testName=$1
|
||||
option=$2
|
||||
[[ ! $testName ]] && testName='gecko_complete'
|
||||
|
||||
# Get local IP and set .env
|
||||
ip_address=$(hostname -I | awk '{print $1}')
|
||||
echo "ip_address=$ip_address" > .env
|
||||
[[ $option == 'human' ]] && echo "isHumanReading=true" >> .env
|
||||
|
||||
## Start local Duniter node
|
||||
cd integration_test/duniter
|
||||
docker compose down
|
||||
rm -rf data/chains
|
||||
docker compose up -d
|
||||
cd ../..
|
||||
|
||||
# Start integration test
|
||||
flutter test integration_test/$testName.dart && echo '0' > /tmp/geckoTestResult || echo '1' > /tmp/geckoTestResult
|
||||
|
||||
# Reset .env
|
||||
echo "ip_address=127.0.0.1" > .env
|
||||
|
||||
# Stop Duniter
|
||||
cd integration_test/duniter
|
||||
docker compose down
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'general_actions.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
void main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
await dotenv.load();
|
||||
|
||||
testWidgets('Migrate Cesium identity and balance', (testerLoc) async {
|
||||
tester = testerLoc;
|
||||
// Connect local node and import test chest in background
|
||||
await bkFastStart();
|
||||
|
||||
// Open chest
|
||||
await firstOpenChest();
|
||||
|
||||
// Go to test1 options and check if balance growup with UDs creations
|
||||
await tapKey(keyAddDerivation);
|
||||
await waitFor('Portefeuille 6');
|
||||
|
||||
await scrollUntil(keyImportG1v1);
|
||||
await tapKey(keyImportG1v1);
|
||||
await enterText(keyCesiumId, 'test');
|
||||
await enterText(keyCesiumPassword, 'test');
|
||||
await waitFor(cesiumTest1.shortAddress());
|
||||
await waitFor('100.0 $currencyName');
|
||||
await waitFor('3', exactMatch: true);
|
||||
|
||||
isObscureText();
|
||||
await tapKey(keyCesiumIdVisible);
|
||||
await tester.pumpAndSettle();
|
||||
isObscureText(false);
|
||||
await tapKey(keyCesiumIdVisible);
|
||||
await tester.pumpAndSettle();
|
||||
isObscureText();
|
||||
|
||||
await tapKey(keySelectWallet);
|
||||
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
||||
await waitForButtonEnabled(keyConfirm);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 2000);
|
||||
await waitFor('validé !');
|
||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||
|
||||
await tapKey(keyOpenWallet(test6.address), duration: 300);
|
||||
await waitFor('3', exactMatch: true);
|
||||
await waitFor('Membre validé !');
|
||||
|
||||
await waitFor('99.98 $currencyName');
|
||||
}, timeout: testTimeout());
|
||||
}
|
||||
|
||||
isObscureText([bool isObscure = true]) {
|
||||
final passwordTextFormField = find.descendant(
|
||||
of: find.byKey(keyCesiumId),
|
||||
matching: find.byType(EditableText),
|
||||
);
|
||||
final input = tester.widget<EditableText>(passwordTextFormField);
|
||||
expect(input.obscureText, isObscure ? isTrue : isFalse);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'general_actions.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
void main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
await dotenv.load();
|
||||
|
||||
testWidgets('Onboarding and multi chest', (testerLoc) async {
|
||||
tester = testerLoc;
|
||||
await bkFastStart(false);
|
||||
await onboardingNewChest();
|
||||
}, timeout: testTimeout());
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'dart:io' as io;
|
||||
import 'package:gecko/main.dart' as app;
|
||||
|
||||
final bool isHumanReading =
|
||||
dotenv.env['isHumanReading'] == 'true' ? true : false;
|
||||
Timeout testTimeout([int seconds = 120]) =>
|
||||
Timeout(Duration(seconds: isHumanReading ? 600 : seconds));
|
||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||
late WidgetTester tester;
|
||||
|
||||
// TEST WALLETS CONSTS
|
||||
const testMnemonic =
|
||||
'pipe paddle ketchup filter life ice feel embody glide quantum ride usage';
|
||||
final test1 =
|
||||
TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test1');
|
||||
final test2 =
|
||||
TestWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb', 'test2');
|
||||
final test3 =
|
||||
TestWallet('5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p', 'test3');
|
||||
final test4 =
|
||||
TestWallet('5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5', 'test4');
|
||||
final test5 =
|
||||
TestWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R', 'test5');
|
||||
final test6 =
|
||||
TestWallet('5GxEp3do81j97kNaH4JyZgDXuPoKWoTuxXXWGyyNXeKeVLHb', 'test6');
|
||||
final test7 =
|
||||
TestWallet('5FZ1sSvREbQLCtSSCvMUx7KCAnpJkB7q5mfz2oixiZq2ChET', 'test7');
|
||||
final test8 =
|
||||
TestWallet('5CoKV9EEgwb2NmWamTXUAa6ycfNb2k1iNfVGvJAkg7dLq9RH', 'test8');
|
||||
final cesiumTest1 = TestWallet(
|
||||
'5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1', 'cesiumTest1');
|
||||
final cesiumTest2 = TestWallet(
|
||||
'5DTnny1tTkUs1SXHZTx98RUAj76Z88FfFhsQjd48dXnk8gHR', 'cesiumTest2');
|
||||
final cesiumTest3 = TestWallet(
|
||||
'5EJct9jTDNKco4YiYfETAseq1gaduBtsJUcNnFicfvh3bTV6', 'cesiumTest3');
|
||||
final cesiumTest4 = TestWallet(
|
||||
'5HD1oSv6A7VNxPYos6F86JFZ3bhz5LnEaWC4hkwLMj84v4ww', 'cesiumTest4');
|
||||
|
||||
// CUSTOM FUNCTIONS
|
||||
|
||||
Future sleep([int time = 1000]) async {
|
||||
await Future.delayed(Duration(milliseconds: time));
|
||||
}
|
||||
|
||||
Future<String> clipPaste() async =>
|
||||
(await Clipboard.getData('text/plain'))?.text ?? '';
|
||||
|
||||
clipCopy(String text) async =>
|
||||
await Clipboard.setData(ClipboardData(text: text));
|
||||
|
||||
Future humanRead([int time = 1, bool force = false]) async {
|
||||
if (isHumanReading || force) io.sleep(Duration(seconds: time));
|
||||
}
|
||||
|
||||
Future tapKey(Key buttonKey,
|
||||
{Finder? customFinder, int duration = 100, bool selectLast = false}) async {
|
||||
if (duration != 0) {
|
||||
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
||||
}
|
||||
final Finder finder = customFinder ?? find.byKey(buttonKey);
|
||||
log.d('INTEGRATION TEST: Tap on ${finder.description}}');
|
||||
await tester.tap(selectLast ? finder.last : finder);
|
||||
humanRead();
|
||||
}
|
||||
|
||||
Finder findByKey(Key key) {
|
||||
return find.byKey(key);
|
||||
}
|
||||
|
||||
bool isButtonEnabled(Key key) {
|
||||
return tester.widget<ElevatedButton>(findByKey(key)).enabled;
|
||||
}
|
||||
|
||||
Future scrollUntil(Key element) async {
|
||||
final findList = find.byType(Scrollable);
|
||||
final findElement = findByKey(element);
|
||||
await tester.scrollUntilVisible(
|
||||
findElement,
|
||||
500.0,
|
||||
scrollable: findList,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> waitForButtonEnabled(Key key,
|
||||
{Duration timeout = const Duration(seconds: 5),
|
||||
bool reverse = false}) async {
|
||||
final end = DateTime.now().add(timeout);
|
||||
|
||||
log.d('INTEGRATION TEST: Wait for $key to be enabled');
|
||||
|
||||
do {
|
||||
if (DateTime.now().isAfter(end)) {
|
||||
throw Exception('Timed out waiting for button enabled: $key');
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
} while (reverse ? isButtonEnabled(key) : !isButtonEnabled(key));
|
||||
humanRead();
|
||||
}
|
||||
|
||||
Future goBack() async {
|
||||
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
||||
log.d('INTEGRATION TEST: Go back');
|
||||
navigator.pop();
|
||||
await tester.pump();
|
||||
humanRead();
|
||||
}
|
||||
|
||||
Future enterText(Key fieldKey, String textIn, [int duration = 200]) async {
|
||||
if (duration != 0) {
|
||||
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
||||
}
|
||||
log.d('INTEGRATION TEST: Enter text: $textIn');
|
||||
await tester.enterText(find.byKey(fieldKey), textIn);
|
||||
humanRead();
|
||||
}
|
||||
|
||||
Future<void> waitFor(String text,
|
||||
{Duration timeout = const Duration(seconds: 5),
|
||||
bool reverse = false,
|
||||
bool exactMatch = false}) async {
|
||||
final end = DateTime.now().add(timeout);
|
||||
|
||||
Finder finder = exactMatch ? find.text(text) : find.textContaining(text);
|
||||
log.d('INTEGRATION TEST: Wait for: $text');
|
||||
|
||||
do {
|
||||
if (DateTime.now().isAfter(end)) {
|
||||
throw Exception('Timed out waiting for text $text');
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
||||
humanRead();
|
||||
}
|
||||
|
||||
// Test if text is visible on screen, return a boolean
|
||||
Future<bool> isPresent(String text,
|
||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
||||
try {
|
||||
await waitFor(text, timeout: timeout);
|
||||
humanRead();
|
||||
return true;
|
||||
} catch (exception) {
|
||||
humanRead();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test if widget exist on screen, return a boolean
|
||||
Future<bool> isIconPresent(IconData icon,
|
||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
||||
await tester.pumpAndSettle();
|
||||
final finder = find.byIcon(icon);
|
||||
log.d('tatatatatatata: ${finder.evaluate()}');
|
||||
humanRead();
|
||||
return finder.evaluate().isEmpty ? false : true;
|
||||
}
|
||||
|
||||
Future spawnBlock({int number = 1, int duration = 200, int? until}) async {
|
||||
if (duration != 0) {
|
||||
await sleep(duration);
|
||||
}
|
||||
if (until != null) {
|
||||
number = until - sub.blocNumber;
|
||||
}
|
||||
await sub.spawnBlock(number);
|
||||
await sleep(200);
|
||||
}
|
||||
|
||||
// Pay in background
|
||||
Future bkPay(
|
||||
{required String fromAddress,
|
||||
required String destAddress,
|
||||
required double amount}) async {
|
||||
sub.pay(
|
||||
fromAddress: fromAddress,
|
||||
destAddress: destAddress,
|
||||
amount: amount,
|
||||
password: 'AAAAA');
|
||||
await spawnBlock();
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
// Certify in background
|
||||
Future bkCertify(
|
||||
{required String fromAddress, required String destAddress}) async {
|
||||
sub.certify(fromAddress, destAddress, 'AAAAA');
|
||||
await spawnBlock();
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
// Confirm my identity in background
|
||||
Future bkConfirmIdentity(
|
||||
{required String fromAddress, required String name}) async {
|
||||
sub.confirmIdentity(fromAddress, name, 'AAAAA');
|
||||
await spawnBlock();
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
// Change node in background
|
||||
Future bkSetNode([String? endpoint]) async {
|
||||
if (endpoint == null) {
|
||||
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
|
||||
endpoint = 'ws://$ipAddress:9944';
|
||||
}
|
||||
configBox.put('customEndpoint', endpoint);
|
||||
sub.connectNode(homeContext);
|
||||
}
|
||||
|
||||
// Restore chest in background
|
||||
Future bkRestoreChest([String mnemonic = testMnemonic]) async {
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
||||
final generateWalletProvider =
|
||||
Provider.of<GenerateWalletsProvider>(homeContext, listen: false);
|
||||
|
||||
await generateWalletProvider.storeHDWChest(homeContext);
|
||||
|
||||
for (int number = 0; number <= 4; number++) {
|
||||
await _addImportAccount(
|
||||
mnemonic: mnemonic,
|
||||
chest: 0,
|
||||
number: number,
|
||||
name: 'test${number + 1}',
|
||||
derivation: (number + 1) * 2);
|
||||
}
|
||||
myWalletProvider.rebuildWidget();
|
||||
}
|
||||
|
||||
Future<WalletData> _addImportAccount(
|
||||
{required String mnemonic,
|
||||
required int chest,
|
||||
required int number,
|
||||
required String name,
|
||||
required int derivation}) async {
|
||||
final address = await sub.importAccount(
|
||||
mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA');
|
||||
final myWallet = WalletData(
|
||||
version: dataVersion,
|
||||
chest: chest,
|
||||
address: address,
|
||||
number: number,
|
||||
name: name,
|
||||
derivation: derivation,
|
||||
imageDefaultPath: '${number % 4}.png');
|
||||
await walletBox.add(myWallet);
|
||||
|
||||
return myWallet;
|
||||
}
|
||||
|
||||
// Delete all wallets in background
|
||||
Future bkDeleteAllWallets() async {
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
||||
final isWalletsPresents =
|
||||
await isPresent('Scanner un', timeout: const Duration(milliseconds: 300));
|
||||
if (isWalletsPresents) {
|
||||
await walletBox.clear();
|
||||
await chestBox.clear();
|
||||
await configBox.delete('defaultWallet');
|
||||
await sub.deleteAllAccounts();
|
||||
myWalletProvider.pinCode = '';
|
||||
myWalletProvider.rebuildWidget();
|
||||
}
|
||||
}
|
||||
|
||||
Future bkFastStart([bool restoreChest = true]) async {
|
||||
// Start app and wait finish starting
|
||||
await startWait();
|
||||
|
||||
// Connect to local endpoint
|
||||
await bkSetNode();
|
||||
await sleep();
|
||||
|
||||
// Delete all existing chests is exists
|
||||
await bkDeleteAllWallets();
|
||||
|
||||
if (restoreChest) {
|
||||
// Restore the test chest
|
||||
await bkRestoreChest();
|
||||
await waitFor("y'a pas de lézard");
|
||||
}
|
||||
}
|
||||
|
||||
Future startWait() async {
|
||||
app.main();
|
||||
await waitFor('Test starting...', reverse: true);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 300));
|
||||
await sleep(3000);
|
||||
}
|
||||
|
||||
String getWidgetText(Key key) {
|
||||
final word4Finder = find.byKey(key);
|
||||
return (word4Finder.evaluate().single.widget as Text).data!;
|
||||
}
|
||||
|
||||
class TestWallet {
|
||||
String address;
|
||||
String name;
|
||||
|
||||
TestWallet(this.address, this.name);
|
||||
|
||||
endAddress() => address.substring(address.length - 6);
|
||||
shortAddress() => getShortPubkey(address);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'general_actions.dart';
|
||||
import 'tests_utility.dart';
|
||||
|
||||
void main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
await dotenv.load();
|
||||
|
||||
testWidgets('UDs creation state', (testerLoc) async {
|
||||
tester = testerLoc;
|
||||
// Connect local node and import test chest in background
|
||||
await bkFastStart();
|
||||
|
||||
// Open chest
|
||||
await firstOpenChest();
|
||||
|
||||
// Go to test1 options and check if balance growup with UDs creations
|
||||
await tapKey(keyOpenWallet(test1.address));
|
||||
await waitFor('100.0 $currencyName');
|
||||
await spawnBlock(until: 10);
|
||||
await waitFor('200.0 $currencyName');
|
||||
await spawnBlock(until: 20);
|
||||
await waitFor('300.0 $currencyName');
|
||||
}, timeout: testTimeout());
|
||||
}
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
|
@ -51,6 +52,10 @@ Future<void> main() async {
|
|||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await EasyLocalization.ensureInitialized();
|
||||
|
||||
if (kDebugMode) {
|
||||
await dotenv.load();
|
||||
}
|
||||
|
||||
HomeProvider homeProvider = HomeProvider();
|
||||
// DuniterIndexer _duniterIndexer = DuniterIndexer();
|
||||
await initHiveForFlutter();
|
||||
|
@ -105,7 +110,7 @@ Future<void> main() async {
|
|||
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
|
||||
path: 'assets/translations',
|
||||
fallbackLocale: const Locale('en'),
|
||||
child: Gecko(indexerEndpoint),
|
||||
child: const Gecko(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -117,15 +122,14 @@ Future<void> main() async {
|
|||
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
|
||||
path: 'assets/translations',
|
||||
fallbackLocale: const Locale('en'),
|
||||
child: Gecko(indexerEndpoint),
|
||||
child: const Gecko(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Gecko extends StatelessWidget {
|
||||
const Gecko(this.indexerEndpoint, {Key? key}) : super(key: key);
|
||||
final String? indexerEndpoint;
|
||||
const Gecko({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
// General
|
||||
const keyInfoPopup = Key('keyInfoPopup');
|
||||
const keyGoNext = Key('keyGoNext');
|
||||
const keyCancel = Key('keyCancel');
|
||||
const keyConfirm = Key('keyConfirm');
|
||||
const keyAppBarSearch = Key('keyAppBarSearch');
|
||||
const keyAppBarQrcode = Key('keyAppBarQrcode');
|
||||
const keyAppBarChest = Key('keyAppBarChest');
|
||||
|
||||
// Home
|
||||
const keyParameters = Key('keyParameters');
|
||||
const keyContacts = Key('keyContacts');
|
||||
const keyDrawerMenu = Key('keyDrawerMenu');
|
||||
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
||||
const keyOpenSearch = Key('keyOpenSearch');
|
||||
const keyRestoreChest = Key('keyRestoreChest');
|
||||
const keyOnboardingNewChest = Key('keyOnboardingNewChest');
|
||||
|
||||
// Wallets home
|
||||
const keyImportG1v1 = Key('keyImportG1v1');
|
||||
const keyChangeChest = Key('keyChangeChest');
|
||||
const keyListWallets = Key('keyListWallets');
|
||||
const keyAddDerivation = Key('keyAddDerivation');
|
||||
|
||||
// Wallet options
|
||||
const keyCopyAddress = Key('keyCopyAddress');
|
||||
const keyOpenActivity = Key('keyOpenActivity');
|
||||
const keyManageMembership = Key('keyManageMembership');
|
||||
const keySetDefaultWallet = Key('keySetDefaultWallet');
|
||||
const keyDeleteWallet = Key('keyDeleteWallet');
|
||||
const keyWalletName = Key('keyWalletName');
|
||||
const keyRenameWallet = Key('keyRenameWallet');
|
||||
const keyConfirmIdentity = Key('keyConfirmIdentity');
|
||||
const keyEnterIdentityUsername = Key('keyEnterIdentityUsername');
|
||||
|
||||
// Chest options
|
||||
const keyShowSeed = Key('keyShowSeed');
|
||||
const keyChangePin = Key('keyChangePin');
|
||||
const keycreateRootDerivation = Key('keycreateRootDerivation');
|
||||
const keyDeleteChest = Key('keyDeleteChest');
|
||||
|
||||
// Manage membership
|
||||
const keyMigrateIdentity = Key('keyMigrateIdentity');
|
||||
const keyRevokeIdty = Key('keyRevokeIdty');
|
||||
|
||||
// Choose chest
|
||||
const keyCreateNewChest = Key('keyCreateNewChest');
|
||||
const keyImportChest = Key('keyImportChest');
|
||||
|
||||
// Profile view
|
||||
const keyViewActivity = Key('keyViewActivity');
|
||||
const keyCertify = Key('keyCertify');
|
||||
const keyPay = Key('keyPay');
|
||||
const keyAmountField = Key('keyAmountField');
|
||||
const keyConfirmPayment = Key('keyConfirmPayment');
|
||||
const keyCloseTransactionScreen = Key('keyCloseTransactionScreen');
|
||||
|
||||
// Activity view
|
||||
const keyListTransactions = Key('keyListTransactions');
|
||||
|
||||
// Unlock wallet
|
||||
const keyPinForm = Key('keyPinForm');
|
||||
const keyPopButton = Key('keyPopButton');
|
||||
const keyCachePassword = Key('keyCachePassword');
|
||||
|
||||
// Settings
|
||||
const keyDeleteAllWallets = Key('keyDeleteAllWallets');
|
||||
const keySelectDuniterNodeDropDown = Key('keySelectDuniterNodeDropDown');
|
||||
const keyCustomDuniterEndpoint = Key('keyCustomDuniterEndpoint');
|
||||
const keyConnectToEndpoint = Key('keyConnectToEndpoint');
|
||||
|
||||
// Onboarding
|
||||
const keyPastMnemonic = Key('keyPastMnemonic');
|
||||
const keyBubbleSpeak = Key('keyBubbleSpeak');
|
||||
const keyGenerateMnemonic = Key('keyGenerateMnemonic');
|
||||
const keyAskedWord = Key('keyAskedWord');
|
||||
const keyInputWord = Key('keyInputWord');
|
||||
const keyGeneratedPin = Key('keyGeneratedPin');
|
||||
const keyGoWalletsHome = Key('keyGoWalletsHome');
|
||||
|
||||
// Search
|
||||
const keySearchField = Key('keySearchField');
|
||||
const keyConfirmSearch = Key('keyConfirmSearch');
|
||||
|
||||
// Import Cesium wallet
|
||||
const keyCesiumId = Key('keyCesiumId');
|
||||
const keyCesiumPassword = Key('keyCesiumPassword');
|
||||
const keySelectWallet = Key('keySelectWallet');
|
||||
const keyCesiumIdVisible = Key('keyCesiumIdVisible');
|
||||
|
||||
// Items keys
|
||||
Key keyTransaction(int keyId) => Key('keyTransaction$keyId');
|
||||
Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word');
|
||||
Key keySearchResult(String address) => Key('keySearchResult$address');
|
||||
Key keySelectDuniterNode(String endpoint) =>
|
||||
Key('keySelectDuniterNode$endpoint');
|
||||
Key keyOpenWallet(String address) => Key('keyOpenWallet$address');
|
||||
Key keySelectThisWallet(String address) => Key('keySelectThisWallet$address');
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -59,13 +60,13 @@ class ChestProvider with ChangeNotifier {
|
|||
title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text("no".tr(), key: const Key('cancelDeleting')),
|
||||
child: Text("no".tr(), key: keyCancel),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, false);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text("yes".tr(), key: const Key('confirmDeleting')),
|
||||
child: Text("yes".tr(), key: keyConfirm),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, true);
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:gecko/globals.dart';
|
|||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/models/queries_indexer.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
|
@ -293,7 +294,6 @@ class DuniterIndexer with ChangeNotifier {
|
|||
return Text('noResult'.tr());
|
||||
}
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
return Expanded(
|
||||
child: ListView(children: <Widget>[
|
||||
|
@ -301,7 +301,7 @@ class DuniterIndexer with ChangeNotifier {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult(profile['id']),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider.defaultAvatar(avatarSize),
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:durt/durt.dart' as durt;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -354,6 +353,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
cellController10,
|
||||
cellController11
|
||||
];
|
||||
if (sentence?.text == null) return;
|
||||
for (var word in sentence!.text!.split(' ')) {
|
||||
bool isValid = isBipWord(word, false);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:flutter/services.dart';
|
|||
import 'dart:async';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/wallets_profiles.dart';
|
||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||
|
@ -148,6 +149,7 @@ class HomeProvider with ChangeNotifier {
|
|||
const Spacer(),
|
||||
const SizedBox(width: 11),
|
||||
IconButton(
|
||||
key: keyAppBarSearch,
|
||||
iconSize: 40,
|
||||
icon: const Image(image: AssetImage('assets/loupe-noire.png')),
|
||||
onPressed: () {
|
||||
|
@ -166,6 +168,7 @@ class HomeProvider with ChangeNotifier {
|
|||
const SizedBox(width: 22),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
key: keyAppBarQrcode,
|
||||
iconSize: 70,
|
||||
icon: const Image(image: AssetImage('assets/qrcode-scan.png')),
|
||||
onPressed: () async {
|
||||
|
@ -179,6 +182,7 @@ class HomeProvider with ChangeNotifier {
|
|||
const Spacer(),
|
||||
const SizedBox(width: 15),
|
||||
IconButton(
|
||||
key: keyAppBarChest,
|
||||
iconSize: 60,
|
||||
icon: const Image(image: AssetImage('assets/wallet.png')),
|
||||
onPressed: () async {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:typed_data';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
|
@ -37,7 +37,8 @@ class SubstrateSdk with ChangeNotifier {
|
|||
TextEditingController csSalt = TextEditingController();
|
||||
TextEditingController csPassword = TextEditingController();
|
||||
String g1V1NewAddress = '';
|
||||
bool isCesiumIDVisible = true;
|
||||
bool isCesiumIDVisible = false;
|
||||
bool isCesiumAddresLoading = false;
|
||||
|
||||
/////////////////////////////////////
|
||||
////////// 1: API METHODS ///////////
|
||||
|
@ -80,10 +81,11 @@ class SubstrateSdk with ChangeNotifier {
|
|||
[null])[0];
|
||||
}
|
||||
|
||||
TxSenderData _setSender() {
|
||||
Future<TxSenderData> _setSender(String address) async {
|
||||
final fromPubkey = await sdk.api.account.decodeAddress([address]);
|
||||
return TxSenderData(
|
||||
keyring.current.address,
|
||||
keyring.current.pubKey,
|
||||
address,
|
||||
fromPubkey!.keys.first,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -685,7 +687,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
);
|
||||
const tx1 = 'api.tx.universalDividend.claimUds()';
|
||||
final tx2 = amount == -1
|
||||
? 'api.tx.balances.transferAll(false)'
|
||||
? 'api.tx.balances.transferAll("$destAddress", false)'
|
||||
: 'api.tx.balances.transferKeepAlive("$destAddress", $amountUnit)';
|
||||
|
||||
rawParams = '[[$tx1, $tx2]]';
|
||||
|
@ -696,14 +698,14 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<String> certify(
|
||||
String fromAddress, String password, String toAddress) async {
|
||||
String fromAddress, String destAddress, String password) async {
|
||||
transactionStatus = '';
|
||||
|
||||
final myIdtyStatus = await idtyStatus(fromAddress);
|
||||
final toIdtyStatus = await idtyStatus(toAddress);
|
||||
final toIdtyStatus = await idtyStatus(destAddress);
|
||||
|
||||
final fromIndex = await _getIdentityIndexOf(fromAddress);
|
||||
final toIndex = await _getIdentityIndexOf(toAddress);
|
||||
final toIndex = await _getIdentityIndexOf(destAddress);
|
||||
|
||||
if (myIdtyStatus != 'Validated') {
|
||||
transactionStatus = 'notMember';
|
||||
|
@ -711,12 +713,12 @@ class SubstrateSdk with ChangeNotifier {
|
|||
return 'notMember';
|
||||
}
|
||||
|
||||
final sender = _setSender();
|
||||
final sender = await _setSender(fromAddress);
|
||||
TxInfoData txInfo;
|
||||
List txOptions = [];
|
||||
String? rawParams;
|
||||
|
||||
final toCerts = await getCerts(toAddress);
|
||||
final toCerts = await getCerts(destAddress);
|
||||
|
||||
// log.d('debug: ${currencyParameters['minCertForMembership']}');
|
||||
|
||||
|
@ -726,7 +728,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
'createIdentity',
|
||||
sender,
|
||||
);
|
||||
txOptions = [toAddress];
|
||||
txOptions = [destAddress];
|
||||
} else if (toIdtyStatus == 'Validated' ||
|
||||
toIdtyStatus == 'ConfirmedByOwner') {
|
||||
if (toCerts[0] >= currencyParameters['minCertForMembership']! - 1 &&
|
||||
|
@ -776,11 +778,11 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
Future<String> confirmIdentity(
|
||||
String fromAddress, String name, String password) async {
|
||||
log.d('me: ${keyring.current.address!}');
|
||||
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
|
||||
|
||||
final sender = TxSenderData(
|
||||
keyring.current.address,
|
||||
keyring.current.pubKey,
|
||||
fromAddress,
|
||||
fromPubkey!.keys.first,
|
||||
);
|
||||
|
||||
final txInfo = TxInfoData(
|
||||
|
@ -848,10 +850,11 @@ newKeySig: $newKeySig""");
|
|||
const tx1 = 'api.tx.universalDividend.claimUds()';
|
||||
final tx2 =
|
||||
'api.tx.identity.changeOwnerKey("$destAddress", "$newKeySig")';
|
||||
// const tx3 = 'api.tx.balances.transferAll(false)';
|
||||
final tx3 = 'api.tx.balances.transferAll("$destAddress", false)';
|
||||
|
||||
rawParams =
|
||||
fromBalance['unclaimedUds'] == 0 ? '[[$tx2]]' : '[[$tx1, $tx2]]';
|
||||
rawParams = fromBalance['unclaimedUds'] == 0
|
||||
? '[[$tx2, $tx3]]'
|
||||
: '[[$tx1, $tx2, $tx3]]';
|
||||
} else {
|
||||
txInfo = TxInfoData(
|
||||
'identity',
|
||||
|
@ -873,7 +876,6 @@ newKeySig: $newKeySig""");
|
|||
keyring.current.pubKey,
|
||||
);
|
||||
|
||||
log.d(sender.address);
|
||||
TxInfoData txInfo;
|
||||
|
||||
txInfo = TxInfoData(
|
||||
|
@ -940,6 +942,17 @@ newKeySig: $newKeySig""");
|
|||
await sdk.api.keyring.deleteAccount(keyring, keypair);
|
||||
}
|
||||
|
||||
Future spawnBlock([int number = 1, int until = 0]) async {
|
||||
if (!kDebugMode) return;
|
||||
if (blocNumber < until) {
|
||||
number = until - blocNumber;
|
||||
}
|
||||
for (var i = 1; i <= number; i++) {
|
||||
await sdk.webView!
|
||||
.evalJavascript('api.rpc.engine.createBlock(true, true)');
|
||||
}
|
||||
}
|
||||
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
|
@ -136,7 +137,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
_showText(String text,
|
||||
showText(String text,
|
||||
[double size = 18, bool bold = false, bool smooth = true]) {
|
||||
log.d('$address $text');
|
||||
return AnimatedFadeOutIn<String>(
|
||||
|
@ -162,16 +163,16 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
switch (snapshot.data.toString()) {
|
||||
case 'noid':
|
||||
{
|
||||
return _showText('noIdentity'.tr());
|
||||
return showText('noIdentity'.tr());
|
||||
}
|
||||
case 'Created':
|
||||
{
|
||||
return _showText('identityCreated'.tr());
|
||||
return showText('identityCreated'.tr());
|
||||
}
|
||||
case 'ConfirmedByOwner':
|
||||
{
|
||||
return isOwner
|
||||
? _showText('identityConfirmed'.tr())
|
||||
? showText('identityConfirmed'.tr())
|
||||
: duniterIndexer.getNameByAddress(
|
||||
context,
|
||||
address,
|
||||
|
@ -186,7 +187,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
case 'Validated':
|
||||
{
|
||||
return isOwner
|
||||
? _showText('memberValidated'.tr(), 18, true)
|
||||
? showText('memberValidated'.tr(), 18, true)
|
||||
: duniterIndexer.getNameByAddress(
|
||||
context,
|
||||
address,
|
||||
|
@ -200,11 +201,11 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
|
||||
case 'expired':
|
||||
{
|
||||
return _showText('identityExpired'.tr());
|
||||
return showText('identityExpired'.tr());
|
||||
}
|
||||
}
|
||||
return SizedBox(
|
||||
child: _showText('', 18, false, false),
|
||||
child: showText('', 18, false, false),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -238,6 +239,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
child: Column(children: [
|
||||
const SizedBox(height: 20),
|
||||
TextField(
|
||||
key: keyEnterIdentityUsername,
|
||||
onChanged: (_) => notifyListeners(),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
// FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")),
|
||||
|
@ -258,7 +260,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, wOptions, _) {
|
||||
return TextButton(
|
||||
key: const Key('infoPopup'),
|
||||
key: keyConfirm,
|
||||
child: Text(
|
||||
"validate".tr(),
|
||||
style: TextStyle(
|
||||
|
@ -354,7 +356,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, wOptions, _) {
|
||||
return TextButton(
|
||||
key: const Key('infoPopup'),
|
||||
key: keyInfoPopup,
|
||||
child: Text(
|
||||
"validate".tr(),
|
||||
style: TextStyle(
|
||||
|
@ -381,7 +383,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
key: const Key('cancel'),
|
||||
key: keyCancel,
|
||||
child: Text(
|
||||
"cancel".tr(),
|
||||
style: TextStyle(
|
||||
|
@ -457,7 +459,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
width: 260,
|
||||
child: Stack(children: <Widget>[
|
||||
TextField(
|
||||
key: const Key('walletName'),
|
||||
key: keyWalletName,
|
||||
autofocus: false,
|
||||
focusNode: walletNameFocus,
|
||||
enabled: isEditing,
|
||||
|
@ -481,7 +483,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Positioned(
|
||||
right: 0,
|
||||
child: InkWell(
|
||||
key: const Key('renameWallet'),
|
||||
key: keyRenameWallet,
|
||||
onTap: () async {
|
||||
// _isNewNameValid =
|
||||
// walletProvider.editWalletName(wallet.id(), isCesium: false);
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
|
@ -166,7 +167,7 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
),
|
||||
Row(children: [
|
||||
GestureDetector(
|
||||
key: const Key('copyPubkey'),
|
||||
key: keyCopyAddress,
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: address));
|
||||
snackCopyKey(context);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/queries_indexer.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
|
@ -12,7 +15,6 @@ import 'package:gecko/screens/wallet_view.dart';
|
|||
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||
ActivityScreen({required this.address, this.avatar, this.username, Key? key})
|
||||
: super(key: key);
|
||||
|
@ -132,7 +134,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
child: Builder(
|
||||
builder: (context) => Expanded(
|
||||
child: ListView(
|
||||
key: const Key('listTransactions'),
|
||||
key: keyListTransactions,
|
||||
controller: scrollController,
|
||||
children: <Widget>[historyView(context, result)],
|
||||
),
|
||||
|
@ -286,7 +288,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
child:
|
||||
// Row(children: [Column(children: [],)],)
|
||||
ListTile(
|
||||
key: Key('transaction${keyID++}'),
|
||||
key: keyTransaction(keyID++),
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 20, right: 30, top: 15, bottom: 15),
|
||||
leading: ClipOval(
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:gecko/models/home.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AvatarFullscreen extends StatelessWidget {
|
||||
TextEditingController tplController = TextEditingController();
|
||||
|
||||
AvatarFullscreen(this.avatar, {this.title, this.color, Key? key})
|
||||
const AvatarFullscreen(this.avatar, {this.title, this.color, Key? key})
|
||||
: super(key: key);
|
||||
final Image? avatar;
|
||||
final String? title;
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
@ -62,10 +63,10 @@ class CommonElements {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, backgroundColor: orangeC,
|
||||
elevation: 4, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
@ -247,7 +248,7 @@ Future<bool?> confirmPopup(BuildContext context, String title) async {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
key: const Key('confirmPopop'),
|
||||
key: keyConfirm,
|
||||
child: Text(
|
||||
"yes".tr(),
|
||||
style: const TextStyle(
|
||||
|
@ -295,7 +296,7 @@ Future<void> infoPopup(BuildContext context, String title) async {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
key: const Key('infoPopup'),
|
||||
key: keyInfoPopup,
|
||||
child: const Text(
|
||||
"D'accord",
|
||||
style: TextStyle(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/stateful_wrapper.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/chest_provider.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
|
@ -64,7 +65,7 @@ class HomeScreen extends StatelessWidget {
|
|||
]),
|
||||
),
|
||||
ListTile(
|
||||
key: const Key('parameters'),
|
||||
key: keyParameters,
|
||||
title: Text('parameters'.tr()),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -77,7 +78,7 @@ class HomeScreen extends StatelessWidget {
|
|||
},
|
||||
),
|
||||
ListTile(
|
||||
key: const Key('contacts'),
|
||||
key: keyContacts,
|
||||
title: Text('contactsManagement'.tr()),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -89,26 +90,6 @@ class HomeScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
),
|
||||
|
||||
// ListTile(
|
||||
// key: const Key('substrateSandbox'),
|
||||
// title: const Text('Substrate debug'),
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(builder: (context) {
|
||||
// return const SubstrateSandBox();
|
||||
// }),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
|
||||
// ListTile(
|
||||
// title: const Text('A propos'),
|
||||
// onTap: () {
|
||||
// },
|
||||
// ),
|
||||
])),
|
||||
Align(
|
||||
alignment: FractionalOffset.bottomCenter,
|
||||
|
@ -141,17 +122,19 @@ class HomeScreen extends StatelessWidget {
|
|||
myWalletProvider.rebuildWidget();
|
||||
}
|
||||
|
||||
var connectivityResult =
|
||||
await (Connectivity().checkConnectivity());
|
||||
// var connectivityResult =
|
||||
// await (Connectivity().checkConnectivity());
|
||||
|
||||
// if (connectivityResult != ConnectivityResult.mobile &&
|
||||
// connectivityResult != ConnectivityResult.wifi) {
|
||||
// homeProvider.changeMessage(
|
||||
// "notConnectedToInternet".tr(), 0);
|
||||
// sub.nodeConnected = false;
|
||||
// }
|
||||
|
||||
// TODO: fix random bad network status on startup
|
||||
HomeProvider homeProvider =
|
||||
Provider.of<HomeProvider>(ctx, listen: false);
|
||||
if (connectivityResult != ConnectivityResult.mobile &&
|
||||
connectivityResult != ConnectivityResult.wifi) {
|
||||
homeProvider.changeMessage(
|
||||
"notConnectedToInternet".tr(), 0);
|
||||
sub.nodeConnected = false;
|
||||
}
|
||||
|
||||
Connectivity()
|
||||
.onConnectivityChanged
|
||||
.listen((ConnectivityResult result) async {
|
||||
|
@ -166,6 +149,7 @@ class HomeScreen extends StatelessWidget {
|
|||
await sub.connectNode(ctx);
|
||||
}
|
||||
});
|
||||
// await sub.connectNode(ctx);
|
||||
}
|
||||
// _duniterIndexer.checkIndexerEndpointBackground();
|
||||
});
|
||||
|
@ -220,7 +204,7 @@ Widget geckHome(context) {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('drawerMenu'),
|
||||
key: keyDrawerMenu,
|
||||
icon: const Icon(
|
||||
Icons.menu,
|
||||
color: Colors.white,
|
||||
|
@ -301,6 +285,7 @@ Widget geckHome(context) {
|
|||
child: Material(
|
||||
color: orangeC, // button color
|
||||
child: InkWell(
|
||||
key: keyOpenSearch,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(18),
|
||||
child: Image(
|
||||
|
@ -343,7 +328,7 @@ Widget geckHome(context) {
|
|||
],
|
||||
),
|
||||
child: ClipOval(
|
||||
key: const Key('manageWallets'),
|
||||
key: keyOpenWalletsHomme,
|
||||
child: Material(
|
||||
color: orangeC, // button color
|
||||
child: InkWell(
|
||||
|
@ -466,7 +451,7 @@ Widget welcomeHome(context) {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('drawerMenu'),
|
||||
key: keyDrawerMenu,
|
||||
icon: const Icon(
|
||||
Icons.menu,
|
||||
color: Colors.white,
|
||||
|
@ -554,10 +539,10 @@ Widget welcomeHome(context) {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyOnboardingNewChest,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
@ -581,6 +566,7 @@ Widget welcomeHome(context) {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: OutlinedButton(
|
||||
key: keyRestoreChest,
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(width: 4, color: orangeC)),
|
||||
onPressed: () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
// ignore_for_file: use_build_context_synchronously, must_be_immutable
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -10,11 +10,9 @@ import 'package:gecko/models/wallet_data.dart';
|
|||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
||||
ChangePinScreen(
|
||||
{Key? keyMyWallets,
|
||||
|
@ -23,9 +21,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
|||
: super(key: keyMyWallets);
|
||||
final String? walletName;
|
||||
final MyWalletsProvider walletProvider;
|
||||
Directory? appPath;
|
||||
|
||||
TextEditingController newPin = TextEditingController();
|
||||
final TextEditingController newPin = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -102,9 +99,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
|||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 12,
|
||||
primary: Colors.green[400], //smoothYellow, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 12,
|
||||
backgroundColor: Colors.green[400], // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData defaultWallet =
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:gecko/globals.dart';
|
|||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/chest_provider.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
|
@ -58,7 +59,7 @@ class ChestOptions extends StatelessWidget {
|
|||
child: Column(children: <Widget>[
|
||||
SizedBox(height: 30 * ratio),
|
||||
InkWell(
|
||||
key: const Key('showSeed'),
|
||||
key: keyShowSeed,
|
||||
onTap: () async {
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
@ -108,7 +109,7 @@ class ChestOptions extends StatelessWidget {
|
|||
SizedBox(height: 10 * ratio),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: const Key('changePin'),
|
||||
key: keyChangePin,
|
||||
onTap: sub.nodeConnected
|
||||
? () async {
|
||||
// await _chestProvider.changePin(context, cesiumWallet);
|
||||
|
@ -152,7 +153,7 @@ class ChestOptions extends StatelessWidget {
|
|||
SizedBox(height: 10 * ratio),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: const Key('createRootDerivation'),
|
||||
key: keycreateRootDerivation,
|
||||
onTap: sub.nodeConnected
|
||||
? () async {
|
||||
await Navigator.push(
|
||||
|
@ -188,7 +189,7 @@ class ChestOptions extends StatelessWidget {
|
|||
}),
|
||||
SizedBox(height: 10 * ratio),
|
||||
InkWell(
|
||||
key: const Key('deleteChest'),
|
||||
key: keyDeleteChest,
|
||||
onTap: () async {
|
||||
await chestProvider.deleteChest(context, currentChest);
|
||||
},
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -22,7 +23,6 @@ class ChooseChest extends StatefulWidget {
|
|||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class _ChooseChestState extends State<ChooseChest> {
|
||||
TextEditingController tplController = TextEditingController();
|
||||
CarouselController buttonCarouselController = CarouselController();
|
||||
|
@ -111,8 +111,8 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
await configBox.put('currentChest', currentChest);
|
||||
|
@ -156,7 +156,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: InkWell(
|
||||
key: const Key('createNewChest'),
|
||||
key: keyCreateNewChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -179,7 +179,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
),
|
||||
),
|
||||
InkWell(
|
||||
key: const Key('importChest'),
|
||||
key: keyImportChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
// ignore_for_file: use_build_context_synchronously, must_be_immutable
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
|
@ -7,6 +7,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
|
@ -15,7 +16,6 @@ import 'package:provider/provider.dart';
|
|||
// import 'package:gecko/models/home.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ChooseWalletScreen extends StatelessWidget {
|
||||
ChooseWalletScreen({Key? key, required this.pin}) : super(key: key);
|
||||
final String pin;
|
||||
|
@ -46,10 +46,10 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
width: 470,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirm,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
await sub.setCurrentWallet(selectedWallet!);
|
||||
|
@ -112,7 +112,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
return CustomScrollView(slivers: <Widget>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
||||
SliverGrid.count(
|
||||
key: const Key('listWallets'),
|
||||
key: keyListWallets,
|
||||
crossAxisCount: nTule,
|
||||
childAspectRatio: 1,
|
||||
crossAxisSpacing: 0,
|
||||
|
@ -122,6 +122,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
key: keySelectThisWallet(repository.address!),
|
||||
onTap: () {
|
||||
selectedWallet = repository;
|
||||
myWalletProvider.rebuildWidget();
|
||||
|
|
|
@ -107,9 +107,8 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
|||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData? defaultWallet =
|
||||
|
|
|
@ -7,6 +7,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
|
@ -21,7 +22,6 @@ class ImportG1v1 extends StatelessWidget {
|
|||
@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 =
|
||||
|
@ -109,6 +109,7 @@ class ImportG1v1 extends StatelessWidget {
|
|||
return Column(children: <Widget>[
|
||||
const SizedBox(height: 20),
|
||||
TextFormField(
|
||||
key: keyCesiumId,
|
||||
autofocus: true,
|
||||
onChanged: (text) {
|
||||
if (debounce?.isActive ?? false) {
|
||||
|
@ -116,21 +117,23 @@ class ImportG1v1 extends StatelessWidget {
|
|||
}
|
||||
debounce = Timer(
|
||||
const Duration(milliseconds: debouneTime), () {
|
||||
sub.reload();
|
||||
sub.csToV2Address(
|
||||
sub.csSalt.text, sub.csPassword.text);
|
||||
});
|
||||
},
|
||||
keyboardType: TextInputType.text,
|
||||
controller: sub.csSalt,
|
||||
obscureText: sub
|
||||
obscureText: !sub
|
||||
.isCesiumIDVisible, //This will obscure text dynamically
|
||||
decoration: InputDecoration(
|
||||
hintText: 'enterCesiumId'.tr(),
|
||||
suffixIcon: IconButton(
|
||||
key: keyCesiumIdVisible,
|
||||
icon: Icon(
|
||||
sub.isCesiumIDVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: Colors.black,
|
||||
),
|
||||
onPressed: () {
|
||||
|
@ -141,6 +144,7 @@ class ImportG1v1 extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 20),
|
||||
TextFormField(
|
||||
key: keyCesiumPassword,
|
||||
autofocus: true,
|
||||
onChanged: (text) {
|
||||
if (debounce?.isActive ?? false) {
|
||||
|
@ -148,21 +152,23 @@ class ImportG1v1 extends StatelessWidget {
|
|||
}
|
||||
debounce = Timer(
|
||||
const Duration(milliseconds: debouneTime), () {
|
||||
sub.g1V1NewAddress = '';
|
||||
sub.reload();
|
||||
sub.csToV2Address(
|
||||
sub.csSalt.text, sub.csPassword.text);
|
||||
});
|
||||
},
|
||||
keyboardType: TextInputType.text,
|
||||
controller: sub.csPassword,
|
||||
obscureText: sub
|
||||
obscureText: !sub
|
||||
.isCesiumIDVisible, //This will obscure text dynamically
|
||||
decoration: InputDecoration(
|
||||
hintText: 'enterCesiumPassword'.tr(),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
sub.isCesiumIDVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: Colors.black,
|
||||
),
|
||||
onPressed: () {
|
||||
|
@ -173,7 +179,7 @@ class ImportG1v1 extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 20),
|
||||
GestureDetector(
|
||||
key: const Key('copyPubkey'),
|
||||
key: keyCopyAddress,
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: sub.g1V1NewAddress));
|
||||
|
@ -187,14 +193,6 @@ class ImportG1v1 extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// getShortPubkey(sub.g1V1NewAddress),
|
||||
// style: const TextStyle(
|
||||
// fontSize: 18,
|
||||
// color: Colors.black,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontFamily: 'Monospace'),
|
||||
// ),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'${balance['transferableBalance']} $currencyName',
|
||||
|
@ -213,12 +211,14 @@ class ImportG1v1 extends StatelessWidget {
|
|||
Text('selectDestWallet'.tr()),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonHideUnderline(
|
||||
key: keySelectWallet,
|
||||
child: DropdownButton(
|
||||
// alignment: AlignmentDirectional.topStart,
|
||||
value: selectedWallet,
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
items: myWalletProvider.listWallets.map((wallet) {
|
||||
return DropdownMenuItem(
|
||||
key: keySelectThisWallet(wallet.address!),
|
||||
value: wallet,
|
||||
child: Text(
|
||||
wallet.name!,
|
||||
|
@ -237,14 +237,13 @@ class ImportG1v1 extends StatelessWidget {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirm,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () async {
|
||||
log.d('GOOO');
|
||||
WalletData? defaultWallet =
|
||||
myWalletProvider.getDefaultWallet();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/screens/myWallets/migrate_identity.dart';
|
||||
// import 'package:gecko/models/wallet_data.dart';
|
||||
// import 'package:gecko/providers/my_wallets.dart';
|
||||
|
@ -41,7 +42,7 @@ class ManageMembership extends StatelessWidget {
|
|||
|
||||
Widget migrateIdentity(BuildContext context) {
|
||||
return InkWell(
|
||||
key: const Key('migrateIdentity'),
|
||||
key: keyMigrateIdentity,
|
||||
onTap: () async {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -64,7 +65,7 @@ class ManageMembership extends StatelessWidget {
|
|||
|
||||
Widget revokeMyIdentity(BuildContext context) {
|
||||
return InkWell(
|
||||
key: const Key('revokeIdty'),
|
||||
key: keyRevokeIdty,
|
||||
onTap: () async {
|
||||
// TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options
|
||||
// final _answer = await confirmPopup(context,
|
||||
|
|
|
@ -188,9 +188,8 @@ class MigrateIdentityScreen extends StatelessWidget {
|
|||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () async {
|
||||
|
|
|
@ -3,6 +3,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
|
@ -91,10 +92,10 @@ class RestoreChest extends StatelessWidget {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
if (await sub
|
||||
|
@ -130,10 +131,10 @@ class RestoreChest extends StatelessWidget {
|
|||
width: 190,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
key: keyPastMnemonic,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: yellowC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 4,
|
||||
backgroundColor: yellowC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
genW.pasteMnemonic(context);
|
||||
|
@ -173,7 +174,7 @@ class RestoreChest extends StatelessWidget {
|
|||
color: Colors.white,
|
||||
child: Text(
|
||||
text,
|
||||
key: const Key('importText'),
|
||||
key: keyBubbleSpeak,
|
||||
textAlign: TextAlign.justify,
|
||||
style: const TextStyle(
|
||||
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:typed_data';
|
||||
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/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
|
@ -73,12 +73,12 @@ class ShowSeed extends StatelessWidget {
|
|||
height: 40,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
elevation: 1,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
backgroundColor: orangeC,
|
||||
elevation: 1, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
|
@ -123,9 +123,8 @@ class ShowSeed extends StatelessWidget {
|
|||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -206,7 +205,7 @@ class ShowSeed extends StatelessWidget {
|
|||
),
|
||||
Text(
|
||||
dataWord,
|
||||
key: Key('word$dataWord'),
|
||||
key: keyMnemonicWord(dataWord),
|
||||
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
|
||||
),
|
||||
]),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
|
@ -5,7 +7,6 @@ import 'package:flutter/material.dart';
|
|||
// import 'package:gecko/models/home.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class TransactionCommentScreen extends StatelessWidget {
|
||||
TextEditingController tplController = TextEditingController();
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
|
@ -12,7 +16,6 @@ import 'package:pin_code_fields/pin_code_fields.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class UnlockingWallet extends StatelessWidget {
|
||||
UnlockingWallet({Key? keyUnlockWallet, required this.wallet})
|
||||
: super(key: keyUnlockWallet);
|
||||
|
@ -23,7 +26,6 @@ class UnlockingWallet extends StatelessWidget {
|
|||
|
||||
// ignore: close_sinks
|
||||
StreamController<ErrorAnimationType>? errorController;
|
||||
final formKey = GlobalKey<FormState>();
|
||||
Color? pinColor = const Color(0xffF9F9F1);
|
||||
var walletPin = '';
|
||||
|
||||
|
@ -52,7 +54,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('popButton'),
|
||||
key: keyPopButton,
|
||||
icon: const Icon(
|
||||
Icons.arrow_back,
|
||||
color: Colors.black,
|
||||
|
@ -103,6 +105,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
SizedBox(height: 3 * ratio),
|
||||
if (canUnlock)
|
||||
InkWell(
|
||||
key: keyCachePassword,
|
||||
onTap: () {
|
||||
walletOptions.changePinCacheChoice();
|
||||
},
|
||||
|
@ -127,7 +130,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
const SizedBox(height: 10),
|
||||
// if (canUnlock)
|
||||
InkWell(
|
||||
key: const Key('chooseChest'),
|
||||
key: keyChangeChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -182,10 +185,11 @@ class UnlockingWallet extends StatelessWidget {
|
|||
}
|
||||
|
||||
return Form(
|
||||
key: formKey,
|
||||
// key: keyPinForm,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30),
|
||||
child: PinCodeTextField(
|
||||
key: keyPinForm,
|
||||
focusNode: pinFocus,
|
||||
autoFocus: true,
|
||||
appContext: context,
|
||||
|
@ -213,6 +217,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
fieldWidth: 50,
|
||||
activeFillColor: Colors.black,
|
||||
),
|
||||
showCursor: kDebugMode ? false : true,
|
||||
cursorColor: Colors.black,
|
||||
animationDuration: const Duration(milliseconds: 300),
|
||||
textStyle: const TextStyle(fontSize: 20, height: 1.6),
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
|
@ -37,6 +38,10 @@ class WalletOptions extends StatelessWidget {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
// SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
// sub.spawnBlock();
|
||||
// sub.spawnBlock(0, 20);
|
||||
|
||||
log.d(walletOptions.address.text);
|
||||
|
||||
final int currentChest = myWalletProvider.getCurrentChest();
|
||||
|
@ -213,7 +218,7 @@ class WalletOptions extends StatelessWidget {
|
|||
else
|
||||
const SizedBox(),
|
||||
if (isMember.data!)
|
||||
manageMemberStatus(context)
|
||||
manageMembership(context)
|
||||
]);
|
||||
}),
|
||||
]);
|
||||
|
@ -292,10 +297,10 @@ class WalletOptions extends StatelessWidget {
|
|||
width: 320,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirmIdentity,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
walletProvider.confirmIdentityPopup(context);
|
||||
|
@ -334,7 +339,7 @@ class WalletOptions extends StatelessWidget {
|
|||
Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) {
|
||||
final String shortPubkey = getShortPubkey(walletProvider.address.text);
|
||||
return GestureDetector(
|
||||
key: const Key('copyPubkey'),
|
||||
key: keyCopyAddress,
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: walletProvider.address.text));
|
||||
snackCopyKey(ctx);
|
||||
|
@ -359,12 +364,12 @@ class WalletOptions extends StatelessWidget {
|
|||
height: 40,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
elevation: 1,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
backgroundColor: orangeC,
|
||||
elevation: 1, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
|
@ -394,7 +399,7 @@ class WalletOptions extends StatelessWidget {
|
|||
WalletsProfilesProvider historyProvider,
|
||||
WalletOptionsProvider walletProvider) {
|
||||
return InkWell(
|
||||
key: const Key('displayActivity'),
|
||||
key: keyOpenActivity,
|
||||
onTap: () {
|
||||
// _historyProvider.nPage = 1;
|
||||
Navigator.push(
|
||||
|
@ -431,11 +436,11 @@ class WalletOptions extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget manageMemberStatus(BuildContext context) {
|
||||
Widget manageMembership(BuildContext context) {
|
||||
WalletOptionsProvider walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||
return InkWell(
|
||||
key: const Key('manageStatus'),
|
||||
key: keyManageMembership,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -471,7 +476,7 @@ class WalletOptions extends StatelessWidget {
|
|||
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
|
||||
return InkWell(
|
||||
key: const Key('setDefaultWallet'),
|
||||
key: keySetDefaultWallet,
|
||||
onTap: !walletProvider.isDefaultWallet
|
||||
? () async {
|
||||
await setDefaultWallet(context, currentChest);
|
||||
|
@ -544,7 +549,7 @@ class WalletOptions extends StatelessWidget {
|
|||
!hasConsumers.data! &&
|
||||
(balance > 2 || balance == 0);
|
||||
return InkWell(
|
||||
key: const Key('deleteWallet'),
|
||||
key: keyDeleteWallet,
|
||||
onTap: canDelete
|
||||
? () async {
|
||||
await walletProvider.deleteWallet(context, wallet);
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
|
@ -59,7 +60,6 @@ class WalletsHome extends StatelessWidget {
|
|||
);
|
||||
}),
|
||||
title: Text(currentChest.name!,
|
||||
key: const Key('myWallets'),
|
||||
style: TextStyle(color: Colors.grey[850])),
|
||||
backgroundColor: const Color(0xffFFD58D),
|
||||
),
|
||||
|
@ -87,9 +87,8 @@ class WalletsHome extends StatelessWidget {
|
|||
height: 60,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 2,
|
||||
primary: floattingYellow, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 2,
|
||||
backgroundColor: floattingYellow, // foreground
|
||||
),
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
|
@ -108,7 +107,7 @@ class WalletsHome extends StatelessWidget {
|
|||
)),
|
||||
const SizedBox(height: 30),
|
||||
InkWell(
|
||||
key: const Key('importG1v1'),
|
||||
key: keyImportG1v1,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -130,7 +129,7 @@ class WalletsHome extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 5),
|
||||
InkWell(
|
||||
key: const Key('changeChest'),
|
||||
key: keyChangeChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -190,7 +189,7 @@ class WalletsHome extends StatelessWidget {
|
|||
return CustomScrollView(slivers: <Widget>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
||||
SliverGrid.count(
|
||||
key: const Key('listWallets'),
|
||||
key: keyListWallets,
|
||||
crossAxisCount: nTule,
|
||||
childAspectRatio: 1,
|
||||
crossAxisSpacing: 0,
|
||||
|
@ -200,6 +199,7 @@ class WalletsHome extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
key: keyOpenWallet(repository.address!),
|
||||
onTap: () {
|
||||
walletOptions.getAddress(
|
||||
currentChestNumber, repository.derivation!);
|
||||
|
@ -366,7 +366,7 @@ class WalletsHome extends StatelessWidget {
|
|||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
key: const Key('addDerivation'),
|
||||
key: keyAddDerivation,
|
||||
onTap: () async {
|
||||
if (!myWalletProvider.isNewDerivationLoading) {
|
||||
WalletData? defaultWallet =
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
|
@ -28,7 +29,6 @@ class ContactsScreen extends StatelessWidget {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
|
||||
final myContacts = contactsBox.toMap().values.toList();
|
||||
|
@ -71,7 +71,7 @@ class ContactsScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult('keyID++'),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// ignore_for_file: file_names
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
|
@ -15,7 +18,6 @@ import 'package:gecko/screens/onBoarding/11_congratulations.dart';
|
|||
import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class OnboardingStepTen extends StatelessWidget {
|
||||
OnboardingStepTen({Key? validationKey, this.scanDerivation = false})
|
||||
: super(key: validationKey);
|
||||
|
@ -100,6 +102,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return sub.nodeConnected
|
||||
? InkWell(
|
||||
key: keyCachePassword,
|
||||
onTap: () {
|
||||
walletOptions.changePinCacheChoice();
|
||||
},
|
||||
|
@ -149,7 +152,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
|
||||
child: PinCodeTextField(
|
||||
key: const Key('formKey2'),
|
||||
key: keyPinForm,
|
||||
autoFocus: true,
|
||||
appContext: context,
|
||||
pastedTextStyle: TextStyle(
|
||||
|
@ -176,6 +179,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
fieldWidth: 50,
|
||||
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
|
||||
),
|
||||
showCursor: kDebugMode ? false : true,
|
||||
cursorColor: Colors.black,
|
||||
animationDuration: const Duration(milliseconds: 300),
|
||||
textStyle: const TextStyle(fontSize: 20, height: 1.6),
|
||||
|
@ -224,6 +228,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
|
||||
generateWalletProvider.generatedMnemonic = '';
|
||||
myWalletProvider.resetPinCode();
|
||||
// sleep(const Duration(milliseconds: 500));
|
||||
Navigator.push(
|
||||
context,
|
||||
FaderTransition(
|
||||
|
|
|
@ -4,10 +4,9 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
import 'package:gecko/screens/myWallets/wallets_home.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class OnboardingStepEleven extends StatelessWidget {
|
||||
const OnboardingStepEleven({Key? key}) : super(key: key);
|
||||
|
||||
|
@ -54,20 +53,28 @@ Widget finishButton(BuildContext context) {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: const Key('goWalletHome'),
|
||||
key: keyGoWalletsHome,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC,
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const WalletsHome();
|
||||
}),
|
||||
ModalRoute.withName('/'),
|
||||
);
|
||||
//TODO: fix bad widget ancestor when pupUntil (multi_chest test failed)
|
||||
|
||||
// Navigator.popUntil(homeContext, ModalRoute.withName('/'));
|
||||
// Navigator.of(homeContext, rootNavigator: true)
|
||||
// .popUntil(ModalRoute.withName('/'));
|
||||
// while (Navigator.of(homeContext).canPop()) {
|
||||
// Navigator.of(homeContext).pop();
|
||||
// }
|
||||
|
||||
// Navigator.pushNamed(homeContext, '/mywallets');
|
||||
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, '/mywallets', (route) => route.isFirst);
|
||||
|
||||
// Navigator.pushNamedAndRemoveUntil(
|
||||
// homeContext, '/mywallets', ModalRoute.withName('/'));
|
||||
},
|
||||
child: Text("accessMyChest".tr(),
|
||||
style:
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
|
@ -80,11 +81,10 @@ class _ChooseChestState extends State<OnboardingStepFive> {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: const Key('generateMnemonic'),
|
||||
key: keyGenerateMnemonic,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: const Color(0xffFFD58D),
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 4,
|
||||
backgroundColor: const Color(0xffFFD58D), // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
// _generateWalletProvider.reloadBuild();
|
||||
|
@ -101,7 +101,8 @@ class _ChooseChestState extends State<OnboardingStepFive> {
|
|||
SizedBox(height: 22 * ratio),
|
||||
nextButton(
|
||||
context, "iNotedMyMnemonic".tr(), false, widget.skipIntro),
|
||||
SizedBox(height: 35 * ratio),
|
||||
const Spacer(),
|
||||
// SizedBox(height: 35 * ratio),
|
||||
]),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
|
@ -174,14 +175,13 @@ Widget arrayCell(dataWord) {
|
|||
),
|
||||
Text(
|
||||
dataWord.split(':')[1],
|
||||
key: Key('word${dataWord.split(':')[0]}'),
|
||||
key: keyMnemonicWord(dataWord.split(':')[0]),
|
||||
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class PrintWallet extends StatelessWidget {
|
||||
const PrintWallet(this.sentence, {Key? key}) : super(key: key);
|
||||
|
||||
|
@ -230,10 +230,10 @@ Widget nextButton(
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt();
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
// ignore_for_file: file_names
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
import 'package:gecko/screens/onBoarding/7.dart';
|
||||
import 'package:gecko/screens/onBoarding/9.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class OnboardingStepSix extends StatelessWidget {
|
||||
OnboardingStepSix(
|
||||
{Key? key, required this.skipIntro, required this.generatedMnemonic})
|
||||
|
@ -66,7 +67,7 @@ class OnboardingStepSix extends StatelessWidget {
|
|||
true),
|
||||
SizedBox(height: isTall ? 70 : 20),
|
||||
Text('${generateWalletProvider.nbrWord + 1}',
|
||||
key: const Key('askedWord'),
|
||||
key: keyAskedWord,
|
||||
style: TextStyle(
|
||||
fontSize: isTall ? 17 : 15,
|
||||
color: orangeC,
|
||||
|
@ -81,7 +82,7 @@ class OnboardingStepSix extends StatelessWidget {
|
|||
)),
|
||||
width: 430,
|
||||
child: TextFormField(
|
||||
key: const Key('inputWord'),
|
||||
key: keyInputWord,
|
||||
autofocus: true,
|
||||
enabled: !generateWalletProvider.isAskedWordValid,
|
||||
controller: wordController,
|
||||
|
@ -206,7 +207,7 @@ Widget arrayCell(dataWord) {
|
|||
),
|
||||
Text(
|
||||
dataWord.split(':')[1],
|
||||
key: Key('word${dataWord.split(':')[0]}'),
|
||||
key: keyMnemonicWord(dataWord.split(':')[0]),
|
||||
style: const TextStyle(fontSize: 20, color: Colors.black),
|
||||
),
|
||||
]),
|
||||
|
@ -224,10 +225,10 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
|
|
@ -3,12 +3,12 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/generate_wallets.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
import 'package:gecko/screens/onBoarding/10.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class OnboardingStepNine extends StatelessWidget {
|
||||
const OnboardingStepNine({Key? key, this.scanDerivation = false})
|
||||
: super(key: key);
|
||||
|
@ -52,7 +52,7 @@ class OnboardingStepNine extends StatelessWidget {
|
|||
alignment: Alignment.centerRight,
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
key: const Key('generatedPin'),
|
||||
key: keyGeneratedPin,
|
||||
enabled: false,
|
||||
controller: generateWalletProvider.pin,
|
||||
maxLines: 1,
|
||||
|
@ -79,11 +79,12 @@ class OnboardingStepNine extends StatelessWidget {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: const Key('changeSecretCode'),
|
||||
key: keyChangePin,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
elevation: 4,
|
||||
primary: const Color(0xffFFD58D),
|
||||
onPrimary: Colors.black, // foreground
|
||||
backgroundColor:
|
||||
const Color(0xffFFD58D), // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
generateWalletProvider.changePinCode(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -6,7 +8,6 @@ import 'package:qr_flutter/qr_flutter.dart';
|
|||
// import 'package:gecko/models/home.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class QrCodeFullscreen extends StatelessWidget {
|
||||
TextEditingController tplController = TextEditingController();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/models/widgets_keys.dart';
|
||||
// import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/search.dart';
|
||||
import 'package:gecko/screens/common_elements.dart';
|
||||
|
@ -51,6 +52,7 @@ class SearchScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
child: TextField(
|
||||
key: keySearchField,
|
||||
controller: searchProvider.searchController,
|
||||
autofocus: true,
|
||||
maxLines: 1,
|
||||
|
@ -91,10 +93,10 @@ class SearchScreen extends StatelessWidget {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirmSearch,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: searchProvider.searchController.text.length >= 2
|
||||
? () {
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
|
@ -31,7 +32,6 @@ class SearchResultScreen extends StatelessWidget {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
|
||||
return Scaffold(
|
||||
|
@ -94,7 +94,7 @@ class SearchResultScreen extends StatelessWidget {
|
|||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult(g1Wallet.pubkey!),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/settings_provider.dart';
|
||||
|
@ -8,9 +9,7 @@ import 'package:gecko/providers/substrate_sdk.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:polkawallet_sdk/api/types/networkParams.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SettingsScreen extends StatelessWidget {
|
||||
final MyWalletsProvider _myWallets = MyWalletsProvider();
|
||||
|
||||
|
@ -45,7 +44,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
width: buttonWidth,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
key: const Key('deleteChest'),
|
||||
key: keyDeleteAllWallets,
|
||||
onTap: () async {
|
||||
log.i('Oublier tous mes coffres');
|
||||
await _myWallets.deleteAllWallet(context);
|
||||
|
@ -115,11 +114,14 @@ class SettingsScreen extends StatelessWidget {
|
|||
Icon(sub.nodeConnected && !sub.isLoadingEndpoint
|
||||
? Icons.check
|
||||
: Icons.close),
|
||||
if (sub.nodeConnected && !sub.isLoadingEndpoint)
|
||||
const Icon(Icons.add_card_sharp, size: 0.01),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 265,
|
||||
child: Consumer<SettingsProvider>(builder: (context, set, _) {
|
||||
return DropdownButtonHideUnderline(
|
||||
key: keySelectDuniterNodeDropDown,
|
||||
child: DropdownButton(
|
||||
// alignment: AlignmentDirectional.topStart,
|
||||
value: selectedDuniterEndpoint,
|
||||
|
@ -127,6 +129,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
items: duniterBootstrapNodes
|
||||
.map((NetworkParams endpointParams) {
|
||||
return DropdownMenuItem(
|
||||
key: keySelectDuniterNode(endpointParams.endpoint!),
|
||||
value: endpointParams.endpoint,
|
||||
child: Text(endpointParams.endpoint!),
|
||||
);
|
||||
|
@ -145,6 +148,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
? CircularProgressIndicator(color: orangeC)
|
||||
: Consumer<SettingsProvider>(builder: (context, set, _) {
|
||||
return IconButton(
|
||||
key: keyConnectToEndpoint,
|
||||
icon: Icon(
|
||||
Icons.send,
|
||||
color: selectedDuniterEndpoint !=
|
||||
|
@ -185,6 +189,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
width: 200,
|
||||
height: 50,
|
||||
child: TextField(
|
||||
key: keyCustomDuniterEndpoint,
|
||||
controller: endpointController,
|
||||
autocorrect: false,
|
||||
),
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallets_profiles.dart';
|
||||
|
@ -9,7 +10,6 @@ import 'package:provider/provider.dart';
|
|||
// import 'package:gecko/models/home.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class TransactionInProgress extends StatelessWidget {
|
||||
const TransactionInProgress(
|
||||
{Key? key, this.transType = 'pay', this.fromAddress, this.toAddress})
|
||||
|
@ -33,6 +33,8 @@ class TransactionInProgress extends StatelessWidget {
|
|||
// Map jsonResult;
|
||||
final result = sub.transactionStatus;
|
||||
|
||||
// sub.spawnBlock();
|
||||
|
||||
log.d(walletViewProvider.address!);
|
||||
|
||||
final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!;
|
||||
|
@ -263,10 +265,10 @@ class TransactionInProgress extends StatelessWidget {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyCloseTransactionScreen,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
|
@ -42,12 +43,15 @@ class WalletViewScreen extends StatelessWidget {
|
|||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
HomeProvider homeProvider =
|
||||
Provider.of<HomeProvider>(context, listen: false);
|
||||
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
|
||||
sub.setCurrentWallet(defaultWallet);
|
||||
|
||||
// sub.spawnBlock();
|
||||
// sub.spawnBlock(0, 25);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
resizeToAvoidBottomInset: true,
|
||||
|
@ -116,7 +120,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
child: Material(
|
||||
color: yellowC, //const Color(0xffFFD58D), // button color
|
||||
child: InkWell(
|
||||
key: const Key('viewHistory'),
|
||||
key: keyViewActivity,
|
||||
splashColor: orangeC, // inkwell color
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(13),
|
||||
|
@ -206,7 +210,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
color:
|
||||
const Color(0xffFFD58D), // button color
|
||||
child: InkWell(
|
||||
key: const Key('certify'),
|
||||
key: keyCertify,
|
||||
splashColor: orangeC, // inkwell color
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(bottom: 0),
|
||||
|
@ -245,8 +249,9 @@ class WalletViewScreen extends StatelessWidget {
|
|||
final acc = sub.getCurrentWallet();
|
||||
sub.certify(
|
||||
acc.address!,
|
||||
pin ?? myWalletProvider.pinCode,
|
||||
walletViewProvider.address!);
|
||||
walletViewProvider.address!,
|
||||
pin ??
|
||||
myWalletProvider.pinCode);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -290,7 +295,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
child: Material(
|
||||
color: const Color(0xffFFD58D), // button color
|
||||
child: InkWell(
|
||||
key: const Key('copyKey'),
|
||||
key: keyCopyAddress,
|
||||
splashColor: orangeC, // inkwell color
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
|
@ -331,7 +336,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
child: Material(
|
||||
color: orangeC, // button color
|
||||
child: InkWell(
|
||||
key: const Key('pay'),
|
||||
key: keyPay,
|
||||
splashColor: yellowC,
|
||||
onTap: sub.nodeConnected
|
||||
? () {
|
||||
|
@ -481,6 +486,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
const SizedBox(height: 10),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: keyChangeChest,
|
||||
onTap: () async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
|
@ -572,6 +578,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 10),
|
||||
TextField(
|
||||
key: keyAmountField,
|
||||
controller: walletViewProvider.payAmount,
|
||||
autofocus: true,
|
||||
maxLines: 1,
|
||||
|
@ -617,10 +624,10 @@ class WalletViewScreen extends StatelessWidget {
|
|||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirmPayment,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () async {
|
||||
|
|
273
pubspec.lock
273
pubspec.lock
|
@ -7,21 +7,21 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "44.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
version: "4.7.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.11"
|
||||
version: "3.3.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -29,20 +29,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
assorted_layout_widgets:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: assorted_layout_widgets
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
version: "2.9.0"
|
||||
auth_header:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -56,7 +49,7 @@ packages:
|
|||
name: barcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.2.3"
|
||||
barcode_scan2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -147,7 +140,7 @@ packages:
|
|||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.4.0"
|
||||
version: "8.4.1"
|
||||
carousel_slider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -161,7 +154,7 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -182,7 +175,7 @@ packages:
|
|||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -197,20 +190,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
confirm_dialog:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: confirm_dialog
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
connectivity_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.6"
|
||||
version: "2.3.6+1"
|
||||
connectivity_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -253,13 +239,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -268,12 +247,12 @@ packages:
|
|||
source: hosted
|
||||
version: "0.3.3+1"
|
||||
crypto:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -287,14 +266,7 @@ packages:
|
|||
name: dbus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
desktop_window:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: desktop_window
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
version: "0.7.8"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -309,13 +281,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
dropdown_button2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dropdown_button2
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.1"
|
||||
durt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -343,9 +308,9 @@ packages:
|
|||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
fast_base58:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fast_base58
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -384,6 +349,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_dotenv
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
flutter_driver:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -415,20 +387,13 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_logs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_logs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
flutter_markdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_markdown
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.10+3"
|
||||
version: "0.6.10+5"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -436,13 +401,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.7"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -564,7 +522,7 @@ packages:
|
|||
source: hosted
|
||||
version: "0.2.0"
|
||||
hive:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -577,15 +535,8 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -618,7 +569,7 @@ packages:
|
|||
name: icons_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.5"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -632,21 +583,21 @@ packages:
|
|||
name: image_cropper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
version: "3.0.0"
|
||||
image_cropper_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_cropper_for_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4"
|
||||
version: "1.0.2"
|
||||
image_cropper_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_cropper_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "3.0.2"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -674,7 +625,7 @@ packages:
|
|||
name: image_picker_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.5+6"
|
||||
version: "0.8.6"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -682,20 +633,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
infinite_scroll_pagination:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: infinite_scroll_pagination
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
integration_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -784,28 +728,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.11"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.4"
|
||||
matrix4_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matrix4_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -834,13 +771,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
normalize:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -861,7 +791,7 @@ packages:
|
|||
name: package_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.3"
|
||||
version: "1.4.3+1"
|
||||
package_info_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -903,14 +833,7 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_drawing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.8.2"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -931,7 +854,7 @@ packages:
|
|||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.17"
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -966,7 +889,7 @@ packages:
|
|||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.3"
|
||||
path_tree:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -980,7 +903,7 @@ packages:
|
|||
name: pdf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.8.2"
|
||||
version: "3.8.3"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1115,14 +1038,7 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
pull_to_refresh:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pull_to_refresh
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "1.2.1"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1139,13 +1055,6 @@ packages:
|
|||
url: "https://github.com/insinfo/qr.flutter.git"
|
||||
source: git
|
||||
version: "4.0.0"
|
||||
responsive_builder:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: responsive_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
responsive_framework:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1161,19 +1070,19 @@ packages:
|
|||
source: hosted
|
||||
version: "0.27.5"
|
||||
sentry:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.9.0"
|
||||
version: "6.9.1"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.9.0"
|
||||
version: "6.9.1"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1215,7 +1124,7 @@ packages:
|
|||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1237,20 +1146,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1263,48 +1158,13 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
sliver_tools:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sliver_tools
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.7"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1332,42 +1192,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
sync_http:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sync_http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.3.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.21.1"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.9"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.13"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1388,7 +1234,7 @@ packages:
|
|||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1423,7 +1269,7 @@ packages:
|
|||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.2.2"
|
||||
version: "9.0.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1432,7 +1278,7 @@ packages:
|
|||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -1445,13 +1291,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
webview_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1465,14 +1304,14 @@ packages:
|
|||
name: webview_flutter_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.9.3"
|
||||
version: "2.10.0"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
version: "1.9.3"
|
||||
webview_flutter_wkwebview:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1493,9 +1332,9 @@ packages:
|
|||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0+1"
|
||||
version: "0.2.0+2"
|
||||
xml:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
|
|
25
pubspec.yaml
25
pubspec.yaml
|
@ -15,23 +15,12 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_driver:
|
||||
sdk: flutter
|
||||
assorted_layout_widgets: ^6.1.1
|
||||
bubble: ^1.2.1
|
||||
carousel_slider: ^4.0.0
|
||||
confirm_dialog: ^1.0.0
|
||||
crypto: ^3.0.1
|
||||
fast_base58: ^0.2.0
|
||||
flutter_lints: ^2.0.1
|
||||
flutter_logs: ^2.1.4
|
||||
flutter_svg: ^1.1.3
|
||||
graphql_flutter: ^5.1.1-beta.3
|
||||
hive: ^2.0.4
|
||||
hive_flutter: ^1.1.0
|
||||
http: ^0.13.4
|
||||
# image_gallery_saver: ^1.6.9
|
||||
image_picker: ^0.8.4
|
||||
infinite_scroll_pagination: ^3.1.0
|
||||
intl: ^0.17.0
|
||||
jdenticon_dart: ^2.0.0
|
||||
logger: ^1.1.0
|
||||
path_provider: ^2.0.9
|
||||
|
@ -45,19 +34,12 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/insinfo/qr.flutter.git
|
||||
ref: master
|
||||
responsive_builder: ^0.4.1
|
||||
responsive_framework: ^0.2.0
|
||||
sentry: ^6.5.1
|
||||
sentry_flutter: ^6.5.1
|
||||
shared_preferences: ^2.0.7
|
||||
sync_http: ^0.3.0
|
||||
test: ^1.17.10
|
||||
truncate: ^3.0.1
|
||||
unorm_dart: ^0.2.0
|
||||
xml: ^6.1.0
|
||||
pull_to_refresh: ^2.0.0
|
||||
dio: ^4.0.4
|
||||
desktop_window: ^0.4.0
|
||||
durt: ^0.1.6
|
||||
package_info_plus: ^1.4.2
|
||||
polkawallet_sdk: #^0.4.9
|
||||
|
@ -68,14 +50,13 @@ dependencies:
|
|||
# ref: gecko-old
|
||||
ref: gecko-unwrapbytes
|
||||
dots_indicator: ^2.1.0
|
||||
web_socket_channel: ^2.2.0
|
||||
connectivity_plus: ^2.3.3
|
||||
image_cropper: ^2.0.3
|
||||
image_cropper: ^3.0.0
|
||||
easy_localization: ^3.0.1
|
||||
flutter_markdown: ^0.6.10+2
|
||||
dropdown_button2: ^1.6.3
|
||||
pointycastle: ^3.6.1
|
||||
hex: ^0.2.0
|
||||
flutter_dotenv: ^5.0.2
|
||||
|
||||
dev_dependencies:
|
||||
# flutter_launcher_icons: ^0.9.2
|
||||
|
@ -84,7 +65,6 @@ dev_dependencies:
|
|||
build_runner: ^2.1.2
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
hive_generator: ^1.1.1
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
|
||||
|
@ -112,3 +92,4 @@ flutter:
|
|||
- assets/onBoarding/progress_bar/
|
||||
- assets/walletOptions/
|
||||
- sounds/
|
||||
- .env
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
flutter drive --target=test_driver/app.dart
|
|
@ -1,30 +0,0 @@
|
|||
// // This is a basic Flutter widget test.
|
||||
// //
|
||||
// // To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// // utility that Flutter provides. For example, you can send tap and scroll
|
||||
// // gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// // tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
// import 'package:gecko/main.dart';
|
||||
|
||||
// void main() {
|
||||
// testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// // Build our app and trigger a frame.
|
||||
// await tester.pumpWidget(Gecko());
|
||||
|
||||
// // Verify that our counter starts at 0.
|
||||
// expect(find.text('0'), findsOneWidget);
|
||||
// expect(find.text('1'), findsNothing);
|
||||
|
||||
// // Tap the '+' icon and trigger a frame.
|
||||
// await tester.tap(find.byIcon(Icons.add));
|
||||
// await tester.pump();
|
||||
|
||||
// // Verify that our counter has incremented.
|
||||
// expect(find.text('0'), findsNothing);
|
||||
// expect(find.text('1'), findsOneWidget);
|
||||
// });
|
||||
// }
|
|
@ -1,11 +0,0 @@
|
|||
import 'package:flutter_driver/driver_extension.dart';
|
||||
import 'package:gecko/main.dart' as app;
|
||||
|
||||
void main() {
|
||||
// This line enables the extension.
|
||||
enableFlutterDriverExtension();
|
||||
|
||||
// Call the `main()` function of the app, or call `runApp` with
|
||||
// any widget you are interested in testing.
|
||||
app.main();
|
||||
}
|
|
@ -1,455 +0,0 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:test/test.dart';
|
||||
// import 'package:flutter/services.dart';
|
||||
|
||||
void main() {
|
||||
int globalTimeout = 2;
|
||||
group('Gecko App', () {
|
||||
// First, define the Finders and use them to locate widgets from the
|
||||
// test suite. Note: the Strings provided to the `byValueKey` method must
|
||||
// be the same as the Strings we used for the Keys in step 1.
|
||||
final manageWalletsFinder = find.byValueKey('manageWallets');
|
||||
// final buttonFinder = find.byValueKey('increment');
|
||||
|
||||
FlutterDriver? driver;
|
||||
String? pinCode;
|
||||
|
||||
// Connect to the Flutter driver before running any tests.
|
||||
setUpAll(() async {
|
||||
driver = await FlutterDriver.connect();
|
||||
await driver!.waitUntilFirstFrameRasterized();
|
||||
});
|
||||
|
||||
// Close the connection to the driver after the tests have completed.
|
||||
tearDownAll(() async {
|
||||
if (driver != null) {
|
||||
driver!.close();
|
||||
}
|
||||
});
|
||||
|
||||
// *** Global functions *** //
|
||||
|
||||
// Function to tap the widget by key
|
||||
Future tapOn(String key) async {
|
||||
await driver!.tap(find.byValueKey(key));
|
||||
}
|
||||
|
||||
// Easy get text
|
||||
Future<String> getText(String text) async {
|
||||
return await driver!.getText(find.byValueKey(
|
||||
text,
|
||||
));
|
||||
}
|
||||
|
||||
// Function to go back to previous screen
|
||||
Future goBack() async {
|
||||
await Process.run(
|
||||
'adb',
|
||||
<String>['shell', 'input', 'keyevent', 'KEYCODE_BACK'],
|
||||
runInShell: true,
|
||||
);
|
||||
}
|
||||
|
||||
// Easy sleep
|
||||
Future sleep(int time) async {
|
||||
await Future.delayed(Duration(milliseconds: time));
|
||||
}
|
||||
|
||||
// Test if widget exist on screen, return a boolean
|
||||
Future<bool> isPresent(SerializableFinder byValueKey,
|
||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
||||
try {
|
||||
await driver!.waitFor(byValueKey, timeout: timeout);
|
||||
return true;
|
||||
} catch (exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a derivation
|
||||
Future createDerivation() async {
|
||||
await tapOn('addDerivation');
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Delete a derivation
|
||||
Future deleteWallet(bool confirm) async {
|
||||
await tapOn('deleteWallet');
|
||||
await sleep(100);
|
||||
confirm ? await tapOn('confirmDeleting') : await tapOn('cancelDeleting');
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Delete all wallets
|
||||
Future deleteAllWallets() async {
|
||||
await tapOn('drawerMenu');
|
||||
await sleep(300);
|
||||
await tapOn('parameters');
|
||||
await sleep(300);
|
||||
await tapOn('deleteAllWallets');
|
||||
await sleep(300);
|
||||
await tapOn('confirmDeletingAllWallets');
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Fast creation of new Keychain
|
||||
Future<String?> createNewKeychain(String name) async {
|
||||
await tapOn('drawerMenu');
|
||||
await sleep(300);
|
||||
await tapOn('parameters');
|
||||
await sleep(300);
|
||||
await tapOn('generateKeychain');
|
||||
while (await getText('generatedPin') == '') {
|
||||
log.d('Waiting for pin code generation...');
|
||||
await sleep(100);
|
||||
}
|
||||
pinCode = await getText('generatedPin');
|
||||
await tapOn('storeKeychain');
|
||||
await sleep(100);
|
||||
await driver!.enterText('triche');
|
||||
await tapOn('walletName');
|
||||
await driver!.enterText(name);
|
||||
await sleep(50);
|
||||
await tapOn('confirmStorage');
|
||||
await sleep(300);
|
||||
return pinCode;
|
||||
}
|
||||
|
||||
// *** Begin of tests *** //
|
||||
|
||||
test('OnBoarding - Open wallets management', (
|
||||
{timeout = Timeout.none}) async {
|
||||
// await driver.runUnsynchronized(() async { // Needed if we want to manage async drivers
|
||||
await driver!.tap(manageWalletsFinder);
|
||||
|
||||
// If a wallet exist, go to delete theme all
|
||||
if (!await isPresent(find.byValueKey('goStep1'))) {
|
||||
await goBack();
|
||||
|
||||
await deleteAllWallets();
|
||||
|
||||
await driver!.tap(manageWalletsFinder);
|
||||
}
|
||||
|
||||
// Get the SerializableFinder for text widget with key 'textOnboarding'
|
||||
SerializableFinder textOnboarding = find.byValueKey(
|
||||
'textOnboarding',
|
||||
);
|
||||
|
||||
await sleep(100);
|
||||
|
||||
// Verify onboarding is starting, with text
|
||||
expect(await driver!.getText(textOnboarding),
|
||||
"Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.");
|
||||
});
|
||||
|
||||
test('OnBoarding - Go to create restore sentance', (
|
||||
{timeout = Timeout.none}) async {
|
||||
await tapOn('goStep1');
|
||||
await tapOn('goStep2');
|
||||
await tapOn('goStep3');
|
||||
await tapOn('goStep4');
|
||||
await tapOn('goStep5');
|
||||
await tapOn('goStep6');
|
||||
|
||||
expect(
|
||||
await driver!.getText(find.byValueKey(
|
||||
'step6',
|
||||
)),
|
||||
"iGeneratedYourMnemonicKeepItSecret".tr());
|
||||
});
|
||||
|
||||
test('OnBoarding - Generate sentance and confirme it', (
|
||||
{timeout = Timeout.none}) async {
|
||||
await tapOn('goStep7');
|
||||
|
||||
while (await getText('word1') == '...') {
|
||||
log.d('Waiting for Mnemonic generation...');
|
||||
await sleep(100);
|
||||
}
|
||||
|
||||
Future selectWord() async {
|
||||
List words = [for (var i = 1; i <= 13; i += 1) i];
|
||||
|
||||
for (var j = 1; j < 13; j++) {
|
||||
words[j] = await getText('word$j');
|
||||
}
|
||||
expect(
|
||||
await getText('step7'), "C'est le moment de noter votre phrase !");
|
||||
|
||||
await tapOn('goStep8');
|
||||
await sleep(200);
|
||||
|
||||
String goodWord = words[int.parse(
|
||||
await getText('askedWord'),
|
||||
)];
|
||||
|
||||
// Enter the expected word
|
||||
await driver!.enterText(goodWord);
|
||||
|
||||
// Check if word is valid
|
||||
await driver!.waitFor(find.text("C'est le bon mot !"));
|
||||
|
||||
// Continue onboarding workflow
|
||||
await tapOn('goStep9');
|
||||
}
|
||||
|
||||
await selectWord();
|
||||
|
||||
//Go back 2 times to mnemonic generation screen
|
||||
await goBack();
|
||||
await goBack();
|
||||
await sleep(100);
|
||||
|
||||
// Generate 3 times mnemonic
|
||||
await tapOn('generateMnemonic');
|
||||
await tapOn('generateMnemonic');
|
||||
await tapOn('generateMnemonic');
|
||||
await sleep(500);
|
||||
|
||||
await selectWord();
|
||||
});
|
||||
test('OnBoarding - Generate secret code and confirm it', (
|
||||
{timeout = Timeout.none}) async {
|
||||
expect(await getText('step9'),
|
||||
"Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre coffre de clefs, ce qui le rend inutilisable par d’autres, par exemple si vous perdez votre téléphone ou si on vous le vole.");
|
||||
await sleep(800);
|
||||
await tapOn('goStep10');
|
||||
await sleep(50);
|
||||
await tapOn('goStep11');
|
||||
|
||||
while (await getText('generatedPin') == '') {
|
||||
log.d('Waiting for pin code generation...');
|
||||
await sleep(100);
|
||||
}
|
||||
|
||||
// Change secret code 4 times
|
||||
for (int i = 0; i < 4; i++) {
|
||||
await tapOn('changeSecretCode');
|
||||
}
|
||||
|
||||
await sleep(500);
|
||||
pinCode = await getText('generatedPin');
|
||||
|
||||
await tapOn('goStep12');
|
||||
await sleep(300);
|
||||
|
||||
// //Enter bad secret code
|
||||
// await driver.enterText('abcde');
|
||||
// await tapOn('formKey');
|
||||
// await sleep(1500);
|
||||
// await tapOn('formKey2');
|
||||
|
||||
//Enter good secret code
|
||||
await driver!.enterText(pinCode!);
|
||||
|
||||
expect(await getText('step13'),
|
||||
"Top !\n\nVotre coffre et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !");
|
||||
});
|
||||
|
||||
test('My wallets - Rename first derivation', (
|
||||
{timeout = const Duration(seconds: 2)}) async {
|
||||
await tapOn('goWalletHome');
|
||||
|
||||
expect(await getText('myWallets'), "geckoChest".tr());
|
||||
await sleep(300);
|
||||
|
||||
// Go to first derivation and rename it
|
||||
await driver!.tap(find.text('Mon portefeuille courant'));
|
||||
await sleep(300);
|
||||
await tapOn('renameWallet');
|
||||
await sleep(100);
|
||||
await tapOn('walletName');
|
||||
await sleep(100);
|
||||
await driver!.enterText('Renommage wallet 1');
|
||||
await sleep(300);
|
||||
await tapOn('renameWallet');
|
||||
await sleep(400);
|
||||
await driver!.waitFor(find.text('Renommage wallet 1'), timeout: timeout);
|
||||
// expect(await getText('walletName'), "Renommage wallet 1");
|
||||
await goBack();
|
||||
});
|
||||
|
||||
test('My wallets - Create a derivations, open thems, tap all buttons', (
|
||||
{timeout = const Duration(seconds: 2)}) async {
|
||||
await driver!.waitFor(find.text('Renommage wallet 1'), timeout: timeout);
|
||||
// Add a second derivation
|
||||
await createDerivation();
|
||||
|
||||
// Go to second derivation options
|
||||
await driver!.tap(find.text('Portefeuille 2'));
|
||||
await sleep(100);
|
||||
|
||||
// Test options
|
||||
await tapOn('displayBalance');
|
||||
await tapOn('displayHistory');
|
||||
await sleep(300);
|
||||
await goBack();
|
||||
await tapOn('displayBalance');
|
||||
await sleep(100);
|
||||
await tapOn('displayBalance');
|
||||
await sleep(100);
|
||||
await tapOn('displayBalance');
|
||||
await tapOn('setDefaultWallet');
|
||||
await sleep(50);
|
||||
await tapOn('copyPubkey');
|
||||
await driver!.waitFor(find
|
||||
.text('Cette clé publique a été copié dans votre presse-papier.'));
|
||||
await goBack();
|
||||
|
||||
// Add a third derivation
|
||||
await createDerivation();
|
||||
|
||||
// Add a fourth derivation
|
||||
await createDerivation();
|
||||
await sleep(50);
|
||||
|
||||
// Go to third derivation options
|
||||
await driver!.tap(find.text('Portefeuille 3'));
|
||||
await sleep(100);
|
||||
await tapOn('displayBalance');
|
||||
|
||||
// Delete third derivation
|
||||
await deleteWallet(true);
|
||||
});
|
||||
|
||||
test('My wallets - Extra tests', (
|
||||
{timeout = const Duration(seconds: 2)}) async {
|
||||
// Add derivation 5,6 and 7
|
||||
await driver!.waitFor(find.text('Portefeuille 4'), timeout: timeout);
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
|
||||
// Go home and come back to my wallets view
|
||||
await goBack();
|
||||
await sleep(100);
|
||||
await tapOn('manageWallets');
|
||||
await sleep(200);
|
||||
//Enter secret code
|
||||
await driver!.enterText(pinCode!);
|
||||
await sleep(200);
|
||||
|
||||
// Go to derivation 6 and delete it
|
||||
await driver!.tap(find.text('Portefeuille 6'));
|
||||
await sleep(100);
|
||||
await deleteWallet(true);
|
||||
|
||||
// Go to 2nd derivation and check if it's de default
|
||||
await driver!.tap(find.text('Portefeuille 2'));
|
||||
await driver!.waitFor(find.text('Ce portefeuille est celui par defaut'));
|
||||
await tapOn('setDefaultWallet');
|
||||
await sleep(100);
|
||||
await driver!.waitFor(find.text('Ce portefeuille est celui par defaut'));
|
||||
await sleep(300);
|
||||
|
||||
// Display history, copy pubkey, go back and rename wallet name
|
||||
await tapOn('displayHistory');
|
||||
await sleep(400);
|
||||
await tapOn('copyPubkey');
|
||||
await driver!.waitFor(find
|
||||
.text('Cette clé publique a été copié dans votre presse-papier.'));
|
||||
await sleep(800);
|
||||
await goBack();
|
||||
await sleep(300);
|
||||
await tapOn('renameWallet');
|
||||
await sleep(100);
|
||||
await tapOn('walletName');
|
||||
await sleep(100);
|
||||
await driver!.enterText('Renommage wallet 2');
|
||||
await sleep(300);
|
||||
await tapOn('renameWallet');
|
||||
await sleep(400);
|
||||
await goBack();
|
||||
await driver!.waitFor(find.text('Renommage wallet 2'));
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await createDerivation();
|
||||
await driver!.scrollIntoView(find.text('+'));
|
||||
await createDerivation();
|
||||
await sleep(400);
|
||||
|
||||
// Scroll the wallet screen until Derivation 20 and open it
|
||||
await driver!.scrollUntilVisible(
|
||||
find.byValueKey('listWallets'),
|
||||
find.text('Portefeuille 20'),
|
||||
dyScroll: -300.0,
|
||||
);
|
||||
|
||||
await driver!.waitFor(find.text('Portefeuille 20'));
|
||||
await sleep(400);
|
||||
await driver!.tap(find.text('Portefeuille 20'));
|
||||
await tapOn('copyPubkey');
|
||||
});
|
||||
|
||||
test('Search - Search Pi profile, navigate in history transactions', (
|
||||
{timeout = const Duration(seconds: 2)}) async {
|
||||
await driver!.waitFor(find.text('Portefeuille 20'), timeout: timeout);
|
||||
await goBack();
|
||||
await goBack();
|
||||
await sleep(200);
|
||||
await tapOn('searchIcon');
|
||||
await sleep(400);
|
||||
await driver!.enterText('D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU');
|
||||
await sleep(100);
|
||||
await tapOn('copyPubkey');
|
||||
await sleep(500);
|
||||
await tapOn('switchPayHistory');
|
||||
await sleep(1200);
|
||||
// await driver.scrollIntoView(find.byValueKey('listTransactions'));
|
||||
await driver!.scrollUntilVisible(
|
||||
find.byValueKey('listTransactions'),
|
||||
find.byValueKey('transaction35'),
|
||||
dyScroll: -600.0,
|
||||
);
|
||||
await sleep(100);
|
||||
await tapOn('transaction33');
|
||||
await driver!.waitFor(find.text('Commentaire:'));
|
||||
|
||||
// Want to paste pubkey copied, but doesn't work actualy with flutter driver: https://github.com/flutter/flutter/issues/47448
|
||||
// final ClipboardData pubkeyCopied =
|
||||
// await Clipboard.getData(Clipboard.kTextPlain);
|
||||
// await driver.enterText(pubkeyCopied.text);
|
||||
|
||||
await sleep(300);
|
||||
}, timeout: Timeout(Duration(minutes: globalTimeout)));
|
||||
|
||||
test('Wallet generation - Fast wallets generations', (
|
||||
{timeout = const Duration(seconds: 2)}) async {
|
||||
await driver!.waitFor(find.text('Commentaire:'), timeout: timeout);
|
||||
await goBack();
|
||||
await goBack();
|
||||
await deleteAllWallets();
|
||||
await sleep(100);
|
||||
final String? pincode = await (createNewKeychain('Fast wallet'));
|
||||
await sleep(200);
|
||||
await driver!.enterText(pincode!);
|
||||
await sleep(100);
|
||||
await createDerivation();
|
||||
await sleep(100);
|
||||
await driver!.tap(find.text('Fast wallet'));
|
||||
await driver!.waitFor(find.text('Fast wallet'));
|
||||
// Wait 3 seconds at the end
|
||||
await sleep(3000);
|
||||
});
|
||||
}, timeout: Timeout(Duration(minutes: globalTimeout)));
|
||||
}
|
Loading…
Reference in New Issue