Added selection of new wallet type. Returned support of bitcoin wallet.

This commit is contained in:
M 2020-11-12 18:31:53 +02:00
parent 37d3bf3fa9
commit e8f53766a0
10 changed files with 110 additions and 57 deletions

View file

@ -58,6 +58,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
{@required String password, {@required String password,
@required String name, @required String name,
@required String dirPath, @required String dirPath,
@required WalletInfo walletInfo,
String jsonSource}) { String jsonSource}) {
final data = json.decode(jsonSource) as Map; final data = json.decode(jsonSource) as Map;
final mnemonic = data['mnemonic'] as String; final mnemonic = data['mnemonic'] as String;
@ -83,7 +84,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
name: name, name: name,
accountIndex: accountIndex, accountIndex: accountIndex,
initialAddresses: addresses, initialAddresses: addresses,
initialBalance: balance); initialBalance: balance,
walletInfo: walletInfo);
} }
static BitcoinWallet build( static BitcoinWallet build(
@ -91,6 +93,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
@required String password, @required String password,
@required String name, @required String name,
@required String dirPath, @required String dirPath,
@required WalletInfo walletInfo,
List<BitcoinAddressRecord> initialAddresses, List<BitcoinAddressRecord> initialAddresses,
BitcoinBalance initialBalance, BitcoinBalance initialBalance,
int accountIndex = 0}) { int accountIndex = 0}) {
@ -107,7 +110,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
accountIndex: accountIndex, accountIndex: accountIndex,
initialAddresses: initialAddresses, initialAddresses: initialAddresses,
initialBalance: initialBalance, initialBalance: initialBalance,
transactionHistory: history); transactionHistory: history,
walletInfo: walletInfo);
} }
@override @override

View file

@ -1,21 +1,23 @@
import 'package:cake_wallet/core/wallet_credentials.dart'; import 'package:cake_wallet/core/wallet_credentials.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
class BitcoinNewWalletCredentials extends WalletCredentials { class BitcoinNewWalletCredentials extends WalletCredentials {
BitcoinNewWalletCredentials({String name}) : super(name: name); BitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
: super(name: name, walletInfo: walletInfo);
} }
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials { class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
BitcoinRestoreWalletFromSeedCredentials( BitcoinRestoreWalletFromSeedCredentials(
{String name, String password, this.mnemonic}) {String name, String password, this.mnemonic, WalletInfo walletInfo})
: super(name: name, password: password); : super(name: name, password: password, walletInfo: walletInfo);
final String mnemonic; final String mnemonic;
} }
class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials { class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
BitcoinRestoreWalletFromWIFCredentials( BitcoinRestoreWalletFromWIFCredentials(
{String name, String password, this.wif}) {String name, String password, this.wif, WalletInfo walletInfo})
: super(name: name, password: password); : super(name: name, password: password, walletInfo: walletInfo);
final String wif; final String wif;
} }

View file

@ -2,15 +2,22 @@ import 'dart:io';
import 'package:bip39/bip39.dart' as bip39; import 'package:bip39/bip39.dart' as bip39;
import 'package:cake_wallet/bitcoin/file.dart'; import 'package:cake_wallet/bitcoin/file.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/entities/pathForWallet.dart'; import 'package:cake_wallet/entities/pathForWallet.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:hive/hive.dart';
class BitcoinWalletService extends WalletService< class BitcoinWalletService extends WalletService<
BitcoinNewWalletCredentials, BitcoinNewWalletCredentials,
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials> { BitcoinRestoreWalletFromWIFCredentials> {
BitcoinWalletService(this.walletInfoSource);
final Box<WalletInfo> walletInfoSource;
@override @override
Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async { Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async {
final dirPath = await pathForWalletDir( final dirPath = await pathForWalletDir(
@ -19,7 +26,8 @@ class BitcoinWalletService extends WalletService<
dirPath: dirPath, dirPath: dirPath,
mnemonic: bip39.generateMnemonic(), mnemonic: bip39.generateMnemonic(),
password: credentials.password, password: credentials.password,
name: credentials.name); name: credentials.name,
walletInfo: credentials.walletInfo);
await wallet.save(); await wallet.save();
await wallet.init(); await wallet.init();
@ -37,11 +45,15 @@ class BitcoinWalletService extends WalletService<
await pathForWalletDir(name: name, type: WalletType.bitcoin); await pathForWalletDir(name: name, type: WalletType.bitcoin);
final walletPath = '$walletDirPath/$name'; final walletPath = '$walletDirPath/$name';
final walletJSONRaw = await read(path: walletPath, password: password); final walletJSONRaw = await read(path: walletPath, password: password);
final walletInfo = walletInfoSource.values.firstWhere(
(info) => info.id == WalletBase.idFor(name, WalletType.bitcoin),
orElse: () => null);
final wallet = BitcoinWalletBase.fromJSON( final wallet = BitcoinWalletBase.fromJSON(
password: password, password: password,
name: name, name: name,
dirPath: walletDirPath, dirPath: walletDirPath,
jsonSource: walletJSONRaw); jsonSource: walletJSONRaw,
walletInfo: walletInfo);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -68,7 +80,8 @@ class BitcoinWalletService extends WalletService<
dirPath: dirPath, dirPath: dirPath,
name: credentials.name, name: credentials.name,
password: credentials.password, password: credentials.password,
mnemonic: credentials.mnemonic); mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo);
await wallet.save(); await wallet.save();
await wallet.init(); await wallet.init();

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/entities/wallet_info.dart'; import 'package:cake_wallet/entities/wallet_info.dart';
abstract class WalletCredentials { abstract class WalletCredentials {
WalletCredentials({this.name, this.password, this.height}); WalletCredentials({this.name, this.password, this.height, this.walletInfo});
final String name; final String name;
final int height; final int height;

View file

@ -14,6 +14,7 @@ import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/faq/faq_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart'; import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
@ -353,7 +354,7 @@ Future setup(
getIt.registerFactory(() => MoneroWalletService(walletInfoSource)); getIt.registerFactory(() => MoneroWalletService(walletInfoSource));
getIt.registerFactory(() => BitcoinWalletService()); getIt.registerFactory(() => BitcoinWalletService(walletInfoSource));
getIt.registerFactoryParam<WalletService, WalletType, void>( getIt.registerFactoryParam<WalletService, WalletType, void>(
(WalletType param1, __) { (WalletType param1, __) {
@ -397,4 +398,9 @@ Future setup(
transactionInfo, transactionInfo,
getIt.get<SettingsStore>().shouldSaveRecipientAddress, getIt.get<SettingsStore>().shouldSaveRecipientAddress,
transactionDescriptionBox)); transactionDescriptionBox));
getIt.registerFactoryParam<NewWalletTypePage,
void Function(BuildContext, WalletType), bool>(
(para1, param2) => NewWalletTypePage(getIt.get<WalletNewVM>(),
onTypeSelected: para1, isNewWallet: param2));
} }

View file

@ -60,29 +60,18 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newWalletFromWelcome: case Routes.newWalletFromWelcome:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(param1: builder: (_) => getIt.get<SetupPinCodePage>(
(PinCodeState<PinCodeWidget> context, dynamic _) async { param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
try { Navigator.of(context.context)
context.changeProcessText( .pushNamed(Routes.newWalletType)),
'Creating new wallet'); // FIXME: Unnamed constant
final newWalletVM =
getIt.get<WalletNewVM>(param1: WalletType.monero);
await newWalletVM.create(
options: 'English'); // FIXME: Unnamed constant
context.hideProgressText();
await Navigator.of(context.context)
.pushNamed(Routes.seed, arguments: true);
} catch (e) {
context.changeProcessText('Error: ${e.toString()}');
}
}),
fullscreenDialog: true); fullscreenDialog: true);
case Routes.newWalletType: case Routes.newWalletType:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => NewWalletTypePage( builder: (_) => getIt.get<NewWalletTypePage>(
onTypeSelected: (context, type) => Navigator.of(context) param1: (BuildContext context, WalletType _) =>
.pushNamed(Routes.newWallet, arguments: type))); Navigator.of(context).pushNamed(Routes.seed, arguments: true),
param2: true));
case Routes.newWallet: case Routes.newWallet:
final type = WalletType.monero; // settings.arguments as WalletType; final type = WalletType.monero; // settings.arguments as WalletType;
@ -104,11 +93,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.restoreWalletType: case Routes.restoreWalletType:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => NewWalletTypePage( builder: (_) => getIt.get<NewWalletTypePage>(
onTypeSelected: (context, type) => Navigator.of(context) param1: (BuildContext context, WalletType type) =>
.pushNamed(Routes.restoreWalletOptions, arguments: type), Navigator.of(context)
isNewWallet: false, .pushNamed(Routes.restoreWalletFromSeed, arguments: type),
)); param2: false));
case Routes.restoreOptions: case Routes.restoreOptions:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
@ -146,7 +135,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>( builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) => param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
Navigator.pushNamed(context.context, Routes.restoreWallet)), Navigator.pushNamed(context.context, Routes.restoreWalletType)),
fullscreenDialog: true); fullscreenDialog: true);
case Routes.seed: case Routes.seed:
@ -160,12 +149,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
getIt.get<WalletRestorePage>(param1: WalletType.monero)); getIt.get<WalletRestorePage>(param1: WalletType.monero));
case Routes.restoreWalletFromSeed: case Routes.restoreWalletFromSeed:
// final args = settings.arguments as List<dynamic>; final type = settings.arguments as WalletType;
final type = WalletType.monero; //args.first as WalletType;
// final language = type == WalletType.monero
// ? args[1] as String
// : LanguageList.english;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletFromSeedPage(type: type)); builder: (_) => RestoreWalletFromSeedPage(type: type));

View file

@ -1,6 +1,11 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:flushbar/flushbar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
@ -10,25 +15,28 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
class NewWalletTypePage extends BasePage { class NewWalletTypePage extends BasePage {
NewWalletTypePage({this.onTypeSelected, this.isNewWallet = true}); NewWalletTypePage(this.walletNewVM,
{this.onTypeSelected, this.isNewWallet});
final void Function(BuildContext, WalletType) onTypeSelected; final void Function(BuildContext, WalletType) onTypeSelected;
final bool isNewWallet; final bool isNewWallet;
final WalletNewVM walletNewVM;
@override @override
String get title => isNewWallet String get title =>
? S.current.new_wallet isNewWallet ? S.current.new_wallet : S.current.wallet_list_restore_wallet;
: S.current.wallet_list_restore_wallet;
@override @override
Widget body(BuildContext context) => Widget body(BuildContext context) =>
WalletTypeForm(onTypeSelected: onTypeSelected); WalletTypeForm(walletNewVM, isNewWallet, onTypeSelected: onTypeSelected);
} }
class WalletTypeForm extends StatefulWidget { class WalletTypeForm extends StatefulWidget {
WalletTypeForm({this.onTypeSelected}); WalletTypeForm(this.walletNewVM, this.isNewWallet, {this.onTypeSelected});
final void Function(BuildContext, WalletType) onTypeSelected; final void Function(BuildContext, WalletType) onTypeSelected;
final WalletNewVM walletNewVM;
final bool isNewWallet;
@override @override
WalletTypeFormState createState() => WalletTypeFormState(); WalletTypeFormState createState() => WalletTypeFormState();
@ -42,10 +50,12 @@ class WalletTypeFormState extends State<WalletTypeForm> {
final bitcoinIcon = final bitcoinIcon =
Image.asset('assets/images/bitcoin.png', height: 24, width: 24); Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
final walletTypeImage = Image.asset('assets/images/wallet_type.png'); final walletTypeImage = Image.asset('assets/images/wallet_type.png');
final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png'); final walletTypeLightImage =
Image.asset('assets/images/wallet_type_light.png');
WalletType selected; WalletType selected;
List<WalletType> types; List<WalletType> types;
Flushbar<void> _progressBar;
@override @override
void initState() { void initState() {
@ -56,7 +66,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final walletImage = getIt.get<SettingsStore>().isDarkTheme final walletImage = getIt.get<SettingsStore>().isDarkTheme
? walletTypeImage : walletTypeLightImage; ? walletTypeImage
: walletTypeLightImage;
return Container( return Container(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
@ -94,7 +105,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
), ),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: PrimaryButton( bottomSection: PrimaryButton(
onPressed: () => widget.onTypeSelected(context, selected), onPressed: () => onTypeSelected(),
text: S.of(context).seed_language_next, text: S.of(context).seed_language_next,
color: Colors.green, color: Colors.green,
textColor: Colors.white, textColor: Colors.white,
@ -114,4 +125,35 @@ class WalletTypeFormState extends State<WalletTypeForm> {
return null; return null;
} }
} }
Future<void> onTypeSelected() async {
if (!widget.isNewWallet) {
widget.onTypeSelected(context, selected);
return;
}
try {
_changeProcessText(S.of(context).creating_new_wallet);
widget.walletNewVM.type = selected;
await widget.walletNewVM
.create(options: 'English'); // FIXME: Unnamed constant
await _progressBar?.dismiss();
final state = widget.walletNewVM.state;
if (state is ExecutedSuccessfullyState) {
widget.onTypeSelected(context, selected);
}
if (state is FailureState) {
_changeProcessText(
S.of(context).creating_new_wallet_error(state.error));
}
} catch (e) {
_changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
}
}
void _changeProcessText(String text) {
_progressBar = createBar<void>(text, duration: null)..show(context);
}
} }

View file

@ -165,7 +165,7 @@ class WalletListBodyState extends State<WalletListBody> {
), ),
bottomSection: Column(children: <Widget>[ bottomSection: Column(children: <Widget>[
PrimaryImageButton( PrimaryImageButton(
onPressed: () => _generateNewWallet(), onPressed: () => Navigator.of(context).pushNamed(Routes.newWalletType),
image: newWalletImage, image: newWalletImage,
text: S.of(context).wallet_list_create_new_wallet, text: S.of(context).wallet_list_create_new_wallet,
color: Theme.of(context).accentTextTheme.subtitle.decorationColor, color: Theme.of(context).accentTextTheme.subtitle.decorationColor,
@ -175,7 +175,7 @@ class WalletListBodyState extends State<WalletListBody> {
SizedBox(height: 10.0), SizedBox(height: 10.0),
PrimaryImageButton( PrimaryImageButton(
onPressed: () => onPressed: () =>
Navigator.of(context).pushNamed(Routes.restoreWallet), Navigator.of(context).pushNamed(Routes.restoreWalletType),
image: restoreWalletImage, image: restoreWalletImage,
text: S.of(context).wallet_list_restore_wallet, text: S.of(context).wallet_list_restore_wallet,
color: Theme.of(context).accentTextTheme.caption.color, color: Theme.of(context).accentTextTheme.caption.color,

View file

@ -27,7 +27,7 @@ abstract class WalletCreationVMBase with Store {
@observable @observable
ExecutionState state; ExecutionState state;
final WalletType type; WalletType type;
final bool isRecovery; final bool isRecovery;
final Box<WalletInfo> _walletInfoSource; final Box<WalletInfo> _walletInfoSource;
final AppStore _appStore; final AppStore _appStore;

View file

@ -43,6 +43,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
} }
@override @override
Future<WalletBase> process(WalletCredentials credentials) async => Future<WalletBase> process(WalletCredentials credentials) async {
_walletCreationService.create(credentials); _walletCreationService.changeWalletType(type: type);
return _walletCreationService.create(credentials);
}
} }