Merge branch 'wallets_refactor' into wallets-refactor-epic

This commit is contained in:
julian 2023-09-20 17:02:51 -06:00
commit 3e889a6d27
33 changed files with 662 additions and 602 deletions

5
.gitignore vendored
View file

@ -57,8 +57,3 @@ libepic_cash_wallet.dll
libmobileliblelantus.dll
libtor_ffi.dll
/libisar.so
libtor_ffi.so
tor_logs.txt
torrc

BIN
assets/gif/stacy_onion.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

View file

@ -46,6 +46,7 @@ class DB {
// in use (keep for now)
static const String boxNameDBInfo = "dbInfo";
static const String boxNamePrefs = "prefs";
static const String boxNameOneTimeDialogsShown = "oneTimeDialogsShown";
String _boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";

View file

@ -15,9 +15,9 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/exceptions/json_rpc/json_rpc_exception.dart';
import 'package:stackwallet/networking/socks_socket.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:tor_ffi_plugin/socks_socket.dart';
// Json RPC class to handle connecting to electrumx servers
class JsonRPC {
@ -247,6 +247,8 @@ class JsonRPC {
cancelOnError: true,
);
}
return;
}
}

View file

@ -1,343 +0,0 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
/// A SOCKS5 socket.
///
/// This class is a wrapper around a Socket that connects to a SOCKS5 proxy
/// server and sends all data through the proxy.
///
/// This class is used to connect to the Tor proxy server.
///
/// Attributes:
/// - [proxyHost]: The host of the SOCKS5 proxy server.
/// - [proxyPort]: The port of the SOCKS5 proxy server.
/// - [_socksSocket]: The underlying [Socket] that connects to the SOCKS5 proxy
/// server.
/// - [_responseController]: A [StreamController] that listens to the
/// [_socksSocket] and broadcasts the response.
///
/// Methods:
/// - connect: Connects to the SOCKS5 proxy server.
/// - connectTo: Connects to the specified [domain] and [port] through the
/// SOCKS5 proxy server.
/// - write: Converts [object] to a String by invoking [Object.toString] and
/// sends the encoding of the result to the socket.
/// - sendServerFeaturesCommand: Sends the server.features command to the
/// proxy server.
/// - close: Closes the connection to the Tor proxy.
///
/// Usage:
/// ```dart
/// // Instantiate a socks socket at localhost and on the port selected by the
/// // tor service.
/// var socksSocket = await SOCKSSocket.create(
/// proxyHost: InternetAddress.loopbackIPv4.address,
/// proxyPort: tor.port,
/// // sslEnabled: true, // For SSL connections.
/// );
///
/// // Connect to the socks instantiated above.
/// await socksSocket.connect();
///
/// // Connect to bitcoincash.stackwallet.com on port 50001 via socks socket.
/// await socksSocket.connectTo(
/// 'bitcoincash.stackwallet.com', 50001);
///
/// // Send a server features command to the connected socket, see method for
/// // more specific usage example..
/// await socksSocket.sendServerFeaturesCommand();
/// await socksSocket.close();
/// ```
///
/// See also:
/// - SOCKS5 protocol(https://www.ietf.org/rfc/rfc1928.txt)
class SOCKSSocket {
/// The host of the SOCKS5 proxy server.
final String proxyHost;
/// The port of the SOCKS5 proxy server.
final int proxyPort;
/// The underlying Socket that connects to the SOCKS5 proxy server.
late final Socket _socksSocket;
/// Getter for the underlying Socket that connects to the SOCKS5 proxy server.
Socket get socket => sslEnabled ? _secureSocksSocket : _socksSocket;
/// A wrapper around the _socksSocket that enables SSL connections.
late final Socket _secureSocksSocket;
/// A StreamController that listens to the _socksSocket and broadcasts.
final StreamController<List<int>> _responseController =
StreamController.broadcast();
/// A StreamController that listens to the _secureSocksSocket and broadcasts.
final StreamController<List<int>> _secureResponseController =
StreamController.broadcast();
/// Getter for the StreamController that listens to the _socksSocket and
/// broadcasts, or the _secureSocksSocket and broadcasts if SSL is enabled.
StreamController<List<int>> get responseController =>
sslEnabled ? _secureResponseController : _responseController;
/// A StreamSubscription that listens to the _socksSocket or the
/// _secureSocksSocket if SSL is enabled.
StreamSubscription<List<int>>? _subscription;
/// Getter for the StreamSubscription that listens to the _socksSocket or the
/// _secureSocksSocket if SSL is enabled.
StreamSubscription<List<int>>? get subscription => _subscription;
/// Is SSL enabled?
final bool sslEnabled;
/// Private constructor.
SOCKSSocket._(this.proxyHost, this.proxyPort, this.sslEnabled);
/// Creates a SOCKS5 socket to the specified [proxyHost] and [proxyPort].
///
/// This method is a factory constructor that returns a Future that resolves
/// to a SOCKSSocket instance.
///
/// Parameters:
/// - [proxyHost]: The host of the SOCKS5 proxy server.
/// - [proxyPort]: The port of the SOCKS5 proxy server.
///
/// Returns:
/// A Future that resolves to a SOCKSSocket instance.
static Future<SOCKSSocket> create(
{required String proxyHost,
required int proxyPort,
bool sslEnabled = false}) async {
// Create a SOCKS socket instance.
var instance = SOCKSSocket._(proxyHost, proxyPort, sslEnabled);
// Initialize the SOCKS socket.
await instance._init();
// Return the SOCKS socket instance.
return instance;
}
/// Constructor.
SOCKSSocket(
{required this.proxyHost,
required this.proxyPort,
required this.sslEnabled}) {
_init();
}
/// Initializes the SOCKS socket.
///
/// This method is a private method that is called by the constructor.
///
/// Returns:
/// A Future that resolves to void.
Future<void> _init() async {
// Connect to the SOCKS proxy server.
_socksSocket = await Socket.connect(
proxyHost,
proxyPort,
);
// Listen to the socket.
_subscription = _socksSocket.listen(
(data) {
// Add the data to the response controller.
_responseController.add(data);
},
onError: (e) {
// Handle errors.
if (e is Object) {
_responseController.addError(e);
}
// If the error is not an object, send the error as a string.
_responseController.addError("$e");
// TODO make sure sending error as string is acceptable.
},
onDone: () {
// Close the response controller when the socket is closed.
_responseController.close();
},
);
}
/// Connects to the SOCKS socket.
///
/// Returns:
/// A Future that resolves to void.
Future<void> connect() async {
// Greeting and method selection.
_socksSocket.add([0x05, 0x01, 0x00]);
// Wait for server response.
var response = await _responseController.stream.first;
// Check if the connection was successful.
if (response[1] != 0x00) {
throw Exception(
'socks_socket.connect(): Failed to connect to SOCKS5 proxy.');
}
}
/// Connects to the specified [domain] and [port] through the SOCKS socket.
///
/// Parameters:
/// - [domain]: The domain to connect to.
/// - [port]: The port to connect to.
///
/// Returns:
/// A Future that resolves to void.
Future<void> connectTo(String domain, int port) async {
// Connect command.
var request = [
0x05, // SOCKS version.
0x01, // Connect command.
0x00, // Reserved.
0x03, // Domain name.
domain.length,
...domain.codeUnits,
(port >> 8) & 0xFF,
port & 0xFF
];
// Send the connect command to the SOCKS proxy server.
_socksSocket.add(request);
// Wait for server response.
var response = await _responseController.stream.first;
// Check if the connection was successful.
if (response[1] != 0x00) {
throw Exception(
'socks_socket.connectTo(): Failed to connect to target through SOCKS5 proxy.');
}
// Upgrade to SSL if needed
if (sslEnabled) {
// Upgrade to SSL.
_secureSocksSocket = await SecureSocket.secure(
_socksSocket,
host: domain,
// onBadCertificate: (_) => true, // Uncomment this to bypass certificate validation (NOT recommended for production).
);
// Listen to the secure socket.
_subscription = _secureSocksSocket.listen(
(data) {
// Add the data to the response controller.
_secureResponseController.add(data);
},
onError: (e) {
// Handle errors.
if (e is Object) {
_secureResponseController.addError(e);
}
// If the error is not an object, send the error as a string.
_secureResponseController.addError("$e");
// TODO make sure sending error as string is acceptable.
},
onDone: () {
// Close the response controller when the socket is closed.
_secureResponseController.close();
},
);
}
return;
}
/// Converts [object] to a String by invoking [Object.toString] and
/// sends the encoding of the result to the socket.
///
/// Parameters:
/// - [object]: The object to write to the socket.
///
/// Returns:
/// A Future that resolves to void.
void write(Object? object) {
// Don't write null.
if (object == null) return;
// Write the data to the socket.
List<int> data = utf8.encode(object.toString());
if (sslEnabled) {
_secureSocksSocket.add(data);
} else {
_socksSocket.add(data);
}
}
/// Sends the server.features command to the proxy server.
///
/// This method is used to send the server.features command to the proxy
/// server. This command is used to request the features of the proxy server.
/// It serves as a demonstration of how to send commands to the proxy server.
///
/// Returns:
/// A Future that resolves to void.
Future<void> sendServerFeaturesCommand() async {
// The server.features command.
const String command =
'{"jsonrpc":"2.0","id":"0","method":"server.features","params":[]}';
if (!sslEnabled) {
// Send the command to the proxy server.
_socksSocket.writeln(command);
// Wait for the response from the proxy server.
var responseData = await _responseController.stream.first;
print("responseData: ${utf8.decode(responseData)}");
} else {
// Send the command to the proxy server.
_secureSocksSocket.writeln(command);
// Wait for the response from the proxy server.
var responseData = await _secureResponseController.stream.first;
print("secure responseData: ${utf8.decode(responseData)}");
}
return;
}
/// Closes the connection to the Tor proxy.
///
/// Returns:
/// A Future that resolves to void.
Future<void> close() async {
// Ensure all data is sent before closing.
//
// TODO test this.
if (sslEnabled) {
await _socksSocket.flush();
await _secureResponseController.close();
}
await _socksSocket.flush();
await _responseController.close();
return await _socksSocket.close();
}
StreamSubscription<List<int>> listen(
void Function(List<int> data)? onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) {
return sslEnabled
? _secureResponseController.stream.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
)
: _responseController.stream.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
}
}

View file

@ -18,6 +18,7 @@ import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
import 'package:stackwallet/themes/stack_colors.dart';
@ -40,8 +41,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
import '../../../services/exchange/exchange.dart';
class ExchangeCurrencySelectionView extends StatefulWidget {
const ExchangeCurrencySelectionView({
Key? key,

View file

@ -36,14 +36,12 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart
import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart';
import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/amount/amount_unit.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/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
@ -80,11 +78,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
late final Coin? coin;
late final bool walletInitiated;
var exchanges = [
MajesticBankExchange.instance,
ChangeNowExchange.instance,
TrocadorExchange.instance,
];
List<Exchange> get usableExchanges {
if (ref.read(prefsChangeNotifierProvider).useTor) {
return Exchange.exchangesWithTorSupport;
} else {
return [
MajesticBankExchange.instance,
ChangeNowExchange.instance,
TrocadorExchange.instance,
];
}
}
late final TextEditingController _sendController;
late final TextEditingController _receiveController;
@ -623,7 +627,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
final uuid = const Uuid().v1();
_latestUuid = uuid;
_addUpdate(uuid);
for (final exchange in exchanges) {
for (final exchange in usableExchanges) {
ref.read(efEstimatesListProvider(exchange.name).notifier).state = null;
}
@ -644,7 +648,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
final Map<String, Tuple2<ExchangeResponse<List<Estimate>>, Range?>>
results = {};
for (final exchange in exchanges) {
for (final exchange in usableExchanges) {
final sendCurrency = pair.send?.forExchange(exchange.name);
final receiveCurrency = pair.receive?.forExchange(exchange.name);
@ -674,7 +678,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
}
for (final exchange in exchanges) {
for (final exchange in usableExchanges) {
if (uuid == _latestUuid) {
ref.read(efEstimatesListProvider(exchange.name).notifier).state =
results[exchange.name];
@ -775,14 +779,6 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
});
}
// Instantiate the Tor service.
torService = TorService.sharedInstance;
// Filter exchanges based on Tor support.
if (Prefs.instance.useTor) {
exchanges = Exchange.exchangesWithTorSupport;
}
super.initState();
}
@ -1017,7 +1013,4 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
],
);
}
// TorService instance.
late TorService torService;
}

View file

@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/onetime_popups/tor_has_been_add_dialog.dart';
import 'package:stackwallet/widgets/small_tor_icon.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@ -129,19 +130,9 @@ class _HomeViewState extends ConsumerState<HomeView> {
ref.read(notificationsProvider).startCheckingWatchedNotifications();
/// todo change to watch tor network
// if (ref.read(managerProvider).isRefreshing) {
// _currentSyncStatus = WalletSyncStatus.syncing;
// _currentNodeStatus = NodeConnectionStatus.connected;
// } else {
// _currentSyncStatus = WalletSyncStatus.synced;
// if (ref.read(managerProvider).isConnected) {
// _currentNodeStatus = NodeConnectionStatus.connected;
// } else {
// _currentNodeStatus = NodeConnectionStatus.disconnected;
// _currentSyncStatus = WalletSyncStatus.unableToSync;
// }
// }
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
showOneTimeTorHasBeenAddedDialogIfRequired(context);
});
super.initState();
}

View file

@ -242,7 +242,8 @@ class _OrdinalImageGroup extends ConsumerWidget {
);
if (response.code != 200) {
throw Exception("statusCode=${response.code} body=${response.bodyBytes}");
throw Exception(
"OrdinalDetailsView _savePngToFile statusCode=${response.code} body=${response.bodyBytes}");
}
final bytes = response.bodyBytes;

View file

@ -12,13 +12,20 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/providers/global/debug_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/onetime_popups/tor_has_been_add_dialog.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class HiddenSettings extends StatelessWidget {
@ -32,9 +39,29 @@ class HiddenSettings extends StatelessWidget {
child: Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: Container(),
leading: Util.isDesktop
? Padding(
padding: const EdgeInsets.all(8.0),
child: AppBarIconButton(
size: 32,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.arrowLeft,
width: 18,
height: 18,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: Navigator.of(context).pop,
),
)
: Container(),
title: Text(
"Not so secret anymore",
"Dev options",
style: STextStyles.navBarTitle(context),
),
),
@ -146,6 +173,48 @@ class HiddenSettings extends StatelessWidget {
),
);
}),
const SizedBox(
height: 12,
),
Consumer(builder: (_, ref, __) {
return GestureDetector(
onTap: () async {
await showOneTimeTorHasBeenAddedDialogIfRequired(
context,
);
},
child: RoundedWhiteContainer(
child: Text(
"Test tor stacy popup",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
);
}),
const SizedBox(
height: 12,
),
Consumer(builder: (_, ref, __) {
return GestureDetector(
onTap: () async {
final box = await Hive.openBox<bool>(
DB.boxNameOneTimeDialogsShown);
await box.clear();
},
child: RoundedWhiteContainer(
child: Text(
"Reset tor stacy popup",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
);
}),
// const SizedBox(
// height: 12,
// ),

View file

@ -225,11 +225,11 @@ class _TorAnimatedButtonState extends ConsumerState<TorAnimatedButton>
// Connect or disconnect when the user taps the status.
switch (_status) {
case TorConnectionStatus.disconnected:
await _connectTor(ref, context);
await connectTor(ref, context);
break;
case TorConnectionStatus.connected:
await _disconnectTor(ref, context);
await disconnectTor(ref, context);
break;
@ -435,11 +435,11 @@ class _TorButtonState extends ConsumerState<TorButton> {
// Connect or disconnect when the user taps the status.
switch (_status) {
case TorConnectionStatus.disconnected:
await _connectTor(ref, context);
await connectTor(ref, context);
break;
case TorConnectionStatus.connected:
await _disconnectTor(ref, context);
await disconnectTor(ref, context);
break;
@ -583,7 +583,7 @@ class _UpperCaseTorTextState extends ConsumerState<UpperCaseTorText> {
/// Throws an exception if the Tor service fails to start.
///
/// Returns a Future that completes when the Tor service has started.
Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
Future<void> connectTor(WidgetRef ref, BuildContext context) async {
try {
// Init the Tor service if it hasn't already been.
final torDir = await StackFileSystem.applicationTorDirectory();
@ -600,8 +600,6 @@ Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
);
// TODO: show dialog with error message
}
return;
}
/// Disconnect from the Tor network.
@ -611,7 +609,7 @@ Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
/// Throws an exception if the Tor service fails to stop.
///
/// Returns a Future that completes when the Tor service has stopped.
Future<void> _disconnectTor(WidgetRef ref, BuildContext context) async {
Future<void> disconnectTor(WidgetRef ref, BuildContext context) async {
// Stop the Tor service.
try {
await ref.read(pTorService).disable();

View file

@ -16,6 +16,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart';
import 'package:stackwallet/pages/settings_views/sub_widgets/nodes_list.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart';
@ -35,8 +36,6 @@ 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/stack_file_system.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/animated_text.dart';
@ -100,6 +99,26 @@ class _WalletNetworkSettingsViewState
/// The current status of the Tor connection.
late TorConnectionStatus _torConnectionStatus;
bool _buttonLockTor = false;
Future<void> onTorTapped() async {
if (_buttonLockTor) {
return;
}
_buttonLockTor = true;
try {
if (ref.read(prefsChangeNotifierProvider).useTor) {
await disconnectTor(ref, context);
} else {
await connectTor(ref, context);
}
} catch (_) {
// Nothing. Just using finally to ensure button lock is reset in case
// some unexpected error happens
} finally {
_buttonLockTor = false;
}
}
Future<void> _attemptRescan() async {
if (!Platform.isLinux) await Wakelock.enable();
@ -477,17 +496,14 @@ class _WalletNetworkSettingsViewState
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
GestureDetector(
CustomTextButton(
text: "Resync",
onTap: () {
ref
.read(walletsChangeNotifierProvider)
.getManager(widget.walletId)
.refresh();
},
child: Text(
"Resync",
style: STextStyles.link2(context),
),
),
],
),
@ -769,55 +785,13 @@ class _WalletNetworkSettingsViewState
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
if (ref.watch(
prefsChangeNotifierProvider.select((value) => value.useTor)))
GestureDetector(
onTap: () async {
// Stop the Tor service.
try {
await ref.read(pTorService).disable();
// 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 (!ref.watch(
prefsChangeNotifierProvider.select((value) => value.useTor)))
GestureDetector(
onTap: () async {
try {
// Init the Tor service if it hasn't already been.
final torDir =
await StackFileSystem.applicationTorDirectory();
ref.read(pTorService).init(torDataDirPath: torDir.path);
// Start the Tor service.
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,
);
// TODO: show dialog with error message
}
},
child: Text(
"Connect",
style: STextStyles.link2(context),
),
),
CustomTextButton(
text: ref.watch(prefsChangeNotifierProvider
.select((value) => value.useTor))
? "Disconnect"
: "Connect",
onTap: onTorTapped,
),
],
),
SizedBox(

View file

@ -13,6 +13,7 @@ import 'dart:async';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/models/epicbox_config_model.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
@ -36,11 +37,14 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/show_loading.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:tuple/tuple.dart';
/// [eventBus] should only be set during testing
@ -306,6 +310,61 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
);
},
),
if (coin == Coin.firo)
const SizedBox(
height: 8,
),
if (coin == Coin.firo)
Consumer(
builder: (_, ref, __) {
return SettingsListButton(
iconAssetName: Assets.svg.eye,
title: "Clear electrumx cache",
onPressed: () async {
String? result;
await showDialog<void>(
useSafeArea: false,
barrierDismissible: true,
context: context,
builder: (_) => StackOkDialog(
title:
"Are you sure you want to clear "
"${coin.prettyName} electrumx cache?",
onOkPressed: (value) {
result = value;
},
leftButton: SecondaryButton(
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
),
);
if (result == "OK" && mounted) {
await showLoading(
whileFuture: Future.wait<void>(
[
Future.delayed(
const Duration(
milliseconds: 1500,
),
),
DB.instance
.clearSharedTransactionCache(
coin: coin,
),
],
),
context: context,
message: "Clearing cache...",
);
}
},
);
},
),
if (coin == Coin.nano || coin == Coin.banano)
const SizedBox(
height: 8,

View file

@ -47,7 +47,7 @@ class TxIcon extends ConsumerWidget {
if (isReceived) {
if (isCancelled) {
return assets.receive;
return assets.receiveCancelled;
}
if (isPending) {
return assets.receivePending;

View file

@ -358,8 +358,6 @@ class _TransactionDetailsViewState
final currentHeight = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId).currentHeight));
print("THIS TRANSACTION IS $_transaction");
return ConditionalParent(
condition: !isDesktop,
builder: (child) => Background(

View file

@ -30,6 +30,7 @@ import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/onetime_popups/tor_has_been_add_dialog.dart';
final currentWalletIdProvider = StateProvider<String?>((_) => null);
@ -53,6 +54,11 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
onGenerateRoute: RouteGenerator.generateRoute,
initialRoute: MyStackView.routeName,
);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
showOneTimeTorHasBeenAddedDialogIfRequired(context);
});
super.initState();
}

View file

@ -13,11 +13,13 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/hidden_settings.dart';
import 'package:stackwallet/pages/wallets_view/sub_widgets/empty_wallets.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/my_wallets.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/themes/theme_providers.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
@ -52,27 +54,77 @@ class _MyStackViewState extends ConsumerState<MyStackView> {
}
}
class DesktopMyStackTitle extends ConsumerWidget {
const DesktopMyStackTitle({Key? key}) : super(key: key);
class DesktopMyStackTitle extends ConsumerStatefulWidget {
const DesktopMyStackTitle({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
ConsumerState<DesktopMyStackTitle> createState() =>
_DesktopMyStackTitleState();
}
class _DesktopMyStackTitleState extends ConsumerState<DesktopMyStackTitle> {
late final RotateIconController _rotateIconController;
DateTime _hiddenTime = DateTime.now();
int _hiddenCount = 0;
void _hiddenOptions() {
_rotateIconController.reset?.call();
_rotateIconController.forward?.call();
if (_hiddenCount == 5) {
Navigator.of(context).pushNamed(HiddenSettings.routeName);
}
final now = DateTime.now();
const timeout = Duration(seconds: 1);
if (now.difference(_hiddenTime) < timeout) {
_hiddenCount++;
} else {
_hiddenCount = 0;
}
_hiddenTime = now;
}
@override
void initState() {
_rotateIconController = RotateIconController();
super.initState();
}
@override
dispose() {
_rotateIconController.forward = null;
_rotateIconController.reverse = null;
_rotateIconController.reset = null;
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
const SizedBox(
width: 24,
),
SizedBox(
width: 32,
height: 32,
child: SvgPicture.file(
File(
ref.watch(
themeProvider.select(
(value) => value.assets.stackIcon,
GestureDetector(
onTap: _hiddenOptions,
child: RotateIcon(
icon: SizedBox(
width: 32,
height: 32,
child: SvgPicture.file(
File(
ref.watch(
themeProvider.select(
(value) => value.assets.stackIcon,
),
),
),
),
),
curve: Curves.easeInOutCubic,
rotationPercent: 1.0,
controller: _rotateIconController,
),
),
const SizedBox(

View file

@ -62,7 +62,8 @@ class _DesktopOrdinalDetailsViewState
);
if (response.code != 200) {
throw Exception("statusCode=${response.code} body=${response.bodyBytes}");
throw Exception(
"DesktopOrdinalDetailsView _savePngToFile statusCode=${response.code} body=${response.bodyBytes}");
}
final bytes = response.bodyBytes;

View file

@ -457,7 +457,6 @@ class EpicCashWallet extends CoinServiceAPI
// TODO determine whether it is worth sending change to a change address.
dynamic message;
print("THIS TX DATA IS $txData");
String receiverAddress = txData['addresss'] as String;

View file

@ -162,18 +162,21 @@ class ExchangeDataLoadingService {
// await _loadChangeNowEstimatedRatePairs();
*/
// Exchanges which support Tor just get treated normally.
final futures = [
loadMajesticBankCurrencies(),
loadTrocadorCurrencies(),
];
// If using Tor, don't load data for exchanges which don't support Tor.
//
// Add to this list when adding an exchange which doesn't supports Tor.
if (!Prefs.instance.useTor) {
await _loadChangeNowCurrencies();
futures.add(_loadChangeNowCurrencies());
}
// Exchanges which support Tor just get treated normally.
await Future.wait([
loadMajesticBankCurrencies(),
loadTrocadorCurrencies(),
]);
// wait for all loading futures to complete
await Future.wait(futures);
Logging.instance.log(
"ExchangeDataLoadingService.loadAll finished in ${DateTime.now().difference(start).inSeconds} seconds",

View file

@ -21,6 +21,7 @@ abstract class Assets {
static const socials = _SOCIALS();
static const exchange = _EXCHANGE();
static const buy = _BUY();
static const gif = _GIF();
}
class _SOCIALS {
@ -260,3 +261,9 @@ class _ANIMATIONS {
String get arrowRotate => "assets/lottie/arrow_rotate.json";
String get onionTor => "assets/lottie/onion_animation.json";
}
class _GIF {
const _GIF();
String get stacyOnion => "assets/gif/stacy_onion.gif";
}

View file

@ -120,50 +120,56 @@ class _DesktopTorStatusButtonState extends ConsumerState<DesktopTorStatusButton>
.extension<StackColors>()!
.getDesktopMenuButtonStyle(context),
onPressed: widget.onPressed,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 16,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedContainer(
duration: widget.transitionDuration,
width: _iconOnly ? 0 : 16,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16,
),
SvgPicture.asset(
Assets.svg.tor,
color: _color(_torConnectionStatus),
width: 20,
height: 20,
),
AnimatedOpacity(
duration: widget.transitionDuration,
opacity: _iconOnly ? 0 : 1.0,
child: SizeTransition(
sizeFactor: animationController,
axis: Axis.horizontal,
axisAlignment: -1,
child: SizedBox(
width: labelLength,
child: Row(
children: [
const SizedBox(
width: 12,
),
Text(
_torConnectionStatus.name.capitalize(),
style: STextStyles.smallMed12(context).copyWith(
color: _color(_torConnectionStatus),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedContainer(
duration: widget.transitionDuration,
width: _iconOnly ? 0 : 16,
),
SvgPicture.asset(
Assets.svg.tor,
color: _color(_torConnectionStatus),
width: 20,
height: 20,
),
AnimatedOpacity(
duration: widget.transitionDuration,
opacity: _iconOnly ? 0 : 1.0,
child: SizeTransition(
sizeFactor: animationController,
axis: Axis.horizontal,
axisAlignment: -1,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 12,
),
),
],
Text(
_torConnectionStatus.name.capitalize(),
style: STextStyles.smallMed12(context).copyWith(
color: _color(_torConnectionStatus),
),
),
const SizedBox(
width: 21,
),
],
),
),
),
),
],
),
],
),
),
],
),
);
}

View file

@ -0,0 +1,167 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
const _kOneTimeTorHasBeenAddedDialogWasShown =
"oneTimeTorHasBeenAddedDialogWasShown";
Future<void> showOneTimeTorHasBeenAddedDialogIfRequired(
BuildContext context) async {
final box = await Hive.openBox<bool>(DB.boxNameOneTimeDialogsShown);
if (!box.get(
_kOneTimeTorHasBeenAddedDialogWasShown,
defaultValue: false,
)! &&
context.mounted) {
await showDialog<void>(
context: context,
barrierDismissible: false,
builder: (_) => const _TorHasBeenAddedDialog(),
);
}
}
class _TorHasBeenAddedDialog extends StatefulWidget {
const _TorHasBeenAddedDialog({super.key});
@override
State<_TorHasBeenAddedDialog> createState() => _TorHasBeenAddedDialogState();
}
class _TorHasBeenAddedDialogState extends State<_TorHasBeenAddedDialog> {
bool _lock = false;
void setDoNotShowAgain() async {
if (_lock) {
return;
}
_lock = true;
try {
final box = await Hive.openBox<bool>(DB.boxNameOneTimeDialogsShown);
await box.put(_kOneTimeTorHasBeenAddedDialogWasShown, true);
} catch (_) {
//
} finally {
_lock = false;
}
}
@override
Widget build(BuildContext context) {
return ConditionalParent(
condition: Util.isDesktop,
builder: (child) => DesktopDialog(
maxHeight: double.infinity,
maxWidth: 450,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 32),
child: Text(
"",
style: STextStyles.desktopH3(context),
),
),
DesktopDialogCloseButton(
onPressedOverride: () {
setDoNotShowAgain();
Navigator.of(context).pop();
},
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: child,
),
Padding(
padding: const EdgeInsets.all(32),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PrimaryButton(
buttonHeight: ButtonHeight.l,
width: 180,
label: "Ok",
onPressed: () {
setDoNotShowAgain();
Navigator.of(context).pop();
},
),
],
),
)
],
),
),
child: ConditionalParent(
condition: !Util.isDesktop,
builder: (child) => StackDialogBase(
child: Column(
children: [
child,
const SizedBox(
height: 28,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: PrimaryButton(
label: "Ok",
onPressed: () {
setDoNotShowAgain();
Navigator.of(context).pop();
},
),
),
],
),
],
),
),
child: Column(
children: [
const StacyOnion(),
SizedBox(
height: Util.isDesktop ? 24 : 16,
),
Text(
"Tor has been added to help keep your connections private and secure!",
style: Util.isDesktop
? STextStyles.desktopTextMedium(context)
: STextStyles.smallMed14(context),
),
],
),
),
);
}
}
class StacyOnion extends StatelessWidget {
const StacyOnion({super.key});
@override
Widget build(BuildContext context) {
return Image(
height: 200,
image: AssetImage(
Assets.gif.stacyOnion,
),
);
}
}

View file

@ -37,10 +37,10 @@ packages:
dependency: "direct main"
description:
name: archive
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
sha256: e0902a06f0e00414e4e3438a084580161279f137aeb862274710f29ec10cf01e
url: "https://pub.dev"
source: hosted
version: "3.3.7"
version: "3.3.9"
args:
dependency: transitive
description:
@ -53,10 +53,10 @@ packages:
dependency: transitive
description:
name: asn1lib
sha256: b74e3842a52c61f8819a1ec8444b4de5419b41a7465e69d4aa681445377398b0
sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd"
url: "https://pub.dev"
source: hosted
version: "1.4.1"
version: "1.5.0"
async:
dependency: "direct main"
description:
@ -178,10 +178,10 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20"
sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.3.2"
build_runner:
dependency: "direct dev"
description:
@ -210,10 +210,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
sha256: ff627b645b28fb8bdb69e645f910c2458fd6b65f6585c3a53e0626024897dedf
url: "https://pub.dev"
source: hosted
version: "8.6.1"
version: "8.6.2"
characters:
dependency: transitive
description:
@ -250,10 +250,10 @@ packages:
dependency: transitive
description:
name: code_builder
sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
sha256: "315a598c7fbe77f22de1c9da7cfd6fd21816312f16ffa124453b4fc679e540f1"
url: "https://pub.dev"
source: hosted
version: "4.5.0"
version: "4.6.0"
coinlib:
dependency: "direct main"
description:
@ -274,10 +274,10 @@ packages:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "8599ae9edca5ff96163fca3e36f8e481ea917d1e71cdad912c084b5579913f34"
sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
version: "4.0.2"
connectivity_plus_platform_interface:
dependency: transitive
description:
@ -306,10 +306,10 @@ packages:
dependency: transitive
description:
name: cross_file
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
version: "0.3.3+5"
crypto:
dependency: "direct main"
description:
@ -398,10 +398,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.3.3"
dartx:
dependency: transitive
description:
@ -438,18 +438,18 @@ packages:
dependency: "direct main"
description:
name: desktop_drop
sha256: "4ca4d960f4b11c032e9adfd2a0a8ac615bc3fddb4cbe73dcf840dd8077582186"
sha256: ebba9c9cb0b54385998a977d741cc06fd8324878c08d5a36e9da61cd56b04cc6
url: "https://pub.dev"
source: hosted
version: "0.4.1"
version: "0.4.3"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b"
sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659"
url: "https://pub.dev"
source: hosted
version: "9.0.2"
version: "9.0.3"
device_info_plus_platform_interface:
dependency: transitive
description:
@ -478,10 +478,10 @@ packages:
dependency: "direct main"
description:
name: dropdown_button2
sha256: "83c54a5022f898d63e3abe21240b64b937e676103207287e6705d3f9bb04d654"
sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1
url: "https://pub.dev"
source: hosted
version: "2.3.6"
version: "2.3.9"
eip1559:
dependency: transitive
description:
@ -510,10 +510,10 @@ packages:
dependency: transitive
description:
name: encrypt
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
url: "https://pub.dev"
source: hosted
version: "5.0.1"
version: "5.0.3"
equatable:
dependency: "direct main"
description:
@ -631,10 +631,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
flutter_local_notifications:
dependency: "direct main"
description:
@ -671,18 +671,18 @@ packages:
dependency: "direct main"
description:
name: flutter_native_splash
sha256: ba45d8cfbd778478a74696b012f33ffb6b1760c9bc531b21e2964444a4870dae
sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360"
sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
url: "https://pub.dev"
source: hosted
version: "2.0.15"
version: "2.0.16"
flutter_riverpod:
dependency: "direct main"
description:
@ -703,50 +703,50 @@ packages:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "98352186ee7ad3639ccc77ad7924b773ff6883076ab952437d20f18a61f0a7c5"
sha256: "22dbf16f23a4bcf9d35e51be1c84ad5bb6f627750565edd70dab70f3ff5fff8f"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
version: "8.1.0"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: "0912ae29a572230ad52d8a4697e5518d7f0f429052fd51df7e5a7952c7efe2a3"
sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
version: "1.2.0"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: "083add01847fc1c80a07a08e1ed6927e9acd9618a35e330239d4422cd2a58c50"
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
url: "https://pub.dev"
source: hosted
version: "3.0.0"
version: "3.0.1"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: b3773190e385a3c8a382007893d678ae95462b3c2279e987b55d140d3b0cb81b
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
version: "1.0.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: "42938e70d4b872e856e678c423cc0e9065d7d294f45bc41fc1981a4eb4beaffe"
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: fc2910ec9b28d60598216c29ea763b3a96c401f0ce1d13cdf69ccb0e5c93c3ee
sha256: "38f9501c7cb6f38961ef0e1eacacee2b2d4715c63cc83fe56449c4d3d0b47255"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "2.1.1"
flutter_svg:
dependency: "direct main"
description:
@ -830,10 +830,10 @@ packages:
dependency: "direct dev"
description:
name: hive_generator
sha256: "65998cc4d2cd9680a3d9709d893d2f6bb15e6c1f92626c3f1fa650b4b3281521"
sha256: "06cb8f58ace74de61f63500564931f9505368f45f98958bd7a6c35ba24159db4"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "2.0.1"
hive_test:
dependency: "direct dev"
description:
@ -1010,10 +1010,10 @@ packages:
dependency: "direct main"
description:
name: lottie
sha256: "0793a5866062e5cc8a8b24892fa94c3095953ea914a7fdf790f550dd7537fe60"
sha256: b8bdd54b488c54068c57d41ae85d02808da09e2bee8b8dd1f59f441e7efa60cd
url: "https://pub.dev"
source: hosted
version: "2.5.0"
version: "2.6.0"
matcher:
dependency: transitive
description:
@ -1130,10 +1130,10 @@ packages:
dependency: "direct main"
description:
name: package_info_plus
sha256: ceb027f6bc6a60674a233b4a90a7658af1aebdea833da0b5b53c1e9821a78c7b
sha256: "6ff267fcd9d48cb61c8df74a82680e8b82e940231bb5f68356672fde0397334a"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.1.0"
package_info_plus_platform_interface:
dependency: transitive
description:
@ -1218,10 +1218,10 @@ packages:
dependency: transitive
description:
name: permission_handler_android
sha256: "6901d50f4d4b9a27e1749dbd4adbf06aa00d90a21a2db563405d5ce27ee120ac"
sha256: f23cfe9af0d49c6b9fd8a8b09f7b3301ca7e346204939b5afef4404d36d2608f
url: "https://pub.dev"
source: hosted
version: "11.0.0"
version: "11.0.1"
permission_handler_apple:
dependency: transitive
description:
@ -1274,10 +1274,10 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
url: "https://pub.dev"
source: hosted
version: "2.1.5"
version: "2.1.6"
pointycastle:
dependency: "direct main"
description:
@ -1402,18 +1402,18 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8
sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11"
url: "https://pub.dev"
source: hosted
version: "7.0.2"
version: "7.1.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981"
sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
version: "3.3.0"
shelf:
dependency: transitive
description:
@ -1656,8 +1656,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "8a26a160bdc4dcac2ba5a0350a151a345d1dead9"
resolved-ref: "8a26a160bdc4dcac2ba5a0350a151a345d1dead9"
ref: "7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf"
resolved-ref: "7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf"
url: "https://github.com/cypherstack/tor.git"
source: git
version: "0.0.1"
@ -1697,66 +1697,66 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
url: "https://pub.dev"
source: hosted
version: "6.1.12"
version: "6.1.14"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330
url: "https://pub.dev"
source: hosted
version: "6.0.37"
version: "6.1.0"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "6.1.5"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.0.7"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.5"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2
url: "https://pub.dev"
source: hosted
version: "2.0.18"
version: "2.0.19"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069"
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "3.0.8"
uuid:
dependency: "direct main"
description:
@ -1898,10 +1898,10 @@ packages:
dependency: transitive
description:
name: webkit_inspection_protocol
sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d"
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.2.1"
websocket_universal:
dependency: "direct main"
description:
@ -1914,10 +1914,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067
url: "https://pub.dev"
source: hosted
version: "5.0.5"
version: "5.0.8"
win32_registry:
dependency: transitive
description:

View file

@ -60,7 +60,7 @@ dependencies:
tor_ffi_plugin:
git:
url: https://github.com/cypherstack/tor.git
ref: 8a26a160bdc4dcac2ba5a0350a151a345d1dead9
ref: 7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf
# Utility plugins
http: ^0.13.0
@ -373,6 +373,9 @@ flutter:
# buy
- assets/svg/buy/
# gif
- assets/gif/
# lottie animations
# basic
- assets/lottie/test2.json

View file

@ -1,5 +1,11 @@
#!/bin/bash
set -e
# libepiccash requires old rust
source ../rust_version.sh
set_rust_to_1680
mkdir build
. ./config.sh
./install_ndk.sh
@ -7,7 +13,10 @@ mkdir build
(cd ../../crypto_plugins/flutter_liblelantus/scripts/android && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libepiccash/scripts/android && ./install_ndk.sh && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/android/ && ./build_all.sh ) &
(cd ../../crypto_plugins/tor/scripts/android && ./install_ndk.sh && ./build_all.sh ) &
wait
echo "Done building"
# set rust (back) to a more recent stable release to allow stack wallet to build tor
set_rust_to_1720

View file

@ -1,8 +1,25 @@
#!/bin/bash
set -e
# libepiccash requires old rust
source ../rust_version.sh
set_rust_to_1680
# ensure ios rust triples are there
rustup target add aarch64-apple-ios
rustup target add x86_64-apple-ios
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh ) &
wait
echo "Done building"
echo "Done building"
# set rust (back) to a more recent stable release to allow stack wallet to build tor
set_rust_to_1720
# ensure ios rust triples are there
rustup target add aarch64-apple-ios
rustup target add x86_64-apple-ios

View file

@ -1,5 +1,11 @@
#!/bin/bash
set -e
# libepiccash requires old rust
source ../rust_version.sh
set_rust_to_1680
# for arm
# flutter-elinux clean
# flutter-elinux pub get
@ -9,7 +15,10 @@ mkdir -p build
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_monero_all.sh && ./build_sharedfile.sh ) &
(cd ../../crypto_plugins/tor/scripts/linux && ./build_all.sh ) &
wait
echo "Done building"
# set rust (back) to a more recent stable release to allow stack wallet to build tor
set_rust_to_1720

View file

@ -1,8 +1,17 @@
#!/bin/bash
set -e
# libepiccash requires old rust
source ../rust_version.sh
set_rust_to_1680
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh ) &
wait
echo "Done building"
echo "Done building"
# set rust (back) to a more recent stable release to allow stack wallet to build tor
set_rust_to_1720

19
scripts/rust_version.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
set_rust_to_1680() {
if rustup toolchain list | grep -q "1.68.0"; then
rustup default 1.68.0
else
echo "Rust version 1.68.0 is not installed. Please install it using 'rustup install 1.68.0'." >&2
exit 1
fi
}
set_rust_to_1720() {
if rustup toolchain list | grep -q "1.72.0"; then
rustup default 1.72.0
else
echo "Rust version 1.72.0 is not installed. Please install it using 'rustup install 1.72.0'." >&2
exit 1
fi
}

View file

@ -1,9 +1,18 @@
#!/bin/bash
set -e
# libepiccash requires old rust
source ../rust_version.sh
set_rust_to_1680
mkdir -p build
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) &
# (cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) &
wait
echo "Done building"
# set rust (back) to a more recent stable release to allow stack wallet to build tor
set_rust_to_1720

View file

@ -20,6 +20,13 @@ add_executable(${BINARY_NAME} WIN32
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add preprocessor definitions for the build version.
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
# Disable Windows macros that collide with C++ standard library functions.
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")

View file

@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
// Version
//
#ifdef FLUTTER_BUILD_NUMBER
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else
#define VERSION_AS_NUMBER 1,0,0
#define VERSION_AS_NUMBER 1,0,0,0
#endif
#ifdef FLUTTER_BUILD_NAME
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
#if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING FLUTTER_VERSION
#else
#define VERSION_AS_STRING "1.0.0"
#endif