WIP: Manage keystore

This commit is contained in:
poka 2022-02-18 02:19:08 +01:00
parent 3513b0440d
commit 1f1f7a3e85
11 changed files with 169 additions and 74 deletions

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/models/chest_data.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:hive/hive.dart';
import 'package:logger/logger.dart';
@ -20,6 +21,7 @@ late Box<WalletData> walletBox;
late Box<ChestData> chestBox;
late Box configBox;
late Box<G1WalletsList> g1WalletsBox;
late Box<KeyStoreData> keystoreBox;
String cesiumPod = "https://g1.data.le-sou.org";
// String cesiumPod = "https://g1.data.e-is.pro";

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
// it under the terms of the GNU Affero General Public License as
@ -19,6 +19,7 @@ import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/keystore_data.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/change_pin.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:graphql_flutter/graphql_flutter.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
import 'package:responsive_framework/responsive_framework.dart';
@ -66,10 +68,13 @@ Future<void> main() async {
Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter());
Hive.registerAdapter(KeyStoreDataAdapter());
Hive.registerAdapter(KeyPairData());
walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox");
configBox = await Hive.openBox("configBox");
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
keystoreBox = await Hive.openBox<KeyStoreData>("keystoreBox");
g1WalletsBox.clear();

View File

@ -1,7 +1,5 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_local_variable
part of 'g1_wallets_list.dart';
// **************************************************************************
@ -66,10 +64,6 @@ class IdAdapter extends TypeAdapter<Id> {
@override
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();
}

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 'package:hive_flutter/hive_flutter.dart';
part 'wallet_data.g.dart';
@HiveType(typeId: 0)

View File

@ -1,4 +1,7 @@
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/polkawallet_sdk.dart';
import 'package:polkawallet_sdk/storage/keyring.dart';
@ -13,6 +16,9 @@ class SubstrateSdk with ChangeNotifier {
bool nodeConnected = false;
int blocNumber = 0;
TextEditingController jsonKeystore = TextEditingController();
TextEditingController keystorePassword = TextEditingController();
Future<void> initApi() async {
await keyring.init([0, 2]);
@ -42,4 +48,28 @@ class SubstrateSdk with ChangeNotifier {
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();
}
}

View File

@ -1,5 +1,6 @@
import 'package:bubble/bubble.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/wallets_profiles.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}) {
return Bubble(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/change_pin.dart';
import 'package:gecko/providers/my_wallets.dart';
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;
}
}

View File

@ -1,5 +1,6 @@
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';
@ -33,6 +34,42 @@ class SubstrateSandBox extends StatelessWidget {
'Noeud connecté ?: ${_sub.nodeConnected} (${_sub.subNode})'),
if (_sub.nodeConnected)
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;
}
}