mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-16 09:17:37 +00:00
dynamic secure storage provider
This commit is contained in:
parent
2aa8dd2bec
commit
2bdf5f152c
44 changed files with 701 additions and 564 deletions
|
@ -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 = {};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
|
18
lib/providers/global/secure_store_provider.dart
Normal file
18
lib/providers/global/secure_store_provider.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
});
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -141,7 +141,8 @@ void main() {
|
|||
);
|
||||
|
||||
setUp(() async {
|
||||
await NodeService().updateDefaults();
|
||||
await NodeService(secureStorageInterface: FakeSecureStorage())
|
||||
.updateDefaults();
|
||||
});
|
||||
|
||||
test("setPrimaryNodeFor and getPrimaryNodeFor", () async {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue