forked from axiom-team/gecko
WIP: Manage keystore
This commit is contained in:
parent
3513b0440d
commit
1f1f7a3e85
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.dart';
|
||||||
import 'package:gecko/models/g1_wallets_list.dart';
|
import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
|
import 'package:gecko/models/keystore_data.dart';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
@ -20,6 +21,7 @@ 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<KeyStoreData> keystoreBox;
|
||||||
|
|
||||||
String cesiumPod = "https://g1.data.le-sou.org";
|
String cesiumPod = "https://g1.data.le-sou.org";
|
||||||
// String cesiumPod = "https://g1.data.e-is.pro";
|
// String cesiumPod = "https://g1.data.e-is.pro";
|
||||||
|
|
|
@ -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
|
||||||
|
@ -19,6 +19,7 @@ import 'dart:async';
|
||||||
import 'dart:io';
|
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/models/keystore_data.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/providers/change_pin.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.dart';
|
||||||
|
@ -39,6 +40,7 @@ import 'package:gecko/screens/search.dart';
|
||||||
import 'package:gecko/screens/search_result.dart';
|
import 'package:gecko/screens/search_result.dart';
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:responsive_framework/responsive_framework.dart';
|
import 'package:responsive_framework/responsive_framework.dart';
|
||||||
|
@ -66,10 +68,13 @@ 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());
|
||||||
|
Hive.registerAdapter(KeyPairData());
|
||||||
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");
|
||||||
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
|
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
|
||||||
|
keystoreBox = await Hive.openBox<KeyStoreData>("keystoreBox");
|
||||||
|
|
||||||
g1WalletsBox.clear();
|
g1WalletsBox.clear();
|
||||||
|
|
||||||
|
|
|
@ -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';
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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!;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/keystore_data.dart';
|
||||||
|
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||||
import 'package:polkawallet_sdk/api/types/networkParams.dart';
|
import 'package:polkawallet_sdk/api/types/networkParams.dart';
|
||||||
import 'package:polkawallet_sdk/polkawallet_sdk.dart';
|
import 'package:polkawallet_sdk/polkawallet_sdk.dart';
|
||||||
import 'package:polkawallet_sdk/storage/keyring.dart';
|
import 'package:polkawallet_sdk/storage/keyring.dart';
|
||||||
|
@ -13,6 +16,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
bool nodeConnected = false;
|
bool nodeConnected = false;
|
||||||
int blocNumber = 0;
|
int blocNumber = 0;
|
||||||
|
|
||||||
|
TextEditingController jsonKeystore = TextEditingController();
|
||||||
|
TextEditingController keystorePassword = TextEditingController();
|
||||||
|
|
||||||
Future<void> initApi() async {
|
Future<void> initApi() async {
|
||||||
await keyring.init([0, 2]);
|
await keyring.init([0, 2]);
|
||||||
|
|
||||||
|
@ -42,4 +48,28 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> importFromKeystore() async {
|
||||||
|
final json = await sdk.api.keyring.importAccount(
|
||||||
|
keyring,
|
||||||
|
keyType: KeyType.keystore,
|
||||||
|
key: jsonKeystore.text,
|
||||||
|
name: 'testKey',
|
||||||
|
password: keystorePassword.text,
|
||||||
|
);
|
||||||
|
final acc = await sdk.api.keyring.addAccount(
|
||||||
|
keyring,
|
||||||
|
keyType: KeyType.mnemonic,
|
||||||
|
acc: json!,
|
||||||
|
password: keystorePassword.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
KeyStoreData _keystore = KeyStoreData(keystore: acc);
|
||||||
|
await keystoreBox.add(_keystore);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reload() {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -532,27 +533,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(
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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/models/stateful_wrapper.dart';
|
||||||
import 'package:gecko/providers/change_pin.dart';
|
import 'package:gecko/providers/change_pin.dart';
|
||||||
import 'package:gecko/providers/my_wallets.dart';
|
import 'package:gecko/providers/my_wallets.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
@ -116,25 +117,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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/stateful_wrapper.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -33,6 +34,42 @@ class SubstrateSandBox extends StatelessWidget {
|
||||||
'Noeud connecté ?: ${_sub.nodeConnected} (${_sub.subNode})'),
|
'Noeud connecté ?: ${_sub.nodeConnected} (${_sub.subNode})'),
|
||||||
if (_sub.nodeConnected)
|
if (_sub.nodeConnected)
|
||||||
Text('Numéro de bloc: ${_sub.blocNumber}'),
|
Text('Numéro de bloc: ${_sub.blocNumber}'),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text('List des trousseaux:'),
|
||||||
|
Text(keystoreBox.isEmpty
|
||||||
|
? '-'
|
||||||
|
: keystoreBox.toMap().entries.toString()),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text('Trousseau:'),
|
||||||
|
TextField(
|
||||||
|
controller: _sub.jsonKeystore,
|
||||||
|
onChanged: (_) => _sub.reload(),
|
||||||
|
minLines: 5,
|
||||||
|
maxLines: 5,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text('Mot de passe:'),
|
||||||
|
TextField(
|
||||||
|
controller: _sub.keystorePassword,
|
||||||
|
onChanged: (_) => _sub.reload(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: yellowC, // background
|
||||||
|
onPrimary: Colors.black, // foreground
|
||||||
|
),
|
||||||
|
onPressed: _sub.jsonKeystore.text.isNotEmpty &&
|
||||||
|
_sub.keystorePassword.text.isNotEmpty
|
||||||
|
? () async => await _sub.importFromKeystore()
|
||||||
|
: null,
|
||||||
|
child: const Text(
|
||||||
|
'Importer la trousseau',
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -40,25 +77,3 @@ class SubstrateSandBox extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue