Merge branch 'substrate-sdk'

This commit is contained in:
poka 2022-05-23 11:08:24 +02:00
commit 7a6bda3545
101 changed files with 4884 additions and 3086 deletions

View File

@ -45,8 +45,8 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "gecko.axiomteam.fr" applicationId "gecko.axiomteam.fr"
minSdkVersion 16 minSdkVersion 19
targetSdkVersion 30 targetSdkVersion 31
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
multiDexEnabled true multiDexEnabled true

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gecko"> package="gecko.axiomteam.fr">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gecko"> package="gecko.axiomteam.fr">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that <!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method. calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide In most cases you can leave this as-is, but you if you want to provide
@ -9,32 +9,34 @@
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application android:requestLegacyExternalStorage="true" <application
android:requestLegacyExternalStorage="true"
android:name="${applicationName}" android:name="${applicationName}"
android:label="Ğecko"> android:label="Ğecko"
android:usesCleartextTraffic="true">
<!-- TODO: Remove usesCleartextTraffic for production mode ! kopa -->
<!-- android:icon="@mipmap/ic_launcher"> --> <!-- android:icon="@mipmap/ic_launcher"> -->
<activity <activity
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:name=".MainActivity" android:name=".MainActivity"
android:resource="@style/NormalTheme"
android:icon="@mipmap/ic_launcher"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize"
android:exported="true">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. --> to determine the Window background behind the Flutter UI. -->
<meta-data <!-- <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"
/> android:icon="@mipmap/ic_launcher"
/> -->
<!-- Theme to apply as soon as Flutter begins rendering frames -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -1,4 +1,4 @@
package com.example.gecko package gecko.axiomteam.fr
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gecko"> package="gecko.axiomteam.fr">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@ -1,5 +1,3 @@
[ [
"https://g1.librelois.fr/gva", "https://g1.librelois.fr/gva"
"https://duniter-gva.axiom-team.fr/gva",
"https://duniter-g1.p2p.legal/gva"
] ]

View File

@ -299,7 +299,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.gecko; PRODUCT_BUNDLE_IDENTIFIER = gecko.axiomteam.fr;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -431,7 +431,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.gecko; PRODUCT_BUNDLE_IDENTIFIER = gecko.axiomteam.fr;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -458,7 +458,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.gecko; PRODUCT_BUNDLE_IDENTIFIER = gecko.axiomteam.fr;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -492,4 +492,4 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };
rootObject = 97C146E61CF9000F007C117D /* Project object */; rootObject = 97C146E61CF9000F007C117D /* Project object */;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -14,14 +14,16 @@ late String appVersion;
late SharedPreferences prefs; late SharedPreferences prefs;
late String endPointGVA; late String endPointGVA;
const int pinLength = 5; const int pinLength = 5;
const String appLang = 'french'; const String appLang = 'english';
late Box<WalletData> walletBox; late Box<WalletData> walletBox;
late Box<ChestData> chestBox; late Box<ChestData> chestBox;
late Box configBox; late Box configBox;
late Box<G1WalletsList> g1WalletsBox; late Box<G1WalletsList> g1WalletsBox;
// late Box keystoreBox;
String cesiumPod = "https://g1.data.le-sou.org"; // String cesiumPod = "https://g1.data.le-sou.org";
String cesiumPod = "https://g1.data.presles.fr";
// String cesiumPod = "https://g1.data.e-is.pro"; // String cesiumPod = "https://g1.data.e-is.pro";
// Responsive ratios // Responsive ratios
@ -36,3 +38,10 @@ Color orangeC = const Color(0xffd07316);
Color yellowC = const Color(0xffFFD68E); Color yellowC = const Color(0xffFFD68E);
Color floattingYellow = const Color(0xffEFEFBF); Color floattingYellow = const Color(0xffEFEFBF);
Color backgroundColor = const Color(0xFFF5F5F5); Color backgroundColor = const Color(0xFFF5F5F5);
// Substrate settings
const int ss58 = 42;
String currencyName = 'Ğdev';
// Debug
const debugPin = true;

View File

@ -1,4 +1,4 @@
// Copyright (C) 2020 Axiom-Team. // Copyright (C) 2022 Axiom-Team.
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as // it under the terms of the GNU Affero General Public License as
@ -20,11 +20,11 @@ import 'dart:io';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/change_pin.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
@ -65,19 +65,23 @@ Future<void> main() async {
Hive.registerAdapter(ChestDataAdapter()); Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter()); Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter()); Hive.registerAdapter(IdAdapter());
// Hive.registerAdapter(KeyStoreDataAdapter());
walletBox = await Hive.openBox<WalletData>("walletBox"); walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox"); chestBox = await Hive.openBox<ChestData>("chestBox");
configBox = await Hive.openBox("configBox"); configBox = await Hive.openBox("configBox");
await Hive.deleteBoxFromDisk('g1WalletsBox');
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox"); g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
// keystoreBox = await Hive.openBox("keystoreBox");
g1WalletsBox.clear(); // g1WalletsBox.clear();
// final HiveStore _store = // final HiveStore _store =
// await HiveStore.open(path: '${appPath.path}/gqlCache'); // await HiveStore.open(path: '${appPath.path}/gqlCache');
// Get a valid GVA endpoint // Get a valid GVA endpoint
// endPointGVA = 'https://g1.librelois.fr/gva'; endPointGVA = 'https://g1.librelois.fr/gva';
endPointGVA = 'https://duniter-g1.p2p.legal/gva'; // endPointGVA = 'https://duniter-g1.p2p.legal/gva';
// await _homeProvider.getValidEndpoint(); // await _homeProvider.getValidEndpoint();
// if (endPointGVA == 'HS') { // if (endPointGVA == 'HS') {
@ -152,9 +156,9 @@ class Gecko extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ChestProvider()), ChangeNotifierProvider(create: (_) => ChestProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()), ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()), ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
ChangeNotifierProvider(create: (_) => ChangePinProvider()),
ChangeNotifierProvider(create: (_) => SearchProvider()), ChangeNotifierProvider(create: (_) => SearchProvider()),
ChangeNotifierProvider(create: (_) => CesiumPlusProvider()) ChangeNotifierProvider(create: (_) => CesiumPlusProvider()),
ChangeNotifierProvider(create: (_) => SubstrateSdk())
], ],
child: GraphQLProvider( child: GraphQLProvider(
client: _client, client: _client,
@ -178,8 +182,8 @@ class Gecko extends StatelessWidget {
), ),
primaryColor: const Color(0xffFFD58D), primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme( textTheme: const TextTheme(
bodyText1: TextStyle(), bodyText1: TextStyle(fontSize: 16),
bodyText2: TextStyle(), bodyText2: TextStyle(fontSize: 18),
).apply( ).apply(
bodyColor: const Color(0xFF000000), bodyColor: const Color(0xFF000000),
), ),

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,10 @@ part 'chest_data.g.dart';
@HiveType(typeId: 1) @HiveType(typeId: 1)
class ChestData extends HiveObject { class ChestData extends HiveObject {
@HiveField(0) @HiveField(0)
String? dewif; String? address;
@HiveField(1)
String? rootAddress;
@HiveField(2) @HiveField(2)
String? name; String? name;
@ -25,7 +28,8 @@ class ChestData extends HiveObject {
bool? isCesium; bool? isCesium;
ChestData({ ChestData({
this.dewif, this.address,
this.rootAddress,
this.name, this.name,
this.defaultWallet, this.defaultWallet,
this.imageName, this.imageName,

View File

@ -17,7 +17,8 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
}; };
return ChestData( return ChestData(
dewif: fields[0] as String?, address: fields[0] as String?,
rootAddress: fields[1] as String?,
name: fields[2] as String?, name: fields[2] as String?,
defaultWallet: fields[3] as int?, defaultWallet: fields[3] as int?,
imageName: fields[4] as String?, imageName: fields[4] as String?,
@ -29,9 +30,11 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
@override @override
void write(BinaryWriter writer, ChestData obj) { void write(BinaryWriter writer, ChestData obj) {
writer writer
..writeByte(6) ..writeByte(7)
..writeByte(0) ..writeByte(0)
..write(obj.dewif) ..write(obj.address)
..writeByte(1)
..write(obj.rootAddress)
..writeByte(2) ..writeByte(2)
..write(obj.name) ..write(obj.name)
..writeByte(3) ..writeByte(3)

View File

@ -11,19 +11,19 @@ class G1WalletsList {
@HiveField(1) @HiveField(1)
double? balance; double? balance;
@HiveField(3) @HiveField(2)
Id? id; Id? id;
@HiveField(4) @HiveField(3)
Image? avatar; Image? avatar;
@HiveField(5) @HiveField(4)
String? username; String? username;
@HiveField(6) @HiveField(5)
String? csName; String? csName;
@HiveField(7) @HiveField(6)
bool? isMembre; bool? isMembre;
G1WalletsList({ G1WalletsList({

View File

@ -1,7 +1,5 @@
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_local_variable
part of 'g1_wallets_list.dart'; part of 'g1_wallets_list.dart';
// ************************************************************************** // **************************************************************************
@ -21,11 +19,11 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
return G1WalletsList( return G1WalletsList(
pubkey: fields[0] as String?, pubkey: fields[0] as String?,
balance: fields[1] as double?, balance: fields[1] as double?,
id: fields[3] as Id?, id: fields[2] as Id?,
avatar: fields[4] as Image?, avatar: fields[3] as Image?,
username: fields[5] as String?, username: fields[4] as String?,
csName: fields[6] as String?, csName: fields[5] as String?,
isMembre: fields[7] as bool?, isMembre: fields[6] as bool?,
); );
} }
@ -37,15 +35,15 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
..write(obj.pubkey) ..write(obj.pubkey)
..writeByte(1) ..writeByte(1)
..write(obj.balance) ..write(obj.balance)
..writeByte(3) ..writeByte(2)
..write(obj.id) ..write(obj.id)
..writeByte(4) ..writeByte(3)
..write(obj.avatar) ..write(obj.avatar)
..writeByte(5) ..writeByte(4)
..write(obj.username) ..write(obj.username)
..writeByte(6) ..writeByte(5)
..write(obj.csName) ..write(obj.csName)
..writeByte(7) ..writeByte(6)
..write(obj.isMembre); ..write(obj.isMembre);
} }
@ -66,10 +64,6 @@ class IdAdapter extends TypeAdapter<Id> {
@override @override
Id read(BinaryReader reader) { Id read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Id(); return Id();
} }

View File

@ -0,0 +1,28 @@
import 'package:hive_flutter/hive_flutter.dart';
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
part 'keystore_data.g.dart';
@HiveType(typeId: 4)
class KeyStoreData extends HiveObject {
@HiveField(0)
KeyPairData? keystore;
KeyStoreData({this.keystore});
@override
String toString() {
return keystore!.address!;
}
String name() {
return keystore!.name!;
}
String pubkey() {
return keystore!.pubKey!;
}
Map indexInfo() {
return keystore!.indexInfo!;
}
}

View File

@ -0,0 +1,41 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'keystore_data.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class KeyStoreDataAdapter extends TypeAdapter<KeyStoreData> {
@override
final int typeId = 4;
@override
KeyStoreData read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return KeyStoreData(
keystore: fields[0] as KeyPairData?,
);
}
@override
void write(BinaryWriter writer, KeyStoreData obj) {
writer
..writeByte(1)
..writeByte(0)
..write(obj.keystore);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is KeyStoreDataAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({Key? key, required this.onInit, required this.child})
: super(key: key);
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
widget.onInit();
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -1,7 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'wallet_data.g.dart'; part 'wallet_data.g.dart';
@HiveType(typeId: 0) @HiveType(typeId: 0)
@ -10,22 +8,26 @@ class WalletData extends HiveObject {
int? chest; int? chest;
@HiveField(1) @HiveField(1)
int? number; String? address;
@HiveField(2) @HiveField(2)
String? name; int? number;
@HiveField(3) @HiveField(3)
int? derivation; String? name;
@HiveField(4) @HiveField(4)
String? imageName; int? derivation;
@HiveField(5) @HiveField(5)
String? imageName;
@HiveField(6)
File? imageFile; File? imageFile;
WalletData( WalletData(
{this.chest, {this.chest,
this.address,
this.number, this.number,
this.name, this.name,
this.derivation, this.derivation,
@ -48,3 +50,10 @@ class WalletData extends HiveObject {
return [chest, number]; return [chest, number];
} }
} }
class NewWallet {
final String address;
final String password;
NewWallet._(this.address, this.password);
}

View File

@ -18,29 +18,32 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
}; };
return WalletData( return WalletData(
chest: fields[0] as int?, chest: fields[0] as int?,
number: fields[1] as int?, address: fields[1] as String?,
name: fields[2] as String?, number: fields[2] as int?,
derivation: fields[3] as int?, name: fields[3] as String?,
imageName: fields[4] as String?, derivation: fields[4] as int?,
imageFile: fields[5] as File?, imageName: fields[5] as String?,
imageFile: fields[6] as File?,
); );
} }
@override @override
void write(BinaryWriter writer, WalletData obj) { void write(BinaryWriter writer, WalletData obj) {
writer writer
..writeByte(6) ..writeByte(7)
..writeByte(0) ..writeByte(0)
..write(obj.chest) ..write(obj.chest)
..writeByte(1) ..writeByte(1)
..write(obj.number) ..write(obj.address)
..writeByte(2) ..writeByte(2)
..write(obj.name) ..write(obj.number)
..writeByte(3) ..writeByte(3)
..write(obj.derivation) ..write(obj.name)
..writeByte(4) ..writeByte(4)
..write(obj.imageName) ..write(obj.derivation)
..writeByte(5) ..writeByte(5)
..write(obj.imageName)
..writeByte(6)
..write(obj.imageFile); ..write(obj.imageFile);
} }

View File

@ -63,7 +63,7 @@ class CesiumPlusProvider with ChangeNotifier {
Future<String> getName(String? _pubkey) async { Future<String> getName(String? _pubkey) async {
String? _name; String? _name;
if (g1WalletsBox.get(_pubkey)!.csName != null) { if (g1WalletsBox.get(_pubkey)?.csName != null) {
return g1WalletsBox.get(_pubkey)!.csName!; return g1WalletsBox.get(_pubkey)!.csName!;
} }

View File

@ -1,48 +0,0 @@
import 'package:durt/durt.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
class ChangePinProvider with ChangeNotifier {
bool ischangedPin = false;
TextEditingController newPin = TextEditingController();
String? pinToGive;
NewWallet? get badWallet => null;
Future<NewWallet?> changePin(String _oldPin, {String? newCustomPin}) async {
final NewWallet newWalletFile;
try {
final _chest = chestBox.get(configBox.get('currentChest'))!;
if (_chest.isCesium!) {
newWalletFile = await Dewif().changeCesiumPassword(
dewif: _chest.dewif!,
oldPassword: _oldPin.toUpperCase(),
newPassword: newCustomPin);
} else {
newWalletFile = await Dewif().changePassword(
dewif: _chest.dewif!,
oldPassword: _oldPin.toUpperCase(),
newPassword: newCustomPin);
}
newPin.text = pinToGive = newWalletFile.password;
ischangedPin = true;
// notifyListeners();
return newWalletFile;
} catch (e) {
log.e('Impossible de changer le code PIN: $e');
return badWallet;
}
}
void storeNewPinChest(context, NewWallet _newWalletFile) {
// ChestData currentChest = chestBox.getAt(configBox.get('currentChest'));
// currentChest.dewif = _newWalletFile.dewif;
// await chestBox.add(currentChest);
chestBox.get(configBox.get('currentChest'))!.dewif = _newWalletFile.dewif;
Navigator.pop(context, pinToGive);
pinToGive = '';
}
}

View File

@ -1,21 +1,22 @@
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:durt/durt.dart'; import 'package:durt/durt.dart' as durt;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/bip39_words.dart'; import 'package:gecko/models/bip39_words.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:pdf/pdf.dart'; import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw; import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart'; import 'package:provider/provider.dart';
import "package:unorm_dart/unorm_dart.dart" as unorm; import "package:unorm_dart/unorm_dart.dart" as unorm;
class GenerateWalletsProvider with ChangeNotifier { class GenerateWalletsProvider with ChangeNotifier {
GenerateWalletsProvider(); GenerateWalletsProvider();
// NewWallet generatedWallet; // NewWallet generatedWallet;
NewWallet? actualWallet; durt.NewWallet? actualWallet;
FocusNode walletNameFocus = FocusNode(); FocusNode walletNameFocus = FocusNode();
Color? askedWordColor = Colors.black; Color? askedWordColor = Colors.black;
@ -37,7 +38,7 @@ class GenerateWalletsProvider with ChangeNotifier {
bool isCesiumIDVisible = false; bool isCesiumIDVisible = false;
bool isCesiumPWDVisible = false; bool isCesiumPWDVisible = false;
bool canImport = false; bool canImport = false;
late CesiumWallet cesiumWallet; late durt.CesiumWallet cesiumWallet;
// Import Chest // Import Chest
TextEditingController cellController0 = TextEditingController(); TextEditingController cellController0 = TextEditingController();
@ -55,7 +56,7 @@ class GenerateWalletsProvider with ChangeNotifier {
bool isFirstTimeSentenceComplete = true; bool isFirstTimeSentenceComplete = true;
Future storeHDWChest( Future storeHDWChest(
NewWallet _wallet, String _name, BuildContext context) async { String address, String _name, BuildContext context) async {
int chestNumber = 0; int chestNumber = 0;
chestBox.toMap().forEach((key, value) { chestBox.toMap().forEach((key, value) {
if (!value.isCesium!) { if (!value.isCesium!) {
@ -70,7 +71,7 @@ class GenerateWalletsProvider with ChangeNotifier {
chestName = 'Coffre à Ğecko ${chestNumber + 1}'; chestName = 'Coffre à Ğecko ${chestNumber + 1}';
} }
ChestData thisChest = ChestData( ChestData thisChest = ChestData(
dewif: _wallet.dewif, address: address,
name: chestName, name: chestName,
defaultWallet: 0, defaultWallet: 0,
imageName: '${chestNumber % 8}.png', imageName: '${chestNumber % 8}.png',
@ -81,9 +82,10 @@ class GenerateWalletsProvider with ChangeNotifier {
WalletData myWallet = WalletData( WalletData myWallet = WalletData(
chest: chestKey, chest: chestKey,
address: address,
number: 0, number: 0,
name: _name, name: _name,
derivation: 3, derivation: 2,
imageName: '0.png'); imageName: '0.png');
await walletBox.add(myWallet); await walletBox.add(myWallet);
@ -152,64 +154,78 @@ class GenerateWalletsProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<NewWallet?> generateWallet(String generatedMnemonic,
{required bool isImport}) async {
try {
actualWallet = await Dewif().generateDewif(
generatedMnemonic, randomSecretCode(pinLength),
lang: appLang);
} catch (e) {
log.e(e);
}
if (!isImport) {
mnemonicController.text = generatedMnemonic;
pin.text = actualWallet!.password;
}
// notifyListeners();
return actualWallet;
}
String changePinCode({required bool reload}) { String changePinCode({required bool reload}) {
pin.text = randomSecretCode(pinLength); pin.text = durt.randomSecretCode(pinLength);
if (reload) { if (reload) {
notifyListeners(); notifyListeners();
} }
return pin.text; return pin.text;
} }
Future<Uint8List> printWallet(String? _title) async { Future<Uint8List> printWallet(AsyncSnapshot<List>? mnemoList) async {
final ByteData fontData = final ByteData fontData =
await rootBundle.load("assets/OpenSans-Regular.ttf"); await rootBundle.load("assets/OpenSans-Regular.ttf");
final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData()); final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData());
final pdf = pw.Document(); final pdf = pw.Document();
const imageProvider = AssetImage('assets/icon/gecko_final.png'); // const imageProvider = AssetImage('assets/icon/gecko_final.png');
final geckoLogo = await flutterImageProvider(imageProvider); // final geckoLogo = await flutterImageProvider(imageProvider);
pw.Widget arrayCell(dataWord) {
return pw.SizedBox(
width: 120,
child: pw.Column(children: <pw.Widget>[
pw.Text(
dataWord.split(':')[0],
style: pw.TextStyle(
fontSize: 15, color: const PdfColor(0.5, 0, 0), font: ttf),
),
pw.Text(
dataWord.split(':')[1],
style: pw.TextStyle(
fontSize: 20, color: const PdfColor(0, 0, 0), font: ttf),
),
pw.SizedBox(height: 10)
]),
);
}
pdf.addPage( pdf.addPage(
pw.Page( pw.Page(
pageFormat: PdfPageFormat.a4, pageFormat: PdfPageFormat.a4,
build: (context) { build: (context) {
return pw.Column(children: <pw.Widget>[ return pw.Column(
pw.SizedBox(height: 20), // mainAxisAlignment: pw.MainAxisAlignment.center,
pw.Text("Phrase de restauration:", // mainAxisSize: pw.MainAxisSize.max,
style: pw.TextStyle(fontSize: 20, font: ttf)), // crossAxisAlignment: pw.CrossAxisAlignment.center,
pw.SizedBox(height: 10), children: <pw.Widget>[
pw.Text(_title!, pw.Row(children: <pw.Widget>[
style: pw.TextStyle(fontSize: 15, font: ttf), arrayCell(mnemoList!.data![0]),
textAlign: pw.TextAlign.center), arrayCell(mnemoList.data![1]),
pw.Expanded( arrayCell(mnemoList.data![2]),
child: pw.Align( arrayCell(mnemoList.data![3]),
alignment: pw.Alignment.bottomCenter, ]),
child: pw.Text( pw.Row(children: <pw.Widget>[
"Gardez cette feuille en lieu sûr, à l'abris des regards indiscrets.", arrayCell(mnemoList.data![4]),
style: pw.TextStyle(fontSize: 10, font: ttf), arrayCell(mnemoList.data![5]),
))), arrayCell(mnemoList.data![6]),
pw.SizedBox(height: 15), arrayCell(mnemoList.data![7]),
pw.Image(geckoLogo, height: 50) ]),
]); pw.Row(children: <pw.Widget>[
arrayCell(mnemoList.data![8]),
arrayCell(mnemoList.data![9]),
arrayCell(mnemoList.data![10]),
arrayCell(mnemoList.data![11])
]),
pw.Expanded(
child: pw.Align(
alignment: pw.Alignment.bottomCenter,
child: pw.Text(
"Gardez cette feuille préciseusement, à labri des lézards indiscrets.",
style: pw.TextStyle(fontSize: 15, font: ttf),
)))
],
);
}, },
), ),
); );
@ -219,63 +235,13 @@ class GenerateWalletsProvider with ChangeNotifier {
Future<void> generateCesiumWalletPubkey( Future<void> generateCesiumWalletPubkey(
String _cesiumID, String _cesiumPWD) async { String _cesiumID, String _cesiumPWD) async {
cesiumWallet = CesiumWallet(_cesiumID, _cesiumPWD); cesiumWallet = durt.CesiumWallet(_cesiumID, _cesiumPWD);
String _walletPubkey = cesiumWallet.pubkey; String _walletPubkey = cesiumWallet.pubkey;
cesiumPubkey.text = _walletPubkey; cesiumPubkey.text = _walletPubkey;
log.d(_walletPubkey); log.d(_walletPubkey);
} }
Future<int?> importCesiumWallet() async {
// String _walletPubkey = await DubpRust.getLegacyPublicKey(
// salt: _cesiumID, password: _cesiumPWD);
// String shortPubkey = truncate(_walletPubkey, 9,
// omission: "...", position: TruncatePosition.end);
// await storeWallet(
// actualWallet, 'Portefeuille Cesium - $shortPubkey', context);
// NewWallet myCesiumWallet = await DubpRust.genWalletFromDeprecatedSaltPassword(salt: _cesiumID, password: _cesiumPWD);
cesiumID.text = '';
cesiumPWD.text = '';
cesiumPubkey.text = '';
canImport = false;
isCesiumIDVisible = false;
isCesiumPWDVisible = false;
int chestNumber = 0;
chestBox.toMap().forEach((key, value) {
if (value.isCesium!) {
chestNumber++;
}
});
String chestName;
if (chestNumber == 0) {
chestName = 'Coffre à Césium';
} else {
chestName = 'Coffre à Césium ${chestNumber + 1}';
}
log.d(pin.text);
NewWallet cesiumDewif =
await Dewif().generateCesiumDewif(cesiumWallet.seed, pin.text);
ChestData cesiumChest = ChestData(
dewif: cesiumDewif.dewif,
name: chestName,
imageName: 'cesium.png',
defaultWallet: 0,
isCesium: true);
await chestBox.add(cesiumChest).then((value) => null);
int? chestKey = await chestBox.toMap().keys.last;
// chestBox.toMap().
await configBox.put('currentChest', chestKey);
pin.text = '';
return chestKey;
}
void cesiumIDisVisible() { void cesiumIDisVisible() {
isCesiumIDVisible = !isCesiumIDVisible; isCesiumIDVisible = !isCesiumIDVisible;
notifyListeners(); notifyListeners();
@ -293,8 +259,10 @@ class GenerateWalletsProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
List<String> generateWordList() { Future<List<String>> generateWordList(BuildContext context) async {
generatedMnemonic = generateMnemonic(lang: appLang); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
generatedMnemonic = await _sub.generateMnemonic(lang: appLang);
List<String> _wordsList = []; List<String> _wordsList = [];
String word; String word;
int _nbr = 1; int _nbr = 1;
@ -313,7 +281,7 @@ class GenerateWalletsProvider with ChangeNotifier {
// Needed for bad encoding of UTF-8 // Needed for bad encoding of UTF-8
word = word.replaceAll('é', ''); word = word.replaceAll('é', '');
word = word.replaceAll('è', ''); word = word.replaceAll('è', '');
return bip39Words.contains(word); return bip39Words(appLang).contains(word);
} }
bool isBipWordsList(List<String> words) { bool isBipWordsList(List<String> words) {
@ -322,7 +290,7 @@ class GenerateWalletsProvider with ChangeNotifier {
// Needed for bad encoding of UTF-8 // Needed for bad encoding of UTF-8
word = word.replaceAll('é', ''); word = word.replaceAll('é', '');
word = word.replaceAll('è', ''); word = word.replaceAll('è', '');
if (!bip39Words.contains(word)) { if (!bip39Words(appLang).contains(word)) {
isValid = false; isValid = false;
} }
} }
@ -333,8 +301,8 @@ class GenerateWalletsProvider with ChangeNotifier {
cellController0.text = cellController1.text = cellController2.text = cellController0.text = cellController1.text = cellController2.text =
cellController3.text = cellController4.text = cellController5.text = cellController3.text = cellController4.text = cellController5.text =
cellController6.text = cellController7.text = cellController8.text = cellController6.text = cellController7.text = cellController8.text =
cellController9.text = cellController10.text = cellController9.text =
cellController11.text = ''; cellController10.text = cellController11.text = '';
isFirstTimeSentenceComplete = true; isFirstTimeSentenceComplete = true;
notifyListeners(); notifyListeners();
} }
@ -366,22 +334,31 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
} }
Future<bool> isSentenceValid() async { Future pasteMnemonic(BuildContext context) async {
String inputMnemonic = final sentence = await Clipboard.getData('text/plain');
'${cellController0.text} ${cellController1.text} ${cellController2.text} ${cellController3.text} ${cellController4.text} ${cellController5.text} ${cellController6.text} ${cellController7.text} ${cellController8.text} ${cellController9.text} ${cellController10.text} ${cellController11.text}'; int nbr = 0;
// Needed for bad encoding of UTF-8 List cells = [
inputMnemonic = inputMnemonic.replaceAll('é', ''); cellController0,
inputMnemonic = inputMnemonic.replaceAll('è', ''); cellController1,
cellController2,
cellController3,
cellController4,
cellController5,
cellController6,
cellController7,
cellController8,
cellController9,
cellController10,
cellController11
];
for (var word in sentence!.text!.split(' ')) {
bool isValid = isBipWord(word);
NewWallet? generatedWallet = if (isValid) {
await generateWallet(inputMnemonic, isImport: true); cells[nbr].text = word;
}
if (generatedWallet == null) { nbr++;
return false;
} else {
generatedMnemonic = inputMnemonic;
return true;
} }
} }

View File

@ -139,22 +139,6 @@ class HomeProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void snackNode(context) {
if (isFirstBuild) {
String _message;
if (endPointGVA == 'HS') {
_message =
"Aucun noeud Duniter disponible, veuillez réessayer ultérieurement";
} else {
_message = "Vous êtes connecté au noeud\n${endPointGVA.split('/')[2]}";
}
final snackBar = SnackBar(
content: Text(_message), duration: const Duration(seconds: 2));
isFirstBuild = false;
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
void rebuildWidget() { void rebuildWidget() {
notifyListeners(); notifyListeners();
} }

View File

@ -1,10 +1,11 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:durt/durt.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
class MyWalletsProvider with ChangeNotifier { class MyWalletsProvider with ChangeNotifier {
List<WalletData> listWallets = []; List<WalletData> listWallets = [];
@ -21,25 +22,13 @@ class MyWalletsProvider with ChangeNotifier {
return configBox.get('currentChest'); return configBox.get('currentChest');
} }
String dewifToMnemonic(context, WalletData _wallet, String _pin) {
String _mnemonic;
try {
String _localDewif = chestBox.get(_wallet.chest)!.dewif!;
_mnemonic = Dewif()
.mnemonicFromDewif(_localDewif, _pin.toUpperCase(), lang: appLang);
} on ChecksumException catch (e) {
log.e(e.cause);
return 'bad';
} catch (e) {
// _homeProvider.playSound('non', 0.6);
log.e('ERROR READING FILE: $e');
return 'bad';
}
return _mnemonic;
}
bool checkIfWalletExist() { bool checkIfWalletExist() {
// configBox.delete('endpoint');
if (!configBox.containsKey('endpoint') || configBox.get('endpoint') == '') {
log.d('No endpoint, configure...');
configBox.put('endpoint', 'ws://127.0.0.1:9944');
}
if (chestBox.isEmpty) { if (chestBox.isEmpty) {
log.i('No wallets detected'); log.i('No wallets detected');
return false; return false;
@ -85,6 +74,7 @@ class MyWalletsProvider with ChangeNotifier {
} }
Future<int> deleteAllWallet(context) async { Future<int> deleteAllWallet(context) async {
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
try { try {
log.w('DELETE ALL WALLETS ?'); log.w('DELETE ALL WALLETS ?');
@ -93,9 +83,7 @@ class MyWalletsProvider with ChangeNotifier {
await walletBox.clear(); await walletBox.clear();
await chestBox.clear(); await chestBox.clear();
await configBox.delete('defaultWallet'); await configBox.delete('defaultWallet');
// await Future.delayed(const Duration(milliseconds: 50)); await _sub.deleteAllAccounts();
// notifyListeners();
await Navigator.of(context).pushNamedAndRemoveUntil( await Navigator.of(context).pushNamedAndRemoveUntil(
'/', '/',
ModalRoute.withName('/'), ModalRoute.withName('/'),
@ -113,23 +101,42 @@ class MyWalletsProvider with ChangeNotifier {
barrierDismissible: true, // user must tap button! barrierDismissible: true, // user must tap button!
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: const Text( backgroundColor: backgroundColor,
'Êtes-vous sûr de vouloir supprimer tous vos trousseaux ?'), content: const Text(
content: const SingleChildScrollView(child: Text('')), 'Êtes-vous sûr de vouloir oublier tous vos coffres ?',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
),
actions: <Widget>[ actions: <Widget>[
TextButton( Row(
child: const Text("Non"), mainAxisAlignment: MainAxisAlignment.center,
onPressed: () { children: [
Navigator.pop(context, false); TextButton(
}, key: const Key('confirmDeletingAllWallets'),
), child: const Text(
TextButton( "Oui",
key: const Key('confirmDeletingAllWallets'), style: TextStyle(
child: const Text("Oui"), fontSize: 20,
onPressed: () { color: Color(0xffD80000),
Navigator.pop(context, true); ),
}, ),
), onPressed: () {
Navigator.pop(context, true);
},
),
const SizedBox(width: 20),
TextButton(
child: const Text(
"Non",
style: TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.pop(context, false);
},
),
const SizedBox(height: 120)
],
)
], ],
); );
}, },
@ -143,15 +150,27 @@ class MyWalletsProvider with ChangeNotifier {
List<WalletData> _walletConfig = readAllWallets(_chest); List<WalletData> _walletConfig = readAllWallets(_chest);
if (_walletConfig.isEmpty) { if (_walletConfig.isEmpty) {
_newDerivationNbr = 3; _newDerivationNbr = 2;
_newWalletNbr = 0; _newWalletNbr = 0;
} else { } else {
_newDerivationNbr = _walletConfig.last.derivation! + 3; _newDerivationNbr = _walletConfig.last.derivation! + 2;
_newWalletNbr = _walletConfig.last.number! + 1; _newWalletNbr = _walletConfig.last.number! + 1;
} }
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final int? _currentChestNumber = myWalletProvider.getCurrentChest();
final ChestData _currentChest = chestBox.get(_currentChestNumber)!;
final address = await _sub.derive(
context, _currentChest.address!, _newDerivationNbr, pinCode);
WalletData newWallet = WalletData( WalletData newWallet = WalletData(
chest: _chest, chest: _chest,
address: address,
number: _newWalletNbr, number: _newWalletNbr,
name: _name, name: _name,
derivation: _newDerivationNbr, derivation: _newDerivationNbr,

View File

@ -0,0 +1,371 @@
// ignore_for_file: avoid_print
import 'package:crypto/crypto.dart';
import 'package:fast_base58/fast_base58.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:polkawallet_sdk/api/apiKeyring.dart';
import 'package:polkawallet_sdk/api/types/networkParams.dart';
import 'package:polkawallet_sdk/api/types/txInfoData.dart';
import 'package:polkawallet_sdk/polkawallet_sdk.dart';
import 'package:polkawallet_sdk/storage/keyring.dart';
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
import 'package:truncate/truncate.dart';
class SubstrateSdk with ChangeNotifier {
final int ss58 = 42;
final WalletSDK sdk = WalletSDK();
final Keyring keyring = Keyring();
String generatedMnemonic = '';
bool sdkReady = false;
bool sdkLoading = false;
bool nodeConnected = false;
bool importIsLoading = false;
int blocNumber = 0;
bool isLoadingEndpoint = false;
TextEditingController jsonKeystore = TextEditingController();
TextEditingController keystorePassword = TextEditingController();
Future<void> initApi() async {
sdkLoading = true;
await keyring.init([ss58]);
keyring.setSS58(ss58);
await sdk.init(keyring);
sdkReady = true;
sdkLoading = false;
notifyListeners();
}
Future<void> connectNode(BuildContext ctx) async {
List<NetworkParams> node = [];
final n = NetworkParams();
n.name = currencyName;
n.endpoint = configBox.get('endpoint');
n.ss58 = ss58;
node.add(n);
if (sdk.api.connectedNode?.endpoint != null) {
await sdk.api.setting.unsubscribeBestNumber();
}
isLoadingEndpoint = true;
notifyListeners();
final res = await sdk.api.connectNode(keyring, node).timeout(
const Duration(seconds: 7),
onTimeout: () => null,
);
isLoadingEndpoint = false;
notifyListeners();
if (res != null) {
nodeConnected = true;
notifyListeners();
snackNode(ctx, true);
} else {
nodeConnected = false;
notifyListeners();
snackNode(ctx, false);
}
// Subscribe bloc number
if (nodeConnected) {
sdk.api.setting.subscribeBestNumber((res) {
blocNumber = int.parse(res.toString());
notifyListeners();
});
}
log.d(sdk.api.connectedNode?.endpoint);
}
Future<String> importAccount(
{String mnemonic = '',
bool fromMnemonic = false,
String derivePath = '',
String password = ''}) async {
// toy exercise immense month enter answer table prefer speed cycle gold phone
final clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
if (mnemonic != '') {
fromMnemonic = true;
generatedMnemonic = mnemonic;
} else if (clipboardData!.text!.split(' ').length == 12) {
fromMnemonic = true;
generatedMnemonic = clipboardData.text!;
}
if (password == '') {
password = keystorePassword.text;
}
final KeyType keytype;
final String keyToImport;
if (fromMnemonic) {
keytype = KeyType.mnemonic;
keyToImport = generatedMnemonic;
} else {
keytype = KeyType.keystore;
keyToImport = jsonKeystore.text.replaceAll("'", "\\'");
}
importIsLoading = true;
notifyListeners();
if (clipboardData?.text != null) jsonKeystore.text = clipboardData!.text!;
var json = await sdk.api.keyring
.importAccount(keyring,
keyType: keytype,
key: keyToImport,
name: derivePath,
password: password,
derivePath: derivePath,
cryptoType: CryptoType.sr25519)
.catchError((e) {
importIsLoading = false;
notifyListeners();
});
if (json == null) return '';
print(json);
try {
await sdk.api.keyring.addAccount(
keyring,
keyType: keytype,
acc: json,
password: password,
);
// Clipboard.setData(ClipboardData(text: jsonEncode(acc.toJson())));
} catch (e) {
print(e);
importIsLoading = false;
notifyListeners();
}
importIsLoading = false;
await Future.delayed(const Duration(milliseconds: 20));
notifyListeners();
final bakedAddress = keyring.allAccounts.last.address;
return bakedAddress!;
}
void reload() {
notifyListeners();
}
Future<List<AddressInfo>> getKeyStoreAddress() async {
List<AddressInfo> result = [];
// sdk.api.account.unsubscribeBalance();
for (var element in keyring.allAccounts) {
// Clipboard.setData(ClipboardData(text: jsonEncode(element)));
final account = AddressInfo(address: element.address);
// await sdk.api.account.subscribeBalance(element.address, (p0) {
// account.balance = int.parse(p0.freeBalance) / 100;
// });
// sdk.api.setting.unsubscribeBestNumber();
account.balance = await getBalance(element.address!);
result.add(account);
}
return result;
}
Future<double> getBalance(String address, {bool isUd = false}) async {
double balance = 0.0;
if (nodeConnected) {
final brutBalance = await sdk.api.account.queryBalance(address);
balance = int.parse(brutBalance!.freeBalance) / 100;
}
return balance;
}
KeyPairData getKeypair(String address) {
return keyring.keyPairs.firstWhere((kp) => kp.address == address,
orElse: (() => KeyPairData()));
}
Future<bool> checkPassword(String address, String pass) async {
final account = getKeypair(address);
return await sdk.api.keyring.checkPassword(account, pass);
}
int getDerivationNumber(String address) {
final account = getKeypair(address);
final deriveNbr = account.name!.split('//')[1];
return int.parse(deriveNbr);
}
Future<KeyPairData?> changePassword(
String address, String passOld, String? passNew) async {
final account = getKeypair(address);
keyring.setCurrent(account);
return await sdk.api.keyring.changePassword(keyring, passOld, passNew);
}
Future<void> deleteAllAccounts() async {
for (var account in keyring.allAccounts) {
await sdk.api.keyring.deleteAccount(keyring, account);
}
}
Future<String> generateMnemonic({String lang = appLang}) async {
final gen = await sdk.api.keyring.generateMnemonic(ss58);
generatedMnemonic = gen.mnemonic!;
// final res = await importAccount(fromMnemonic: true);
// await Clipboard.setData(ClipboardData(text: generatedMnemonic));
return gen.mnemonic!;
}
// Future<bool> pay(BuildContext context, String address, double amount,
// String password) async {
// final sender = TxSenderData(
// keyring.current.address,
// keyring.current.pubKey,
// );
// final txInfo = TxInfoData('balances', 'transfer', sender);
// try {
// final hash = await sdk.api.tx.signAndSend(
// txInfo,
// [address, amount * 100],
// password,
// onStatusChange: (status) {
// print('status: ' + status);
// if (status == 'Ready') {
// snack(context, 'Transaction terminé');
// }
// },
// );
// print(hash.toString());
// return true;
// } catch (err) {
// print(err.toString());
// return false;
// }
// }
String setCurrentWallet(String address) {
try {
final acc = getKeypair(address);
keyring.setCurrent(acc);
return acc.address!;
} catch (e) {
return (e.toString());
}
}
KeyPairData getCurrentWallet() {
try {
final acc = keyring.current;
return acc;
} catch (e) {
return KeyPairData();
}
}
Future<String> pay(BuildContext context,
{required String fromAddress,
required String destAddress,
required double amount,
required String password}) async {
setCurrentWallet(fromAddress);
final sender = TxSenderData(
keyring.current.address,
keyring.current.pubKey,
);
final txInfo = TxInfoData('balances', 'transfer', sender);
try {
final hash = await sdk.api.tx.signAndSend(
txInfo,
[destAddress, amount * 100],
password,
onStatusChange: (status) {
print('status: ' + status);
if (status == 'Ready') {
snack(context, 'Transaction terminé');
}
},
);
print(hash.toString());
return 'confirmed';
} catch (e) {
return e.toString();
}
}
Future<String> derive(
BuildContext context, String address, int number, String password) async {
final keypair = getKeypair(address);
final seedMap =
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
print(seedMap);
if (seedMap?['type'] != 'mnemonic') return '';
final List seedList = seedMap!['seed'].split('//');
generatedMnemonic = seedList[0];
int sourceDerivation = -1; // To get derivation number of this account
if (seedList.length > 1) {
sourceDerivation = int.parse(seedList[1]);
}
print(generatedMnemonic);
print(sourceDerivation);
return await importAccount(fromMnemonic: true, derivePath: '//$number');
}
Future<bool> isMnemonicValid(String mnemonic) async {
// Needed for bad encoding of UTF-8
mnemonic = mnemonic.replaceAll('é', '');
mnemonic = mnemonic.replaceAll('è', '');
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
}
}
void snack(BuildContext context, String message, {int duration = 2}) {
final snackBar =
SnackBar(content: Text(message), duration: Duration(seconds: duration));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
class AddressInfo {
final String? address;
double balance;
AddressInfo({@required this.address, this.balance = 0});
}
void snackNode(BuildContext context, bool isConnected) {
String _message;
if (!isConnected) {
_message =
"Aucun noeud Duniter disponible, veuillez réessayer ultérieurement";
} else {
_message =
"Vous êtes connecté au noeud\n${configBox.get('endpoint').split('//')[1]}";
}
final snackBar = SnackBar(
padding: const EdgeInsets.all(20),
content: Text(_message, style: const TextStyle(fontSize: 16)),
duration: const Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
String getShortPubkey(String pubkey) {
List<int> pubkeyByte = Base58Decode(pubkey);
Digest pubkeyS256 = sha256.convert(sha256.convert(pubkeyByte).bytes);
String pubkeyCheksum = Base58Encode(pubkeyS256.bytes);
String pubkeyChecksumShort =
truncate(pubkeyCheksum, 3, omission: "", position: TruncatePosition.end);
String pubkeyShort = truncate(pubkey, 5,
omission: String.fromCharCode(0x2026),
position: TruncatePosition.end) +
truncate(pubkey, 4, omission: "", position: TruncatePosition.start) +
':$pubkeyChecksumShort';
return pubkeyShort;
}

View File

@ -1,139 +1,41 @@
import 'dart:io'; import 'dart:io';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:durt/durt.dart';
import 'package:fast_base58/fast_base58.dart'; import 'package:fast_base58/fast_base58.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import 'package:truncate/truncate.dart'; import 'package:truncate/truncate.dart';
class WalletOptionsProvider with ChangeNotifier { class WalletOptionsProvider with ChangeNotifier {
TextEditingController pubkey = TextEditingController(); TextEditingController address = TextEditingController();
final TextEditingController _newWalletName = TextEditingController(); final TextEditingController _newWalletName = TextEditingController();
bool isWalletUnlock = false; bool isWalletUnlock = false;
bool ischangedPin = false; bool ischangedPin = false;
TextEditingController newPin = TextEditingController(); TextEditingController newPin = TextEditingController();
bool isEditing = false; bool isEditing = false;
bool isBalanceBlur = true; bool isBalanceBlur = false;
FocusNode walletNameFocus = FocusNode(); FocusNode walletNameFocus = FocusNode();
TextEditingController nameController = TextEditingController(); TextEditingController nameController = TextEditingController();
late bool isDefaultWallet; late bool isDefaultWallet;
Future<NewWallet>? get badWallet => null; Future<NewWallet>? get badWallet => null;
String _getPubkeyFromDewif(
String? _dewif, _pin, int _pinLenght, int? derivation) {
RegExp regExp = RegExp(
r'^[A-Z0-9]+$',
caseSensitive: false,
multiLine: false,
);
if (regExp.hasMatch(_pin) == true && _pin.length == _pinLenght) {
} else {
return 'false';
}
if (derivation != -1) {
try {
final _wallet = HdWallet.fromDewif(_dewif!, _pin, lang: appLang);
pubkey.text = _wallet.getPubkey(derivation!);
log.d(pubkey.text);
notifyListeners();
return pubkey.text;
} catch (e) {
log.w('Bad PIN code !\n' + e.toString());
notifyListeners();
return 'false';
}
} else {
try {
pubkey.text = CesiumWallet.fromDewif(_dewif!, _pin).pubkey;
notifyListeners();
return pubkey.text;
} catch (e) {
log.w('Bad PIN code !\n' + e.toString());
notifyListeners();
return 'false';
}
}
}
String? readLocalWallet(
context, WalletData _wallet, String _pin, int _pinLenght,
{String? mnemonic}) {
isWalletUnlock = false;
final String _localPubkey;
try {
String? _localDewif = chestBox.get(_wallet.chest)!.dewif;
if (mnemonic == null) {
_localPubkey = _getPubkeyFromDewif(
_localDewif, _pin.toUpperCase(), _pinLenght, _wallet.derivation);
} else {
final _hdwallet = HdWallet.fromMnemonic(mnemonic);
_localPubkey = _hdwallet.getPubkey(_wallet.derivation!);
}
if (_localPubkey != 'false') {
pubkey.text = _localPubkey;
isWalletUnlock = true;
log.d(pubkey.text);
return _localDewif;
} else {
throw 'Bad pubkey';
}
} on ChecksumException catch (e) {
log.e(e.cause);
return 'bad';
} catch (e) {
// _homeProvider.playSound('non', 0.6);
log.e('ERROR READING FILE: $e');
pubkey.clear();
return 'bad';
}
}
int getPinLenght(_walletNbr) { int getPinLenght(_walletNbr) {
// TODOo: Get real Dewif lenght
// String _localDewif;
// if (_walletNbr is int || _walletNbr == null) {
// _localDewif = chestBox.get(configBox.get('currentChest')).dewif;
// } else {
// _localDewif = _walletNbr;
// }
// final int _pinLenght = DubpRust.getDewifSecretCodeLen(
// dewif: _localDewif, secretCodeType: SecretCodeType.letters);
return pinLength; return pinLength;
} }
Future<double> getBalance(String pubkey, {bool isUd = false}) async { void _renameWallet(List<int?> _walletID, String _newName,
final node = Gva(node: endPointGVA);
return await node.balance(pubkey, ud: isUd);
}
void _renameWallet(List<int?> _walletID, _newName,
{required bool isCesium}) async { {required bool isCesium}) async {
if (isCesium) { MyWalletsProvider myWalletClass = MyWalletsProvider();
ChestData _chestTarget = chestBox.get(_walletID[0])!;
_chestTarget.name = _newName;
await chestBox.put(_chestTarget.key, _chestTarget);
} else {
MyWalletsProvider myWalletClass = MyWalletsProvider();
WalletData _walletTarget = myWalletClass.getWalletData(_walletID)!; WalletData _walletTarget = myWalletClass.getWalletData(_walletID)!;
_walletTarget.name = _newName; _walletTarget.name = _newName;
await walletBox.put(_walletTarget.key, _walletTarget); await walletBox.put(_walletTarget.key, _walletTarget);
}
_newWalletName.text = ''; _newWalletName.text = '';
} }
@ -161,12 +63,13 @@ class WalletOptionsProvider with ChangeNotifier {
final bool? _answer = await (_confirmDeletingWallet(context, wallet.name)); final bool? _answer = await (_confirmDeletingWallet(context, wallet.name));
if (_answer!) { if (_answer!) {
walletBox.delete(wallet.key); await walletBox.delete(wallet.key);
Navigator.popUntil( // Navigator.popUntil(
context, // context,
ModalRoute.withName('/mywallets'), // ModalRoute.withName('/mywallets'),
); // );
Navigator.pop(context);
} }
return 0; return 0;
} }
@ -205,14 +108,6 @@ class WalletOptionsProvider with ChangeNotifier {
); );
} }
snackCopyKey(context) {
const snackBar = SnackBar(
content:
Text("Cette clé publique a été copié dans votre presse-papier."),
duration: Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
String getShortPubkey(String pubkey) { String getShortPubkey(String pubkey) {
List<int> pubkeyByte = Base58Decode(pubkey); List<int> pubkeyByte = Base58Decode(pubkey);
Digest pubkeyS256 = sha256.convert(sha256.convert(pubkeyByte).bytes); Digest pubkeyS256 = sha256.convert(sha256.convert(pubkeyByte).bytes);
@ -242,14 +137,59 @@ class WalletOptionsProvider with ChangeNotifier {
if (pickedFile != null) { if (pickedFile != null) {
_image = File(pickedFile.path); _image = File(pickedFile.path);
////TODO: Store image on disk, store path in walletBox.imagePath
log.i(pickedFile.path); log.i(pickedFile.path);
return _image; return _image;
} else { } else {
log.w('No image selected.'); log.w('No image selected.');
return null;
} }
} }
void reloadBuild() { void reloadBuild() {
notifyListeners(); notifyListeners();
} }
String? getAddress(int chest, int derivation) {
String? _address;
walletBox.toMap().forEach((key, value) {
if (value.chest == chest && value.derivation == derivation) {
_address = value.address!;
return;
}
});
address.text = _address ?? '';
return _address;
}
}
Widget balance(BuildContext context, String address, double size) {
String balanceCache = '';
return Column(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, _sdk, _) {
return FutureBuilder(
future: _sdk.getBalance(address),
builder: (BuildContext context, AsyncSnapshot<num?> _balance) {
if (_balance.connectionState != ConnectionState.done ||
_balance.hasError) {
return Text(balanceCache,
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
));
}
balanceCache = "${_balance.data.toString()} $currencyName";
return Text(
balanceCache,
style: TextStyle(
fontSize: isTall ? size : 18,
),
);
});
}),
]);
} }

View File

@ -1,14 +1,10 @@
import 'dart:io'; import 'dart:io';
import 'package:durt/durt.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:qrscan/qrscan.dart' as scanner; import 'package:qrscan/qrscan.dart' as scanner;
import 'dart:math'; import 'dart:math';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@ -59,34 +55,24 @@ class WalletsProfilesProvider with ChangeNotifier {
return barcode; return barcode;
} }
Future<String> pay(BuildContext context, {int? derivation}) async { // Future<String> pay(BuildContext context, {int? derivation}) async {
MyWalletsProvider _myWalletProvider = // MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); // Provider.of<MyWalletsProvider>(context, listen: false);
int? currentChest = configBox.get('currentChest'); // int? currentChest = configBox.get('currentChest');
String result; // String result;
if (chestBox.get(currentChest)!.isCesium!) { // derivation ??=
result = await Gva(node: endPointGVA).pay( // _myWalletProvider.getDefaultWallet(currentChest)!.derivation!;
recipient: pubkey!, // result = await Gva(node: endPointGVA).pay(
amount: double.parse(payAmount.text), // recipient: pubkey!,
cesiumSeed: _myWalletProvider.cesiumSeed, // amount: double.parse(payAmount.text),
comment: payComment.text, // mnemonic: _myWalletProvider.mnemonic,
derivation: -1, // comment: payComment.text,
lang: appLang); // derivation: derivation,
} else { // lang: appLang);
derivation ??=
_myWalletProvider.getDefaultWallet(currentChest)!.derivation!;
result = await Gva(node: endPointGVA).pay(
recipient: pubkey!,
amount: double.parse(payAmount.text),
mnemonic: _myWalletProvider.mnemonic,
comment: payComment.text,
derivation: derivation,
lang: appLang);
}
return result; // return result;
} // }
bool isPubkey(pubkey) { bool isPubkey(pubkey) {
final RegExp regExp = RegExp( final RegExp regExp = RegExp(
@ -97,7 +83,7 @@ class WalletsProfilesProvider with ChangeNotifier {
if (regExp.hasMatch(pubkey) == true && if (regExp.hasMatch(pubkey) == true &&
pubkey.length > 42 && pubkey.length > 42 &&
pubkey.length < 45) { pubkey.length < 50) {
log.d("C'est une pubkey !"); log.d("C'est une pubkey !");
this.pubkey = pubkey; this.pubkey = pubkey;
@ -253,25 +239,6 @@ class WalletsProfilesProvider with ChangeNotifier {
return num.parse(result); return num.parse(result);
} }
snackCopyKey(context) {
const snackBar = SnackBar(
padding: EdgeInsets.all(20),
content:
Text("Cette clé publique a été copié dans votre presse-papier."),
duration: Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void switchProfileView() {
isHistoryScreen = !isHistoryScreen;
if (isHistoryScreen) {
historySwitchButtun = "Payer";
} else {
historySwitchButtun = "Voir l'historique";
}
notifyListeners();
}
String generateIdenticon(String _pubkey) { String generateIdenticon(String _pubkey) {
return Jdenticon.toSvg(_pubkey); return Jdenticon.toSvg(_pubkey);
} }
@ -299,3 +266,12 @@ class WalletsProfilesProvider with ChangeNotifier {
return balance; return balance;
} }
} }
snackCopyKey(context) {
const snackBar = SnackBar(
padding: EdgeInsets.all(20),
content: Text("Cette clé publique a été copié dans votre presse-papier.",
style: TextStyle(fontSize: 16)),
duration: Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

View File

@ -1,5 +1,5 @@
import 'package:dots_indicator/dots_indicator.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:bubble/bubble.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
class CommonElements { class CommonElements {
@ -8,95 +8,104 @@ class CommonElements {
return const Text('Coucou'); return const Text('Coucou');
} }
Widget bubbleSpeak(String text, Widget buildImage(String assetName,
{double? long, Key? textKey, bool isMaxWidth = true}) { [double boxHeight = 440, double imageWidth = 350]) {
return Container(
padding: const EdgeInsets.all(0),
width: 440,
height: boxHeight,
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xffd2d4cf),
Color(0xffeaeae7),
],
),
border: Border.all(color: Colors.grey[900]!)),
child: Image.asset('assets/onBoarding/$assetName', width: imageWidth));
}
Widget buildText(List<TextSpan> text, [double size = 20]) {
return Container(
padding: const EdgeInsets.all(12),
width: 440,
decoration: BoxDecoration(
color: Colors.white, border: Border.all(color: Colors.grey[900]!)),
child: RichText(
textAlign: TextAlign.justify,
text: TextSpan(
style: TextStyle(
fontSize: size, color: Colors.black, letterSpacing: 0.3),
children: text,
),
),
);
}
Widget nextButton(
BuildContext context, String text, nextScreen, bool isFast) {
return SizedBox( return SizedBox(
width: isMaxWidth ? double.infinity : 300, width: 410,
child: Bubble( height: 70,
padding: long == null child: ElevatedButton(
? const BubbleEdges.all(18) style: ElevatedButton.styleFrom(
: BubbleEdges.symmetric(horizontal: long, vertical: 30), elevation: 4,
elevation: 5, primary: orangeC, // background
color: Colors.white, onPrimary: Colors.white, // foreground
margin: const BubbleEdges.fromLTRB(10, 0, 20, 10), ),
// nip: BubbleNip.leftTop, onPressed: () {
Navigator.push(
context, FaderTransition(page: nextScreen, isFast: isFast));
},
child: Text( child: Text(
text, text,
key: textKey, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
style: const TextStyle(
color: Colors.black, fontSize: 18, fontWeight: FontWeight.w400),
), ),
), ),
); );
} }
Widget bubbleSpeakRich(List<TextSpan> text, {Key? textKey}) { Widget buildProgressBar(double pagePosition) {
return SizedBox( return DotsIndicator(
width: double.infinity, dotsCount: 10,
child: Bubble( position: pagePosition,
padding: const BubbleEdges.all(18), decorator: DotsDecorator(
elevation: 5, spacing: const EdgeInsets.symmetric(horizontal: 10),
color: Colors.white, color: Colors.grey[300]!, // Inactive color
margin: const BubbleEdges.fromLTRB(10, 0, 20, 10), activeColor: orangeC,
// nip: BubbleNip.leftTop,
child: RichText(
key: textKey,
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: text,
),
),
), ),
); );
} }
Widget onboardingProgressBar( Widget infoIntro(
BuildContext context, String screenTitle, int progress) { BuildContext context,
return Stack(children: [ List<TextSpan> text,
Container(height: 100), String assetName,
Positioned( String buttonText,
top: 0, left: 0, right: 0, child: GeckoSpeechAppBar(screenTitle)), nextScreen,
Positioned( double pagePosition, {
top: 0, bool isFast = false,
left: 0, double boxHeight = 440,
child: GestureDetector( double imageWidth = 350,
onTap: () { double textSize = 20,
Navigator.popUntil( }) {
context, return Column(children: <Widget>[
ModalRoute.withName('/'), SizedBox(height: isTall ? 40 : 20),
); buildProgressBar(pagePosition),
}, SizedBox(height: isTall ? 40 : 20),
child: Image.asset(
'assets/onBoarding/gecko_bar.png', buildText(text, textSize),
), buildImage(assetName, boxHeight, imageWidth),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: nextButton(context, buttonText, nextScreen, false),
), ),
), ),
if (progress != 0) // const SizedBox(height: 40),
Positioned( SizedBox(height: isTall ? 40 : 10),
top: 75,
left: 90,
child: Image.asset(
'assets/onBoarding/progress_bar/total.png',
),
),
if (progress != 0)
Positioned(
top: 75,
left: 90,
child: Image.asset(
'assets/onBoarding/progress_bar/$progress.png',
),
),
if (progress != 0)
Positioned(
top: 70,
right: 90,
child: Text(progress == 12 ? '11/11' : '$progress/11',
style: const TextStyle(fontSize: 12, color: Colors.black)),
),
]); ]);
} }

View File

@ -33,7 +33,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
CesiumPlusProvider _cesiumPlusProvider = CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false); Provider.of<CesiumPlusProvider>(context, listen: false);
log.i('Build pubkey : ' + pubkey!); log.i('Build pubkey : ' + pubkey!);
WidgetsBinding.instance!.addPostFrameCallback((_) {}); // WidgetsBinding.instance.addPostFrameCallback((_) {});
_historyProvider.balance = _historyProvider.transBC = null; _historyProvider.balance = _historyProvider.transBC = null;
@ -346,7 +346,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
], ],
), ),
), ),
trailing: Text("${repository[4]} Ğ1", trailing: Text("${repository[4]} $currencyName",
style: const TextStyle( style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500), fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.justify), textAlign: TextAlign.justify),
@ -403,7 +403,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
key: const Key('copyPubkey'), key: const Key('copyPubkey'),
onTap: () { onTap: () {
Clipboard.setData(ClipboardData(text: pubkey)); Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context); snackCopyKey(context);
}, },
child: Text( child: Text(
_historyProvider.getShortPubkey(pubkey!), _historyProvider.getShortPubkey(pubkey!),
@ -466,7 +466,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
return const Text('...'); return const Text('...');
} }
return Text( return Text(
"${_balance.data.toString()} Ğ1", "${_balance.data.toString()} $currencyName",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 22, fontWeight: FontWeight.w500), fontSize: 22, fontWeight: FontWeight.w500),

View File

@ -1,9 +1,10 @@
import 'package:bubble/bubble.dart'; import 'package:bubble/bubble.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
@ -12,6 +13,7 @@ import 'package:gecko/screens/onBoarding/1.dart';
import 'package:gecko/screens/search.dart'; import 'package:gecko/screens/search.dart';
import 'package:gecko/screens/settings.dart'; import 'package:gecko/screens/settings.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/screens/substrate_sandbox.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
@ -24,7 +26,7 @@ class HomeScreen extends StatelessWidget {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context); Provider.of<ChestProvider>(context);
HomeProvider homeClass = HomeProvider(); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
@ -65,6 +67,20 @@ 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( // ListTile(
// title: const Text('A propos'), // title: const Text('A propos'),
// onTap: () { // onTap: () {
@ -82,8 +98,11 @@ class HomeScreen extends StatelessWidget {
body: Builder( body: Builder(
builder: (ctx) => StatefulWrapper( builder: (ctx) => StatefulWrapper(
onInit: () { onInit: () {
WidgetsBinding.instance!.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) async {
if (isWalletsExists) homeClass.snackNode(ctx); if (!_sub.sdkReady && !_sub.sdkLoading) await _sub.initApi();
if (_sub.sdkReady && !_sub.nodeConnected) {
await _sub.connectNode(ctx); //kopa
}
}); });
}, },
child: isWalletsExists ? geckHome(context) : welcomeHome(context) child: isWalletsExists ? geckHome(context) : welcomeHome(context)
@ -176,9 +195,10 @@ Widget geckHome(context) {
), ),
], ],
), ),
) ),
]), ]),
), ),
const SizedBox(height: 15),
Expanded( Expanded(
flex: 1, flex: 1,
child: Container( child: Container(
@ -382,31 +402,30 @@ Widget welcomeHome(context) {
]), ]),
Padding( Padding(
padding: EdgeInsets.only(top: 1 * ratio), padding: EdgeInsets.only(top: 1 * ratio),
child: Row( child:
mainAxisAlignment: MainAxisAlignment.center, Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
children: const <Widget>[ Text(
Text( "Lapplication de paiement $currencyName\nplus rapide quun reptile du Vietnam",
"Lapplication de paiement Ğ1\nplus rapide quun reptile du Vietnam", textAlign: TextAlign.center,
textAlign: TextAlign.center, style: const TextStyle(
style: TextStyle( color: Colors.white,
color: Colors.white, fontSize: 24,
fontSize: 24, fontWeight: FontWeight.w700,
fontWeight: FontWeight.w700, shadows: <Shadow>[
shadows: <Shadow>[ Shadow(
Shadow( offset: Offset(0, 0),
offset: Offset(0, 0), blurRadius: 20,
blurRadius: 20, color: Colors.black,
color: Colors.black,
),
Shadow(
offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
],
), ),
) Shadow(
]), offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
],
),
)
]),
), ),
Expanded( Expanded(
flex: 1, flex: 1,
@ -464,7 +483,7 @@ Widget welcomeHome(context) {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) { builder: (context) {
return OnboardingStepOne(); return const OnboardingStepOne();
}, },
), ),
); );
@ -512,28 +531,6 @@ Widget welcomeHome(context) {
); );
} }
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({Key? key, required this.onInit, required this.child})
: super(key: key);
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
widget.onInit();
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
Widget bubbleSpeak(String text, {double? long, Key? textKey}) { Widget bubbleSpeak(String text, {double? long, Key? textKey}) {
return Bubble( return Bubble(
padding: long == null padding: long == null

View File

@ -1,410 +0,0 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/myWallets/change_pin.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart';
bool _isNewNameValid = false;
class CesiumWalletOptions extends StatelessWidget {
const CesiumWalletOptions(
{Key? key, Key? keyMyWallets, required this.cesiumWallet})
: super(key: key);
final ChestData cesiumWallet;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
ChestProvider _chestProvider =
Provider.of<ChestProvider>(context, listen: false);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
if (_isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name!;
} else {
cesiumWallet.name = _walletOptions.nameController.text;
}
return WillPopScope(
onWillPop: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
}),
title: SizedBox(
height: 22,
child: Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Text(_walletOptions.nameController.text);
}),
),
),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Spacer(flex: 1),
InkWell(
onTap: () async {
File newAvatar =
await (_walletOptions.changeAvatar());
cesiumWallet.imageFile = newAvatar;
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile!, width: 110),
),
InkWell(
onTap: () async {
File newAvatar =
await (_walletOptions.changeAvatar());
cesiumWallet.imageFile = newAvatar;
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
height: 40,
),
const SizedBox(height: 80)
])),
const Spacer(flex: 1),
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
minLines: 1,
maxLines: 3,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
)),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data!['balance'] == null) {
wBalanceUD = '0.0';
} else {
int wBalanceG1 =
result.data!['balance']['amount'];
int currentUD =
result.data!['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: _walletOptions.isBalanceBlur
? 6
: 0.001,
sigmaY: _walletOptions.isBalanceBlur
? 5
: 0.001),
child: Text(wBalanceUD,
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black)),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
height: 35,
),
),
]),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = _walletOptions.editWalletName(
[cesiumWallet.key, 0],
isCesium: cesiumWallet.isCesium);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const SizedBox(
height: 60,
)
]),
const Spacer(flex: 3),
]),
);
}),
SizedBox(height: 4 * ratio),
QrImageWidget(
data: _walletOptions.pubkey.text,
version: QrVersions.auto,
size: isTall ? 300 : 270,
),
SizedBox(height: 15 * ratio),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
height: 45,
),
const SizedBox(width: 20),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
height: 25,
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15, color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.nPage = 1;
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return HistoryScreen(
pubkey: _walletOptions.pubkey.text);
}),
);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
height: 45,
),
const SizedBox(width: 22),
const Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('changePin'),
onTap: () async {
// await _chestProvider.changePin(context, cesiumWallet);
String? newPin = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ChangePinScreen(
walletName: cesiumWallet.name,
walletProvider: _myWalletProvider,
);
},
),
);
if (newPin != null) _myWalletProvider.pinCode = newPin;
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 31),
Image.asset(
'assets/chests/secret_code.png',
height: 24,
),
const SizedBox(width: 20),
const Text('Changer mon code secret',
style: TextStyle(fontSize: 20, color: Colors.black)),
]),
),
),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('deleteWallet'),
onTap: () async {
await _chestProvider.deleteChest(context, cesiumWallet);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
height: 45,
),
const SizedBox(width: 21),
const Text(
'Supprimer ce coffre',
style: TextStyle(
fontSize: 20,
color: Color(0xffD80000),
),
),
]),
),
),
]),
),
),
),
);
}
}

View File

@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
import 'package:durt/durt.dart'; import 'package:durt/durt.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/change_pin.dart'; import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'dart:io'; import 'dart:io';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
@ -18,15 +20,16 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
final MyWalletsProvider walletProvider; final MyWalletsProvider walletProvider;
Directory? appPath; Directory? appPath;
TextEditingController newPin = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
ChangePinProvider _changePin = Provider.of<ChangePinProvider>(context); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
// _walletOptions.changePin(walletName, oldPin);
// _walletOptions.newPin.text = _tmpPin;
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
_changePin.newPin.text = ''; newPin.text = '';
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -36,7 +39,7 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
leading: IconButton( leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black), icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { onPressed: () {
_changePin.newPin.text = ''; newPin.text = '';
Navigator.of(context).pop(); Navigator.of(context).pop();
}), }),
title: SizedBox( title: SizedBox(
@ -49,7 +52,7 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
child: Column(children: <Widget>[ child: Column(children: <Widget>[
StatefulWrapper( StatefulWrapper(
onInit: () { onInit: () {
_changePin.newPin.text = randomSecretCode(pinLength); newPin.text = randomSecretCode(pinLength);
}, },
child: Container(), child: Container(),
), ),
@ -68,7 +71,7 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
children: <Widget>[ children: <Widget>[
TextField( TextField(
enabled: false, enabled: false,
controller: _changePin.newPin, controller: newPin,
maxLines: 1, maxLines: 1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
decoration: const InputDecoration(), decoration: const InputDecoration(),
@ -80,7 +83,7 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
icon: const Icon(Icons.replay), icon: const Icon(Icons.replay),
color: orangeC, color: orangeC,
onPressed: () async { onPressed: () async {
_changePin.newPin.text = randomSecretCode(pinLength); newPin.text = randomSecretCode(pinLength);
}, },
), ),
], ],
@ -96,12 +99,12 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
onPrimary: Colors.black, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: () async { onPressed: () async {
NewWallet? _newWalletFile = await _changePin.changePin( final _chest = chestBox.get(configBox.get('currentChest'));
walletProvider.pinCode, await _sub.changePassword(
newCustomPin: _changePin.newPin.text); _chest!.address!, walletProvider.pinCode, newPin.text);
_changePin.newPin.text = ''; walletProvider.pinCode = newPin.text;
_changePin.storeNewPinChest(context, _newWalletFile!); newPin.text = '';
walletProvider.pinCode = _changePin.newPin.text; Navigator.pop(context);
}, },
child: const Text( child: const Text(
'Confirmer', 'Confirmer',
@ -116,25 +119,3 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
); );
} }
} }
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({Key? key, required this.onInit, required this.child})
: super(key: key);
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
widget.onInit();
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -24,14 +24,15 @@ class ChestOptions extends StatelessWidget {
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
leading: IconButton( // leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black), // icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { // onPressed: () {
Navigator.popUntil( // // Navigator.popUntil(
context, // // context,
ModalRoute.withName('/mywallets'), // // ModalRoute.withName('/mywallets'),
); // // );
}), // Navigator.pop(context);
// }),
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text(currentChest.name!), child: Text(currentChest.name!),

View File

@ -3,6 +3,7 @@ import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -11,17 +12,20 @@ import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class ChooseWalletScreen extends StatelessWidget { class ChooseWalletScreen extends StatelessWidget {
ChooseWalletScreen({Key? key}) : super(key: key); ChooseWalletScreen({Key? key, required this.chest, required this.pin})
: super(key: key);
final int chest;
final String pin;
int? _derivation; int? _derivation;
List<int?>? _selectedId; List<int?>? _selectedId;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context); // HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
WalletsProfilesProvider _walletsProfilesProvider =
Provider.of<WalletsProfilesProvider>(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
@ -31,7 +35,7 @@ class ChooseWalletScreen extends StatelessWidget {
)), )),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
myWalletsTiles(context), myWalletsTiles(context, chest),
Positioned.fill( Positioned.fill(
bottom: 60, bottom: 60,
child: Align( child: Align(
@ -46,8 +50,15 @@ class ChooseWalletScreen extends StatelessWidget {
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: () async { onPressed: () async {
final resultPay = await _walletsProfilesProvider final acc = _sub.getCurrentWallet();
.pay(context, derivation: _derivation); log.d(
"fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.outputPubkey.text}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $pin");
final resultPay = await _sub.pay(context,
fromAddress: acc.address!,
destAddress: _walletViewProvider.outputPubkey.text,
amount:
double.parse(_walletViewProvider.payAmount.text),
password: pin);
await paymentsResult(context, resultPay); await paymentsResult(context, resultPay);
}, },
child: const Text( child: const Text(
@ -64,17 +75,19 @@ class ChooseWalletScreen extends StatelessWidget {
)); ));
} }
Widget myWalletsTiles(BuildContext context) { Widget myWalletsTiles(BuildContext context, int? currentChest) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest')); _myWalletProvider.getDefaultWallet(currentChest);
_selectedId ??= defaultWallet!.id(); _selectedId ??= defaultWallet!.id();
_derivation ??= defaultWallet!.derivation!; _derivation ??= defaultWallet!.derivation!;
_sub.setCurrentWallet(defaultWallet!.address!);
_myWalletProvider.readAllWallets(configBox.get('currentChest')); _myWalletProvider.readAllWallets(currentChest);
if (!isWalletsExists) { if (!isWalletsExists) {
return const Text(''); return const Text('');
@ -116,6 +129,7 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
_sub.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}, },
child: ClipOvalShadow( child: ClipOvalShadow(
@ -182,6 +196,7 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
_sub.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}, },
) )
@ -195,24 +210,28 @@ class ChooseWalletScreen extends StatelessWidget {
} }
Future<bool?> paymentsResult(context, String resultPay) { Future<bool?> paymentsResult(context, String resultPay) {
if (resultPay != "success") log.e(resultPay); final bool isValid = resultPay == "confirmed";
if (!isValid) log.e(resultPay);
return showDialog<bool>( return showDialog<bool>(
context: context, context: context,
barrierDismissible: true, // user must tap button! barrierDismissible: true, // user must tap button!
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text(resultPay == "success" title: Text(isValid
? 'Paiement effecuté avec succès !' ? 'Paiement effecuté avec succès !'
: "Une erreur s'est produite lors du paiement:\n$resultPay"), : "Une erreur s'est produite lors du paiement:\n$resultPay"),
content: const SingleChildScrollView(child: Text('')), content: const SingleChildScrollView(child: Text('')),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: const Text("OK"), child: const Text("OK"),
onPressed: () { onPressed: () async {
Navigator.popUntil( isValid
context, ? await Navigator.of(context).pushNamedAndRemoveUntil(
ModalRoute.withName('/'), '/',
); ModalRoute.withName('/'),
)
: Navigator.pop(context);
}, },
), ),
], ],

View File

@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -32,6 +33,7 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final int? _currentChest = _myWalletProvider.getCurrentChest(); final int? _currentChest = _myWalletProvider.getCurrentChest();
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
_mnemonicController.text = generatedMnemonic!; _mnemonicController.text = generatedMnemonic!;
return WillPopScope( return WillPopScope(
@ -53,7 +55,7 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
}), }),
title: const SizedBox( title: const SizedBox(
height: 22, height: 22,
child: Text('Enregistrer ce trousseau'), child: Text('Enregistrer ce coffre'),
)), )),
body: Center( body: Center(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
@ -134,9 +136,16 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
.isAskedWordValid && .isAskedWordValid &&
walletName.text != '') walletName.text != '')
? () async { ? () async {
_generateWalletProvider.storeHDWChest( final address = await _sub.importAccount(
generatedWallet!, fromMnemonic: true,
walletName.text, mnemonic: _generateWalletProvider
.generatedMnemonic!,
password:
_generateWalletProvider.pin.text,
derivePath: '//2');
await _generateWalletProvider.storeHDWChest(
address,
'Mon portefeuille courant',
context); context);
_generateWalletProvider.isAskedWordValid = _generateWalletProvider.isAskedWordValid =
false; false;

View File

@ -1,16 +1,13 @@
import 'package:durt/durt.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/myWallets/confirm_wallet_storage.dart'; import 'package:gecko/screens/myWallets/confirm_wallet_storage.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:super_tooltip/super_tooltip.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class GenerateFastChestScreen extends StatelessWidget { class GenerateFastChestScreen extends StatelessWidget {
SuperTooltip? tooltip;
bool hasError = false; bool hasError = false;
String validPin = 'NO PIN'; String validPin = 'NO PIN';
String currentText = ""; String currentText = "";
@ -25,14 +22,11 @@ class GenerateFastChestScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider = GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context, listen: false);
if (_generateWalletProvider.mnemonicController.text == '') { _generateWalletProvider.pin.text = kDebugMode && debugPin
_generateWalletProvider.generateWordList(); ? 'AAAAA'
_generateWalletProvider.mnemonicController.text = : _generateWalletProvider.changePinCode(reload: false);
_generateWalletProvider.generatedMnemonic!;
_generateWalletProvider.pin.text = randomSecretCode(pinLength);
}
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
@ -52,7 +46,7 @@ class GenerateFastChestScreen extends StatelessWidget {
}), }),
title: const SizedBox( title: const SizedBox(
height: 22, height: 22,
child: Text('Générer un trousseau'), child: Text('Générer un coffre'),
)), )),
floatingActionButton: SizedBox( floatingActionButton: SizedBox(
height: 80.0, height: 80.0,
@ -61,9 +55,7 @@ class GenerateFastChestScreen extends StatelessWidget {
child: FloatingActionButton( child: FloatingActionButton(
heroTag: "buttonGenerateWallet", heroTag: "buttonGenerateWallet",
onPressed: () { onPressed: () {
_generateWalletProvider.generateWordList(); _generateWalletProvider.reloadBuild();
_generateWalletProvider.mnemonicController.text =
_generateWalletProvider.generatedMnemonic!;
}, },
child: SizedBox( child: SizedBox(
height: 40.0, height: 40.0,
@ -79,18 +71,23 @@ class GenerateFastChestScreen extends StatelessWidget {
const SizedBox(height: 20), const SizedBox(height: 20),
toolTips(_toolTipSentence, 'Phrase de restauration:', toolTips(_toolTipSentence, 'Phrase de restauration:',
"Notez et gardez cette phrase précieusement sur un papier, elle vous servira à restaurer votre portefeuille sur un autre appareil"), "Notez et gardez cette phrase précieusement sur un papier, elle vous servira à restaurer votre portefeuille sur un autre appareil"),
TextField( Consumer<GenerateWalletsProvider>(builder: (context, _gWP, _) {
enabled: false, return FutureBuilder(
controller: _generateWalletProvider.mnemonicController, future: _gWP.generateWordList(context),
maxLines: 3, builder: (BuildContext context, AsyncSnapshot<List> _data) {
textAlign: TextAlign.center, if (!_data.hasData) {
decoration: const InputDecoration( return const Text('');
contentPadding: EdgeInsets.all(15.0), } else {
), return Text(_gWP.generatedMnemonic!,
style: const TextStyle( maxLines: 3,
fontSize: 22.0, textAlign: TextAlign.center,
color: Colors.black, style: const TextStyle(
fontWeight: FontWeight.w400)), fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.w400));
}
});
}),
const SizedBox(height: 8), const SizedBox(height: 8),
toolTips(_toolTipSecret, 'Code secret:', toolTips(_toolTipSecret, 'Code secret:',
"Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille"), "Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille"),
@ -112,7 +109,7 @@ class GenerateFastChestScreen extends StatelessWidget {
icon: const Icon(Icons.replay), icon: const Icon(Icons.replay),
color: orangeC, color: orangeC,
onPressed: () { onPressed: () {
_generateWalletProvider.changePinCode(reload: true); _generateWalletProvider.changePinCode(reload: false);
}, },
), ),
], ],
@ -128,11 +125,6 @@ class GenerateFastChestScreen extends StatelessWidget {
? () async { ? () async {
_generateWalletProvider.nbrWord = _generateWalletProvider.nbrWord =
_generateWalletProvider.getRandomInt(); _generateWalletProvider.getRandomInt();
_generateWalletProvider.actualWallet = await Dewif()
.generateDewif(
_generateWalletProvider.generatedMnemonic!,
_generateWalletProvider.pin.text,
lang: appLang);
await Navigator.push( await Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
@ -145,20 +137,20 @@ class GenerateFastChestScreen extends StatelessWidget {
); );
} }
: null, : null,
child: const Text('Enregistrer ce trousseau', child: const Text('Enregistrer ce coffre',
style: TextStyle(fontSize: 20))), style: TextStyle(fontSize: 20))),
const SizedBox(height: 20), const SizedBox(height: 20),
GestureDetector( // GestureDetector(
onTap: () { // onTap: () {
Navigator.push( // Navigator.push(
context, // context,
MaterialPageRoute(builder: (context) { // MaterialPageRoute(builder: (context) {
return PrintWallet( // return PrintWallet(
_generateWalletProvider.generatedMnemonic); // _generateWalletProvider.generatedMnemonic);
}), // }),
); // );
}, // },
child: const Icon(Icons.print)) // child: const Icon(Icons.print))
]), ]),
), ),
), ),
@ -201,30 +193,30 @@ class GenerateFastChestScreen extends StatelessWidget {
} }
} }
// ignore: must_be_immutable // // ignore: must_be_immutable
class PrintWallet extends StatelessWidget { // class PrintWallet extends StatelessWidget {
const PrintWallet(this.sentence, {Key? key}) : super(key: key); // const PrintWallet(this.sentence, {Key? key}) : super(key: key);
final String? sentence; // final String? sentence;
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider = // GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); // Provider.of<GenerateWalletsProvider>(context);
return MaterialApp( // return MaterialApp(
home: Scaffold( // home: Scaffold(
appBar: AppBar( // appBar: AppBar(
leading: IconButton( // leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white), // icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () { // onPressed: () {
Navigator.pop(context); // Navigator.pop(context);
}), // }),
toolbarHeight: 60 * ratio, // toolbarHeight: 60 * ratio,
title: const Text('Imprimer ce trousseau')), // title: const Text('Imprimer ce coffre')),
body: PdfPreview( // body: PdfPreview(
build: (format) => _generateWalletProvider.printWallet(sentence), // build: (format) => _generateWalletProvider.printWallet(sentence),
), // ),
), // ),
); // );
} // }
} // }

View File

@ -1,244 +0,0 @@
import 'dart:async';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:flutter/material.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:provider/provider.dart';
class ImportWalletScreen extends StatelessWidget {
const ImportWalletScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GlobalKey _toolTipSecret = GlobalKey();
Timer? _debounce;
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
_generateWalletProvider.pin.text = randomSecretCode(pinLength);
return WillPopScope(
onWillPop: () {
_generateWalletProvider.resetCesiumImportView();
return Future<bool>.value(true);
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_generateWalletProvider.resetCesiumImportView();
Navigator.of(context).pop();
}),
title: const SizedBox(
height: 22,
child: Text('Importer un portefeuille'),
)),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 20),
Consumer<GenerateWalletsProvider>(
builder: (context, walletProvider, _) {
return TextFormField(
autofocus: true,
onChanged: (text) {
if (_debounce?.isActive ?? false) {
_debounce!.cancel();
}
_debounce = Timer(const Duration(milliseconds: 600), () {
walletProvider
.generateCesiumWalletPubkey(
text, walletProvider.cesiumPWD.text)
.then((value) {
walletProvider.canImport = true;
walletProvider.reloadBuild();
});
});
},
keyboardType: TextInputType.text,
controller: walletProvider.cesiumID,
obscureText: !walletProvider
.isCesiumIDVisible, //This will obscure text dynamically
decoration: InputDecoration(
hintText: 'Entrez votre identifiant Cesium',
suffixIcon: IconButton(
icon: Icon(
walletProvider.isCesiumIDVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.black,
),
onPressed: () {
walletProvider.cesiumIDisVisible();
},
),
),
);
}),
const SizedBox(height: 15),
Consumer<GenerateWalletsProvider>(
builder: (context, walletProvider, _) {
return TextFormField(
onChanged: (text) {
if (_debounce?.isActive ?? false) {
_debounce!.cancel();
}
_debounce = Timer(const Duration(milliseconds: 600), () {
walletProvider
.generateCesiumWalletPubkey(
walletProvider.cesiumID.text, text)
.then((value) {
walletProvider.canImport = true;
walletProvider.reloadBuild();
});
});
},
keyboardType: TextInputType.text,
controller: walletProvider.cesiumPWD,
obscureText: !walletProvider
.isCesiumPWDVisible, //This will obscure text dynamically
decoration: InputDecoration(
hintText: 'Entrez votre mot de passe Cesium',
suffixIcon: IconButton(
icon: Icon(
walletProvider.isCesiumPWDVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.black,
),
onPressed: () {
walletProvider.cesiumPWDisVisible();
},
),
),
);
}),
const SizedBox(height: 15),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: _generateWalletProvider.cesiumPubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Consumer<GenerateWalletsProvider>(
builder: (context, walletProvider, _) {
return Text(
_generateWalletProvider.cesiumPubkey.text,
style: const TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'Monospace'),
);
}),
),
const SizedBox(height: 20),
toolTips(_toolTipSecret, 'Code secret:',
"Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille"),
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
enabled: false,
controller: _generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
fontSize: 30.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.replay),
color: orangeC,
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
),
],
),
const SizedBox(height: 30),
Consumer<GenerateWalletsProvider>(
builder: (context, walletProvider, _) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: walletProvider.canImport
? () async {
final chestKey =
await walletProvider.importCesiumWallet();
_myWalletProvider.rebuildWidget();
await Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: WalletData(chest: chestKey),
action: "mywallets",
);
}),
ModalRoute.withName('/'),
);
_generateWalletProvider.resetCesiumImportView();
}
: null,
child: const Text(
'Importer ce portefeuille Cesium',
style: TextStyle(fontSize: 20),
),
);
}),
]),
),
),
),
);
}
Widget toolTips(_key, _text, _message) {
return GestureDetector(
onTap: () {
final dynamic _toolTip = _key.currentState;
_toolTip.ensureTooltipVisible();
},
child: Tooltip(
padding: const EdgeInsets.all(10),
key: _key,
showDuration: const Duration(seconds: 5),
message: _message,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(width: 20),
Column(children: <Widget>[
SizedBox(
width: 30,
height: 25,
child:
Icon(Icons.info_outline, size: 22, color: orangeC)),
const SizedBox(height: 1)
]),
Text(
_text,
style: TextStyle(
fontSize: 15.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
const SizedBox(width: 45)
])));
}
}

View File

@ -3,8 +3,9 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/11.dart'; import 'package:gecko/screens/onBoarding/9.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart'; // import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart'; // import 'package:provider/provider.dart';
@ -15,14 +16,19 @@ class RestoreChest extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider = GenerateWalletsProvider genW =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
generateWalletProvider.actualWallet = null; genW.actualWallet = null;
if (genW.isSentenceComplete(context)) {
genW.generatedMnemonic =
'${genW.cellController0.text} ${genW.cellController1.text} ${genW.cellController2.text} ${genW.cellController3.text} ${genW.cellController4.text} ${genW.cellController5.text} ${genW.cellController6.text} ${genW.cellController7.text} ${genW.cellController8.text} ${genW.cellController9.text} ${genW.cellController10.text} ${genW.cellController11.text}';
}
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
generateWalletProvider.resetImportView(); genW.resetImportView();
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -31,7 +37,7 @@ class RestoreChest extends StatelessWidget {
leading: IconButton( leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black), icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { onPressed: () {
generateWalletProvider.resetImportView(); genW.resetImportView();
Navigator.of(context).pop(); Navigator.of(context).pop();
}), }),
title: const SizedBox( title: const SizedBox(
@ -48,32 +54,32 @@ class RestoreChest extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
arrayCell(context, generateWalletProvider.cellController0), arrayCell(context, genW.cellController0),
arrayCell(context, generateWalletProvider.cellController1), arrayCell(context, genW.cellController1),
arrayCell(context, generateWalletProvider.cellController2), arrayCell(context, genW.cellController2),
arrayCell(context, generateWalletProvider.cellController3), arrayCell(context, genW.cellController3),
]), ]),
const SizedBox(height: 15), const SizedBox(height: 15),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
arrayCell(context, generateWalletProvider.cellController4), arrayCell(context, genW.cellController4),
arrayCell(context, generateWalletProvider.cellController5), arrayCell(context, genW.cellController5),
arrayCell(context, generateWalletProvider.cellController6), arrayCell(context, genW.cellController6),
arrayCell(context, generateWalletProvider.cellController7), arrayCell(context, genW.cellController7),
]), ]),
const SizedBox(height: 15), const SizedBox(height: 15),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
arrayCell(context, generateWalletProvider.cellController8), arrayCell(context, genW.cellController8),
arrayCell(context, generateWalletProvider.cellController9), arrayCell(context, genW.cellController9),
arrayCell(context, generateWalletProvider.cellController10), arrayCell(context, genW.cellController10),
arrayCell(context, generateWalletProvider.cellController11), arrayCell(context, genW.cellController11),
]), ]),
]), ]),
// const Spacer(), // const Spacer(),
if (generateWalletProvider.isSentenceComplete(context)) if (genW.isSentenceComplete(context))
Expanded( Expanded(
child: Align( child: Align(
alignment: Alignment.center, alignment: Alignment.center,
@ -87,12 +93,13 @@ class RestoreChest extends StatelessWidget {
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: () async { onPressed: () async {
if (await generateWalletProvider.isSentenceValid()) { if (await _sub.isMnemonicValid(genW.generatedMnemonic!)) {
generateWalletProvider.resetImportView(); genW.resetImportView();
await Navigator.push( await Navigator.push(
context, context,
FaderTransition( FaderTransition(
page: const OnboardingStepThirteen(), isFast: true), page: const OnboardingStepThirteen(),
isFast: true),
); );
} else { } else {
await badMnemonicPopup(context); await badMnemonicPopup(context);
@ -107,6 +114,30 @@ class RestoreChest extends StatelessWidget {
), ),
// SizedBox(height: isTall ? 80 : 80), // SizedBox(height: isTall ? 80 : 80),
)) ))
else
Column(children: [
const SizedBox(height: 20),
SizedBox(
width: 150,
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
genW.pasteMnemonic(context);
},
child: const Text(
'Coller depuis le\npresse-papier',
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
),
),
)
])
]), ]),
), ),
), ),
@ -168,7 +199,7 @@ class RestoreChest extends StatelessWidget {
return AlertDialog( return AlertDialog(
title: const Text('Phrase incorrecte'), title: const Text('Phrase incorrecte'),
content: const Text( content: const Text(
'Votre phrase de restauration semble incorrecte, veuillez la corriger.'), 'Votre phrase de restauration semble incorrecte, les mots ne sont pas dans le bon ordre.\nVeuillez la corriger.'),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: const Text("OK"), child: const Text("OK"),

View File

@ -1,13 +1,13 @@
// ignore_for_file: avoid_print
import 'dart:async'; import 'dart:async';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/cesium_wallet_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart'; import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/screens/myWallets/choose_wallet.dart'; import 'package:gecko/screens/myWallets/choose_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart';
@ -21,6 +21,8 @@ class UnlockingWallet extends StatelessWidget {
{Key? keyUnlockWallet, required this.wallet, required this.action}) {Key? keyUnlockWallet, required this.wallet, required this.action})
: super(key: keyUnlockWallet); : super(key: keyUnlockWallet);
WalletData? wallet; WalletData? wallet;
late int currentChestNumber;
late ChestData currentChest;
String action; String action;
// ignore: close_sinks // ignore: close_sinks
@ -34,17 +36,11 @@ class UnlockingWallet extends StatelessWidget {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions = WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
final double statusBarHeight = MediaQuery.of(context).padding.top; // final double statusBarHeight = MediaQuery.of(context).padding.top;
int _pinLenght; currentChestNumber = configBox.get('currentChest');
ChestData currentChest = chestBox.get(configBox.get('currentChest'))!; currentChest = chestBox.get(currentChestNumber)!;
int _pinLenght = _walletOptions.getPinLenght(wallet!.number);
if (currentChest.isCesium!) {
_pinLenght = _walletOptions.getPinLenght(currentChest.dewif);
wallet = WalletData(derivation: -1, chest: currentChest.key);
} else {
_pinLenght = _walletOptions.getPinLenght(wallet!.number);
}
errorController = StreamController<ErrorAnimationType>(); errorController = StreamController<ErrorAnimationType>();
return Scaffold( return Scaffold(
@ -55,7 +51,7 @@ class UnlockingWallet extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Stack(children: <Widget>[ Stack(children: <Widget>[
Positioned( Positioned(
top: statusBarHeight + 10, top: 10, //statusBarHeight + 10,
left: 15, left: 15,
child: Builder( child: Builder(
builder: (context) => IconButton( builder: (context) => IconButton(
@ -63,7 +59,7 @@ class UnlockingWallet extends StatelessWidget {
icon: const Icon( icon: const Icon(
Icons.arrow_back, Icons.arrow_back,
color: Colors.black, color: Colors.black,
size: 25, size: 30,
), ),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
), ),
@ -106,7 +102,7 @@ class UnlockingWallet extends StatelessWidget {
fontWeight: FontWeight.w400), fontWeight: FontWeight.w400),
)), )),
SizedBox(height: 40 * ratio), SizedBox(height: 40 * ratio),
pinForm(context, _pinLenght, currentChest), pinForm(context, _pinLenght),
SizedBox(height: 3 * ratio), SizedBox(height: 3 * ratio),
InkWell( InkWell(
key: const Key('chooseChest'), key: const Key('chooseChest'),
@ -137,7 +133,7 @@ class UnlockingWallet extends StatelessWidget {
)); ));
} }
Widget pinForm(context, _pinLenght, ChestData currentChest) { Widget pinForm(context, _pinLenght) {
// var _walletPin = ''; // var _walletPin = '';
// ignore: close_sinks // ignore: close_sinks
StreamController<ErrorAnimationType> errorController = StreamController<ErrorAnimationType> errorController =
@ -147,8 +143,8 @@ class UnlockingWallet extends StatelessWidget {
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
FocusNode pinFocus = FocusNode(); FocusNode pinFocus = FocusNode();
@ -201,30 +197,12 @@ class UnlockingWallet extends StatelessWidget {
], ],
onCompleted: (_pin) async { onCompleted: (_pin) async {
log.d("Completed"); log.d("Completed");
_myWalletProvider.pinCode = _pin; _myWalletProvider.pinCode = _pin.toUpperCase();
if (currentChest.isCesium!) { final isValid = await _sub.checkPassword(
try { currentChest.address!, _pin.toUpperCase());
String _localDewif = chestBox.get(wallet!.chest)!.dewif!;
final cesiumWallet =
CesiumWallet.fromDewif(_localDewif, _pin.toUpperCase());
_walletOptions.pubkey.text = cesiumWallet.pubkey;
_myWalletProvider.cesiumSeed = cesiumWallet.seed;
_myWalletProvider.mnemonic = 'cesium';
} catch (e) {
log.e(e);
_myWalletProvider.mnemonic = 'bad';
}
} else {
_myWalletProvider.mnemonic = _myWalletProvider.dewifToMnemonic(
context, wallet!, _pin.toUpperCase());
}
// final String? resultWallet = _walletOptions.readLocalWallet(
// context, wallet!, _pin.toUpperCase(), _pinLenght);
// _myWalletProvider.pinCode = _pin.toUpperCase();
_myWalletProvider.pinLenght = _pinLenght;
if (_myWalletProvider.mnemonic == 'bad') { if (!isValid) {
await Future.delayed(const Duration(milliseconds: 50)); await Future.delayed(const Duration(milliseconds: 50));
errorController.add(ErrorAnimationType errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation .shake); // Triggering error shake animation
@ -235,32 +213,20 @@ class UnlockingWallet extends StatelessWidget {
} else { } else {
pinColor = Colors.green[400]; pinColor = Colors.green[400];
if (action == "mywallets") { if (action == "mywallets") {
currentChest.isCesium! Navigator.push(
? Navigator.push( context,
context, MaterialPageRoute(builder: (context) {
MaterialPageRoute(builder: (context) { return const WalletsHome();
return CesiumWalletOptions( }),
cesiumWallet: currentChest); );
}),
).then((value) => _myWalletProvider.mnemonic = '')
: Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
).then((value) => _myWalletProvider.cesiumSeed.clear());
} else if (action == "pay") { } else if (action == "pay") {
if (currentChest.isCesium!) { Navigator.push(
final resultPay = await _historyProvider.pay(context); context,
await paymentsResult(context, resultPay); MaterialPageRoute(builder: (context) {
} else { return ChooseWalletScreen(
Navigator.push( chest: currentChestNumber, pin: _pin.toUpperCase());
context, }),
MaterialPageRoute(builder: (context) { );
return ChooseWalletScreen();
}),
);
}
} }
} }
}, },

View File

@ -1,6 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
@ -27,16 +25,18 @@ class WalletOptions extends StatelessWidget {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
log.d(_walletOptions.pubkey.text); log.d(_walletOptions.address.text);
final int _currentChest = _myWalletProvider.getCurrentChest()!; final int _currentChest = _myWalletProvider.getCurrentChest()!;
log.d("Wallet options: $_currentChest:${wallet.number}"); // final currentWallet = _myWalletProvider.getDefaultWallet(_currentChest);
// log.d(_walletOptions.getAddress(_currentChest, 3));
log.d("Wallet options: $_currentChest:${wallet.derivation}");
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
_walletOptions.isEditing = false; _walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true; _walletOptions.isBalanceBlur = false;
Navigator.pop(context); Navigator.pop(context);
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
@ -49,7 +49,7 @@ class WalletOptions extends StatelessWidget {
icon: const Icon(Icons.arrow_back, color: Colors.black), icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { onPressed: () {
_walletOptions.isEditing = false; _walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true; _walletOptions.isBalanceBlur = false;
Navigator.pop(context); Navigator.pop(context);
}), }),
title: SizedBox( title: SizedBox(
@ -89,15 +89,15 @@ class WalletOptions extends StatelessWidget {
Column(children: <Widget>[ Column(children: <Widget>[
walletName(walletProvider, _walletOptions), walletName(walletProvider, _walletOptions),
SizedBox(height: isTall ? 5 : 0), SizedBox(height: isTall ? 5 : 0),
balance(walletProvider), balance(context, walletProvider.address.text, 20),
]), ]),
const Spacer(flex: 3), const Spacer(flex: 3),
]), ]),
); );
}), }),
SizedBox(height: 4 * ratio), SizedBox(height: 10 * ratio),
QrImageWidget( QrImageWidget(
data: _walletOptions.pubkey.text, data: _walletOptions.address.text,
version: QrVersions.auto, version: QrVersions.auto,
size: isTall ? 300 : 270, size: isTall ? 300 : 270,
), ),
@ -129,8 +129,10 @@ class WalletOptions extends StatelessWidget {
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () async { onTap: () async {
File newAvatar = await (walletProvider.changeAvatar()); wallet.imageFile = await (walletProvider.changeAvatar());
wallet.imageFile = newAvatar; if (wallet.imageFile != null) {
walletBox.put(wallet.key, wallet);
}
walletProvider.reloadBuild(); walletProvider.reloadBuild();
}, },
child: wallet.imageFile == null child: wallet.imageFile == null
@ -148,8 +150,7 @@ class WalletOptions extends StatelessWidget {
top: 0, top: 0,
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
File newAvatar = await (walletProvider.changeAvatar()); wallet.imageFile = await (walletProvider.changeAvatar());
wallet.imageFile = newAvatar;
walletProvider.reloadBuild(); walletProvider.reloadBuild();
}, },
child: Image.asset( child: Image.asset(
@ -220,54 +221,14 @@ class WalletOptions extends StatelessWidget {
); );
} }
Widget balance(WalletOptionsProvider walletProvider) {
return Column(children: <Widget>[
FutureBuilder(
future: walletProvider.getBalance(walletProvider.pubkey.text),
builder: (BuildContext context, AsyncSnapshot<num?> _balance) {
if (_balance.connectionState != ConnectionState.done ||
_balance.hasError) {
return Text('',
style: TextStyle(
fontSize: isTall ? 20 : 18,
));
}
return ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: walletProvider.isBalanceBlur ? 6 : 0,
sigmaY: walletProvider.isBalanceBlur ? 5 : 0),
child: Text(
_balance.data.toString() + ' Ğ1',
style: TextStyle(
fontSize: isTall ? 20 : 18,
),
),
);
}),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
walletProvider.bluringBalance();
},
child: Image.asset(
walletProvider.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
height: 35,
),
),
]);
}
Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) { Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) {
final String shortPubkey = final String shortPubkey =
walletProvider.getShortPubkey(walletProvider.pubkey.text); walletProvider.getShortPubkey(walletProvider.address.text);
return GestureDetector( return GestureDetector(
key: const Key('copyPubkey'), key: const Key('copyPubkey'),
onTap: () { onTap: () {
Clipboard.setData(ClipboardData(text: walletProvider.pubkey.text)); Clipboard.setData(ClipboardData(text: walletProvider.address.text));
walletProvider.snackCopyKey(ctx); snackCopyKey(ctx);
}, },
child: SizedBox( child: SizedBox(
height: 50, height: 50,
@ -303,8 +264,8 @@ class WalletOptions extends StatelessWidget {
), ),
onPressed: () { onPressed: () {
Clipboard.setData( Clipboard.setData(
ClipboardData(text: walletProvider.pubkey.text)); ClipboardData(text: walletProvider.address.text));
walletProvider.snackCopyKey(ctx); snackCopyKey(ctx);
}, },
child: Row(children: <Widget>[ child: Row(children: <Widget>[
Image.asset( Image.asset(
@ -336,7 +297,7 @@ class WalletOptions extends StatelessWidget {
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return HistoryScreen( return HistoryScreen(
pubkey: walletProvider.pubkey.text, pubkey: walletProvider.address.text,
avatar: wallet.imageFile == null avatar: wallet.imageFile == null
? Image.asset( ? Image.asset(
'assets/avatars/${wallet.imageName}', 'assets/avatars/${wallet.imageName}',
@ -422,7 +383,7 @@ class WalletOptions extends StatelessWidget {
onTap: !walletProvider.isDefaultWallet onTap: !walletProvider.isDefaultWallet
? () async { ? () async {
await walletProvider.deleteWallet(context, wallet); await walletProvider.deleteWallet(context, wallet);
WidgetsBinding.instance!.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets = _myWalletProvider.listWallets =
_myWalletProvider.readAllWallets(_currentChest); _myWalletProvider.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();

View File

@ -1,4 +1,3 @@
import 'package:durt/durt.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
@ -55,7 +54,7 @@ class WalletsHome extends StatelessWidget {
backgroundColor: const Color(0xffFFD58D), backgroundColor: const Color(0xffFFD58D),
), ),
body: SafeArea( body: SafeArea(
child: myWalletsTiles(context), child: myWalletsTiles(context, _currentChestNumber!),
), ),
), ),
); );
@ -132,7 +131,7 @@ class WalletsHome extends StatelessWidget {
]); ]);
} }
Widget myWalletsTiles(BuildContext context) { Widget myWalletsTiles(BuildContext context, int _currentChestNumber) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
WalletOptionsProvider _walletOptions = WalletOptionsProvider _walletOptions =
@ -182,9 +181,8 @@ class WalletsHome extends StatelessWidget {
onTap: () { onTap: () {
// _walletOptions.readLocalWallet(context, _repository, // _walletOptions.readLocalWallet(context, _repository,
// _myWalletProvider.pinCode, pinLength); // _myWalletProvider.pinCode, pinLength);
_walletOptions.pubkey.text = _walletOptions.getAddress(
HdWallet.fromMnemonic(_myWalletProvider.mnemonic) _currentChestNumber, _repository.derivation!);
.getPubkey(_repository.derivation!);
Navigator.push( Navigator.push(
context, context,
SmoothTransition( SmoothTransition(
@ -275,10 +273,8 @@ class WalletsHome extends StatelessWidget {
// _repository, // _repository,
// _myWalletProvider.pinCode, // _myWalletProvider.pinCode,
// pinLength); // pinLength);
_walletOptions.pubkey.text = _walletOptions.getAddress(
HdWallet.fromMnemonic( _currentChestNumber, _repository.derivation!);
_myWalletProvider.mnemonic)
.getPubkey(_repository.derivation!);
Navigator.push( Navigator.push(
context, context,
SmoothTransition( SmoothTransition(

View File

@ -1,112 +0,0 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/import_cesium_wallet.dart';
import 'package:gecko/screens/onBoarding/1.dart';
class NoKeyChainScreen extends StatelessWidget {
const NoKeyChainScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold(
extendBodyBehindAppBar: true,
// backgroundColor: Colors.white,
// appBar: GeckoSpeechAppBar('Mes portefeuilles'),
body: SafeArea(
child: Column(children: <Widget>[
common.onboardingProgressBar(context, 'Mes portefeuilles', 0),
common.bubbleSpeak(
"Je ne connais pour linstant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.",
textKey: const Key('textOnboarding')),
const SizedBox(height: 90),
Container(
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
key: const Key('goStep1'),
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(8),
child: Image(
image: AssetImage('assets/onBoarding/wallet.png'),
height: 90)),
onTap: () {
Navigator.push(
context,
FaderTransition(
page: OnboardingStepOne(), isFast: true));
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 15),
const Text(
"Créer un nouveau\nportefeuille",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w500),
),
const SizedBox(height: 70),
Container(
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
splashColor: orangeC, // inkwell color
child: Padding(
padding: const EdgeInsets.all(12),
child:
// Image(
// image: AssetImage('assets/cesium_bw3.png'),
// height: 60),
SvgPicture.asset('assets/cesium_small.svg',
semanticsLabel: 'Cesium Logo', height: 48),
),
onTap: () {
Navigator.push(context,
SlideLeftRoute(page: const ImportWalletScreen()));
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 10),
const Text(
"Importer un\nportefeuille Cesium",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 13),
)
]),
));
}
}

View File

@ -1,63 +1,47 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/2.dart'; import 'package:gecko/screens/onBoarding/2.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepOne extends StatelessWidget { class OnboardingStepOne extends StatelessWidget {
TextEditingController tplController = TextEditingController(); const OnboardingStepOne({Key? key}) : super(key: key);
final int progress = 1;
OnboardingStepOne({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Nouveau portefeuilles', progress), child: Text(
common.bubbleSpeak( 'Nouveau portefeuille',
"Il semblerait que vous nayez pas encore de trousseau.\n\nUn trousseau vous permet de gérer un ou plusieurs portefeuilles.", style: TextStyle(fontWeight: FontWeight.w600),
textKey: const Key('step1')), ),
const SizedBox(height: 90), ),
Image.asset( ),
'assets/onBoarding/keys-and-wallets-horizontal.png', extendBodyBehindAppBar: true,
height: 200, body: SafeArea(
), child: common.infoIntro(
Expanded( context,
child: Align( <TextSpan>[
alignment: Alignment.bottomCenter, const TextSpan(
child: SizedBox( text: 'Gecko fabrique votre portefeuille à partir dune '),
width: 400, const TextSpan(
height: 62, text: 'phrase de restauration',
child: ElevatedButton( style: TextStyle(fontWeight: FontWeight.bold)),
key: const Key('goStep2'), const TextSpan(
style: ElevatedButton.styleFrom( text:
elevation: 5, '. Elle est un peu comme le plan qui permet de construire votre portefeuille.'),
primary: orangeC, ],
onPrimary: Colors.white, // foreground 'fabrication-de-portefeuille.png',
), '>',
onPressed: () { const OnboardingStepTwo(),
Navigator.push( 0),
context, ),
FaderTransition( );
page: OnboardingStepTwo(), isFast: true));
},
child: const Text('Créer mon trousseau',
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 80),
]),
));
} }
} }

View File

@ -1,64 +1,167 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'dart:async';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/11.dart'; 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 // ignore: must_be_immutable
class OnboardingStepTwelve extends StatelessWidget { class OnboardingStepFourteen extends StatelessWidget {
TextEditingController tplController = TextEditingController(); OnboardingStepFourteen({
final int progress = 9; Key? validationKey,
}) : super(key: validationKey);
OnboardingStepTwelve({Key? key}) : super(key: key); final formKey = GlobalKey<FormState>();
Color? pinColor = const Color(0xFFA4B600);
bool hasError = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
final int _pinLenght = _generateWalletProvider.pin.text.length;
return Scaffold( return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text(
'Mon code secret',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
common.onboardingProgressBar( SizedBox(height: isTall ? 40 : 20),
context, 'Ma phrase de restauration', progress), common.buildProgressBar(9),
common.bubbleSpeak( SizedBox(height: isTall ? 40 : 20),
"Si un jour vous changez de téléphone, votre code secret sera différent, mais il vous suffira de me redonner votre phrase de restauration pour recréer votre trousseau.", common.buildText(<TextSpan>[
textKey: const Key('step10'), TextSpan(
), text:
const SizedBox(height: 10), "Gecko va vérifier avec vous si vous avez bien mémorisé votre code secret.\n\nTapez votre code secret dans le champ ci-dessous pour vérifier que vous lavez bien noté.",
Image.asset( style: TextStyle(fontSize: 16 * ratio))
'assets/onBoarding/plusieurs-codes-secrets-un-trousseau.png', ]),
height: isTall ? 410 : 380, SizedBox(height: isTall ? 80 : 20),
), pinForm(context, _walletOptions, _pinLenght, 1, 2)
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goStep11'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
FaderTransition(
page: const OnboardingStepThirteen(),
isFast: true),
);
},
child: const Text("Générer le code secret",
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 80),
]), ]),
)); ));
} }
Widget pinForm(context, WalletOptionsProvider _walletOptions, _pinLenght,
int _walletNbr, int _derivation) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController _enterPin = TextEditingController();
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final int? _currentChest = _myWalletProvider.getCurrentChest();
return Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
key: const Key('formKey2'),
autoFocus: true,
appContext: context,
pastedTextStyle: TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: _pinLenght,
obscureText: true,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v!.length < _pinLenght) {
return "Votre code PIN fait $_pinLenght caractères";
} else {
return null;
}
},
pinTheme: PinTheme(
activeColor: pinColor,
borderWidth: 4,
shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(5),
fieldHeight: 60,
fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
),
cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: _enterPin,
keyboardType: TextInputType.text,
boxShadows: const [
BoxShadow(
offset: Offset(0, 1),
color: Colors.black12,
blurRadius: 10,
)
],
onCompleted: (_pin) async {
_myWalletProvider.pinCode = _pin.toUpperCase();
_myWalletProvider.pinLenght = _pinLenght;
log.d(_pin + ' || ' + _generateWalletProvider.pin.text);
if (_pin.toUpperCase() == _generateWalletProvider.pin.text) {
pinColor = Colors.green[500];
final address = await _sub.importAccount(
fromMnemonic: true,
mnemonic: _generateWalletProvider.generatedMnemonic!,
derivePath: '//2',
password: _generateWalletProvider.pin.text);
await _generateWalletProvider.storeHDWChest(
address, 'Mon portefeuille courant', context);
_myWalletProvider.readAllWallets(_currentChest);
// scheduleMicrotask(() {
// _walletOptions.reloadBuild();
_myWalletProvider.rebuildWidget();
// });
_generateWalletProvider.generatedMnemonic = '';
Navigator.push(
context,
FaderTransition(
page: const OnboardingStepFiveteen(), isFast: false),
);
} else {
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600];
_walletOptions.reloadBuild();
}
},
onChanged: (value) {
if (pinColor != const Color(0xFFA4B600)) {
pinColor = const Color(0xFFA4B600);
}
},
)),
);
}
} }

View File

@ -1,118 +0,0 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/12.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepThirteen extends StatelessWidget {
final int progress = 10;
const OnboardingStepThirteen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
// MyWalletsProvider myWalletProvider =
// Provider.of<MyWalletsProvider>(context);
CommonElements common = CommonElements();
_generateWalletProvider.pin.text =
_generateWalletProvider.changePinCode(reload: false);
return Scaffold(
extendBodyBehindAppBar: true,
body: SafeArea(
child: Column(children: <Widget>[
common.onboardingProgressBar(
context, 'Ma phrase de restauration', progress),
common.bubbleSpeakRich(
<TextSpan>[
const TextSpan(
text:
"Et voilà votre code secret !\n\nMémorisez-le ou notez-le, car il vous sera demandé "),
const TextSpan(
text: 'à chaque fois',
style: TextStyle(fontWeight: FontWeight.bold)),
const TextSpan(
text:
" que vous voudrez effectuer un paiement sur cet appareil."),
],
textKey: const Key('step11'),
),
const SizedBox(height: 100),
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
key: const Key('generatedPin'),
enabled: false,
controller: _generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
letterSpacing: 5,
fontSize: 35.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.replay),
color: orangeC,
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
),
],
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('changeSecretCode'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: const Color(0xffFFD58D),
onPrimary: Colors.black, // foreground
),
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
child: const Text("Choisir un autre code secret",
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 25),
SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goStep12'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () async {
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
Navigator.push(
context,
FaderTransition(
page: OnboardingStepFourteen(), isFast: true),
);
},
child: const Text("J'ai noté mon code secret",
style: TextStyle(fontSize: 20))),
),
const SizedBox(height: 80),
]),
));
}
}

View File

@ -0,0 +1,78 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
// ignore: must_be_immutable
class OnboardingStepFiveteen extends StatelessWidget {
const OnboardingStepFiveteen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text(
'Cest tout bon !',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 40),
common.buildText(<TextSpan>[
const TextSpan(
text:
"Top !\n\nVotre coffre votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !",
)
]),
SizedBox(height: isTall ? 20 : 10),
Image.asset(
'assets/onBoarding/gecko-clin.gif',
height: isTall ? 400 : 300,
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: finishButton(context)),
),
const SizedBox(height: 40),
]),
));
}
}
Widget finishButton(BuildContext context) {
return SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
key: const Key('goWalletHome'),
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
ModalRoute.withName('/'),
);
},
child: const Text("Accéder à mon coffre",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600))),
);
}

View File

@ -1,153 +0,0 @@
// ignore_for_file: file_names
import 'dart:async';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/13_congratulations.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepFourteen extends StatelessWidget {
OnboardingStepFourteen({
Key? validationKey,
}) : super(key: validationKey);
final int progress = 11;
final formKey = GlobalKey<FormState>();
Color? pinColor = const Color(0xFFA4B600);
bool hasError = false;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
CommonElements common = CommonElements();
final int _pinLenght = _generateWalletProvider.pin.text.length;
return Scaffold(
extendBodyBehindAppBar: true,
body: SafeArea(
child: Column(children: <Widget>[
common.onboardingProgressBar(
context, 'Ma phrase de restauration', progress),
common.bubbleSpeak(
"Avez-vous bien mémorisé votre code secret ?\n\nVérifions ça ensemble !\n\nTapez votre code secret dans le champ ci-dessous (après cest fini, promis-juré-gecko).",
textKey: const Key('step12'),
),
SizedBox(height: isTall ? 80 : 10),
pinForm(context, _walletOptions, _pinLenght, 1, 3)
]),
));
}
Widget pinForm(context, WalletOptionsProvider _walletOptions, _pinLenght,
int _walletNbr, int _derivation) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController _enterPin = TextEditingController();
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
final int? _currentChest = _myWalletProvider.getCurrentChest();
return Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
key: const Key('formKey2'),
autoFocus: true,
appContext: context,
pastedTextStyle: TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: _pinLenght,
obscureText: true,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v!.length < _pinLenght) {
return "Votre code PIN fait $_pinLenght caractères";
} else {
return null;
}
},
pinTheme: PinTheme(
activeColor: pinColor,
borderWidth: 4,
shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(5),
fieldHeight: 60,
fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
),
cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: _enterPin,
keyboardType: TextInputType.text,
boxShadows: const [
BoxShadow(
offset: Offset(0, 1),
color: Colors.black12,
blurRadius: 10,
)
],
onCompleted: (_pin) async {
_myWalletProvider.pinCode = _pin.toUpperCase();
_myWalletProvider.pinLenght = _pinLenght;
log.d(_pin + ' || ' + _generateWalletProvider.pin.text);
if (_pin.toUpperCase() == _generateWalletProvider.pin.text) {
pinColor = Colors.green[500];
NewWallet generatedWallet = await Dewif().generateDewif(
_generateWalletProvider.generatedMnemonic!,
_generateWalletProvider.pin.text,
lang: appLang);
await _generateWalletProvider.storeHDWChest(
generatedWallet, 'Mon portefeuille courant', context);
_myWalletProvider.readAllWallets(_currentChest);
// scheduleMicrotask(() {
// _walletOptions.reloadBuild();
_myWalletProvider.rebuildWidget();
// });
_generateWalletProvider.generatedMnemonic = '';
Navigator.push(
context,
FaderTransition(
page: OnboardingStepFiveteen(), isFast: false),
);
} else {
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600];
_walletOptions.reloadBuild();
}
},
onChanged: (value) {
if (pinColor != const Color(0xFFA4B600)) {
pinColor = const Color(0xFFA4B600);
}
},
)),
);
}
}

View File

@ -1,67 +0,0 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
// ignore: must_be_immutable
class OnboardingStepFiveteen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
final int progress = 12;
OnboardingStepFiveteen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold(
extendBodyBehindAppBar: true,
body: SafeArea(
child: Column(children: <Widget>[
common.onboardingProgressBar(
context, 'Ma phrase de restauration', progress),
common.bubbleSpeak(
"Top !\n\nVotre trousseau de clef et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !",
textKey: const Key('step13'),
),
SizedBox(height: isTall ? 20 : 10),
Image.asset(
'assets/onBoarding/gecko-clin.gif',
height: isTall ? 400 : 300,
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goWalletHome'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
ModalRoute.withName('/'),
);
},
child: const Text("Accéder à mes portefeuilles",
style: TextStyle(fontSize: 20))),
),
),
),
const SizedBox(height: 80),
]),
));
}
}

View File

@ -5,16 +5,9 @@ import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/3.dart'; import 'package:gecko/screens/onBoarding/3.dart';
// import 'package:gecko/screens/commonElements.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepTwo extends StatelessWidget { class OnboardingStepTwo extends StatelessWidget {
TextEditingController tplController = TextEditingController(); const OnboardingStepTwo({Key? key}) : super(key: key);
final int progress = 2;
OnboardingStepTwo({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -22,44 +15,30 @@ class OnboardingStepTwo extends StatelessWidget {
CommonElements common = CommonElements(); CommonElements common = CommonElements();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Nouveau portefeuilles', progress), child: Text(
common.bubbleSpeak( 'Votre phrase de restauration',
"Un trousseau est créé à partir dune phrase de restauration.", style: TextStyle(fontWeight: FontWeight.w600),
textKey: const Key('step2'), ),
), ),
const SizedBox(height: 70), ),
Image.asset( extendBodyBehindAppBar: true,
'assets/onBoarding/keys-and-wallets-horizontal-plus-phrase.png'), body: SafeArea(
Expanded( child: common.infoIntro(
child: Align( context,
alignment: Alignment.bottomCenter, <TextSpan>[
child: SizedBox( const TextSpan(
width: 400, text:
height: 62, 'Conservez cette phrase précieusement, car sans elle Gecko ne pourra pas reconstruire vos portefeuilles le jour où vous changez de téléphone.'),
child: ElevatedButton( ],
key: const Key('goStep3'), 'fabrication-de-portefeuille-impossible-sans-phrase.png',
style: ElevatedButton.styleFrom( '>',
elevation: 5, const OnboardingStepThree(),
primary: orangeC, 1),
onPrimary: Colors.white, // foreground ),
), );
onPressed: () {
Navigator.push(
context,
FaderTransition(
page: OnboardingStepFor(), isFast: true),
);
},
child: const Text("D'accord",
style: TextStyle(fontSize: 20)),
),
))),
const SizedBox(height: 80),
]),
));
} }
} }

View File

@ -6,12 +6,8 @@ import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/4.dart'; import 'package:gecko/screens/onBoarding/4.dart';
// ignore: must_be_immutable class OnboardingStepThree extends StatelessWidget {
class OnboardingStepFor extends StatelessWidget { const OnboardingStepThree({Key? key}) : super(key: key);
TextEditingController tplController = TextEditingController();
final int progress = 3;
OnboardingStepFor({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,50 +15,28 @@ class OnboardingStepFor extends StatelessWidget {
CommonElements common = CommonElements(); CommonElements common = CommonElements();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Ma phrase de restauration', progress), child: Text(
common.bubbleSpeak( 'Votre phrase de restauration',
"Si un jour vous changez de téléphone, il vous suffira de me redonner votre phrase de restauration pour recréer votre trousseau.", style: TextStyle(fontWeight: FontWeight.w600),
textKey: const Key('step3'), ),
), ),
SizedBox(height: isTall ? 15 : 0), ),
// Row(children: <Widget>[ extendBodyBehindAppBar: true,
// Align( body: SafeArea(
// alignment: Alignment.centerRight, child: common.infoIntro(
// child: context,
Image.asset( <TextSpan>[
'assets/onBoarding/plusieurs-appareils-un-trousseau.png', const TextSpan(text: 'Dans une blockchain, pas de procédure de récupération par mail. Seule votre phrase de restauration peut vous permettre de récupérer vos Ğ1 à tout moment.'),
height: 400 * ratio, ],
), 'mot-de-passe-oublie.png',
// ]), '>',
Expanded( const OnboardingStepFor(),
child: Align( 2),
alignment: Alignment.bottomCenter, ),
child: SizedBox( );
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goStep4'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
FaderTransition(
page: OnboardingStepFive(), isFast: true),
);
},
child: const Text("J'ai compris",
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 80),
]),
));
} }
} }

View File

@ -6,12 +6,8 @@ import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/5.dart'; import 'package:gecko/screens/onBoarding/5.dart';
// ignore: must_be_immutable class OnboardingStepFor extends StatelessWidget {
class OnboardingStepFive extends StatelessWidget { const OnboardingStepFor({Key? key}) : super(key: key);
TextEditingController tplController = TextEditingController();
final int progress = 4;
OnboardingStepFive({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,45 +15,33 @@ class OnboardingStepFive extends StatelessWidget {
CommonElements common = CommonElements(); CommonElements common = CommonElements();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Ma phrase de restauration', progress), child: Text(
common.bubbleSpeak( 'Votre phrase de restauration',
"Par contre, attention :\n\nDans une blockchain, il ny a pas de procédure de récupération de trousseau.\n\nSi vous perdez votre phrase de restauration, je ne pourrai pas vous la communiquer, et vous ne pourrez donc plus jamais accéder à votre compte.", style: TextStyle(fontWeight: FontWeight.w600),
textKey: const Key('step4'), ),
), ),
SizedBox(height: isTall ? 30 : 10), ),
Image.asset( extendBodyBehindAppBar: true,
'assets/onBoarding/maison-qui-brule.png', body: SafeArea(
width: 320 * ratio, child: common.infoIntro(
), context,
Expanded( <TextSpan>[
child: Align( const TextSpan(text: 'Il est temps de vous munir d'),
alignment: Alignment.bottomCenter, const TextSpan(
child: SizedBox( text: 'un dun papier et dun crayon',
width: 400, style: TextStyle(fontWeight: FontWeight.bold)),
height: 62, const TextSpan(
child: ElevatedButton( text: ' afin de pouvoir noter votre phrase de restauration.'),
key: const Key('goStep5'), ],
style: ElevatedButton.styleFrom( 'gecko-oublie-aussi.png',
elevation: 5, '>',
primary: orangeC, const OnboardingStepFive(),
onPrimary: Colors.white, // foreground 3),
), ),
onPressed: () { );
Navigator.push(
context,
FaderTransition(
page: OnboardingStepSeven(), isFast: true),
);
},
child: const Text("J'ai compris",
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 80),
]),
));
} }
} }

View File

@ -3,78 +3,243 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/6.dart'; import 'package:gecko/screens/onBoarding/6.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable AsyncSnapshot<List>? mnemoList;
class OnboardingStepSeven extends StatelessWidget {
TextEditingController tplController = TextEditingController();
final int progress = 5;
OnboardingStepSeven({Key? key}) : super(key: key); class OnboardingStepFive extends StatelessWidget {
const OnboardingStepFive({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Ma phrase de restauration', progress), child: Text(
common.bubbleSpeakRich( 'Votre phrase de restauration',
<TextSpan>[ style: TextStyle(fontWeight: FontWeight.w600),
const TextSpan(text: "Munissez-vous d'"), ),
const TextSpan( ),
text: 'un papier et dun crayon\n', ),
style: TextStyle(fontWeight: FontWeight.bold)), extendBodyBehindAppBar: true,
const TextSpan( body: SafeArea(
text: child: Column(children: [
"afin de pouvoir noter votre phrase de restauration."), SizedBox(height: isTall ? 40 : 20),
], common.buildProgressBar(4),
textKey: const Key('step5'), SizedBox(height: isTall ? 40 : 20),
common.buildText(
<TextSpan>[
const TextSpan(
text:
'Gecko a généré votre phrase de restauration ! Tâchez de la garder bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.'),
],
),
const SizedBox(height: 40),
sentanceArray(context),
const SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return PrintWallet(_generateWalletProvider.generatedMnemonic);
}),
);
},
child: Image.asset(
'assets/printer.png',
height: 45,
), ),
Expanded( ),
child: Align( const SizedBox(height: 40),
Expanded(
child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ child: SizedBox(
Container( width: 410,
padding: const EdgeInsets.only(bottom: 90), height: 70,
child: common.bubbleSpeak( child: ElevatedButton(
"Moi, jai déjà essayé de\nmémoriser une phrase de\nrestauration, mais je nai\npas une mémoire\ndéléphant.", key: const Key('generateMnemonic'),
isMaxWidth: false), style: ElevatedButton.styleFrom(
), elevation: 4,
Image.asset( primary: const Color(0xffFFD58D),
'assets/onBoarding/chopp-gecko.png', onPrimary: Colors.black, // foreground
height: 200, ),
), onPressed: () {
]), _generateWalletProvider.reloadBuild();
)), // setState(() {});
SizedBox(height: isTall ? 120 : 50), },
SizedBox( child: const Text("Choisir une autre phrase",
width: 400, style: TextStyle(
height: 62, fontSize: 24, fontWeight: FontWeight.w600))),
child: ElevatedButton( ),
key: const Key('goStep6'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
FaderTransition(
page: OnboardingStepEight(), isFast: true),
);
},
child: const Text("J'ai de quoi noter",
style: TextStyle(fontSize: 20))),
), ),
const SizedBox(height: 80), ),
]), const SizedBox(height: 25),
)); nextButton(context, "J'ai noté ma phrase", false),
const SizedBox(height: 40),
]),
),
);
} }
} }
Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Container(
constraints: const BoxConstraints(maxWidth: 450),
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: const Color(0xffeeeedd),
borderRadius: const BorderRadius.all(
Radius.circular(10),
)),
padding: const EdgeInsets.all(20),
child: FutureBuilder(
future: _generateWalletProvider.generateWordList(context),
builder: (BuildContext context, AsyncSnapshot<List> _data) {
if (!_data.hasData) {
return const Text('');
} else {
mnemoList = _data;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(_data.data![0]),
arrayCell(_data.data![1]),
arrayCell(_data.data![2]),
arrayCell(_data.data![3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(_data.data![4]),
arrayCell(_data.data![5]),
arrayCell(_data.data![6]),
arrayCell(_data.data![7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(_data.data![8]),
arrayCell(_data.data![9]),
arrayCell(_data.data![10]),
arrayCell(_data.data![11]),
]),
]);
}
}),
),
);
}
Widget arrayCell(dataWord) {
return SizedBox(
width: 100,
child: Column(children: <Widget>[
Text(
dataWord.split(':')[0],
style: const TextStyle(fontSize: 15, color: Color(0xff6b6b52)),
),
Text(
dataWord.split(':')[1],
key: Key('word${dataWord.split(':')[0]}'),
style: const TextStyle(fontSize: 20, color: Colors.black),
),
]),
);
}
// ignore: must_be_immutable
class PrintWallet extends StatelessWidget {
const PrintWallet(this.sentence, {Key? key}) : super(key: key);
final String? sentence;
@override
Widget build(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.pop(context);
}),
backgroundColor: yellowC,
foregroundColor: Colors.black,
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text(
'Imprimer ma phrase de restauration',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
body: PdfPreview(
canDebug: false,
canChangeOrientation: false,
build: (format) => _generateWalletProvider.printWallet(mnemoList),
),
),
);
}
}
Widget nextButton(BuildContext context, String text, bool isFast) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
return SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
_generateWalletProvider.nbrWord =
_generateWalletProvider.getRandomInt();
_generateWalletProvider.nbrWordAlpha = _generateWalletProvider
.intToString(_generateWalletProvider.nbrWord + 1);
_myWalletProvider.mnemonic = _generateWalletProvider.generatedMnemonic!;
Navigator.push(
context,
FaderTransition(
page: OnboardingStepSix(
generatedMnemonic: _generateWalletProvider.generatedMnemonic),
isFast: true),
);
},
child: Text(
text,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
);
}

View File

@ -1,124 +1,238 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'dart:ui';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/7.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class OnboardingStepEight extends StatelessWidget { class OnboardingStepSix extends StatelessWidget {
TextEditingController tplController = TextEditingController(); OnboardingStepSix({Key? key, required this.generatedMnemonic})
final int progress = 6; : super(key: key);
OnboardingStepEight({Key? key}) : super(key: key); String? generatedMnemonic;
TextEditingController wordController = TextEditingController();
final TextEditingController _mnemonicController = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements(); GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: true);
return Scaffold( CommonElements common = CommonElements();
_mnemonicController.text = generatedMnemonic!;
return WillPopScope(
onWillPop: () {
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( appBar: AppBar(
child: Column(children: <Widget>[ toolbarHeight: 60 * ratio,
common.onboardingProgressBar( title: const SizedBox(
context, 'Ma phrase de restauration', progress), height: 22,
common.bubbleSpeak( child: Text(
"Jai généré votre phrase de restauration !\nTâchez de la garder bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.", 'Votre phrase de restauration',
textKey: const Key('step6'), style: TextStyle(fontWeight: FontWeight.w600),
), ),
SizedBox(height: isTall ? 70 : 40), ),
// SizedBox(height: 30), ),
sentanceArray(context), body: SafeArea(
// ), child: Align(
Expanded( alignment: Alignment.topCenter,
child: Align( child: Column(children: [
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(5),
SizedBox(height: isTall ? 40 : 20),
common.buildText(
<TextSpan>[
TextSpan(
text:
"Avez-vous bien noté votre phrase de restauration ?\n\nPour en être sûr, veuillez taper dans le champ ci-dessous le ",
style: TextStyle(fontSize: 16 * ratio)),
TextSpan(
text: '${_generateWalletProvider.nbrWord + 1}ème mot',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16 * ratio)),
TextSpan(
text: " de votre phrase de restauration :",
style: TextStyle(fontSize: 16 * ratio)),
],
),
SizedBox(height: isTall ? 70 : 20),
Text('${_generateWalletProvider.nbrWord + 1}',
key: const Key('askedWord'),
style: TextStyle(
fontSize: isTall ? 17 : 15,
color: orangeC,
fontWeight: FontWeight.w400)),
const SizedBox(height: 10),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(
color: Colors.grey[600]!,
width: 3,
)),
width: 430,
child: TextFormField(
key: const Key('inputWord'),
autofocus: true,
enabled: !_generateWalletProvider.isAskedWordValid,
controller: wordController,
textInputAction: TextInputAction.next,
onChanged: (value) {
_generateWalletProvider.checkAskedWord(
value, _mnemonicController.text);
},
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 22.0,
color: Colors.grey[500],
fontWeight: FontWeight.w500),
labelText: _generateWalletProvider.isAskedWordValid
? "C'est le bon mot !"
: "${_generateWalletProvider.nbrWordAlpha} mot de votre phrase de restauration",
fillColor: const Color(0xffeeeedd),
filled: true,
contentPadding: const EdgeInsets.all(12),
),
style: TextStyle(
fontSize: 40.0,
color: _generateWalletProvider.askedWordColor,
fontWeight: FontWeight.w500))),
Visibility(
visible: _generateWalletProvider.isAskedWordValid,
child: Expanded(
child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: SizedBox( child: nextButton(context, 'Continuer',
width: 400, const OnboardingStepSeven(), false),
height: 62, ),
child: ElevatedButton( ),
key: const Key('goStep7'), ),
style: ElevatedButton.styleFrom( // Visibility(
elevation: 5, // visible: !_generateWalletProvider.isAskedWordValid,
primary: orangeC, // child: const Expanded(
onPrimary: Colors.white, // foreground // child: Align(
), // alignment: Alignment.bottomCenter,
onPressed: () { // child: Text(''),
Navigator.push( // ),
context, // ),
FaderTransition( // ),
page: OnboardingStepNine(), isFast: false), const SizedBox(height: 40),
); ]),
}, ),
child: const Text("Afficher ma phrase", ),
style: TextStyle(fontSize: 20))), ),
))), );
const SizedBox(height: 80),
]),
));
} }
} }
Widget sentanceArray(BuildContext context) { Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 3),
child: Container( child: Container(
constraints: const BoxConstraints(maxWidth: 450), constraints: const BoxConstraints(maxWidth: 450),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.black), border: Border.all(color: Colors.black),
color: Colors.grey[300], color: const Color(0xffeeeedd),
borderRadius: const BorderRadius.all( borderRadius: const BorderRadius.all(
Radius.circular(10), Radius.circular(10),
)), )),
// color: Colors.grey[300], padding: const EdgeInsets.all(20),
padding: const EdgeInsets.all(20), child: FutureBuilder(
child: Column( future: _generateWalletProvider.generateWordList(context),
mainAxisAlignment: MainAxisAlignment.center, builder: (BuildContext context, AsyncSnapshot<List> _data) {
mainAxisSize: MainAxisSize.max, if (!_data.hasData) {
crossAxisAlignment: CrossAxisAlignment.center, return const Text('');
children: <Widget>[ } else {
Row(children: <Widget>[ return Column(
arrayCell("1:exquis"), mainAxisAlignment: MainAxisAlignment.center,
arrayCell("2:favori"), mainAxisSize: MainAxisSize.max,
arrayCell("3:curseur"), crossAxisAlignment: CrossAxisAlignment.center,
arrayCell("4:relatif"), children: <Widget>[
]), Row(children: <Widget>[
const SizedBox(height: 15), arrayCell(_data.data![0]),
Row(children: <Widget>[ arrayCell(_data.data![1]),
arrayCell("5:embellir"), arrayCell(_data.data![2]),
arrayCell("6:cultiver"), arrayCell(_data.data![3]),
arrayCell("7:bureau"), ]),
arrayCell("8:ossature"), const SizedBox(height: 15),
]), Row(children: <Widget>[
const SizedBox(height: 15), arrayCell(_data.data![4]),
Row(children: <Widget>[ arrayCell(_data.data![5]),
arrayCell("9:labial"), arrayCell(_data.data![6]),
arrayCell("10:science"), arrayCell(_data.data![7]),
arrayCell("11:théorie"), ]),
arrayCell("12:Monnaie"), const SizedBox(height: 15),
]), Row(children: <Widget>[
]))); arrayCell(_data.data![8]),
arrayCell(_data.data![9]),
arrayCell(_data.data![10]),
arrayCell(_data.data![11]),
]),
]);
}
}),
),
);
} }
Widget arrayCell(dataWord) { Widget arrayCell(dataWord) {
return SizedBox( return SizedBox(
width: 102, width: 100,
child: Column( child: Column(children: <Widget>[
children: <Widget>[ Text(
ImageFiltered( dataWord.split(':')[0],
imageFilter: ImageFilter.blur(sigmaX: 1, sigmaY: 1), style: const TextStyle(fontSize: 15, color: Color(0xff6b6b52)),
child: Text(dataWord.split(':')[0], ),
style: const TextStyle(fontSize: 14, color: Colors.black)), Text(
), dataWord.split(':')[1],
const SizedBox(height: 2), key: Key('word${dataWord.split(':')[0]}'),
ImageFiltered( style: const TextStyle(fontSize: 20, color: Colors.black),
imageFilter: ImageFilter.blur(sigmaX: 4, sigmaY: 4), ),
child: Text(dataWord.split(':')[1], ]),
style: const TextStyle(fontSize: 19, color: Colors.black)), );
) }
],
)); Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
return SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context, FaderTransition(page: nextScreen, isFast: isFast));
},
child: Text(
text,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
);
} }

View File

@ -1,209 +1,43 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/8.dart'; import 'package:gecko/screens/onBoarding/8.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable class OnboardingStepSeven extends StatelessWidget {
class OnboardingStepNine extends StatelessWidget { const OnboardingStepSeven({Key? key}) : super(key: key);
TextEditingController tplController = TextEditingController();
final int progress = 6;
OnboardingStepNine({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
// _generateWalletProvider.generateMnemonic();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, appBar: AppBar(
body: SafeArea( toolbarHeight: 60 * ratio,
child: Column(children: <Widget>[ title: const SizedBox(
common.onboardingProgressBar( height: 22,
context, 'Ma phrase de restauration', progress), child: Text(
common.bubbleSpeak( 'Mon code secret',
"C'est le moment de noter votre phrase !", style: TextStyle(fontWeight: FontWeight.w600),
textKey: const Key('step7'), ),
long: 60,
),
SizedBox(height: isTall ? 100 : 70),
sentanceArray(context),
SizedBox(height: isTall ? 20 : 15),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return PrintWallet(
_generateWalletProvider.generatedMnemonic);
}),
);
},
child: Image.asset(
'assets/printer.png',
height: 35,
),
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('generateMnemonic'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: const Color(0xffFFD58D),
onPrimary: Colors.black, // foreground
),
onPressed: () {
_generateWalletProvider.reloadBuild();
},
child: const Text("Choisir une autre phrase",
style: TextStyle(fontSize: 20))),
))),
const SizedBox(height: 25),
SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goStep8'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
_generateWalletProvider.nbrWord =
_generateWalletProvider.getRandomInt();
_generateWalletProvider.nbrWordAlpha =
_generateWalletProvider
.intToString(_generateWalletProvider.nbrWord + 1);
_myWalletProvider.mnemonic =
_generateWalletProvider.generatedMnemonic!;
Navigator.push(
context,
FaderTransition(
page: OnboardingStepTen(
generatedMnemonic:
_generateWalletProvider.generatedMnemonic),
isFast: true),
);
},
child: const Text("J'ai noté ma phrase",
style: TextStyle(fontSize: 20))),
),
const SizedBox(height: 80),
]),
));
}
}
Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
List formatedArray = _generateWalletProvider.generateWordList();
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Container(
constraints: const BoxConstraints(maxWidth: 450),
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: Colors.grey[300],
borderRadius: const BorderRadius.all(
Radius.circular(10),
)),
// color: Colors.grey[300],
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(formatedArray[0]),
arrayCell(formatedArray[1]),
arrayCell(formatedArray[2]),
arrayCell(formatedArray[3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray[4]),
arrayCell(formatedArray[5]),
arrayCell(formatedArray[6]),
arrayCell(formatedArray[7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray[8]),
arrayCell(formatedArray[9]),
arrayCell(formatedArray[10]),
arrayCell(formatedArray[11]),
]),
]),
),
);
}
Widget arrayCell(dataWord) {
return SizedBox(
width: 102,
child: Column(children: <Widget>[
Text(
dataWord.split(':')[0],
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 2),
Text(
dataWord.split(':')[1],
key: Key('word${dataWord.split(':')[0]}'),
style: const TextStyle(fontSize: 19, color: Colors.black),
),
]),
);
}
// ignore: must_be_immutable
class PrintWallet extends StatelessWidget {
const PrintWallet(this.sentence, {Key? key}) : super(key: key);
final String? sentence;
@override
Widget build(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pop(context);
}),
toolbarHeight: 60 * ratio,
title: const Text('Imprimer ce trousseau')),
body: PdfPreview(
build: (format) => _generateWalletProvider.printWallet(sentence),
), ),
), ),
extendBodyBehindAppBar: true,
body: SafeArea(
child: common.infoIntro(
context,
<TextSpan>[
const TextSpan(
text:
'Gecko va maintenant générer pour vous un code secret court qui vous permettra daccéder rapidement à vos portefeuilles, sans avoir à taper votre phrase de restauration à chaque fois.'),
],
'coffre-fort-code-secret-dans-telephone.png',
'>',
const OnboardingStepEight(),
6,
boxHeight: 400),
),
); );
} }
} }

View File

@ -2,134 +2,47 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/screens/onBoarding/9.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable class OnboardingStepEight extends StatelessWidget {
class OnboardingStepTen extends StatelessWidget { const OnboardingStepEight({Key? key}) : super(key: key);
OnboardingStepTen({
Key? validationKey,
required this.generatedMnemonic,
}) : super(key: validationKey);
String? generatedMnemonic;
TextEditingController tplController = TextEditingController();
TextEditingController wordController = TextEditingController();
final TextEditingController _mnemonicController = TextEditingController();
final int progress = 7;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
_mnemonicController.text = generatedMnemonic!; return Scaffold(
appBar: AppBar(
return WillPopScope( toolbarHeight: 60 * ratio,
onWillPop: () { title: const SizedBox(
_generateWalletProvider.isAskedWordValid = false; height: 22,
_generateWalletProvider.askedWordColor = Colors.black; child: Text(
return Future<bool>.value(true); 'Mon code secret',
}, style: TextStyle(fontWeight: FontWeight.w600),
child: Scaffold( ),
resizeToAvoidBottomInset: false, ),
extendBodyBehindAppBar: true, ),
body: SafeArea( extendBodyBehindAppBar: true,
child: Column(children: <Widget>[ body: SafeArea(
common.onboardingProgressBar( child: common.infoIntro(
context, 'Valider ma phrase de restauration', progress), context,
common.bubbleSpeakRich( <TextSpan>[
<TextSpan>[ const TextSpan(
TextSpan( text:
text: 'Ce code secret protège vos portefeuilles dans un coffre-fort '),
"Avez-vous bien noté votre phrase de restauration ?\n\nPour en être sûr, veuillez taper dans le champ ci-dessous le ", const TextSpan(
style: TextStyle(fontSize: 16 * ratio)), text: 'dont vous seul possédez le code',
TextSpan( style: TextStyle(fontWeight: FontWeight.bold)),
text: '${_generateWalletProvider.nbrWord + 1}ème mot', const TextSpan(
style: TextStyle( text:
fontWeight: FontWeight.bold, fontSize: 16 * ratio)), ', de sorte que vos portefeuilles seront inutilisables par dautres.'),
TextSpan( ],
text: " de votre phrase de restauration :", 'coffre-fort-protege-les-portefeuilles.png',
style: TextStyle(fontSize: 16 * ratio)), '>',
], const OnboardingStepThirteen(),
textKey: const Key('step8'), 7),
), ),
SizedBox(height: isTall ? 70 : 10), );
Text('${_generateWalletProvider.nbrWord + 1}',
key: const Key('askedWord'),
style: TextStyle(
fontSize: isTall ? 17 : 10,
color: orangeC,
fontWeight: FontWeight.w400)),
SizedBox(height: isTall ? 10 : 0),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(
color: Colors.grey[600]!,
width: 3,
)),
width: 430,
child: TextFormField(
key: const Key('inputWord'),
autofocus: true,
enabled: !_generateWalletProvider.isAskedWordValid,
controller: wordController,
textInputAction: TextInputAction.next,
onChanged: (value) {
_generateWalletProvider.checkAskedWord(
value, _mnemonicController.text);
},
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 22.0,
color: Colors.grey[500],
fontWeight: FontWeight.w500),
labelText: _generateWalletProvider.isAskedWordValid
? "C'est le bon mot !"
: "${_generateWalletProvider.nbrWordAlpha} mot de votre phrase de restauration",
fillColor: Colors.grey[300],
filled: true,
contentPadding: const EdgeInsets.all(12),
),
style: TextStyle(
fontSize: 40.0,
color: _generateWalletProvider.askedWordColor,
fontWeight: FontWeight.w500))),
Visibility(
visible: _generateWalletProvider.isAskedWordValid,
child: Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 400,
height: 62,
child: ElevatedButton(
key: const Key('goStep9'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
FaderTransition(
page: OnboardingStepEleven(),
isFast: true),
);
},
child: const Text("Continuer",
style: TextStyle(fontSize: 20))),
)))),
const SizedBox(height: 80),
]),
)));
} }
} }

View File

@ -1,71 +1,109 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/10.dart'; import 'package:gecko/screens/onBoarding/10.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class OnboardingStepEleven extends StatelessWidget { class OnboardingStepThirteen extends StatelessWidget {
TextEditingController tplController = TextEditingController(); const OnboardingStepThirteen({Key? key}) : super(key: key);
final int progress = 8;
OnboardingStepEleven({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
// MyWalletsProvider myWalletProvider =
// Provider.of<MyWalletsProvider>(context);
CommonElements common = CommonElements(); CommonElements common = CommonElements();
_generateWalletProvider.pin.text = kDebugMode && debugPin
? 'AAAAA'
: _generateWalletProvider.changePinCode(reload: false);
return Scaffold( return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text(
'Mon code secret',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
common.onboardingProgressBar( SizedBox(height: isTall ? 40 : 20),
context, 'Ma phrase de restauration', progress), common.buildProgressBar(8),
common.bubbleSpeakRich( SizedBox(height: isTall ? 40 : 20),
common.buildText(
<TextSpan>[ <TextSpan>[
const TextSpan( const TextSpan(
text: "Super !\n\nJe vais maintenant créer votre "), text:
"Et voilà votre code secret !\n\nMémorisez-le ou notez-le, car il vous sera demandé "),
const TextSpan( const TextSpan(
text: 'code secret.', text: 'à chaque fois',
style: TextStyle(fontWeight: FontWeight.bold)), style: TextStyle(fontWeight: FontWeight.bold)),
const TextSpan( const TextSpan(
text: text:
" \n\nVotre code secret chiffre votre trousseau de clefs, ce qui le rend inutilisable par dautres, par exemple si vous perdez votre téléphone ou si on vous le vole."), " que vous voudrez effectuer un paiement sur cet appareil."),
], ],
textKey: const Key('step9'),
), ),
SizedBox(height: isTall ? 50 : 10), const SizedBox(height: 100),
Image.asset( Stack(
'assets/onBoarding/treasure-chest-gecko-souligne.png', alignment: Alignment.centerRight,
height: 280 * ratio, //5": 400 children: <Widget>[
TextField(
key: const Key('generatedPin'),
enabled: false,
controller: _generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
letterSpacing: 5,
fontSize: 35.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.replay),
color: orangeC,
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
),
],
), ),
Expanded( Expanded(
child: Align( child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: SizedBox( child: SizedBox(
width: 400, width: 410,
height: 62, height: 70,
child: ElevatedButton( child: ElevatedButton(
key: const Key('goStep10'), key: const Key('changeSecretCode'),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
elevation: 5, elevation: 4,
primary: orangeC, primary: const Color(0xffFFD58D),
onPrimary: Colors.white, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: () { onPressed: () {
Navigator.push( _generateWalletProvider.changePinCode(reload: true);
context,
FaderTransition(
page: OnboardingStepTwelve(), isFast: true),
);
}, },
child: const Text("J'ai compris", child: const Text("Choisir un autre code secret",
style: TextStyle(fontSize: 20))), style: TextStyle(
fontSize: 24, fontWeight: FontWeight.w600))),
))), ))),
const SizedBox(height: 80), const SizedBox(height: 25),
common.nextButton(context, "J'ai noté mon code secret",
OnboardingStepFourteen(), false),
const SizedBox(height: 40),
]), ]),
)); ));
} }

View File

@ -3,6 +3,7 @@ import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/providers/search.dart'; import 'package:gecko/providers/search.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/screens/wallet_view.dart';
@ -57,9 +58,9 @@ class SearchResultScreen extends StatelessWidget {
), ),
), ),
const SizedBox(height: 40), const SizedBox(height: 40),
const Text( Text(
'Dans la blockchain Ğ1', 'Dans la blockchain $currencyName',
style: TextStyle(fontSize: 20), style: const TextStyle(fontSize: 20),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
FutureBuilder( FutureBuilder(
@ -107,9 +108,11 @@ class SearchResultScreen extends StatelessWidget {
]); ]);
} }
if (_avatar.hasData) { if (_avatar.hasData) {
g1WalletsBox final _w =
.get(g1Wallet.pubkey)! g1WalletsBox.get(g1Wallet.pubkey);
.avatar = _avatar.data; if (_w != null) {
_w.avatar = _avatar.data;
}
return ClipOval(child: _avatar.data); return ClipOval(child: _avatar.data);
} else { } else {
g1WalletsBox g1WalletsBox
@ -131,6 +134,11 @@ class SearchResultScreen extends StatelessWidget {
fontWeight: FontWeight.w500), fontWeight: FontWeight.w500),
textAlign: TextAlign.center), textAlign: TextAlign.center),
]), ]),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
balance(context, g1Wallet.pubkey!, 16)
]),
subtitle: Row(children: <Widget>[ subtitle: Row(children: <Widget>[
Text(g1Wallet.id?.username ?? '', Text(g1Wallet.id?.username ?? '',
style: const TextStyle( style: const TextStyle(

View File

@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
import 'package:durt/durt.dart'; import 'package:durt/durt.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/myWallets/generate_wallets.dart'; import 'package:gecko/screens/myWallets/generate_wallets.dart';
import 'dart:io'; import 'dart:io';
import 'package:gecko/screens/myWallets/import_cesium_wallet.dart'; // import 'package:gecko/screens/myWallets/import_cesium_wallet.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class SettingsScreen extends StatelessWidget { class SettingsScreen extends StatelessWidget {
@ -29,105 +31,121 @@ class SettingsScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
const double buttonHigh = 50;
const double buttonWidth = 240;
const double fontSize = 16;
TextEditingController _endpointController =
TextEditingController(text: configBox.get('endpoint'));
// getAppDirectory(); // getAppDirectory();
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
title: const SizedBox( title: const SizedBox(
height: 22, height: 22,
child: Text('Paramètres'), child: Text('Paramètres'),
)), )),
body: Column(children: <Widget>[ body: Column(
const SizedBox(height: 40), // crossAxisAlignment: CrossAxisAlignment.start,
SizedBox( children: <Widget>[
height: 70, const SizedBox(height: 60),
width: 500, Row(children: [
child: ElevatedButton( Text(' Noeud $currencyName :'),
style: ElevatedButton.styleFrom( const SizedBox(width: 20),
elevation: 5, SizedBox(
primary: yellowC, // background width: 200,
onPrimary: Colors.black, // foreground height: 50,
child: TextField(
controller: _endpointController,
autocorrect: false,
),
), ),
onPressed: () => Navigator.push( const Spacer(),
context, Consumer<SubstrateSdk>(builder: (context, _sub, _) {
MaterialPageRoute(builder: (context) { return _sub.isLoadingEndpoint
return const ImportWalletScreen(); ? CircularProgressIndicator(color: orangeC)
}), : IconButton(
).then((value) => { icon: Icon(
if (value == true) {Navigator.pop(context)} Icons.send,
color: orangeC,
size: 40,
),
onPressed: () async {
configBox.put('endpoint', _endpointController.text);
await _sub.connectNode(context);
});
}),
const Spacer(),
]),
SizedBox(height: isTall ? 50 : 20),
SizedBox(
height: buttonHigh,
width: buttonWidth,
child: ElevatedButton(
key: const Key('generateKeychain'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return GenerateFastChestScreen();
}), }),
child: const Text( ),
"Importer un portefeuille Cesium", child: const Text(
style: TextStyle(fontSize: 16), "Générer un coffre",
style: TextStyle(fontSize: fontSize),
),
), ),
), ),
), const SizedBox(height: 20),
const SizedBox(height: 30), SizedBox(
SizedBox( height: buttonHigh,
height: 70, width: buttonWidth,
width: 500, child: ElevatedButton(
child: ElevatedButton( key: const Key('generateKeychain'),
key: const Key('generateKeychain'), style: ElevatedButton.styleFrom(
style: ElevatedButton.styleFrom( elevation: 5,
elevation: 5, primary: yellowC, // background
primary: yellowC, // background onPrimary: Colors.black, // foreground
onPrimary: Colors.black, // foreground ),
), onPressed: () => Navigator.push(
onPressed: () => Navigator.push( context,
context, MaterialPageRoute(builder: (context) {
MaterialPageRoute(builder: (context) { return const RestoreChest();
return GenerateFastChestScreen(); }),
}), ),
), child: const Text(
child: const Text( "Restaurer un coffre",
"Générer un nouveau trousseau", style: TextStyle(fontSize: fontSize),
style: TextStyle(fontSize: 16), ),
), ),
), ),
), const SizedBox(height: 25),
const SizedBox(height: 30), SizedBox(
SizedBox( height: buttonHigh,
height: 70, width: buttonWidth,
width: 500, child: Center(
child: ElevatedButton( child: InkWell(
key: const Key('generateKeychain'), key: const Key('deleteChest'),
style: ElevatedButton.styleFrom( onTap: () async {
elevation: 5, log.i('Oublier tous mes coffres');
primary: yellowC, // background await _myWallets.deleteAllWallet(context);
onPrimary: Colors.black, // foreground },
), child: const Text(
onPressed: () => Navigator.push( 'Oublier tous mes coffres',
context, style: TextStyle(
MaterialPageRoute(builder: (context) { fontSize: fontSize + 3,
return const RestoreChest(); color: Color(0xffD80000),
}), fontWeight: FontWeight.w500,
), ),
child: const Text( ),
"Restaurer un coffre", ),
style: TextStyle(fontSize: 16),
), ),
), ),
), ]),
Expanded( );
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 100,
width: 500,
child: ElevatedButton(
key: const Key('deleteAllWallets'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: Colors.redAccent, // background
onPrimary: Colors.black, // foreground
),
onPressed: () async => {
log.i('Suppression de tous les wallets'),
await _myWallets.deleteAllWallet(context)
},
child: const Text("EFFACER TOUS MES PORTEFEUILLES",
style: TextStyle(fontSize: 20)))))),
const SizedBox(height: 50),
]));
} }
} }

View File

@ -0,0 +1,172 @@
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
class SubstrateSandBox extends StatelessWidget {
const SubstrateSandBox({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
return StatefulWrapper(
onInit: () async {
// if (!_sub.sdkReady && !_sub.sdkLoading) await _sub.initApi();
// if (_sub.sdkReady && !_sub.nodeConnected) await _sub.connectNode();
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Substrate Sandbox'),
),
),
body: SafeArea(
child: Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('js-api chargé ?: ${_sub.sdkReady}'),
InkWell(
onTap: () async {
await _sub.connectNode(context);
},
child: Text(
'Noeud connecté ?: ${_sub.nodeConnected} (${configBox.get('endpoint')})')),
if (_sub.nodeConnected)
Text('Noeud "$currencyName", bloc N°${_sub.blocNumber}'),
const SizedBox(height: 20),
Row(children: [
const Text('Liste des coffres:'),
const Spacer(),
InkWell(
child: Image.asset(
'assets/walletOptions/trash.png',
height: 35,
),
onTap: () async {
await _sub.deleteAllAccounts();
_sub.reload();
},
),
const SizedBox(width: 10),
]),
FutureBuilder(
future: _sub.getKeyStoreAddress(),
builder: (BuildContext context,
AsyncSnapshot<List<AddressInfo>> _data) {
return Column(children: [
if (_data.data != null)
for (final AddressInfo addressInfo in _data.data!)
Row(children: [
InkWell(
onTap: () => _sub.keyring.setCurrent(_sub
.keyring.keyPairs
.firstWhere((element) =>
element.address ==
addressInfo.address!)),
child: Text(
getShortPubkey(addressInfo.address!),
style: const TextStyle(
fontFamily: 'Monospace'),
),
),
const SizedBox(width: 20),
// InkWell(
// onTap: () async => await _sub.pay(
// context,
// addressInfo.address!,
// 10,
// _sub.keystorePassword.text),
// child:
Text(
"${addressInfo.balance.toString()} $currencyName"),
// ),
const SizedBox(width: 20),
InkWell(
onTap: () async => await _sub.derive(
context,
addressInfo.address!,
2,
_sub.keystorePassword.text),
child: const Text("Dériver"),
)
])
]);
}),
const SizedBox(height: 20),
const Text('Mot de passe du coffre:'),
TextField(
controller: _sub.keystorePassword,
obscureText: true,
obscuringCharacter: '',
enableSuggestions: false,
autocorrect: false,
onChanged: (_) => _sub.reload(),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 20, width: double.infinity),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: _sub.keystorePassword.text.isNotEmpty
? () async {
final res = await _sub.importAccount();
_sub.importIsLoading = false;
_sub.reload();
snack(
context,
res != ''
? 'Portefeuille importé'
: 'Le format de coffre est invalide');
}
: null,
child: const Text(
'Importer depuis le presse-papier',
style: TextStyle(fontSize: 20),
),
),
if (_sub.importIsLoading)
const CircularProgressIndicator(),
const SizedBox(height: 20),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () async {
await _sub.generateMnemonic();
_sub.importIsLoading = false;
_sub.reload();
snack(context, 'Le mnemonic a été copié');
},
child: const Text(
"Générer un mnemonic et le copier",
style: TextStyle(fontSize: 20),
),
),
const SizedBox(height: 10),
SizedBox(
width: 400,
child: Text(
_sub.generatedMnemonic,
textAlign: TextAlign.center,
),
)
])
]),
);
}),
),
),
);
}
}

View File

@ -2,15 +2,12 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/screens/avatar_fullscreen.dart'; import 'package:gecko/screens/avatar_fullscreen.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class WalletViewScreen extends StatelessWidget { class WalletViewScreen extends StatelessWidget {
@ -53,7 +50,8 @@ class WalletViewScreen extends StatelessWidget {
height: buttonSize, height: buttonSize,
child: ClipOval( child: ClipOval(
child: Material( child: Material(
color: const Color(0xffFFD58D), // button color color: Colors
.grey[300], //const Color(0xffFFD58D), // button color
child: InkWell( child: InkWell(
key: const Key('viewHistory'), key: const Key('viewHistory'),
splashColor: orangeC, // inkwell color splashColor: orangeC, // inkwell color
@ -64,19 +62,20 @@ class WalletViewScreen extends StatelessWidget {
'assets/walletOptions/clock.png'), 'assets/walletOptions/clock.png'),
height: 90)), height: 90)),
onTap: () { onTap: () {
_historyProvider.nPage = 1; ////TODO: wait for subsquid indexer
Navigator.push( // _historyProvider.nPage = 1;
context, // Navigator.push(
FaderTransition( // context,
page: HistoryScreen( // FaderTransition(
pubkey: pubkey, // page: HistoryScreen(
username: username ?? // pubkey: pubkey,
g1WalletsBox.get(pubkey)?.username, // username: username ??
avatar: avatar ?? // g1WalletsBox.get(pubkey)?.username,
g1WalletsBox.get(pubkey)?.avatar, // avatar: avatar ??
), // g1WalletsBox.get(pubkey)?.avatar,
isFast: false), // ),
); // isFast: false),
// );
}), }),
), ),
), ),
@ -105,7 +104,7 @@ class WalletViewScreen extends StatelessWidget {
height: 90)), height: 90)),
onTap: () { onTap: () {
Clipboard.setData(ClipboardData(text: pubkey)); Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context); snackCopyKey(context);
}), }),
), ),
), ),
@ -191,6 +190,7 @@ class WalletViewScreen extends StatelessWidget {
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest')); _myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
_walletViewProvider.outputPubkey.text = pubkey!;
showModalBottomSheet<void>( showModalBottomSheet<void>(
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
@ -254,7 +254,7 @@ class WalletViewScreen extends StatelessWidget {
// onChanged: (v) => _searchProvider.rebuildWidget(), // onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration( decoration: InputDecoration(
hintText: '0.00', hintText: '0.00',
suffix: const Text('Ğ1'), suffix: Text(currencyName),
filled: true, filled: true,
fillColor: Colors.transparent, fillColor: Colors.transparent,
// border: OutlineInputBorder( // border: OutlineInputBorder(
@ -285,21 +285,21 @@ class WalletViewScreen extends StatelessWidget {
primary: orangeC, // background primary: orangeC, // background
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: onPressed: _walletViewProvider.payAmount.text !=
_walletViewProvider.payAmount.text != '' ''
? () { ? () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) { builder: (context) {
return UnlockingWallet( return UnlockingWallet(
wallet: defaultWallet, wallet: defaultWallet,
action: "pay"); action: "pay");
}, },
), ),
); );
} }
: null, : null,
child: const Text( child: const Text(
'Effectuer le virement', 'Effectuer le virement',
style: TextStyle( style: TextStyle(
@ -351,7 +351,7 @@ class WalletViewScreen extends StatelessWidget {
key: const Key('copyPubkey'), key: const Key('copyPubkey'),
onTap: () { onTap: () {
Clipboard.setData(ClipboardData(text: pubkey)); Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context); snackCopyKey(context);
}, },
child: Text( child: Text(
_historyProvider.getShortPubkey(pubkey!), _historyProvider.getShortPubkey(pubkey!),
@ -362,40 +362,45 @@ class WalletViewScreen extends StatelessWidget {
), ),
), ),
]), ]),
const SizedBox(height: 10), const SizedBox(height: 25),
if (username == null && Consumer<WalletOptionsProvider>(
g1WalletsBox.get(pubkey)?.username == null) builder: (context, walletProvider, _) {
Query( return balance(context, pubkey!, 20);
options: QueryOptions( }),
document: gql(getId), ////
variables: { // if (username == null &&
'pubkey': pubkey, // g1WalletsBox.get(pubkey)?.username == null)
}, // Query(
), // options: QueryOptions(
builder: (QueryResult result, // document: gql(getId),
{VoidCallback? refetch, FetchMore? fetchMore}) { // variables: {
if (result.isLoading || result.hasException) { // 'pubkey': pubkey,
return const Text('...'); // },
} else if (result.data!['idty'] == null || // ),
result.data!['idty']['username'] == null) { // builder: (QueryResult result,
g1WalletsBox.get(pubkey)?.username = ''; // {VoidCallback? refetch, FetchMore? fetchMore}) {
return const Text(''); // if (result.isLoading || result.hasException) {
} else { // return const Text('...');
g1WalletsBox.get(pubkey)?.username = // } else if (result.data!['idty'] == null ||
result.data!['idty']['username'] ?? ''; // result.data!['idty']['username'] == null) {
return SizedBox( // g1WalletsBox.get(pubkey)?.username = '';
width: 230, // return const Text('');
child: Text( // } else {
result.data!['idty']['username'] ?? '', // g1WalletsBox.get(pubkey)?.username =
style: const TextStyle( // result.data!['idty']['username'] ?? '';
fontSize: 27, // return SizedBox(
color: Color(0xff814C00), // width: 230,
), // child: Text(
), // result.data!['idty']['username'] ?? '',
); // style: const TextStyle(
} // fontSize: 27,
}, // color: Color(0xff814C00),
), // ),
// ),
// );
// }
// },
// ),
if (username == null && if (username == null &&
g1WalletsBox.get(pubkey)?.username != null) g1WalletsBox.get(pubkey)?.username != null)
SizedBox( SizedBox(
@ -420,19 +425,20 @@ class WalletViewScreen extends StatelessWidget {
), ),
), ),
const SizedBox(height: 25), const SizedBox(height: 25),
FutureBuilder( //// To get Cs+ name
future: _cesiumPlusProvider.getName(pubkey), // FutureBuilder(
initialData: '...', // future: _cesiumPlusProvider.getName(pubkey),
builder: (context, snapshot) { // initialData: '...',
return SizedBox( // builder: (context, snapshot) {
width: 230, // return SizedBox(
child: Text( // width: 230,
snapshot.data.toString(), // child: Text(
style: const TextStyle( // snapshot.data.toString(),
fontSize: 18, color: Colors.black), // style: const TextStyle(
), // fontSize: 18, color: Colors.black),
); // ),
}), // );
// }),
const SizedBox(height: 30), const SizedBox(height: 30),
]), ]),
const Spacer(), const Spacer(),

View File

@ -6,19 +6,21 @@ import FlutterMacOS
import Foundation import Foundation
import connectivity_plus_macos import connectivity_plus_macos
import package_info import desktop_window
import package_info_plus_macos import package_info_plus_macos
import path_provider_macos import path_provider_macos
import printing import printing
import sentry_flutter import sentry_flutter
import shared_preferences_macos import shared_preferences_macos
import window_size
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) DesktopWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWindowPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin")) SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
WindowSizePlugin.register(with: registry.registrar(forPlugin: "WindowSizePlugin"))
} }

View File

@ -8,7 +8,7 @@
PRODUCT_NAME = gecko PRODUCT_NAME = gecko
// The application's bundle identifier // The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.example.gecko PRODUCT_BUNDLE_IDENTIFIER = gecko.axiomteam.fr
// The copyright displayed in application information // The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. PRODUCT_COPYRIGHT = Copyright © 2021 gecko.axiomteam.fr. All rights reserved.

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages. # pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.4+8 version: 0.0.5+3
environment: environment:
sdk: '>=2.12.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
@ -17,7 +17,7 @@ dependencies:
sdk: flutter sdk: flutter
window_size: window_size:
git: git:
url: git://github.com/google/flutter-desktop-embedding.git url: https://github.com/google/flutter-desktop-embedding.git
path: plugins/window_size path: plugins/window_size
assorted_layout_widgets: ^5.2.1 assorted_layout_widgets: ^5.2.1
bubble: ^1.2.1 bubble: ^1.2.1
@ -25,11 +25,14 @@ dependencies:
confirm_dialog: ^1.0.0 confirm_dialog: ^1.0.0
crypto: ^3.0.1 crypto: ^3.0.1
fast_base58: ^0.2.0 fast_base58: ^0.2.0
flutter_launcher_icons: ^0.9.2
flutter_lints: ^1.0.4 flutter_lints: ^1.0.4
flutter_logs: ^2.1.4 flutter_logs: ^2.1.4
flutter_svg: ^0.22.0 flutter_svg: ^0.22.0
graphql_flutter: ^5.0.0 graphql_flutter: #^5.1.0
git:
url: https://github.com/Quantit-Github/graphql-flutter.git
path: packages/graphql_flutter
ref: f1ccb2d # commit hash
hive: ^2.0.4 hive: ^2.0.4
hive_flutter: ^1.1.0 hive_flutter: ^1.1.0
http: ^0.13.4 http: ^0.13.4
@ -43,25 +46,25 @@ dependencies:
pdf: ^3.7.1 pdf: ^3.7.1
permission_handler: ^8.3.0 permission_handler: ^8.3.0
pin_code_fields: ^7.3.0 pin_code_fields: ^7.3.0
printing: ^5.7.2 printing: #^5.8.0
git:
url: https://github.com/DavBfr/dart_pdf.git
path: printing
provider: ^6.0.1 provider: ^6.0.1
# qrscan: ^0.3.2 qrscan: #^0.3.2
qrscan:
git: git:
url: git://github.com/leyan95/qrcode_scanner.git url: https://github.com/leyan95/qrcode_scanner.git
ref: master # branch name ref: master # branch name
# qr_code_scanner: ^0.6.1 # qr_code_scanner: ^0.6.1
# qr_flutter: ^4.0.0 qr_flutter: #^4.0.0
qr_flutter:
git: git:
url: git://github.com/insinfo/qr.flutter.git url: https://github.com/insinfo/qr.flutter.git
ref: master # branch name ref: master # branch name
responsive_builder: ^0.4.1 responsive_builder: ^0.4.1
responsive_framework: ^0.1.4 responsive_framework: ^0.1.4
sentry: ^6.0.0 sentry: ^6.5.1
sentry_flutter: ^6.0.0 sentry_flutter: ^6.5.1
shared_preferences: ^2.0.7 shared_preferences: ^2.0.7
super_tooltip: ^1.0.1
sync_http: ^0.3.0 sync_http: ^0.3.0
test: ^1.17.10 test: ^1.17.10
truncate: ^3.0.1 truncate: ^3.0.1
@ -71,15 +74,17 @@ dependencies:
dio: ^4.0.4 dio: ^4.0.4
desktop_window: ^0.4.0 desktop_window: ^0.4.0
durt: ^0.1.6 durt: ^0.1.6
package_info_plus: ^1.3.0 package_info_plus: ^1.4.2
polkawallet_sdk: #^0.4.5
flutter_icons: git:
android: "ic_launcher" url: https://github.com/poka-IT/sdk.git
ios: true ref: fixAndroidActivityVersion
image_path: "assets/icon/gecko_flat.png" dots_indicator: ^2.1.0
cupertino_icons: ^1.0.0
dev_dependencies: dev_dependencies:
# flutter_launcher_icons: ^0.9.2
# flutter_launcher_icons_maker: ^^0.10.2
icons_launcher: ^1.1.8
build_runner: ^2.1.2 build_runner: ^2.1.2
flutter_test: flutter_test:
sdk: flutter sdk: flutter
@ -87,6 +92,14 @@ dev_dependencies:
integration_test: integration_test:
sdk: flutter sdk: flutter
flutter_icons:
android: true
ios: true
image_path: "assets/icon/gecko_flat.png"
remove_alpha_ios: true
uses-material-design: true
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:
uses-material-design: true uses-material-design: true

View File

@ -19,7 +19,7 @@ cargo make
# Build APK # Build APK
echo "Build APK..." echo "Build APK..."
flutter clean #flutter clean
flutter build apk --release --build-name $VERSION --build-number $BUILD flutter build apk --release --build-name $VERSION --build-number $BUILD
# Create artifacts folder # Create artifacts folder

View File

@ -22,7 +22,9 @@ else
# flutter build apk --release --build-name $VERSION --build-number $BUILD # flutter build apk --release --build-name $VERSION --build-number $BUILD
fi fi
if [[ -d $HOME/Téléchargements ]]; then if [[ -d $HOME/Nextcloud/Gecko-APK ]]; then
DL="$HOME/Nextcloud/Gecko-APK"
elif [[ -d $HOME/Téléchargements ]]; then
DL="$HOME/Téléchargements" DL="$HOME/Téléchargements"
elif [[ -d $HOME/Downloads ]]; then elif [[ -d $HOME/Downloads ]]; then
DL="$HOME/Downloads" DL="$HOME/Downloads"

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
flutter pub run flutter_launcher_icons:main flutter pub run icons_launcher:main
exit 0 exit 0

View File

@ -216,7 +216,7 @@ void main() {
test('OnBoarding - Generate secret code and confirm it', ( test('OnBoarding - Generate secret code and confirm it', (
{timeout = Timeout.none}) async { {timeout = Timeout.none}) async {
expect(await getText('step9'), 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 dautres, par exemple si vous perdez votre téléphone ou si on vous le vole."); "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 dautres, par exemple si vous perdez votre téléphone ou si on vous le vole.");
await sleep(800); await sleep(800);
await tapOn('goStep10'); await tapOn('goStep10');
await sleep(50); await sleep(50);
@ -248,7 +248,7 @@ void main() {
await driver!.enterText(pinCode!); await driver!.enterText(pinCode!);
expect(await getText('step13'), 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 !"); "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', ( test('My wallets - Rename first derivation', (

View File

@ -10,6 +10,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
window_size window_size
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST}) foreach(plugin ${FLUTTER_PLUGIN_LIST})
@ -18,3 +21,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>) list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin) endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)

Some files were not shown because too many files have changed in this diff Show More