mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-03 11:46:41 +00:00
Merge branch 'arti' of https://github.com/cypherstack/stack_wallet into arti
This commit is contained in:
commit
126229a38b
6 changed files with 286 additions and 146 deletions
|
@ -174,6 +174,7 @@ void main() async {
|
|||
// Some refactoring will need to be done here to make sure we don't make any
|
||||
// network calls before starting up tor
|
||||
if (Prefs.instance.useTor) {
|
||||
TorService.sharedInstance.init();
|
||||
await TorService.sharedInstance.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
||||
import 'package:stackwallet/services/tor_service.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
|
@ -35,7 +36,7 @@ class TorSettingsView extends ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _TorSettingsViewState extends ConsumerState<TorSettingsView> {
|
||||
TorConnectionStatus _networkStatus = TorConnectionStatus.disconnected;
|
||||
late TorConnectionStatus _networkStatus;
|
||||
|
||||
Widget _buildTorIcon(TorConnectionStatus status) {
|
||||
switch (status) {
|
||||
|
@ -123,6 +124,9 @@ class _TorSettingsViewState extends ConsumerState<TorSettingsView> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_networkStatus = ref.read(pTorService).enabled
|
||||
? TorConnectionStatus.connected
|
||||
: TorConnectionStatus.disconnected;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -195,7 +199,7 @@ class _TorSettingsViewState extends ConsumerState<TorSettingsView> {
|
|||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
|
@ -213,7 +217,7 @@ class _TorSettingsViewState extends ConsumerState<TorSettingsView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
|
|
|
@ -35,6 +35,7 @@ import 'package:stackwallet/themes/stack_colors.dart';
|
|||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
import 'package:stackwallet/widgets/animated_text.dart';
|
||||
|
@ -550,14 +551,6 @@ class _WalletNetworkSettingsViewState
|
|||
"Synchronized",
|
||||
style: STextStyles.w600_12(context),
|
||||
),
|
||||
Text(
|
||||
"100%",
|
||||
style: STextStyles.syncPercent(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.accentColorGreen,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -788,20 +781,47 @@ class _WalletNetworkSettingsViewState
|
|||
? STextStyles.desktopTextExtraExtraSmall(context)
|
||||
: STextStyles.smallMed12(context),
|
||||
),
|
||||
if (TorService.sharedInstance.enabled)
|
||||
if (ref.watch(
|
||||
prefsChangeNotifierProvider.select((value) => value.useTor)))
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
TorService.sharedInstance.stop();
|
||||
onTap: () async {
|
||||
// Stop the Tor service.
|
||||
try {
|
||||
await ref.read(pTorService).stop();
|
||||
|
||||
// Toggle the useTor preference on success.
|
||||
ref.read(prefsChangeNotifierProvider).useTor = false;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Error stopping tor: $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
"Disconnect",
|
||||
style: STextStyles.link2(context),
|
||||
),
|
||||
),
|
||||
if (!TorService.sharedInstance.enabled)
|
||||
if (!ref.watch(
|
||||
prefsChangeNotifierProvider.select((value) => value.useTor)))
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
TorService.sharedInstance.start();
|
||||
onTap: () async {
|
||||
// Init the Tor service if it hasn't already been.
|
||||
ref.read(pTorService).init();
|
||||
|
||||
// Start the Tor service.
|
||||
try {
|
||||
await ref.read(pTorService).start();
|
||||
|
||||
// Toggle the useTor preference on success.
|
||||
ref.read(prefsChangeNotifierProvider).useTor = true;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Error starting tor: $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
"Connect",
|
||||
|
@ -813,6 +833,99 @@ class _WalletNetworkSettingsViewState
|
|||
SizedBox(
|
||||
height: isDesktop ? 12 : 9,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
borderColor: isDesktop
|
||||
? Theme.of(context).extension<StackColors>()!.background
|
||||
: null,
|
||||
padding:
|
||||
isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
children: [
|
||||
if (ref.watch(prefsChangeNotifierProvider
|
||||
.select((value) => value.useTor)))
|
||||
Container(
|
||||
width: _iconSize,
|
||||
height: _iconSize,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.accentColorGreen
|
||||
.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(_iconSize),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
Assets.svg.tor,
|
||||
height: isDesktop ? 19 : 14,
|
||||
width: isDesktop ? 19 : 14,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.accentColorGreen,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!ref.watch(prefsChangeNotifierProvider
|
||||
.select((value) => value.useTor)))
|
||||
Container(
|
||||
width: _iconSize,
|
||||
height: _iconSize,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textDark
|
||||
.withOpacity(0.08),
|
||||
borderRadius: BorderRadius.circular(_iconSize),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
Assets.svg.tor,
|
||||
height: isDesktop ? 19 : 14,
|
||||
width: isDesktop ? 19 : 14,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: _boxPadding,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Tor status",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textDark,
|
||||
),
|
||||
),
|
||||
if (_torConnectionStatus == TorConnectionStatus.connected)
|
||||
Text(
|
||||
"Connected",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||
),
|
||||
if (_torConnectionStatus == TorConnectionStatus.connecting)
|
||||
Text(
|
||||
"Connecting...",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||
),
|
||||
if (_torConnectionStatus ==
|
||||
TorConnectionStatus.disconnected)
|
||||
Text(
|
||||
"Disconnected",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 32 : 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
|
@ -21,6 +21,7 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
|||
import 'package:stackwallet/services/tor_service.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
|
||||
|
@ -29,8 +30,6 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
|
|||
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
|
||||
import '../../../../utilities/prefs.dart';
|
||||
|
||||
class TorSettings extends ConsumerStatefulWidget {
|
||||
const TorSettings({Key? key}) : super(key: key);
|
||||
|
||||
|
@ -41,9 +40,6 @@ class TorSettings extends ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _TorSettingsState extends ConsumerState<TorSettings> {
|
||||
// The Prefs instance.
|
||||
final Prefs _prefs = Prefs.instance;
|
||||
|
||||
/// The global event bus.
|
||||
EventBus eventBus = GlobalEventBus.instance;
|
||||
|
||||
|
@ -52,8 +48,7 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
|
|||
_torConnectionStatusSubscription;
|
||||
|
||||
/// The current status of the Tor connection.
|
||||
late TorConnectionStatus _torConnectionStatus =
|
||||
TorConnectionStatus.disconnected;
|
||||
late TorConnectionStatus _torConnectionStatus;
|
||||
|
||||
/// Build the connect/disconnect button.
|
||||
Widget _buildConnectButton(TorConnectionStatus status) {
|
||||
|
@ -63,12 +58,22 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
|
|||
label: "Connect to Tor",
|
||||
width: 200,
|
||||
buttonHeight: ButtonHeight.m,
|
||||
onPressed: () {
|
||||
// Toggle the useTor preference.
|
||||
_prefs.useTor = true;
|
||||
onPressed: () async {
|
||||
// Init the Tor service if it hasn't already been.
|
||||
ref.read(pTorService).init();
|
||||
|
||||
// Start the Tor service.
|
||||
ref.read(pTorService).start();
|
||||
try {
|
||||
await ref.read(pTorService).start();
|
||||
|
||||
// Toggle the useTor preference on success.
|
||||
ref.read(prefsChangeNotifierProvider).useTor = true;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Error starting tor: $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
case TorConnectionStatus.connecting:
|
||||
|
@ -85,12 +90,19 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
|
|||
label: "Disconnect from Tor",
|
||||
width: 200,
|
||||
buttonHeight: ButtonHeight.m,
|
||||
onPressed: () {
|
||||
// Toggle the useTor preference.
|
||||
_prefs.useTor = false;
|
||||
|
||||
onPressed: () async {
|
||||
// Stop the Tor service.
|
||||
ref.read(pTorService).stop();
|
||||
try {
|
||||
await ref.read(pTorService).stop();
|
||||
|
||||
// Toggle the useTor preference on success.
|
||||
ref.read(prefsChangeNotifierProvider).useTor = false;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Error stopping tor: $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -196,63 +208,62 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
|
|||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return DesktopDialog(
|
||||
maxWidth: 580,
|
||||
maxHeight: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return DesktopDialog(
|
||||
maxWidth: 580,
|
||||
maxHeight: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
DesktopDialogCloseButton(
|
||||
onPressedOverride: () =>
|
||||
Navigator.of(context)
|
||||
.pop(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
DesktopDialogCloseButton(
|
||||
onPressedOverride: () =>
|
||||
Navigator.of(context)
|
||||
.pop(true),
|
||||
Text(
|
||||
"What is Tor?",
|
||||
style:
|
||||
STextStyles.desktopH2(
|
||||
context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"Short for \"The Onion Router\", is an open-source software that enables internet communication"
|
||||
" to remain anonymous by routing internet traffic through a series of layered nodes,"
|
||||
" to obscure the origin and destination of data.",
|
||||
style: STextStyles
|
||||
.desktopTextMedium(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textDark3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
"What is Tor?",
|
||||
style:
|
||||
STextStyles.desktopH2(
|
||||
context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"Short for \"The Onion Router\", is an open-source software that enables internet communication"
|
||||
" to remain anonymous by routing internet traffic through a series of layered nodes,"
|
||||
" to obscure the origin and destination of data.",
|
||||
style: STextStyles
|
||||
.desktopTextMedium(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textDark3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -299,66 +310,64 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
|
|||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return DesktopDialog(
|
||||
maxWidth: 580,
|
||||
maxHeight: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return DesktopDialog(
|
||||
maxWidth: 580,
|
||||
maxHeight: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
DesktopDialogCloseButton(
|
||||
onPressedOverride: () =>
|
||||
Navigator.of(context)
|
||||
.pop(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.max,
|
||||
children: [
|
||||
DesktopDialogCloseButton(
|
||||
onPressedOverride: () =>
|
||||
Navigator.of(
|
||||
Text(
|
||||
"What is Tor killswitch?",
|
||||
style: STextStyles
|
||||
.desktopH2(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"A security feature that protects your information from accidental exposure by"
|
||||
" disconnecting your device from the Tor network if your virtual private network (VPN)"
|
||||
" connection is disrupted or compromised.",
|
||||
style: STextStyles
|
||||
.desktopTextMedium(
|
||||
context)
|
||||
.pop(true),
|
||||
.copyWith(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textDark3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
20),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
"What is Tor killswitch?",
|
||||
style: STextStyles
|
||||
.desktopH2(
|
||||
context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"A security feature that protects your information from accidental exposure by"
|
||||
" disconnecting your device from the Tor network if your virtual private network (VPN)"
|
||||
" connection is disrupted or compromised.",
|
||||
style: STextStyles
|
||||
.desktopTextMedium(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textDark3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:tor/tor.dart';
|
|||
final pTorService = Provider((_) => TorService.sharedInstance);
|
||||
|
||||
class TorService {
|
||||
final _tor = Tor();
|
||||
Tor? _tor;
|
||||
|
||||
/// Flag to indicate that a Tor circuit is thought to have been established.
|
||||
bool _enabled = false;
|
||||
|
@ -30,9 +30,15 @@ class TorService {
|
|||
int port,
|
||||
}) get proxyInfo => (
|
||||
host: InternetAddress.loopbackIPv4,
|
||||
port: _tor.port,
|
||||
port: _tor!.port,
|
||||
);
|
||||
|
||||
/// Initialize the tor ffi lib instance if it hasn't already been set. Nothing
|
||||
/// changes if _tor is already been set.
|
||||
void init({Tor? mockableOverride}) {
|
||||
_tor ??= mockableOverride ?? Tor();
|
||||
}
|
||||
|
||||
/// Start the Tor service.
|
||||
///
|
||||
/// This will start the Tor service and establish a Tor circuit.
|
||||
|
@ -41,6 +47,10 @@ class TorService {
|
|||
///
|
||||
/// Returns a Future that completes when the Tor service has started.
|
||||
Future<void> start() async {
|
||||
if (_tor == null) {
|
||||
throw Exception("TorService.init has not been called!");
|
||||
}
|
||||
|
||||
if (_enabled) {
|
||||
// already started so just return
|
||||
// could throw an exception here or something so the caller
|
||||
|
@ -58,7 +68,7 @@ class TorService {
|
|||
"Tor connection status changed: connecting",
|
||||
),
|
||||
);
|
||||
await _tor.start();
|
||||
await _tor!.start();
|
||||
// no exception or error so we can (probably?) assume tor
|
||||
// has started successfully
|
||||
_enabled = true;
|
||||
|
@ -89,6 +99,10 @@ class TorService {
|
|||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
if (_tor == null) {
|
||||
throw Exception("TorService.init has not been called!");
|
||||
}
|
||||
|
||||
if (!_enabled) {
|
||||
// already stopped so just return
|
||||
// could throw an exception here or something so the caller
|
||||
|
@ -99,7 +113,7 @@ class TorService {
|
|||
|
||||
// Stop the Tor service.
|
||||
try {
|
||||
await _tor.disable();
|
||||
await _tor!.disable();
|
||||
// no exception or error so we can (probably?) assume tor
|
||||
// has started successfully
|
||||
_enabled = false;
|
||||
|
|
|
@ -129,7 +129,6 @@ class _DesktopTorStatusButtonState extends ConsumerState<DesktopTorStatusButton>
|
|||
// Clean up the subscription to the TorConnectionStatusChangedEvent.
|
||||
_torConnectionStatusSubscription.cancel();
|
||||
|
||||
|
||||
controller?.dispose();
|
||||
animationController.dispose();
|
||||
super.dispose();
|
||||
|
|
Loading…
Reference in a new issue