From 6c3f15ca84a854b8da209f8fd88236882cb7754c Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 25 Jun 2024 14:34:09 -0500 Subject: [PATCH 01/10] add build_app.sh docs --- docs/building.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/building.md b/docs/building.md index 79e1bfb64..3d35acea2 100644 --- a/docs/building.md +++ b/docs/building.md @@ -116,6 +116,22 @@ cd .. or manually by creating the files referenced in that script with the specified content. ### Build plugins +#### Build script: `build_app.sh` +The `build_app.sh` script is use to build applications Stack Wallet. View the script's help message with `./build_app.sh -h` for more information on its usage. + +Options: + + - `a <app>`: Specify the application ID (required). Valid options are `stack_wallet` or `stack_duo`. + - `b <build_number>`: Specify the build number in 123 (required). + - `p <platform>`: Specify the platform to build for (required). Valid options are `android`, `ios`, `macos`, `linux`, or `windows`. + - `v <version>`: Specify the version of the application in 1.2.3 format (required). + - `i`: Optional flag to skip building crypto plugins. Useful for updating `pubspec.yaml` and white-labelling different apps with the same plugins. + +For example, +``` +./build_app.sh -a stack_wallet -p linux -v 2.1.0 -b 210 +``` + #### Building plugins for Android > Warning: This will take a long time, please be patient ``` From 0ce0a389508f52058d1b5a277d2eae854d66f229 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sun, 30 Jun 2024 23:03:50 -0500 Subject: [PATCH 02/10] add autoPin pref --- lib/utilities/prefs.dart | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart index abd236416..535f1310e 100644 --- a/lib/utilities/prefs.dart +++ b/lib/utilities/prefs.dart @@ -11,18 +11,19 @@ import 'dart:async'; import 'package:flutter/cupertino.dart'; +import 'package:uuid/uuid.dart'; + +import '../app_config.dart'; import '../db/hive/db.dart'; import '../services/event_bus/events/global/tor_status_changed_event.dart'; import '../services/event_bus/global_event_bus.dart'; -import '../app_config.dart'; +import '../wallets/crypto_currency/crypto_currency.dart'; +import '../wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart'; import 'amount/amount_unit.dart'; import 'constants.dart'; import 'enums/backup_frequency_type.dart'; import 'enums/languages_enum.dart'; import 'enums/sync_type_enum.dart'; -import '../wallets/crypto_currency/crypto_currency.dart'; -import '../wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart'; -import 'package:uuid/uuid.dart'; class Prefs extends ChangeNotifier { Prefs._(); @@ -1103,4 +1104,30 @@ class Prefs extends ChangeNotifier { return actualMap; } + + // Automatic PIN entry. + + bool _autoPin = false; + + bool get autoPin => _autoPin; + + set autoPin(bool autoPin) { + if (_autoPin != autoPin) { + DB.instance.put<dynamic>( + boxName: DB.boxNamePrefs, + key: "autoPin", + value: autoPin, + ); + _autoPin = autoPin; + notifyListeners(); + } + } + + Future<bool> _getAutoPin() async { + return await DB.instance.get<dynamic>( + boxName: DB.boxNamePrefs, + key: "autoPin", + ) as bool? ?? + false; + } } From 8e8b57d8e8e33474ad622f479fa870114983b921 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 1 Jul 2024 10:15:17 -0500 Subject: [PATCH 03/10] enter pin automatically if autopin pref is set --- lib/pages/pinpad_views/lock_screen_view.dart | 18 +++++++++++++++++- .../change_pin_view/change_pin_view.dart | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart index afb7c7a1d..ed20c12b7 100644 --- a/lib/pages/pinpad_views/lock_screen_view.dart +++ b/lib/pages/pinpad_views/lock_screen_view.dart @@ -188,12 +188,14 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> { _timeout = Duration.zero; _checkUseBiometrics(); + _pinTextController.addListener(_onPinChanged); super.initState(); } @override dispose() { // _shakeController.dispose(); + _pinTextController.removeListener(_onPinChanged); super.dispose(); } @@ -208,13 +210,27 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> { ); } - final _pinTextController = TextEditingController(); final FocusNode _pinFocusNode = FocusNode(); late SecureStorageInterface _secureStore; late Biometrics biometrics; int pinCount = 1; + final _pinTextController = TextEditingController(); + + void _onPinChanged() async { + String enteredPin = _pinTextController.text; + final storedPin = await _secureStore.read(key: 'stack_pin'); + final autoPin = ref.read(prefsChangeNotifierProvider).autoPin; + + if (autoPin && enteredPin == storedPin) { + await Future<void>.delayed( + const Duration(milliseconds: 200), + ); + unawaited(_onUnlock()); + } + } + Widget get _body => Background( child: SafeArea( child: Scaffold( diff --git a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart index 57fa710ad..bc1eb6fae 100644 --- a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart +++ b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart @@ -61,9 +61,12 @@ class _ChangePinViewState extends ConsumerState<ChangePinView> { int pinCount = 1; + final TextEditingController _pinTextController = TextEditingController(); + @override void initState() { _secureStore = ref.read(secureStoreProvider); + _pinTextController.addListener(_onPinChanged); super.initState(); } @@ -74,9 +77,23 @@ class _ChangePinViewState extends ConsumerState<ChangePinView> { _pinPutController2.dispose(); _pinPutFocusNode1.dispose(); _pinPutFocusNode2.dispose(); + _pinTextController.removeListener(_onPinChanged); super.dispose(); } + void _onPinChanged() async { + String enteredPin = _pinTextController.text; + final storedPin = await _secureStore.read(key: 'stack_pin'); + final autoPin = ref.read(prefsChangeNotifierProvider).autoPin; + + if (autoPin && enteredPin == storedPin) { + await _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.linear, + ); + } + } + @override Widget build(BuildContext context) { return Background( From 603824a21c2ea0722dd619c0c7b0a8f1f8324395 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 1 Jul 2024 10:19:42 -0500 Subject: [PATCH 04/10] add autopin pref to security settings --- .../security_views/security_view.dart | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/security_views/security_view.dart b/lib/pages/settings_views/global_settings_view/security_views/security_view.dart index ff35130fe..e80374320 100644 --- a/lib/pages/settings_views/global_settings_view/security_views/security_view.dart +++ b/lib/pages/settings_views/global_settings_view/security_views/security_view.dart @@ -10,8 +10,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../../../pinpad_views/lock_screen_view.dart'; -import 'change_pin_view/change_pin_view.dart'; + import '../../../../providers/global/prefs_provider.dart'; import '../../../../route_generator.dart'; import '../../../../themes/stack_colors.dart'; @@ -21,6 +20,8 @@ import '../../../../widgets/background.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../widgets/custom_buttons/draggable_switch_button.dart'; import '../../../../widgets/rounded_white_container.dart'; +import '../../../pinpad_views/lock_screen_view.dart'; +import 'change_pin_view/change_pin_view.dart'; class SecurityView extends StatelessWidget { const SecurityView({ @@ -203,6 +204,54 @@ class SecurityView extends StatelessWidget { }, ), ), + // The "autoPin" preference (whether to automatically accept a correct PIN). + const SizedBox( + height: 8, + ), + RoundedWhiteContainer( + child: Consumer( + builder: (_, ref, __) { + return RawMaterialButton( + // splashColor: Theme.of(context).extension<StackColors>()!.highlight, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: null, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Auto-accept correct PIN", + style: STextStyles.titleBold12(context), + textAlign: TextAlign.left, + ), + SizedBox( + height: 20, + width: 40, + child: DraggableSwitchButton( + isOn: ref.watch( + prefsChangeNotifierProvider + .select((value) => value.autoPin), + ), + onValueChanged: (newValue) { + ref + .read(prefsChangeNotifierProvider) + .autoPin = newValue; + }, + ), + ), + ], + ), + ), + ); + }, + ), + ), ], ), ), From f836136ef0c52354152f297121e4db1324edfc78 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 1 Jul 2024 10:23:33 -0500 Subject: [PATCH 05/10] only auto-enter pins of length 4 or more --- lib/pages/pinpad_views/lock_screen_view.dart | 2 +- .../security_views/change_pin_view/change_pin_view.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart index ed20c12b7..a2b61c404 100644 --- a/lib/pages/pinpad_views/lock_screen_view.dart +++ b/lib/pages/pinpad_views/lock_screen_view.dart @@ -223,7 +223,7 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> { final storedPin = await _secureStore.read(key: 'stack_pin'); final autoPin = ref.read(prefsChangeNotifierProvider).autoPin; - if (autoPin && enteredPin == storedPin) { + if (enteredPin.length >= 4 && autoPin && enteredPin == storedPin) { await Future<void>.delayed( const Duration(milliseconds: 200), ); diff --git a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart index bc1eb6fae..4c4bfa66c 100644 --- a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart +++ b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart @@ -86,7 +86,7 @@ class _ChangePinViewState extends ConsumerState<ChangePinView> { final storedPin = await _secureStore.read(key: 'stack_pin'); final autoPin = ref.read(prefsChangeNotifierProvider).autoPin; - if (autoPin && enteredPin == storedPin) { + if (enteredPin.length >= 4 && autoPin && enteredPin == storedPin) { await _pageController.nextPage( duration: const Duration(milliseconds: 300), curve: Curves.linear, From a64cf911079cdd5a2e4463f2dba4f2e5c0e0a0f7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 27 Jun 2024 17:23:31 -0500 Subject: [PATCH 06/10] add copy to clipboard button to order details view https://github.com/cypherstack/stack_wallet/issues/340 Closes #340 --- lib/pages/buy_view/buy_order_details.dart | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/pages/buy_view/buy_order_details.dart b/lib/pages/buy_view/buy_order_details.dart index 4144a85ab..7021309a2 100644 --- a/lib/pages/buy_view/buy_order_details.dart +++ b/lib/pages/buy_view/buy_order_details.dart @@ -8,11 +8,15 @@ * */ +import 'dart:async'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import '../../models/buy/response_objects/order.dart'; +import '../../notifications/show_flush_bar.dart'; import '../../themes/stack_colors.dart'; import '../../themes/theme_providers.dart'; import '../../utilities/assets.dart'; @@ -44,6 +48,16 @@ class _BuyOrderDetailsViewState extends ConsumerState<BuyOrderDetailsView> { @override Widget build(BuildContext context) { + final orderDetails = ''' +Purchase ID: ${widget.order.paymentId} +User ID: ${widget.order.userId} +Quote ID: ${widget.order.quote.id} +Quoted cost: ${widget.order.quote.youPayFiatPrice.toStringAsFixed(2)} ${widget.order.quote.fiat.ticker.toUpperCase()} +Quoted amount: ${widget.order.quote.youReceiveCryptoAmount} ${widget.order.quote.crypto.ticker.toUpperCase()} +Receiving ${widget.order.quote.crypto.ticker.toUpperCase()} address: ${widget.order.quote.receivingAddress} +Provider: Simplex +'''; + return ConditionalParent( condition: !isDesktop, builder: (child) { @@ -272,6 +286,43 @@ class _BuyOrderDetailsViewState extends ConsumerState<BuyOrderDetailsView> { ), ], ), + const SizedBox(height: 8), + TextButton( + onPressed: () async { + await Clipboard.setData(ClipboardData(text: orderDetails)); + if (context.mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + } + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.svg.copy, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + const SizedBox( + width: 10, + ), + Text( + "Copy to clipboard", + style: STextStyles.desktopButtonSecondaryEnabled( + context, + ), + ), + ], + ), + ), const Spacer(), PrimaryButton( label: "Dismiss", From 17fbf7f9ab5a583b4d8d03a6f9a09b9fa316615d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 21 Oct 2023 19:35:15 -0500 Subject: [PATCH 07/10] reconfigure logic for rescan for other wallets to remove upper limit now we will continue beyond maxNumberOfIndexesToCheck if there's activity beyond that point. we just keep scanning up until the unused activity gap --- lib/wallets/crypto_currency/coins/bitcoincash.dart | 2 -- lib/wallets/crypto_currency/coins/ecash.dart | 2 -- .../crypto_currency/intermediate/bip39_hd_currency.dart | 2 +- .../wallet_mixin_interfaces/electrumx_interface.dart | 8 ++------ 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/wallets/crypto_currency/coins/bitcoincash.dart b/lib/wallets/crypto_currency/coins/bitcoincash.dart index 5950fc913..9d9a291a8 100644 --- a/lib/wallets/crypto_currency/coins/bitcoincash.dart +++ b/lib/wallets/crypto_currency/coins/bitcoincash.dart @@ -55,8 +55,6 @@ class Bitcoincash extends Bip39HDCurrency with ElectrumXCurrencyInterface { @override int get maxUnusedAddressGap => 50; - @override - int get maxNumberOfIndexesToCheck => 10000000; @override // change this to change the number of confirms a tx needs in order to show as confirmed diff --git a/lib/wallets/crypto_currency/coins/ecash.dart b/lib/wallets/crypto_currency/coins/ecash.dart index 102f509c8..ad1ec4f6c 100644 --- a/lib/wallets/crypto_currency/coins/ecash.dart +++ b/lib/wallets/crypto_currency/coins/ecash.dart @@ -50,8 +50,6 @@ class Ecash extends Bip39HDCurrency with ElectrumXCurrencyInterface { @override int get maxUnusedAddressGap => 50; - @override - int get maxNumberOfIndexesToCheck => 10000000; @override // change this to change the number of confirms a tx needs in order to show as confirmed diff --git a/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart b/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart index bbe5bd2ab..bb97b6754 100644 --- a/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart +++ b/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart @@ -1,6 +1,7 @@ import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib; import 'package:crypto/crypto.dart'; import 'package:flutter/foundation.dart'; + import '../../../models/isar/models/blockchain_data/address.dart'; import '../../../utilities/amount/amount.dart'; import '../../../utilities/enums/derive_path_type_enum.dart'; @@ -16,7 +17,6 @@ abstract class Bip39HDCurrency extends Bip39Currency { List<DerivePathType> get supportedDerivationPathTypes; int get maxUnusedAddressGap => 50; - int get maxNumberOfIndexesToCheck => 10000; String constructDerivePath({ required DerivePathType derivePathType, diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart index c7b8aa259..035ae649f 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart @@ -937,8 +937,7 @@ mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface> int highestIndexWithHistory = 0; for (int index = 0; - index < cryptoCurrency.maxNumberOfIndexesToCheck && - gapCounter < cryptoCurrency.maxUnusedAddressGap; + gapCounter < cryptoCurrency.maxUnusedAddressGap; index += txCountBatchSize) { Logging.instance.log( "index: $index, \t GapCounter $chain ${type.name}: $gapCounter", @@ -1017,10 +1016,7 @@ mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface> final List<Address> addressArray = []; int gapCounter = 0; int index = 0; - for (; - index < cryptoCurrency.maxNumberOfIndexesToCheck && - gapCounter < cryptoCurrency.maxUnusedAddressGap; - index++) { + for (; gapCounter < cryptoCurrency.maxUnusedAddressGap; index++) { Logging.instance.log( "index: $index, \t GapCounter chain=$chain ${type.name}: $gapCounter", level: LogLevel.Info, From f33b6b4416119447f27ff81f857bed0955625467 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 28 Jun 2024 16:05:20 -0600 Subject: [PATCH 08/10] sol tweaks and fixes(?) --- lib/utilities/test_node_connection.dart | 24 +++++---- lib/wallets/wallet/impl/solana_wallet.dart | 61 +++++++++++++++++----- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/lib/utilities/test_node_connection.dart b/lib/utilities/test_node_connection.dart index 5578d5fd0..2160671db 100644 --- a/lib/utilities/test_node_connection.dart +++ b/lib/utilities/test_node_connection.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:solana/solana.dart'; import '../networking/http.dart'; import '../pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; @@ -15,6 +14,7 @@ import '../wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/interfaces/electrumx_currency_interface.dart'; import '../wallets/crypto_currency/intermediate/cryptonote_currency.dart'; import '../wallets/crypto_currency/intermediate/nano_currency.dart'; +import '../wallets/wallet/impl/solana_wallet.dart'; import 'connection_check/electrum_connection_check.dart'; import 'logger.dart'; import 'test_epic_box_connection.dart'; @@ -210,14 +210,20 @@ Future<bool> testNodeConnection({ case Solana(): try { - RpcClient rpcClient; - if (formData.host!.startsWith("http") || - formData.host!.startsWith("https")) { - rpcClient = RpcClient("${formData.host}:${formData.port}"); - } else { - rpcClient = RpcClient("http://${formData.host}:${formData.port}"); - } - await rpcClient.getEpochInfo().then((value) => testPassed = true); + final rpcClient = SolanaWallet.createRpcClient( + formData.host!, + formData.port!, + formData.useSSL ?? false, + ref.read(prefsChangeNotifierProvider), + ref.read(pTorService), + ); + + final health = await rpcClient.getHealth(); + Logging.instance.log( + "Solana testNodeConnection \"health=$health\"", + level: LogLevel.Info, + ); + return true; } catch (_) { testPassed = false; } diff --git a/lib/wallets/wallet/impl/solana_wallet.dart b/lib/wallets/wallet/impl/solana_wallet.dart index 50ff0b31a..5cbfda157 100644 --- a/lib/wallets/wallet/impl/solana_wallet.dart +++ b/lib/wallets/wallet/impl/solana_wallet.dart @@ -18,6 +18,7 @@ import '../../../services/node_service.dart'; import '../../../services/tor_service.dart'; import '../../../utilities/amount/amount.dart'; import '../../../utilities/logger.dart'; +import '../../../utilities/prefs.dart'; import '../../crypto_currency/crypto_currency.dart'; import '../../models/tx_data.dart'; import '../intermediate/bip39_wallet.dart'; @@ -245,14 +246,15 @@ class SolanaWallet extends Bip39Wallet<Solana> { } @override - Future<bool> pingCheck() { + Future<bool> pingCheck() async { + String? health; try { _checkClient(); - _rpcClient?.getHealth(); - return Future.value(true); + health = await _rpcClient?.getHealth(); + return health != null; } catch (e, s) { Logging.instance.log( - "$runtimeType Solana pingCheck failed: $e\n$s", + "$runtimeType Solana pingCheck failed \"health=$health\": $e\n$s", level: LogLevel.Error, ); return Future.value(false); @@ -453,32 +455,67 @@ class SolanaWallet extends Bip39Wallet<Solana> { } @override - Future<bool> updateUTXOs() { + Future<bool> updateUTXOs() async { // No UTXOs in Solana - return Future.value(false); + return false; } /// Make sure the Solana RpcClient uses Tor if it's enabled. /// - void _checkClient() async { + void _checkClient() { + final node = getCurrentNode(); + _rpcClient = createRpcClient( + node.host, + node.port, + node.useSSL, + prefs, + TorService.sharedInstance, + ); + } + + // static helper function for building a sol rpc client + static RpcClient createRpcClient( + final String host, + final int port, + final bool useSSL, + final Prefs prefs, + final TorService torService, + ) { HttpClient? httpClient; if (prefs.useTor) { // Make proxied HttpClient. - final ({InternetAddress host, int port}) proxyInfo = - TorService.sharedInstance.getProxyInfo(); + final proxyInfo = torService.getProxyInfo(); final proxySettings = ProxySettings(proxyInfo.host, proxyInfo.port); httpClient = HttpClient(); SocksTCPClient.assignToHttpClient(httpClient, [proxySettings]); } - _rpcClient = RpcClient( - "${getCurrentNode().host}:${getCurrentNode().port}", + final regex = RegExp("^(http|https)://"); + + String editedHost; + if (host.startsWith(regex)) { + editedHost = host.replaceFirst(regex, ""); + } else { + editedHost = host; + } + + while (editedHost.endsWith("/")) { + editedHost = editedHost.substring(0, editedHost.length - 1); + } + + final uri = Uri( + scheme: useSSL ? "https" : "http", + host: editedHost, + port: port, + ); + + return RpcClient( + uri.toString(), timeout: const Duration(seconds: 30), customHeaders: {}, httpClient: httpClient, ); - return; } } From 803ca443626aa96ee51eaf89d50cec62b845fe28 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 28 Jun 2024 16:18:12 -0600 Subject: [PATCH 09/10] default sol node update --- lib/wallets/crypto_currency/coins/solana.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/wallets/crypto_currency/coins/solana.dart b/lib/wallets/crypto_currency/coins/solana.dart index 1505abead..63b6cc394 100644 --- a/lib/wallets/crypto_currency/coins/solana.dart +++ b/lib/wallets/crypto_currency/coins/solana.dart @@ -46,8 +46,7 @@ class Solana extends Bip39Currency { switch (network) { case CryptoCurrencyNetwork.main: return NodeModel( - host: - "https://api.mainnet-beta.solana.com/", // TODO: Change this to stack wallet one + host: "https://solana.stackwallet.com", port: 443, name: DefaultNodes.defaultName, id: DefaultNodes.buildId(this), From 5b27597481af55cf49128f9e341512b7b1ecdb49 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 1 Jul 2024 10:26:02 -0600 Subject: [PATCH 10/10] sol address validation fix --- lib/wallets/crypto_currency/coins/solana.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/wallets/crypto_currency/coins/solana.dart b/lib/wallets/crypto_currency/coins/solana.dart index 63b6cc394..6cfc185e1 100644 --- a/lib/wallets/crypto_currency/coins/solana.dart +++ b/lib/wallets/crypto_currency/coins/solana.dart @@ -69,9 +69,13 @@ class Solana extends Bip39Currency { @override bool validateAddress(String address) { - return isPointOnEd25519Curve( - Ed25519HDPublicKey.fromBase58(address).toByteArray(), - ); + try { + return isPointOnEd25519Curve( + Ed25519HDPublicKey.fromBase58(address).toByteArray(), + ); + } catch (_) { + return false; + } } @override