stack_wallet/lib/services/tor_service.dart

100 lines
2.7 KiB
Dart
Raw Normal View History

import 'dart:io';
2023-08-07 16:39:04 +00:00
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/utilities/logger.dart';
2023-09-06 21:56:18 +00:00
import 'package:tor/tor.dart';
2023-08-07 16:39:04 +00:00
2023-08-07 16:46:34 +00:00
final pTorService = Provider((_) => TorService.sharedInstance);
2023-08-07 16:39:04 +00:00
class TorService {
final _tor = Tor();
bool _enabled = false;
TorService._();
static final sharedInstance = TorService._();
2023-08-07 16:39:04 +00:00
({
InternetAddress host,
int port,
}) get proxyInfo => (
host: InternetAddress.loopbackIPv4,
port: _tor.port,
);
bool get enabled => _enabled;
2023-08-07 16:39:04 +00:00
Future<void> start() async {
if (_enabled) {
// already started so just return
// could throw an exception here or something so the caller
// is explicitly made aware of this
// TODO restart tor after that's been added to the tor-ffi crate
return;
}
try {
GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent(
TorConnectionStatus.connecting,
"Tor connection status changed: connecting",
),
);
await _tor.start();
// no exception or error so we can (probably?) assume tor
// has started successfully
_enabled = true;
GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent(
TorConnectionStatus.connected,
"Tor connection status changed: connect ($_enabled)",
),
);
} catch (e, s) {
Logging.instance.log(
"TorService.start failed: $e\n$s",
level: LogLevel.Warning,
);
// _enabled should already be false
GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent(
TorConnectionStatus.disconnected,
"Tor connection status changed: $_enabled (failed)",
),
);
rethrow;
}
2023-08-07 16:39:04 +00:00
}
Future<void> stop() async {
if (!_enabled) {
// already stopped so just return
// could throw an exception here or something so the caller
// is explicitly made aware of this
// TODO make sure to kill
return;
}
try {
await _tor.disable();
// no exception or error so we can (probably?) assume tor
// has started successfully
_enabled = false;
GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent(
TorConnectionStatus.disconnected,
"Tor connection status changed: $_enabled (disabled)",
),
);
} catch (e, s) {
Logging.instance.log(
"TorService.stop failed: $e\n$s",
level: LogLevel.Warning,
);
rethrow;
}
2023-08-07 16:39:04 +00:00
}
}