dynamic secure storage provider

This commit is contained in:
julian 2022-11-09 16:43:26 -06:00
parent 2aa8dd2bec
commit 2bdf5f152c
44 changed files with 701 additions and 564 deletions

View file

@ -33,6 +33,7 @@ class DB {
static const String boxNamePriceCache = "priceAPIPrice24hCache";
static const String boxNameDBInfo = "dbInfo";
static const String boxNameTheme = "theme";
static const String boxNameDesktopData = "desktopData";
String boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
String boxNameSetCache({required Coin coin}) =>
@ -58,6 +59,7 @@ class DB {
late final Box<dynamic> _boxPrefs;
late final Box<TradeWalletLookup> _boxTradeLookup;
late final Box<dynamic> _boxDBInfo;
late final Box<String> _boxDesktopData;
final Map<String, Box<dynamic>> _walletBoxes = {};

View file

@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:isar/isar.dart';
@ -51,6 +52,7 @@ import 'package:stackwallet/services/wallets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/db_version_migration.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/utilities/theme/color_theme.dart';
@ -143,15 +145,24 @@ void main() async {
await Hive.initFlutter(appDirectory.path);
await Hive.openBox<dynamic>(DB.boxNameDBInfo);
int dbVersion = DB.instance.get<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
0;
if (dbVersion < Constants.currentHiveDbVersion) {
try {
await DbVersionMigrator().migrate(dbVersion);
} catch (e, s) {
Logging.instance.log("Cannot migrate database\n$e $s",
level: LogLevel.Error, printFullLength: true);
if (!Util.isDesktop) {
int dbVersion = DB.instance.get<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
0;
if (dbVersion < Constants.currentHiveDbVersion) {
try {
await DbVersionMigrator().migrate(
dbVersion,
secureStore: const SecureStorageWrapper(
store: FlutterSecureStorage(),
isDesktop: false,
),
);
} catch (e, s) {
Logging.instance.log("Cannot migrate database\n$e $s",
level: LogLevel.Error, printFullLength: true);
}
}
}

View file

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart';
@ -241,6 +242,7 @@ class _NewWalletRecoveryPhraseWarningViewState
coin,
walletId,
walletName,
ref.read(secureStoreProvider),
node,
txTracker,
ref.read(prefsChangeNotifierProvider),

View file

@ -18,6 +18,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widge
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart';
@ -265,6 +266,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
widget.coin,
walletId,
widget.walletName,
ref.read(secureStoreProvider),
node,
txTracker,
ref.read(prefsChangeNotifierProvider),

View file

@ -2,10 +2,10 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/biometrics.dart';
import 'package:stackwallet/utilities/constants.dart';
@ -20,15 +20,11 @@ class CreatePinView extends ConsumerStatefulWidget {
const CreatePinView({
Key? key,
this.popOnSuccess = false,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
this.biometrics = const Biometrics(),
}) : super(key: key);
static const String routeName = "/createPin";
final FlutterSecureStorageInterface secureStore;
final Biometrics biometrics;
final bool popOnSuccess;
@ -63,7 +59,7 @@ class _CreatePinViewState extends ConsumerState<CreatePinView> {
@override
initState() {
_secureStore = widget.secureStore;
_secureStore = ref.read(secureStoreProvider);
biometrics = widget.biometrics;
super.initState();
}

View file

@ -2,12 +2,12 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
// import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
// import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
@ -33,9 +33,6 @@ class LockscreenView extends ConsumerStatefulWidget {
this.popOnSuccess = false,
this.isInitialAppLogin = false,
this.routeOnSuccessArguments,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
this.biometrics = const Biometrics(),
this.onSuccess,
}) : super(key: key);
@ -50,7 +47,6 @@ class LockscreenView extends ConsumerStatefulWidget {
final String biometricsAuthenticationTitle;
final String biometricsLocalizedReason;
final String biometricsCancelButtonString;
final FlutterSecureStorageInterface secureStore;
final Biometrics biometrics;
final VoidCallback? onSuccess;
@ -134,7 +130,7 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> {
void initState() {
_shakeController = ShakeController();
_secureStore = widget.secureStore;
_secureStore = ref.read(secureStoreProvider);
biometrics = widget.biometrics;
_attempts = 0;
_timeout = Duration.zero;

View file

@ -3,11 +3,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
@ -40,9 +40,6 @@ class AddEditNodeView extends ConsumerStatefulWidget {
required this.coin,
required this.nodeId,
required this.routeOnSuccessOrDelete,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/addEditNode";
@ -51,7 +48,6 @@ class AddEditNodeView extends ConsumerStatefulWidget {
final Coin coin;
final String routeOnSuccessOrDelete;
final String? nodeId;
final FlutterSecureStorageInterface secureStore;
@override
ConsumerState<AddEditNodeView> createState() => _AddEditNodeViewState();
@ -533,7 +529,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
children: [
NodeForm(
node: node,
secureStore: widget.secureStore,
secureStore: ref.read(secureStoreProvider),
readOnly: false,
coin: widget.coin,
onChanged: (canSave, canTest) {

View file

@ -2,11 +2,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -32,14 +32,10 @@ class NodeDetailsView extends ConsumerStatefulWidget {
required this.coin,
required this.nodeId,
required this.popRouteName,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/nodeDetails";
final FlutterSecureStorageInterface secureStore;
final Coin coin;
final String nodeId;
final String popRouteName;
@ -58,7 +54,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
@override
initState() {
secureStore = widget.secureStore;
secureStore = ref.read(secureStoreProvider);
coin = widget.coin;
nodeId = widget.nodeId;
popRouteName = widget.popRouteName;

View file

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/security_views/security_view.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@ -11,23 +12,18 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_pin_put/custom_pin_put.dart';
class ChangePinView extends StatefulWidget {
class ChangePinView extends ConsumerStatefulWidget {
const ChangePinView({
Key? key,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/changePin";
final FlutterSecureStorageInterface secureStore;
@override
State<ChangePinView> createState() => _ChangePinViewState();
ConsumerState<ChangePinView> createState() => _ChangePinViewState();
}
class _ChangePinViewState extends State<ChangePinView> {
class _ChangePinViewState extends ConsumerState<ChangePinView> {
BoxDecoration get _pinPutDecoration {
return BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
@ -53,7 +49,7 @@ class _ChangePinViewState extends State<ChangePinView> {
@override
void initState() {
_secureStore = widget.secureStore;
_secureStore = ref.read(secureStoreProvider);
super.initState();
}

View file

@ -4,7 +4,6 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stack_wallet_backup/stack_wallet_backup.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
@ -13,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@ -21,26 +21,20 @@ import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/progress_bar.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:zxcvbn/zxcvbn.dart';
import 'package:stackwallet/utilities/util.dart';
class CreateAutoBackupView extends ConsumerStatefulWidget {
const CreateAutoBackupView({
Key? key,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/createAutoBackup";
final FlutterSecureStorageInterface secureStore;
@override
ConsumerState<CreateAutoBackupView> createState() =>
_EnableAutoBackupViewState();
@ -75,7 +69,7 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
@override
void initState() {
secureStore = widget.secureStore;
secureStore = ref.read(secureStoreProvider);
stackFileSystem = StackFileSystem();
fileLocationController = TextEditingController();
passwordController = TextEditingController();
@ -585,7 +579,9 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
final String fileToSave =
createAutoBackupFilename(pathToSave, now);
final backup = await SWB.createStackWalletJSON();
final backup = await SWB.createStackWalletJSON(
secureStorage: secureStore,
);
bool result = await SWB.encryptStackWalletWithADK(
fileToSave,

View file

@ -8,6 +8,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@ -443,222 +444,229 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
),
if (!isDesktop) const Spacer(),
!isDesktop
? TextButton(
style: shouldEnableCreate
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
onPressed: !shouldEnableCreate
? null
: () async {
final String pathToSave =
fileLocationController.text;
final String passphrase = passwordController.text;
final String repeatPassphrase =
passwordRepeatController.text;
? Consumer(builder: (context, ref, __) {
return TextButton(
style: shouldEnableCreate
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
onPressed: !shouldEnableCreate
? null
: () async {
final String pathToSave =
fileLocationController.text;
final String passphrase = passwordController.text;
final String repeatPassphrase =
passwordRepeatController.text;
if (pathToSave.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory not chosen",
context: context,
));
return;
}
if (!(await Directory(pathToSave).exists())) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory does not exist",
context: context,
));
return;
}
if (passphrase.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "A passphrase is required",
context: context,
));
return;
}
if (passphrase != repeatPassphrase) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Passphrase does not match",
context: context,
));
return;
}
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackDialog(
title: "Encrypting backup",
message: "This shouldn't take long",
),
));
// make sure the dialog is able to be displayed for at least 1 second
await Future<void>.delayed(
const Duration(seconds: 1));
final DateTime now = DateTime.now();
final String fileToSave =
"$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
final backup = await SWB.createStackWalletJSON();
bool result =
await SWB.encryptStackWalletWithPassphrase(
fileToSave,
passphrase,
jsonEncode(backup),
);
if (mounted) {
// pop encryption progress dialog
Navigator.of(context).pop();
if (result) {
await showDialog<dynamic>(
if (pathToSave.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory not chosen",
context: context,
barrierDismissible: false,
builder: (_) => Platform.isAndroid
? StackOkDialog(
title: "Backup saved to:",
message: fileToSave,
)
: const StackOkDialog(
title: "Backup creation succeeded"),
);
passwordController.text = "";
passwordRepeatController.text = "";
setState(() {});
} else {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackOkDialog(
title: "Backup creation failed"),
);
));
return;
}
}
},
child: Text(
"Create backup",
style: STextStyles.button(context),
),
)
if (!(await Directory(pathToSave).exists())) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory does not exist",
context: context,
));
return;
}
if (passphrase.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "A passphrase is required",
context: context,
));
return;
}
if (passphrase != repeatPassphrase) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Passphrase does not match",
context: context,
));
return;
}
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackDialog(
title: "Encrypting backup",
message: "This shouldn't take long",
),
));
// make sure the dialog is able to be displayed for at least 1 second
await Future<void>.delayed(
const Duration(seconds: 1));
final DateTime now = DateTime.now();
final String fileToSave =
"$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
final backup = await SWB.createStackWalletJSON(
secureStorage: ref.read(secureStoreProvider));
bool result =
await SWB.encryptStackWalletWithPassphrase(
fileToSave,
passphrase,
jsonEncode(backup),
);
if (mounted) {
// pop encryption progress dialog
Navigator.of(context).pop();
if (result) {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => Platform.isAndroid
? StackOkDialog(
title: "Backup saved to:",
message: fileToSave,
)
: const StackOkDialog(
title: "Backup creation succeeded"),
);
passwordController.text = "";
passwordRepeatController.text = "";
setState(() {});
} else {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackOkDialog(
title: "Backup creation failed"),
);
}
}
},
child: Text(
"Create backup",
style: STextStyles.button(context),
),
);
})
: Row(
children: [
PrimaryButton(
width: 183,
desktopMed: true,
label: "Create backup",
enabled: shouldEnableCreate,
onPressed: !shouldEnableCreate
? null
: () async {
final String pathToSave =
fileLocationController.text;
final String passphrase =
passwordController.text;
final String repeatPassphrase =
passwordRepeatController.text;
Consumer(builder: (context, ref, __) {
return PrimaryButton(
width: 183,
desktopMed: true,
label: "Create backup",
enabled: shouldEnableCreate,
onPressed: !shouldEnableCreate
? null
: () async {
final String pathToSave =
fileLocationController.text;
final String passphrase =
passwordController.text;
final String repeatPassphrase =
passwordRepeatController.text;
if (pathToSave.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory not chosen",
context: context,
));
return;
}
if (!(await Directory(pathToSave).exists())) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory does not exist",
context: context,
));
return;
}
if (passphrase.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "A passphrase is required",
context: context,
));
return;
}
if (passphrase != repeatPassphrase) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Passphrase does not match",
context: context,
));
return;
}
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackDialog(
title: "Encrypting backup",
message: "This shouldn't take long",
),
));
// make sure the dialog is able to be displayed for at least 1 second
await Future<void>.delayed(
const Duration(seconds: 1));
final DateTime now = DateTime.now();
final String fileToSave =
"$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
final backup =
await SWB.createStackWalletJSON();
bool result =
await SWB.encryptStackWalletWithPassphrase(
fileToSave,
passphrase,
jsonEncode(backup),
);
if (mounted) {
// pop encryption progress dialog
Navigator.of(context).pop();
if (result) {
await showDialog<dynamic>(
if (pathToSave.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory not chosen",
context: context,
barrierDismissible: false,
builder: (_) => Platform.isAndroid
? StackOkDialog(
title: "Backup saved to:",
message: fileToSave,
)
: const StackOkDialog(
title:
"Backup creation succeeded"),
);
passwordController.text = "";
passwordRepeatController.text = "";
setState(() {});
} else {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackOkDialog(
title: "Backup creation failed"),
);
));
return;
}
}
},
),
if (!(await Directory(pathToSave).exists())) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Directory does not exist",
context: context,
));
return;
}
if (passphrase.isEmpty) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "A passphrase is required",
context: context,
));
return;
}
if (passphrase != repeatPassphrase) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Passphrase does not match",
context: context,
));
return;
}
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackDialog(
title: "Encrypting backup",
message: "This shouldn't take long",
),
));
// make sure the dialog is able to be displayed for at least 1 second
await Future<void>.delayed(
const Duration(seconds: 1));
final DateTime now = DateTime.now();
final String fileToSave =
"$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
final backup =
await SWB.createStackWalletJSON(
secureStorage:
ref.read(secureStoreProvider));
bool result = await SWB
.encryptStackWalletWithPassphrase(
fileToSave,
passphrase,
jsonEncode(backup),
);
if (mounted) {
// pop encryption progress dialog
Navigator.of(context).pop();
if (result) {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => Platform.isAndroid
? StackOkDialog(
title: "Backup saved to:",
message: fileToSave,
)
: const StackOkDialog(
title:
"Backup creation succeeded"),
);
passwordController.text = "";
passwordRepeatController.text = "";
setState(() {});
} else {
await showDialog<dynamic>(
context: context,
barrierDismissible: false,
builder: (_) => const StackOkDialog(
title: "Backup creation failed"),
);
}
}
},
);
}),
const SizedBox(
width: 16,
),

View file

@ -4,7 +4,6 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stack_wallet_backup/stack_wallet_backup.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
@ -13,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@ -21,26 +21,20 @@ import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/progress_bar.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:zxcvbn/zxcvbn.dart';
import '../../../../utilities/util.dart';
class EditAutoBackupView extends ConsumerStatefulWidget {
const EditAutoBackupView({
Key? key,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/editAutoBackup";
final FlutterSecureStorageInterface secureStore;
@override
ConsumerState<EditAutoBackupView> createState() => _EditAutoBackupViewState();
}
@ -74,7 +68,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
@override
void initState() {
secureStore = widget.secureStore;
secureStore = ref.read(secureStoreProvider);
stackFileSystem = StackFileSystem();
fileLocationController = TextEditingController();
passwordController = TextEditingController();
@ -586,7 +580,9 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
final String fileToSave =
createAutoBackupFilename(pathToSave, now);
final backup = await SWB.createStackWalletJSON();
final backup = await SWB.createStackWalletJSON(
secureStorage: ref.read(secureStoreProvider),
);
bool result = await SWB.encryptStackWalletWithADK(
fileToSave,

View file

@ -3,10 +3,7 @@ import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stack_wallet_backup/stack_wallet_backup.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/contact_address_entry.dart';
@ -91,10 +88,13 @@ abstract class SWB {
static bool _shouldCancelRestore = false;
static bool _checkShouldCancel(PreRestoreState? revertToState) {
static bool _checkShouldCancel(
PreRestoreState? revertToState,
FlutterSecureStorageInterface secureStorageInterface,
) {
if (_shouldCancelRestore) {
if (revertToState != null) {
_revert(revertToState);
_revert(revertToState, secureStorageInterface);
} else {
_cancelCompleter!.complete();
_shouldCancelRestore = false;
@ -193,15 +193,15 @@ abstract class SWB {
/// [secureStorage] parameter exposed for testing purposes
static Future<Map<String, dynamic>> createStackWalletJSON({
FlutterSecureStorageInterface? secureStorage,
required FlutterSecureStorageInterface secureStorage,
}) async {
Logging.instance
.log("Starting createStackWalletJSON...", level: LogLevel.Info);
final _wallets = Wallets.sharedInstance;
Map<String, dynamic> backupJson = {};
NodeService nodeService = NodeService();
final _secureStore =
secureStorage ?? const SecureStorageWrapper(FlutterSecureStorage());
NodeService nodeService =
NodeService(secureStorageInterface: secureStorage);
final _secureStore = secureStorage;
Logging.instance.log("createStackWalletJSON awaiting DB.instance.mutex...",
level: LogLevel.Info);
@ -448,6 +448,7 @@ abstract class SWB {
Map<String, dynamic> validJSON,
StackRestoringUIState? uiState,
Map<String, String> oldToNewWalletIdMap,
FlutterSecureStorageInterface secureStorageInterface,
) async {
Map<String, dynamic> prefs = validJSON["prefs"] as Map<String, dynamic>;
List<dynamic>? addressBookEntries =
@ -486,7 +487,11 @@ abstract class SWB {
"SWB restoring nodes",
level: LogLevel.Warning,
);
await _restoreNodes(nodes, primaryNodes);
await _restoreNodes(
nodes,
primaryNodes,
secureStorageInterface,
);
uiState?.nodes = StackRestoringStatus.success;
uiState?.trades = StackRestoringStatus.restoring;
@ -543,6 +548,7 @@ abstract class SWB {
static Future<bool?> restoreStackWalletJSON(
String jsonBackup,
StackRestoringUIState? uiState,
FlutterSecureStorageInterface secureStorageInterface,
) async {
if (!Platform.isLinux) await Wakelock.enable();
@ -550,7 +556,8 @@ abstract class SWB {
"SWB creating temp backup",
level: LogLevel.Warning,
);
final preRestoreJSON = await createStackWalletJSON();
final preRestoreJSON =
await createStackWalletJSON(secureStorage: secureStorageInterface);
Logging.instance.log(
"SWB temp backup created",
level: LogLevel.Warning,
@ -587,19 +594,34 @@ abstract class SWB {
// basic cancel check here
// no reverting required yet as nothing has been written to store
if (_checkShouldCancel(null)) {
if (_checkShouldCancel(
null,
secureStorageInterface,
)) {
return false;
}
await _restoreEverythingButWallets(validJSON, uiState, oldToNewWalletIdMap);
await _restoreEverythingButWallets(
validJSON,
uiState,
oldToNewWalletIdMap,
secureStorageInterface,
);
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
final nodeService = NodeService();
final walletsService = WalletsService();
final nodeService = NodeService(
secureStorageInterface: secureStorageInterface,
);
final walletsService = WalletsService(
secureStorageInterface: secureStorageInterface,
);
final _prefs = Prefs.instance;
await _prefs.init();
@ -609,7 +631,10 @@ abstract class SWB {
for (var walletbackup in wallets) {
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
@ -647,7 +672,10 @@ abstract class SWB {
final failovers = nodeService.failoverNodesFor(coin: coin);
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
@ -655,6 +683,7 @@ abstract class SWB {
coin,
walletId,
walletName,
secureStorageInterface,
node,
txTracker,
_prefs,
@ -665,7 +694,10 @@ abstract class SWB {
managers.add(Tuple2(walletbackup, manager));
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
@ -679,7 +711,10 @@ abstract class SWB {
}
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
@ -690,7 +725,10 @@ abstract class SWB {
// start restoring wallets
for (final tuple in managers) {
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
final bools = await asyncRestore(tuple, uiState, walletsService);
@ -698,13 +736,19 @@ abstract class SWB {
}
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
for (Future<bool> status in restoreStatuses) {
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
await status;
@ -712,7 +756,10 @@ abstract class SWB {
if (!Platform.isLinux) await Wakelock.disable();
// check if cancel was requested and restore previous state
if (_checkShouldCancel(preRestoreState)) {
if (_checkShouldCancel(
preRestoreState,
secureStorageInterface,
)) {
return false;
}
@ -720,7 +767,10 @@ abstract class SWB {
return true;
}
static Future<void> _revert(PreRestoreState revertToState) async {
static Future<void> _revert(
PreRestoreState revertToState,
FlutterSecureStorageInterface secureStorageInterface,
) async {
Map<String, dynamic> prefs =
revertToState.validJSON["prefs"] as Map<String, dynamic>;
List<dynamic>? addressBookEntries =
@ -788,7 +838,9 @@ abstract class SWB {
}
// nodes
NodeService nodeService = NodeService();
NodeService nodeService = NodeService(
secureStorageInterface: secureStorageInterface,
);
final currentNodes = nodeService.nodes;
if (nodes == null) {
// no pre nodes found so we delete all but defaults
@ -914,7 +966,8 @@ abstract class SWB {
}
// finally remove any added wallets
final walletsService = WalletsService();
final walletsService =
WalletsService(secureStorageInterface: secureStorageInterface);
final namesData = await walletsService.walletNames;
for (final entry in namesData.entries) {
if (!revertToState.walletIds.contains(entry.value.walletId)) {
@ -989,8 +1042,11 @@ abstract class SWB {
static Future<void> _restoreNodes(
List<dynamic>? nodes,
List<dynamic>? primaryNodes,
FlutterSecureStorageInterface secureStorageInterface,
) async {
NodeService nodeService = NodeService();
NodeService nodeService = NodeService(
secureStorageInterface: secureStorageInterface,
);
if (nodes != null) {
for (var node in nodes) {
await nodeService.add(

View file

@ -10,6 +10,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/stack_restore/stack_restoring_ui_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
@ -107,6 +108,7 @@ class _StackRestoreProgressViewState
finished = await SWB.restoreStackWalletJSON(
widget.jsonString,
uiState,
ref.read(secureStoreProvider),
);
} catch (e, s) {
Logging.instance.log("$e\n$s", level: LogLevel.Warning);

View file

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
@ -10,7 +9,6 @@ import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.da
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@ -23,15 +21,10 @@ import 'package:zxcvbn/zxcvbn.dart';
class CreatePasswordView extends ConsumerStatefulWidget {
const CreatePasswordView({
Key? key,
this.secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
}) : super(key: key);
static const String routeName = "/createPasswordDesktop";
final FlutterSecureStorageInterface secureStore;
@override
ConsumerState<CreatePasswordView> createState() => _CreatePasswordViewState();
}

View file

@ -1,5 +1,9 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/services/auto_swb_service.dart';
final autoSWBServiceProvider =
ChangeNotifierProvider<AutoSWBService>((_) => AutoSWBService());
final autoSWBServiceProvider = ChangeNotifierProvider<AutoSWBService>(
(ref) => AutoSWBService(
secureStorageInterface: ref.read(secureStoreProvider),
),
);

View file

@ -1,15 +1,16 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/services/node_service.dart';
int _count = 0;
final nodeServiceChangeNotifierProvider =
ChangeNotifierProvider<NodeService>((_) {
ChangeNotifierProvider<NodeService>((ref) {
if (kDebugMode) {
_count++;
debugPrint(
"nodeServiceChangeNotifierProvider instantiation count: $_count");
}
return NodeService();
return NodeService(secureStorageInterface: ref.read(secureStoreProvider));
});

View file

@ -0,0 +1,18 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/util.dart';
final secureStoreProvider = Provider<FlutterSecureStorageInterface>((ref) {
if (Util.isDesktop) {
final handler = ref.read(storageCryptoHandlerProvider).handler;
return SecureStorageWrapper(
store: DesktopPWStore(handler), isDesktop: true);
} else {
return const SecureStorageWrapper(
store: FlutterSecureStorage(),
isDesktop: false,
);
}
});

View file

@ -1,16 +1,19 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/global/secure_store_provider.dart';
import 'package:stackwallet/services/wallets_service.dart';
int _count = 0;
final walletsServiceChangeNotifierProvider =
ChangeNotifierProvider<WalletsService>((_) {
ChangeNotifierProvider<WalletsService>((ref) {
if (kDebugMode) {
_count++;
debugPrint(
"walletsServiceChangeNotifierProvider instantiation count: $_count");
}
return WalletsService();
return WalletsService(
secureStorageInterface: ref.read(secureStoreProvider),
);
});

View file

@ -3,7 +3,6 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/logger.dart';
@ -27,9 +26,7 @@ class AutoSWBService extends ChangeNotifier {
final FlutterSecureStorageInterface secureStorageInterface;
AutoSWBService(
{this.secureStorageInterface =
const SecureStorageWrapper(FlutterSecureStorage())});
AutoSWBService({required this.secureStorageInterface});
/// Attempt a backup.
Future<void> doBackup() async {

View file

@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -1369,7 +1368,7 @@ class BitcoinWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1379,13 +1378,12 @@ class BitcoinWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
@ -1423,7 +1421,8 @@ class BitcoinWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -13,7 +13,6 @@ import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -1274,7 +1273,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1284,13 +1283,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
@ -1328,7 +1326,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -13,6 +13,7 @@ import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'litecoin/litecoin_wallet.dart';
@ -24,6 +25,7 @@ abstract class CoinServiceAPI {
Coin coin,
String walletId,
String walletName,
FlutterSecureStorageInterface secureStorageInterface,
NodeModel node,
TransactionNotificationTracker tracker,
Prefs prefs,
@ -68,6 +70,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -77,6 +80,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -87,6 +91,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -97,6 +102,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -107,6 +113,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -117,6 +124,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -127,6 +135,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -137,6 +146,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -147,6 +157,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
@ -157,6 +168,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
// tracker: tracker,
);
@ -165,6 +177,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
// tracker: tracker,
);
@ -173,6 +186,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
// tracker: tracker,
);
@ -181,6 +195,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
tracker: tracker,
cachedClient: cachedClient,
client: client,
@ -191,6 +206,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,

View file

@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -1137,7 +1136,7 @@ class DogecoinWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1147,13 +1146,12 @@ class DogecoinWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
@ -1191,7 +1189,8 @@ class DogecoinWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -6,7 +6,6 @@ import 'dart:isolate';
import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_libepiccash/epic_cash.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart';
import 'package:mutex/mutex.dart';
@ -518,14 +517,13 @@ class EpicCashWallet extends CoinServiceAPI {
required String walletName,
required Coin coin,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore}) {
required FlutterSecureStorageInterface secureStore}) {
_walletId = walletId;
_walletName = walletName;
_coin = coin;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
Logging.instance.log("$walletName isolate length: ${isolates.length}",
level: LogLevel.Info);
@ -537,7 +535,8 @@ class EpicCashWallet extends CoinServiceAPI {
@override
Future<void> updateNode(bool shouldRefresh) async {
_epicNode = NodeService().getPrimaryNodeFor(coin: coin) ??
_epicNode = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
// TODO notify ui/ fire event for node changed?

View file

@ -11,7 +11,6 @@ import 'package:bitcoindart/bitcoindart.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:lelantus/lelantus.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
@ -1321,7 +1320,7 @@ class FiroWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1331,8 +1330,7 @@ class FiroWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
Logging.instance.log("$walletName isolates length: ${isolates.length}",
level: LogLevel.Info);
@ -1870,7 +1868,7 @@ class FiroWallet extends CoinServiceAPI {
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map(
(e) => ElectrumXNode(
@ -3071,7 +3069,8 @@ class FiroWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> _getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -1371,7 +1370,7 @@ class LitecoinWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1381,13 +1380,12 @@ class LitecoinWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
@ -1425,7 +1423,8 @@ class LitecoinWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -72,7 +72,8 @@ class MoneroWallet extends CoinServiceAPI {
late PriceAPI _priceAPI;
Future<NodeModel> getCurrentNode() async {
return NodeService().getPrimaryNodeFor(coin: coin) ??
return NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
}
@ -81,14 +82,13 @@ class MoneroWallet extends CoinServiceAPI {
required String walletName,
required Coin coin,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore}) {
required FlutterSecureStorageInterface secureStore}) {
_walletId = walletId;
_walletName = walletName;
_coin = coin;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
bool _shouldAutoSync = false;

View file

@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -1362,7 +1361,7 @@ class NamecoinWallet extends CoinServiceAPI {
required CachedElectrumX cachedClient,
required TransactionNotificationTracker tracker,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore,
required FlutterSecureStorageInterface secureStore,
}) {
txTracker = tracker;
_walletId = walletId;
@ -1372,13 +1371,12 @@ class NamecoinWallet extends CoinServiceAPI {
_cachedElectrumXClient = cachedClient;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
@override
Future<void> updateNode(bool shouldRefresh) async {
final failovers = NodeService()
final failovers = NodeService(secureStorageInterface: _secureStore)
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
@ -1416,7 +1414,8 @@ class NamecoinWallet extends CoinServiceAPI {
}
Future<ElectrumXNode> getCurrentNode() async {
final node = NodeService().getPrimaryNodeFor(coin: coin) ??
final node = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
return ElectrumXNode(

View file

@ -73,7 +73,8 @@ class WowneroWallet extends CoinServiceAPI {
late PriceAPI _priceAPI;
Future<NodeModel> getCurrentNode() async {
return NodeService().getPrimaryNodeFor(coin: coin) ??
return NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
}
@ -82,14 +83,13 @@ class WowneroWallet extends CoinServiceAPI {
required String walletName,
required Coin coin,
PriceAPI? priceAPI,
FlutterSecureStorageInterface? secureStore}) {
required FlutterSecureStorageInterface secureStore}) {
_walletId = walletId;
_walletName = walletName;
_coin = coin;
_priceAPI = priceAPI ?? PriceAPI(Client());
_secureStore =
secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
_secureStore = secureStore;
}
bool _shouldAutoSync = false;

View file

@ -1,7 +1,6 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/node_model.dart';
@ -17,9 +16,7 @@ class NodeService extends ChangeNotifier {
/// Exposed [secureStorageInterface] in order to inject mock for tests
NodeService({
this.secureStorageInterface = const SecureStorageWrapper(
FlutterSecureStorage(),
),
required this.secureStorageInterface,
});
Future<void> updateDefaults() async {

View file

@ -205,13 +205,14 @@ class Wallets extends ChangeNotifier {
final txTracker =
TransactionNotificationTracker(walletId: walletId);
final failovers = NodeService().failoverNodesFor(coin: coin);
final failovers = nodeService.failoverNodesFor(coin: coin);
// load wallet
final wallet = CoinServiceAPI.from(
coin,
walletId,
entry.value.name,
nodeService.secureStorageInterface,
node,
txTracker,
prefs,

View file

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
import 'package:stackwallet/services/notifications_service.dart';
@ -55,10 +54,7 @@ class WalletsService extends ChangeNotifier {
_walletNames ??= _fetchWalletNames();
WalletsService({
FlutterSecureStorageInterface secureStorageInterface =
const SecureStorageWrapper(
FlutterSecureStorage(),
),
required FlutterSecureStorageInterface secureStorageInterface,
}) {
_secureStore = secureStorageInterface;
}

View file

@ -1,4 +1,3 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/hive/db.dart';
@ -17,9 +16,7 @@ import 'package:stackwallet/utilities/prefs.dart';
class DbVersionMigrator {
Future<void> migrate(
int fromVersion, {
FlutterSecureStorageInterface secureStore = const SecureStorageWrapper(
FlutterSecureStorage(),
),
required FlutterSecureStorageInterface secureStore,
}) async {
Logging.instance.log(
"Running migrate fromVersion $fromVersion",
@ -29,8 +26,9 @@ class DbVersionMigrator {
case 0:
await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
await Hive.openBox<dynamic>(DB.boxNamePrefs);
final walletsService = WalletsService();
final nodeService = NodeService();
final walletsService =
WalletsService(secureStorageInterface: secureStore);
final nodeService = NodeService(secureStorageInterface: secureStore);
final prefs = Prefs.instance;
final walletInfoList = await walletsService.walletNames;
await prefs.init();
@ -118,7 +116,7 @@ class DbVersionMigrator {
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 1);
// try to continue migrating
return await migrate(1);
return await migrate(1, secureStore: secureStore);
case 1:
await Hive.openBox<ExchangeTransaction>(DB.boxNameTrades);
@ -142,7 +140,7 @@ class DbVersionMigrator {
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 2);
// try to continue migrating
return await migrate(2);
return await migrate(2, secureStore: secureStore);
case 2:
await Hive.openBox<dynamic>(DB.boxNamePrefs);
final prefs = Prefs.instance;
@ -154,7 +152,7 @@ class DbVersionMigrator {
// update version
await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 3);
return await migrate(3);
return await migrate(3, secureStore: secureStore);
default:
// finally return

View file

@ -1,6 +1,6 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:stack_wallet_backup/secure_storage.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/utilities/logger.dart';
const String _kKeyBlobKey = "swbKeyBlobKeyStringID";
@ -24,7 +24,6 @@ String _getMessageFromException(Object exception) {
class DPS {
StorageCryptoHandler? _handler;
final SecureStorageWrapper secureStorageWrapper;
StorageCryptoHandler get handler {
if (_handler == null) {
@ -34,11 +33,7 @@ class DPS {
return _handler!;
}
DPS({
this.secureStorageWrapper = const SecureStorageWrapper(
FlutterSecureStorage(),
),
});
DPS();
Future<void> initFromNew(String passphrase) async {
if (_handler != null) {
@ -47,10 +42,14 @@ class DPS {
try {
_handler = await StorageCryptoHandler.fromNewPassphrase(passphrase);
await secureStorageWrapper.write(
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
await DB.instance.put<String>(
boxName: DB.boxNameDesktopData,
key: _kKeyBlobKey,
value: await _handler!.getKeyBlob(),
);
await box.close();
} catch (e, s) {
Logging.instance.log(
"${_getMessageFromException(e)}\n$s",
@ -65,7 +64,13 @@ class DPS {
throw Exception(
"DPS: attempted to re initialize with existing passphrase");
}
final keyBlob = await secureStorageWrapper.read(key: _kKeyBlobKey);
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
final keyBlob = DB.instance.get<String>(
boxName: DB.boxNameDesktopData,
key: _kKeyBlobKey,
);
await box.close();
if (keyBlob == null) {
throw Exception(
@ -84,6 +89,12 @@ class DPS {
}
Future<bool> hasPassword() async {
return (await secureStorageWrapper.read(key: _kKeyBlobKey)) != null;
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
final keyBlob = DB.instance.get<String>(
boxName: DB.boxNameDesktopData,
key: _kKeyBlobKey,
);
await box.close();
return keyBlob != null;
}
}

View file

@ -1,4 +1,6 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:isar/isar.dart';
import 'package:stack_wallet_backup/secure_storage.dart';
abstract class FlutterSecureStorageInterface {
Future<void> write({
@ -33,10 +35,49 @@ abstract class FlutterSecureStorageInterface {
});
}
class SecureStorageWrapper implements FlutterSecureStorageInterface {
final FlutterSecureStorage secureStore;
class DesktopPWStore {
final StorageCryptoHandler handler;
late final Isar isar;
const SecureStorageWrapper(this.secureStore);
DesktopPWStore(this.handler);
Future<void> init() async {}
Future<String?> read({
required String key,
}) async {
// final String encryptedString =
return "";
}
Future<void> write({
required String key,
required String? value,
}) async {
return;
}
Future<void> delete({
required String key,
}) async {
return;
}
}
/// all *Options params ignored on desktop
class SecureStorageWrapper implements FlutterSecureStorageInterface {
final dynamic _store;
final bool _isDesktop;
const SecureStorageWrapper({
required dynamic store,
required bool isDesktop,
}) : assert(isDesktop
? store is DesktopPWStore
: store is FlutterSecureStorage),
_store = store,
_isDesktop = isDesktop;
@override
Future<String?> read({
@ -47,16 +88,20 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
WebOptions? webOptions,
MacOsOptions? mOptions,
WindowsOptions? wOptions,
}) {
return secureStore.read(
key: key,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
}) async {
if (_isDesktop) {
return await (_store as DesktopPWStore).read(key: key);
} else {
return await (_store as FlutterSecureStorage).read(
key: key,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
}
}
@override
@ -69,17 +114,21 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
WebOptions? webOptions,
MacOsOptions? mOptions,
WindowsOptions? wOptions,
}) {
return secureStore.write(
key: key,
value: value,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
}) async {
if (_isDesktop) {
return await (_store as DesktopPWStore).write(key: key, value: value);
} else {
return await (_store as FlutterSecureStorage).write(
key: key,
value: value,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
}
}
@override
@ -92,15 +141,19 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
MacOsOptions? mOptions,
WindowsOptions? wOptions,
}) async {
await secureStore.delete(
key: key,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
if (_isDesktop) {
return (_store as DesktopPWStore).delete(key: key);
} else {
return await (_store as FlutterSecureStorage).delete(
key: key,
iOptions: iOptions,
aOptions: aOptions,
lOptions: lOptions,
webOptions: webOptions,
mOptions: mOptions,
wOptions: wOptions,
);
}
}
}

View file

@ -13,7 +13,7 @@ void main() {
when(secureStore.write(key: "testKey", value: "some value"))
.thenAnswer((_) async => null);
final wrapper = SecureStorageWrapper(secureStore);
final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
await expectLater(
() async => await wrapper.write(key: "testKey", value: "some value"),
@ -27,7 +27,7 @@ void main() {
final secureStore = MockFlutterSecureStorage();
when(secureStore.read(key: "testKey"))
.thenAnswer((_) async => "some value");
final wrapper = SecureStorageWrapper(secureStore);
final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
final result = await wrapper.read(key: "testKey");
@ -40,7 +40,7 @@ void main() {
test("SecureStorageWrapper delete", () async {
final secureStore = MockFlutterSecureStorage();
when(secureStore.delete(key: "testKey")).thenAnswer((_) async {});
final wrapper = SecureStorageWrapper(secureStore);
final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
await expectLater(
() async => await wrapper.delete(key: "testKey"), returnsNormally);

View file

@ -103,7 +103,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinWallet? testnetWallet;
@ -194,7 +194,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinWallet? mainnetWallet;
@ -363,7 +363,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinWallet? btc;
@ -428,7 +428,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinWallet? btc;
@ -640,7 +640,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinWallet? btc;

View file

@ -64,7 +64,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinCashWallet? mainnetWallet;
@ -203,7 +203,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinCashWallet? mainnetWallet;
@ -314,7 +314,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinCashWallet? bch;
@ -383,7 +383,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinCashWallet? bch;
@ -606,7 +606,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
BitcoinCashWallet? bch;

View file

@ -97,7 +97,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
DogecoinWallet? mainnetWallet;
@ -196,7 +196,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
DogecoinWallet? doge;
@ -266,7 +266,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
DogecoinWallet? doge;
@ -489,7 +489,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
DogecoinWallet? doge;

View file

@ -103,7 +103,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
NamecoinWallet? mainnetWallet;
@ -132,7 +132,7 @@ void main() {
mainnetWallet?.addressType(
address: "N673DDbjPcrNgJmrhJ1xQXF9LLizQzvjEs"),
DerivePathType.bip44);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(tracker);
@ -144,7 +144,7 @@ void main() {
mainnetWallet?.addressType(
address: "nc1q6k4x8ye6865z3rc8zkt8gyu52na7njqt6hsk4v"),
DerivePathType.bip84);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(tracker);
@ -156,7 +156,7 @@ void main() {
() => mainnetWallet?.addressType(
address: "tb1qzzlm6mnc8k54mx6akehl8p9ray8r439va5ndyq"),
throwsArgumentError);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(tracker);
@ -168,7 +168,7 @@ void main() {
() => mainnetWallet?.addressType(
address: "mpMk94ETazqonHutyC1v6ajshgtP8oiFKU"),
throwsArgumentError);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(tracker);
@ -180,7 +180,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
NamecoinWallet? nmc;
@ -208,7 +208,7 @@ void main() {
when(client?.ping()).thenAnswer((_) async => false);
final bool? result = await nmc?.testNetworkConnection();
expect(result, false);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verify(client?.ping()).called(1);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -219,7 +219,7 @@ void main() {
when(client?.ping()).thenThrow(Exception);
final bool? result = await nmc?.testNetworkConnection();
expect(result, false);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verify(client?.ping()).called(1);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -230,7 +230,7 @@ void main() {
when(client?.ping()).thenAnswer((_) async => true);
final bool? result = await nmc?.testNetworkConnection();
expect(result, true);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verify(client?.ping()).called(1);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -245,7 +245,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
NamecoinWallet? nmc;
@ -271,7 +271,7 @@ void main() {
test("get networkType main", () async {
expect(Coin.namecoin, Coin.namecoin);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -289,7 +289,7 @@ void main() {
secureStore: secureStore,
);
expect(Coin.namecoin, Coin.namecoin);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -297,7 +297,7 @@ void main() {
test("get cryptoCurrency", () async {
expect(Coin.namecoin, Coin.namecoin);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -305,7 +305,7 @@ void main() {
test("get coinName", () async {
expect(Coin.namecoin, Coin.namecoin);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -313,7 +313,7 @@ void main() {
test("get coinTicker", () async {
expect(Coin.namecoin, Coin.namecoin);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -323,7 +323,7 @@ void main() {
expect(Coin.namecoin, Coin.namecoin);
nmc?.walletName = "new name";
expect(nmc?.walletName, "new name");
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -338,7 +338,7 @@ void main() {
expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 1699), 712);
expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 2000), 712);
expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 12345), 4628);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -372,7 +372,7 @@ void main() {
verify(client?.estimateFee(blocks: 1)).called(1);
verify(client?.estimateFee(blocks: 5)).called(1);
verify(client?.estimateFee(blocks: 20)).called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -409,7 +409,7 @@ void main() {
verify(client?.estimateFee(blocks: 1)).called(1);
verify(client?.estimateFee(blocks: 5)).called(1);
verify(client?.estimateFee(blocks: 20)).called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -440,7 +440,7 @@ void main() {
// verify(client?.estimateFee(blocks: 1)).called(1);
// verify(client?.estimateFee(blocks: 5)).called(1);
// verify(client?.estimateFee(blocks: 20)).called(1);
// expect(secureStore?.interactions, 0);
// expect(secureStore.interactions, 0);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
// verifyNoMoreInteractions(tracker);
@ -457,7 +457,7 @@ void main() {
MockElectrumX? client;
MockCachedElectrumX? cachedClient;
MockPriceAPI? priceAPI;
FakeSecureStorage? secureStore;
late FakeSecureStorage secureStore;
MockTransactionNotificationTracker? tracker;
NamecoinWallet? nmc;
@ -504,7 +504,7 @@ void main() {
// test("initializeWallet no network", () async {
// when(client?.ping()).thenAnswer((_) async => false);
// expect(await nmc?.initializeWallet(), false);
// expect(secureStore?.interactions, 0);
// expect(secureStore.interactions, 0);
// verify(client?.ping()).called(1);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
@ -515,7 +515,7 @@ void main() {
// when(client?.ping()).thenThrow(Exception("Network connection failed"));
// final wallets = await Hive.openBox(testWalletId);
// expect(await nmc?.initializeExisting(), false);
// expect(secureStore?.interactions, 0);
// expect(secureStore.interactions, 0);
// verify(client?.ping()).called(1);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
@ -539,7 +539,7 @@ void main() {
expectLater(() => nmc?.initializeExisting(), throwsA(isA<Exception>()))
.then((_) {
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
// verify(client?.ping()).called(1);
// verify(client?.getServerFeatures()).called(1);
verifyNoMoreInteractions(client);
@ -560,13 +560,13 @@ void main() {
"hash_function": "sha256",
"services": []
});
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_mnemonic", value: "some mnemonic");
final wallets = await Hive.openBox(testWalletId);
expectLater(() => nmc?.initializeExisting(), throwsA(isA<Exception>()))
.then((_) {
expect(secureStore?.interactions, 1);
expect(secureStore.interactions, 1);
// verify(client?.ping()).called(1);
// verify(client?.getServerFeatures()).called(1);
verifyNoMoreInteractions(client);
@ -603,7 +603,7 @@ void main() {
verify(client?.getServerFeatures()).called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -623,7 +623,7 @@ void main() {
"services": []
});
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_mnemonic", value: "some mnemonic words");
bool hasThrown = false;
@ -640,7 +640,7 @@ void main() {
verify(client?.getServerFeatures()).called(1);
expect(secureStore?.interactions, 2);
expect(secureStore.interactions, 2);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -691,10 +691,10 @@ void main() {
verify(client?.getBatchHistory(args: historyBatchArgs4)).called(1);
verify(client?.getBatchHistory(args: historyBatchArgs5)).called(1);
expect(secureStore?.interactions, 20);
expect(secureStore?.writes, 7);
expect(secureStore?.reads, 13);
expect(secureStore?.deletes, 0);
expect(secureStore.interactions, 20);
expect(secureStore.writes, 7);
expect(secureStore.reads, 13);
expect(secureStore.deletes, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -814,10 +814,10 @@ void main() {
true);
}
expect(secureStore?.interactions, 14);
expect(secureStore?.writes, 7);
expect(secureStore?.reads, 7);
expect(secureStore?.deletes, 0);
expect(secureStore.interactions, 14);
expect(secureStore.writes, 7);
expect(secureStore.reads, 7);
expect(secureStore.deletes, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -911,17 +911,17 @@ void main() {
final preChangeIndexP2SH = await wallet.get('changeIndexP2SH');
final preChangeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
final preUtxoData = await wallet.get('latest_utxo_model');
final preReceiveDerivationsStringP2PKH = await secureStore?.read(
final preReceiveDerivationsStringP2PKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2PKH");
final preChangeDerivationsStringP2PKH = await secureStore?.read(
key: "${testWalletId}_changeDerivationsP2PKH");
final preReceiveDerivationsStringP2SH = await secureStore?.read(
key: "${testWalletId}_receiveDerivationsP2SH");
final preChangeDerivationsStringP2PKH =
await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
final preReceiveDerivationsStringP2SH =
await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
final preChangeDerivationsStringP2SH =
await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
final preReceiveDerivationsStringP2WPKH = await secureStore?.read(
await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
final preReceiveDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2WPKH");
final preChangeDerivationsStringP2WPKH = await secureStore?.read(
final preChangeDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_changeDerivationsP2WPKH");
// destroy the data that the rescan will fix
@ -943,17 +943,17 @@ void main() {
await wallet.put('changeIndexP2PKH', 123);
await wallet.put('changeIndexP2SH', 123);
await wallet.put('changeIndexP2WPKH', 123);
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}");
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_changeDerivationsP2PKH", value: "{}");
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_receiveDerivationsP2SH", value: "{}");
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_changeDerivationsP2SH", value: "{}");
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_receiveDerivationsP2WPKH", value: "{}");
await secureStore?.write(
await secureStore.write(
key: "${testWalletId}_changeDerivationsP2WPKH", value: "{}");
bool hasThrown = false;
@ -980,17 +980,17 @@ void main() {
final changeIndexP2SH = await wallet.get('changeIndexP2SH');
final changeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
final utxoData = await wallet.get('latest_utxo_model');
final receiveDerivationsStringP2PKH = await secureStore?.read(
final receiveDerivationsStringP2PKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2PKH");
final changeDerivationsStringP2PKH = await secureStore?.read(
key: "${testWalletId}_changeDerivationsP2PKH");
final receiveDerivationsStringP2SH = await secureStore?.read(
key: "${testWalletId}_receiveDerivationsP2SH");
final changeDerivationsStringP2PKH =
await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
final receiveDerivationsStringP2SH =
await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
final changeDerivationsStringP2SH =
await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
final receiveDerivationsStringP2WPKH = await secureStore?.read(
await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
final receiveDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2WPKH");
final changeDerivationsStringP2WPKH = await secureStore?.read(
final changeDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_changeDerivationsP2WPKH");
expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH);
@ -1082,9 +1082,9 @@ void main() {
//
// argCount.forEach((key, value) => print("arg: $key\ncount: $value"));
expect(secureStore?.writes, 25);
expect(secureStore?.reads, 32);
expect(secureStore?.deletes, 6);
expect(secureStore.writes, 25);
expect(secureStore.reads, 32);
expect(secureStore.deletes, 6);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -1182,17 +1182,17 @@ void main() {
final preChangeIndexP2SH = await wallet.get('changeIndexP2SH');
final preChangeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
final preUtxoData = await wallet.get('latest_utxo_model');
final preReceiveDerivationsStringP2PKH = await secureStore?.read(
final preReceiveDerivationsStringP2PKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2PKH");
final preChangeDerivationsStringP2PKH = await secureStore?.read(
key: "${testWalletId}_changeDerivationsP2PKH");
final preReceiveDerivationsStringP2SH = await secureStore?.read(
key: "${testWalletId}_receiveDerivationsP2SH");
final preChangeDerivationsStringP2PKH =
await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
final preReceiveDerivationsStringP2SH =
await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
final preChangeDerivationsStringP2SH =
await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
final preReceiveDerivationsStringP2WPKH = await secureStore?.read(
await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
final preReceiveDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2WPKH");
final preChangeDerivationsStringP2WPKH = await secureStore?.read(
final preChangeDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_changeDerivationsP2WPKH");
when(client?.getBatchHistory(args: historyBatchArgs0))
@ -1222,17 +1222,17 @@ void main() {
final changeIndexP2SH = await wallet.get('changeIndexP2SH');
final changeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
final utxoData = await wallet.get('latest_utxo_model');
final receiveDerivationsStringP2PKH = await secureStore?.read(
final receiveDerivationsStringP2PKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2PKH");
final changeDerivationsStringP2PKH = await secureStore?.read(
key: "${testWalletId}_changeDerivationsP2PKH");
final receiveDerivationsStringP2SH = await secureStore?.read(
key: "${testWalletId}_receiveDerivationsP2SH");
final changeDerivationsStringP2PKH =
await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
final receiveDerivationsStringP2SH =
await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
final changeDerivationsStringP2SH =
await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
final receiveDerivationsStringP2WPKH = await secureStore?.read(
await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
final receiveDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_receiveDerivationsP2WPKH");
final changeDerivationsStringP2WPKH = await secureStore?.read(
final changeDerivationsStringP2WPKH = await secureStore.read(
key: "${testWalletId}_changeDerivationsP2WPKH");
expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH);
@ -1296,9 +1296,9 @@ void main() {
verify(cachedClient?.clearSharedTransactionCache(coin: Coin.namecoin))
.called(1);
expect(secureStore?.writes, 19);
expect(secureStore?.reads, 32);
expect(secureStore?.deletes, 12);
expect(secureStore.writes, 19);
expect(secureStore.reads, 32);
expect(secureStore.deletes, 12);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -1366,21 +1366,21 @@ void main() {
height: 4000);
// modify addresses to properly mock data to build a tx
final rcv44 = await secureStore?.read(
final rcv44 = await secureStore.read(
key: testWalletId + "_receiveDerivationsP2PKH");
await secureStore?.write(
await secureStore.write(
key: testWalletId + "_receiveDerivationsP2PKH",
value: rcv44?.replaceFirst("1RMSPixoLPuaXuhR2v4HsUMcRjLncKDaw",
"16FuTPaeRSPVxxCnwQmdyx2PQWxX6HWzhQ"));
final rcv49 = await secureStore?.read(
key: testWalletId + "_receiveDerivationsP2SH");
await secureStore?.write(
final rcv49 =
await secureStore.read(key: testWalletId + "_receiveDerivationsP2SH");
await secureStore.write(
key: testWalletId + "_receiveDerivationsP2SH",
value: rcv49?.replaceFirst("3AV74rKfibWmvX34F99yEvUcG4LLQ9jZZk",
"36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"));
final rcv84 = await secureStore?.read(
final rcv84 = await secureStore.read(
key: testWalletId + "_receiveDerivationsP2WPKH");
await secureStore?.write(
await secureStore.write(
key: testWalletId + "_receiveDerivationsP2WPKH",
value: rcv84?.replaceFirst(
"bc1qggtj4ka8jsaj44hhd5mpamx7mp34m2d3w7k0m0",
@ -1436,10 +1436,10 @@ void main() {
true);
}
expect(secureStore?.interactions, 20);
expect(secureStore?.writes, 10);
expect(secureStore?.reads, 10);
expect(secureStore?.deletes, 0);
expect(secureStore.interactions, 20);
expect(secureStore.writes, 10);
expect(secureStore.reads, 10);
expect(secureStore.deletes, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -1456,7 +1456,7 @@ void main() {
expect(didThrow, true);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -1472,7 +1472,7 @@ void main() {
expect(didThrow, true);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -1492,7 +1492,7 @@ void main() {
rawTx: "a string", requestID: anyNamed("requestID")))
.called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -1513,7 +1513,7 @@ void main() {
rawTx: "a string", requestID: anyNamed("requestID")))
.called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(priceAPI);
@ -1538,7 +1538,7 @@ void main() {
rawTx: "a string", requestID: anyNamed("requestID")))
.called(1);
expect(secureStore?.interactions, 0);
expect(secureStore.interactions, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
verifyNoMoreInteractions(tracker);
@ -1658,10 +1658,10 @@ void main() {
true);
}
expect(secureStore?.interactions, 14);
expect(secureStore?.writes, 7);
expect(secureStore?.reads, 7);
expect(secureStore?.deletes, 0);
expect(secureStore.interactions, 14);
expect(secureStore.writes, 7);
expect(secureStore.reads, 7);
expect(secureStore.deletes, 0);
verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);
@ -1726,10 +1726,10 @@ void main() {
verify(client?.getBatchHistory(args: map)).called(1);
}
expect(secureStore?.interactions, 14);
expect(secureStore?.writes, 7);
expect(secureStore?.reads, 7);
expect(secureStore?.deletes, 0);
expect(secureStore.interactions, 14);
expect(secureStore.writes, 7);
expect(secureStore.reads, 7);
expect(secureStore.deletes, 0);
// verifyNoMoreInteractions(client);
verifyNoMoreInteractions(cachedClient);

View file

@ -141,7 +141,8 @@ void main() {
);
setUp(() async {
await NodeService().updateDefaults();
await NodeService(secureStorageInterface: FakeSecureStorage())
.updateDefaults();
});
test("setPrimaryNodeFor and getPrimaryNodeFor", () async {

View file

@ -32,7 +32,7 @@ void main() {
});
test("get walletNames", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect((await service.walletNames).toString(),
'{wallet_id: WalletInfo: {"name":"My Firo Wallet","id":"wallet_id","coin":"bitcoin"}, wallet_id2: WalletInfo: {"name":"wallet2","id":"wallet_id2","coin":"bitcoin"}}');
});
@ -40,13 +40,13 @@ void main() {
test("get null wallet names", () async {
final wallets = await Hive.openBox<dynamic>('wallets');
await wallets.put('names', null);
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(await service.walletNames, <String, WalletInfo>{});
expect((await service.walletNames).toString(), '{}');
});
test("rename wallet to same name", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(
await service.renameWallet(
from: "My Firo Wallet",
@ -58,7 +58,7 @@ void main() {
});
test("rename wallet to new name", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(
await service.renameWallet(
from: "My Firo Wallet",
@ -71,7 +71,7 @@ void main() {
});
test("attempt rename wallet to another existing name", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(
await service.renameWallet(
from: "My Firo Wallet",
@ -83,7 +83,7 @@ void main() {
});
test("add new wallet name", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(
await service.addNewWallet(
name: "wallet3", coin: Coin.bitcoin, shouldNotifyListeners: false),
@ -92,7 +92,7 @@ void main() {
});
test("add duplicate wallet name fails", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(
await service.addNewWallet(
name: "wallet2", coin: Coin.bitcoin, shouldNotifyListeners: false),
@ -103,27 +103,27 @@ void main() {
test("check for duplicates when null names", () async {
final wallets = await Hive.openBox<dynamic>('wallets');
await wallets.put('names', null);
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(await service.checkForDuplicate("anything"), false);
});
test("check for duplicates when some names with no matches", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(await service.checkForDuplicate("anything"), false);
});
test("check for duplicates when some names with a match", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(await service.checkForDuplicate("wallet2"), true);
});
test("get existing wallet id", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expect(await service.getWalletId("wallet2"), "wallet_id2");
});
test("get non existent wallet id", () async {
final service = WalletsService();
final service = WalletsService(secureStorageInterface: FakeSecureStorage());
expectLater(await service.getWalletId("wallet 99"), null);
});

View file

@ -42,7 +42,7 @@ class MockSecureStorageWrapper extends _i1.Mock
}
@override
_i2.FlutterSecureStorage get secureStore => (super.noSuchMethod(
_i2.FlutterSecureStorage get _secureStore => (super.noSuchMethod(
Invocation.getter(#secureStore),
returnValue: _FakeFlutterSecureStorage_0(
this,