Skip to content

Commit

Permalink
WIP add create wallet use case
Browse files Browse the repository at this point in the history
  • Loading branch information
cygnet3 committed Jul 10, 2024
1 parent 1295ad3 commit 63e5f02
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 81 deletions.
32 changes: 19 additions & 13 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:donationwallet/src/data/providers/chain_api.dart';
import 'package:donationwallet/src/data/providers/wallet_secure_storage.dart';
import 'package:donationwallet/src/data/providers/secure_storage.dart';
import 'package:donationwallet/src/data/repositories/chain_repository.dart';
import 'package:donationwallet/src/data/repositories/wallet_repository.dart';
import 'package:donationwallet/src/domain/usecases/create_wallet_usecase.dart';
import 'package:donationwallet/src/domain/usecases/delete_wallet_usecase.dart';
import 'package:donationwallet/src/domain/usecases/get_chain_tip_usecase.dart';
import 'package:donationwallet/src/domain/usecases/load_wallet_usecase.dart';
Expand Down Expand Up @@ -29,21 +30,26 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
AndroidOptions getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
);
encryptedSharedPreferences: true,
);
final storage = FlutterSecureStorage(aOptions: getAndroidOptions());
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => WalletNotifier(
SaveWalletUseCase(WalletRepository(WalletSecureStorageProvider(storage))),
LoadWalletUseCase(WalletRepository(WalletSecureStorageProvider(storage))),
DeleteWalletUseCase(WalletRepository(WalletSecureStorageProvider(storage))),
UpdateWalletUseCase(ChainRepository(ChainApiProvider())),
)),
ChangeNotifierProvider(create: (_) => ChainNotifier(
GetChainTipUseCase(ChainRepository(ChainApiProvider()))
)
)
ChangeNotifierProvider<WalletNotifier>(
create: (_) => WalletNotifier(
SaveWalletUseCase(
WalletRepository(SecureStorageProvider(storage))),
LoadWalletUseCase(
WalletRepository(SecureStorageProvider(storage))),
DeleteWalletUseCase(
WalletRepository(SecureStorageProvider(storage))),
UpdateWalletUseCase(ChainRepository(ChainApiProvider())),
CreateWalletUseCase(
WalletRepository(SecureStorageProvider(storage))),
)),
ChangeNotifierProvider<ChainNotifier>(
create: (_) => ChainNotifier(
GetChainTipUseCase(ChainRepository(ChainApiProvider()))))
],
child: const SilentPaymentApp(),
);
Expand Down
6 changes: 5 additions & 1 deletion lib/src/data/models/sp_receiver_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ class SPReceiver {

factory SPReceiver.fromJson(Map<String, dynamic> json) {
var labelsList = json['labels'] as List;
List<Label> labels = labelsList.map((i) => Label.fromJson(i)).toList();

// List<Label> labels = labelsList.map((i) => Label.fromJson(i)).toList();

// List<Label> labels = Label.fromJson(labelsList).toList();
final labels = List<Label>.empty();

return SPReceiver(
version: json['version'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:logger/logger.dart';

class WalletSecureStorageProvider {
class SecureStorageProvider {
final FlutterSecureStorage secureStorage;

WalletSecureStorageProvider(this.secureStorage);
SecureStorageProvider(this.secureStorage);

Future<void> saveWalletToSecureStorage(String label, String spWallet) async {
try {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/data/repositories/wallet_repository.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'dart:convert';

import 'package:donationwallet/src/data/providers/wallet_secure_storage.dart';
import 'package:donationwallet/src/data/providers/secure_storage.dart';
import 'package:donationwallet/src/domain/entities/wallet_entity.dart';
import 'package:donationwallet/src/data/models/sp_wallet_model.dart';
import 'package:logger/logger.dart';

class WalletRepository {
final WalletSecureStorageProvider secureStorageProvider;
final SecureStorageProvider secureStorageProvider;

WalletRepository(this.secureStorageProvider);

Expand Down
47 changes: 47 additions & 0 deletions lib/src/domain/usecases/create_wallet_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'dart:convert';

import 'package:donationwallet/generated/rust/api/simple.dart';
import 'package:donationwallet/src/data/models/outputs_model.dart';
import 'package:donationwallet/src/data/models/sp_client_model.dart';
import 'package:donationwallet/src/data/models/sp_wallet_model.dart';
import 'package:donationwallet/src/data/repositories/wallet_repository.dart';
import 'package:donationwallet/src/domain/entities/wallet_entity.dart';
import 'package:donationwallet/src/utils/constants.dart';

class CreateWalletUseCase {
final WalletRepository walletRepository;

CreateWalletUseCase(this.walletRepository);

Future<WalletEntity> call(String label, String network, int birthday) async {
try {
final wallet = await setup(
label: defaultLabel,
mnemonic: null,
scanKey: null,
spendKey: null,
birthday: birthday,
network: network,
);

// final spWallet = SpWallet(client: SpClient(label: wallet., scanSk: '', spendKey: null, mnemonic: '', spReceiver: null), outputs: Outputs(walletFingerprint: [], birthday: null, lastScan: null, outputs: {}));

// return WalletEntity(
// label: spWallet.client.label,
// address: "", // we need to add it later
// network: spWallet.client.spReceiver.network,
// balance: BigInt.zero, // we compute that from all the outputs
// birthday: spWallet.outputs.birthday,
// lastScan: spWallet.outputs.lastScan,
// ownedOutputs: spWallet.outputs.outputs,
// );

final json = jsonDecode(wallet);
final spWallet = SpWallet.fromJson(json);
await walletRepository.saveWallet(label, spWallet);
return await walletRepository.getWallet(label);
} catch (e) {
rethrow;
}
}
}
35 changes: 28 additions & 7 deletions lib/src/presentation/notifiers/wallet_notifier.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';
import 'package:donationwallet/src/data/models/sp_wallet_model.dart';
import 'package:donationwallet/src/domain/usecases/create_wallet_usecase.dart';
import 'package:donationwallet/src/domain/usecases/delete_wallet_usecase.dart';
import 'package:donationwallet/src/domain/usecases/load_wallet_usecase.dart';
import 'package:donationwallet/src/domain/usecases/save_wallet_usecase.dart';
Expand All @@ -14,15 +15,20 @@ class WalletNotifier extends ChangeNotifier {
final LoadWalletUseCase loadWalletUseCase;
final DeleteWalletUseCase deleteWalletUseCase;
final UpdateWalletUseCase updateWalletUseCase;

WalletNotifier(this.saveWalletUseCase, this.loadWalletUseCase,
this.deleteWalletUseCase, this.updateWalletUseCase) {
_initialize();
final CreateWalletUseCase createWalletUseCase;

WalletNotifier(
this.saveWalletUseCase,
this.loadWalletUseCase,
this.deleteWalletUseCase,
this.updateWalletUseCase,
this.createWalletUseCase) {
// _initialize();
}

Future<void> _initialize() async {
await loadWallet(defaultLabel);
}
// Future<void> _initialize() async {
// await loadWallet(defaultLabel);
// }

WalletEntity? _wallet;
WalletEntity? get wallet => _wallet;
Expand Down Expand Up @@ -103,4 +109,19 @@ class WalletNotifier extends ChangeNotifier {
notifyListeners();
}
}

Future<void> createWallet(String label, String network, int birthday) async {
_isLoading = true;
_error = null;
notifyListeners();

try {
_wallet = await createWalletUseCase(label, network, birthday);
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
}
85 changes: 39 additions & 46 deletions lib/src/presentation/screens/setupwallet_screen.dart
Original file line number Diff line number Diff line change
@@ -1,43 +1,13 @@
import 'dart:async';
import 'dart:convert';

import 'package:donationwallet/generated/rust/api/simple.dart';
import 'package:donationwallet/src/data/models/sp_wallet_model.dart';
import 'package:donationwallet/src/presentation/notifiers/chain_notifier.dart';
import 'package:donationwallet/src/presentation/screens/home_screen.dart';
import 'package:donationwallet/src/presentation/notifiers/wallet_notifier.dart';
import 'package:donationwallet/src/presentation/screens/home_screen.dart';
import 'package:donationwallet/src/utils/constants.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';

class SetupWalletScreen extends StatelessWidget {
const SetupWalletScreen({super.key});

Future<void> _setup(WalletNotifier walletNotifier, String? mnemonic,
String? scanKey, String? spendKey, int birthday, String network) async {
if (walletNotifier.wallet != null) {
return;
}

try {
final wallet = await setup(
label: defaultLabel,
mnemonic: mnemonic,
scanKey: scanKey,
spendKey: spendKey,
birthday: birthday,
network: network,
);
final spWallet =
SpWallet.fromJson(jsonDecode(wallet) as Map<String, dynamic>);
await walletNotifier.saveWallet(defaultLabel, spWallet);
await walletNotifier.loadWallet(defaultLabel);
} catch (e) {
rethrow;
}
}

// Future<void> _showKeysInputDialog(BuildContext context, bool watchOnly,
// Function(Exception? e) onSetupComplete) async {
// TextEditingController scanKeyController = TextEditingController();
Expand Down Expand Up @@ -231,6 +201,19 @@ class SetupWalletScreen extends StatelessWidget {

@override
Widget build(BuildContext context) {
final walletNotifier = Provider.of<WalletNotifier>(context);
final chainNotifier = Provider.of<ChainNotifier>(context);

// final walletNotifier = context.watch()<WalletNotifier>();
// final chainNotifier = context.watch()<ChainNotifier>();

// if wallet exists, go to home screen
if (walletNotifier.wallet != null) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
}

return Scaffold(
appBar: AppBar(
title: const Text('Wallet creation/restoration'),
Expand All @@ -240,21 +223,21 @@ class SetupWalletScreen extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
Consumer<WalletNotifier>(builder: (context, walletNotifier, child) {
return Expanded(
child: _buildButton(context, 'Create New Wallet', () async {
final tip =
Provider.of<ChainNotifier>(context, listen: false).tip;
await _setup(
walletNotifier, null, null, null, tip, defaultNetwork);
if (walletNotifier.wallet != null) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => HomeScreen()),
);
}
}));
}),
Expanded(
child: _buildButton(context, 'Create new Wallet', () async {
final tip = chainNotifier.tip;
await walletNotifier.createWallet(
defaultLabel, defaultNetwork, tip);
// goToHomeScreen();
})),

// const Spacer(),
// Consumer<WalletNotifier>(builder: (context, walletNotifier, child) {
// return Expanded(
// child: _buildButton(context, 'Create New Wallet', () async {
// createWallet(context);
// }));
// }),
],
),
),
Expand Down Expand Up @@ -338,3 +321,13 @@ class SetupWalletScreen extends StatelessWidget {
);
}
}

// Future<void> createWallet(BuildContext context) async {
// final tip = Provider.of<ChainNotifier>(context, listen: false).tip;
// await walletNotifier.createWalletUseCase(defaultLabel, defaultNetwork, tip);
// if (walletNotifier.wallet != null) {
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (context) => HomeScreen()),
// );
// }
// }
20 changes: 10 additions & 10 deletions lib/src/presentation/screens/spend_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,21 @@ class SpendScreen extends StatelessWidget {
? "Tap here to choose which coin to spend"
: "Spending ${transactionNotifer.getInputs().length} output(s) for a total of ${transactionNotifer.getTotalAvailable()} sats available",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const OutputsScreen()),
);
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => const OutputsScreen()),
// );
}),
const Spacer(),
SummaryWidget(
displayText: transactionNotifer.recipientsLength() == 0
? "Tap here to add destinations"
: "Sending to ${transactionNotifer.recipientsLength()} output(s) for a total of ${transactionNotifer.getTotalSpent()} sats",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const DestinationScreen()),
);
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => const DestinationScreen()),
// );
}),
const Spacer(),
const Text('Fee Rate (satoshis/vB)'),
Expand All @@ -116,14 +116,14 @@ class SpendScreen extends StatelessWidget {
}
final wallet = await walletNotifier.loadWalletUseCase(defaultLabel);
try {
transactionNotifer.createTransactionUsecase();
// transactionNotifer.createTransactionUsecase();

if (!context.mounted) return;

// navigate to main screen
Navigator.popUntil(context, (route) => route.isFirst);

showAlertDialog('Transaction successfully sent', sentTxId);
// showAlertDialog('Transaction successfully sent', sentTxId);
} catch (e) {
rethrow;
}
Expand Down
1 change: 1 addition & 0 deletions lib/src/presentation/screens/wallet_screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:bitcoin_ui/bitcoin_ui.dart';
import 'package:donationwallet/src/presentation/screens/spend_screen.dart';
import 'package:donationwallet/src/utils/global_functions.dart';
import 'package:donationwallet/src/presentation/notifiers/wallet_notifier.dart';
import 'package:flutter/material.dart';
Expand Down
1 change: 1 addition & 0 deletions lib/src/utils/global_functions.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:donationwallet/src/presentation/screens/home_screen.dart';
import 'package:flutter/material.dart';

final globalNavigatorKey = GlobalKey<NavigatorState>();
Expand Down

0 comments on commit 63e5f02

Please sign in to comment.