implement xmr/wow ffi package optional import
What changed, and why it matters
This commit refactors how Stack Wallet imports the Monero/Wownero foreign-function-interface (FFI) package. Instead of directly importing the cs_monero library everywhere, the app now routes those calls through a generated interface file. The change is mostly an architectural cleanup to make the FFI package optional/importable on demand. There is no obvious security bug in the diff, but because the patch is large and partially reformats code, it is hard to fully verify that no sensitive behavior changed.
Treat as a normal code-review item. Verify that the generated `cs_monero_interface` faithfully proxies all security-critical calls (seed validation, transaction creation, fee estimation, refresh height, churning) to the underlying cs_monero library without altering semantics. Confirm that making the FFI package optional does not accidentally stub out or weaken any cryptographic checks on certain build targets. No immediate incident response is indicated.
Security signals we found
Large refactor of Monero/Wownero FFI bindings
Introduction of generated interface layer between app and cs_monero native library
Direct native library logging configuration moved behind interface (`setUseCsMoneroLoggerInternal`)
No explicit security claim or CVE in commit message or diff
Evidence from the diff
The commit replaces direct import 'package:cs_monero/cs_monero.dart' as lib_monero with import '../../../wl_gen/interfaces/cs_monero_interface.dart' (or similar relative paths) across main.dart, restore, send, fee, settings, churning, wallet model, and Monero/Wownero wallet implementations. It also swaps some direct enum/API usages (e.g., lib_monero.TransactionPriority.high) for helper methods on a csMonero interface object (e.g., csMonero.getTxPriorityHigh()). A new template file tool/wl_templates/XMR_cs_monero_interface_impl.template.dart suggests code generation for the interface. The bulk of the diff is formatting/line-wrapping noise, making functional changes harder to isolate.
Changed components
lib/main.dartlib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dartlib/pages/send_view/send_view.dartlib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dartlib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/edit_refresh_height_view.dartlib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send_fee_form.dartlib/services/churning_service.dartlib/wallets/models/tx_data.dartlib/wallets/wallet/impl/monero_wallet.dartlib/wallets/wallet/impl/wownero_wallet.dartlib/wallets/wallet/intermediate/lib_monero_wallet.dartlib/widgets/desktop/desktop_fee_dialog.dartlib/wl_gen/interfaces/cs_monero_interface.darttool/wl_templates/XMR_cs_monero_interface_impl.template.dartInspect captured patch +2538 / −1748
diff --git a/lib/main.dart b/lib/main.dart
index c750009..c75941e 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -15,7 +15,6 @@ import 'dart:ui';
import 'package:coinlib_flutter/coinlib_flutter.dart';
import 'package:compat/compat.dart' as lib_monero_compat;
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -79,6 +78,7 @@ import 'wallets/crypto_currency/crypto_currency.dart';
import 'wallets/isar/providers/all_wallets_info_provider.dart';
import 'wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
import 'widgets/crypto_notifications.dart';
+import 'wl_gen/interfaces/cs_monero_interface.dart';
final openedFromSWBFileStringStateProvider = StateProvider<String?>(
(ref) => null,
@@ -189,7 +189,7 @@ void main(List<String> args) async {
DB.instance.hive.registerAdapter(lib_monero_compat.WalletTypeAdapter());
- lib_monero.Logging.useLogger = kDebugMode;
+ csMonero.setUseCsMoneroLoggerInternal(kDebugMode);
DB.instance.hive.init(
(await StackFileSystem.applicationHiveDirectory()).path,
@@ -372,8 +372,9 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
Constants.exchangeForExperiencedUsers(familiarity);
if (Util.isDesktop) {
- _desktopHasPassword =
- await ref.read(storageCryptoHandlerProvider).hasPassword();
+ _desktopHasPassword = await ref
+ .read(storageCryptoHandlerProvider)
+ .hasPassword();
}
}
@@ -480,14 +481,14 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
final brightness = WidgetsBinding.instance.window.platformBrightness;
switch (brightness) {
case Brightness.dark:
- themeId =
- ref.read(prefsChangeNotifierProvider).systemBrightnessDarkThemeId;
+ themeId = ref
+ .read(prefsChangeNotifierProvider)
+ .systemBrightnessDarkThemeId;
break;
case Brightness.light:
- themeId =
- ref
- .read(prefsChangeNotifierProvider)
- .systemBrightnessLightThemeId;
+ themeId = ref
+ .read(prefsChangeNotifierProvider)
+ .systemBrightnessLightThemeId;
break;
}
} else {
@@ -506,8 +507,9 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
ref.read(applicationThemesDirectoryPathProvider.notifier).state =
StackFileSystem.themesDir!.path;
- ref.read(themeProvider.state).state =
- ref.read(pThemeService).getTheme(themeId: themeId)!;
+ ref.read(themeProvider.state).state = ref
+ .read(pThemeService)
+ .getTheme(themeId: themeId)!;
if (Platform.isAndroid) {
// fetch open file if it exists
@@ -531,21 +533,22 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
String themeId;
switch (WidgetsBinding.instance.window.platformBrightness) {
case Brightness.dark:
- themeId =
- ref.read(prefsChangeNotifierProvider).systemBrightnessDarkThemeId;
+ themeId = ref
+ .read(prefsChangeNotifierProvider)
+ .systemBrightnessDarkThemeId;
break;
case Brightness.light:
- themeId =
- ref
- .read(prefsChangeNotifierProvider)
- .systemBrightnessLightThemeId;
+ themeId = ref
+ .read(prefsChangeNotifierProvider)
+ .systemBrightnessLightThemeId;
break;
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (ref.read(prefsChangeNotifierProvider).enableSystemBrightness) {
- ref.read(themeProvider.state).state =
- ref.read(pThemeService).getTheme(themeId: themeId)!;
+ ref.read(themeProvider.state).state = ref
+ .read(pThemeService)
+ .getTheme(themeId: themeId)!;
}
});
};
@@ -673,17 +676,16 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
ref.read(pNavKey).currentContext!,
RouteGenerator.getRoute(
shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
- builder:
- (_) => LockscreenView(
- showBackButton: true,
- routeOnSuccess: RestoreFromEncryptedStringView.routeName,
- routeOnSuccessArguments: encrypted,
- biometricsCancelButtonString: "CANCEL",
- biometricsLocalizedReason:
- "Authenticate to restore ${AppConfig.appName} backup",
- biometricsAuthenticationTitle:
- "Restore ${AppConfig.prefix} backup",
- ),
+ builder: (_) => LockscreenView(
+ showBackButton: true,
+ routeOnSuccess: RestoreFromEncryptedStringView.routeName,
+ routeOnSuccessArguments: encrypted,
+ biometricsCancelButtonString: "CANCEL",
+ biometricsLocalizedReason:
+ "Authenticate to restore ${AppConfig.appName} backup",
+ biometricsAuthenticationTitle:
+ "Restore ${AppConfig.prefix} backup",
+ ),
settings: const RouteSettings(name: "/swbrestorelockscreen"),
),
),
@@ -807,85 +809,79 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
),
),
home: CryptoNotifications(
- child:
- Util.isDesktop
- ? FutureBuilder(
- future: loadShared(),
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.done) {
- if (_desktopHasPassword) {
- String? startupWalletId;
- if (ref
+ child: Util.isDesktop
+ ? FutureBuilder(
+ future: loadShared(),
+ builder: (context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.done) {
+ if (_desktopHasPassword) {
+ String? startupWalletId;
+ if (ref
+ .read(prefsChangeNotifierProvider)
+ .gotoWalletOnStartup) {
+ startupWalletId = ref
.read(prefsChangeNotifierProvider)
- .gotoWalletOnStartup) {
- startupWalletId =
- ref
- .read(prefsChangeNotifierProvider)
- .startupWalletId;
- }
-
- return DesktopLoginView(
- startupWalletId: startupWalletId,
- load: () => load(true),
- );
- } else {
- return const IntroView();
+ .startupWalletId;
}
+
+ return DesktopLoginView(
+ startupWalletId: startupWalletId,
+ load: () => load(true),
+ );
} else {
- return const LoadingView();
+ return const IntroView();
}
- },
- )
- : FutureBuilder(
- future: load(false),
- builder: (
- BuildContext context,
- AsyncSnapshot<void> snapshot,
- ) {
- if (snapshot.connectionState == ConnectionState.done) {
- // FlutterNativeSplash.remove();
- if (ref.read(pAllWalletsInfo).isNotEmpty ||
- ref.read(prefsChangeNotifierProvider).hasPin) {
- // return HomeView();
-
- String? startupWalletId;
- if (ref
+ } else {
+ return const LoadingView();
+ }
+ },
+ )
+ : FutureBuilder(
+ future: load(false),
+ builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
+ if (snapshot.connectionState == ConnectionState.done) {
+ // FlutterNativeSplash.remove();
+ if (ref.read(pAllWalletsInfo).isNotEmpty ||
+ ref.read(prefsChangeNotifierProvider).hasPin) {
+ // return HomeView();
+
+ String? startupWalletId;
+ if (ref
+ .read(prefsChangeNotifierProvider)
+ .gotoWalletOnStartup) {
+ startupWalletId = ref
.read(prefsChangeNotifierProvider)
- .gotoWalletOnStartup) {
- startupWalletId =
- ref
- .read(prefsChangeNotifierProvider)
- .startupWalletId;
- }
-
- return LockscreenView(
- isInitialAppLogin: true,
- routeOnSuccess: HomeView.routeName,
- routeOnSuccessArguments: startupWalletId,
- biometricsAuthenticationTitle:
- "Unlock ${AppConfig.prefix}",
- biometricsLocalizedReason:
- "Unlock your ${AppConfig.appName} using biometrics",
- biometricsCancelButtonString: "Cancel",
- );
- } else {
- if (AppConfig.appName == "Campfire" &&
- !CampfireMigration.didRun &&
- CampfireMigration.hasOldWallets) {
- return const CampfireMigrateView();
- } else {
- return const IntroView();
- }
+ .startupWalletId;
}
+
+ return LockscreenView(
+ isInitialAppLogin: true,
+ routeOnSuccess: HomeView.routeName,
+ routeOnSuccessArguments: startupWalletId,
+ biometricsAuthenticationTitle:
+ "Unlock ${AppConfig.prefix}",
+ biometricsLocalizedReason:
+ "Unlock your ${AppConfig.appName} using biometrics",
+ biometricsCancelButtonString: "Cancel",
+ );
} else {
- // CURRENTLY DISABLED as cannot be animated
- // technically not needed as FlutterNativeSplash will overlay
- // anything returned here until the future completes but
- // FutureBuilder requires you to return something
- return const LoadingView();
+ if (AppConfig.appName == "Campfire" &&
+ !CampfireMigration.didRun &&
+ CampfireMigration.hasOldWallets) {
+ return const CampfireMigrateView();
+ } else {
+ return const IntroView();
+ }
}
- },
- ),
+ } else {
+ // CURRENTLY DISABLED as cannot be animated
+ // technically not needed as FlutterNativeSplash will overlay
+ // anything returned here until the future completes but
+ // FutureBuilder requires you to return something
+ return const LoadingView();
+ }
+ },
+ ),
),
);
}
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index dceb76d..f1bf78b 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -16,7 +16,6 @@ import 'dart:math';
import 'package:bip39/bip39.dart' as bip39;
import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -62,6 +61,7 @@ import '../../../widgets/icon_widgets/qrcode_icon.dart';
import '../../../widgets/table_view/table_view.dart';
import '../../../widgets/table_view/table_view_cell.dart';
import '../../../widgets/table_view/table_view_row.dart';
+import '../../../wl_gen/interfaces/cs_monero_interface.dart';
import '../../home_view/home_view.dart';
import '../add_token_view/edit_wallet_tokens_view.dart';
import '../select_wallet_for_token_view.dart';
@@ -153,10 +153,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
_seedWordCount = widget.seedWordsLength;
isDesktop = Util.isDesktop;
- textSelectionControls =
- Platform.isIOS
- ? CustomCupertinoTextSelectionControls(onPaste: onControlsPaste)
- : CustomMaterialTextSelectionControls(onPaste: onControlsPaste);
+ textSelectionControls = Platform.isIOS
+ ? CustomCupertinoTextSelectionControls(onPaste: onControlsPaste)
+ : CustomMaterialTextSelectionControls(onPaste: onControlsPaste);
for (int i = 0; i < _seedWordCount; i++) {
_controllers.add(TextEditingController());
@@ -189,7 +188,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
// Salvium use's Monero's wordlists.
switch (widget.seedWordsLength) {
case 25:
- return lib_monero.getMoneroWordList("English").contains(word);
+ return csMonero.getMoneroWordList("English").contains(word);
case 16:
return Monero.sixteenWordsWordList.contains(word);
default:
@@ -197,9 +196,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
}
}
if (widget.coin is Wownero) {
- final wowneroWordList = lib_monero.getWowneroWordList(
+ final wowneroWordList = csMonero.getWowneroWordList(
"English",
- seedWordsLength: widget.seedWordsLength,
+ widget.seedWordsLength,
);
return wowneroWordList.contains(word);
}
@@ -409,10 +408,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
ref
.read(newEthWalletTriggerTempUntilHiveCompletelyDeleted.state)
.state = !ref
- .read(
- newEthWalletTriggerTempUntilHiveCompletelyDeleted.state,
- )
- .state;
+ .read(newEthWalletTriggerTempUntilHiveCompletelyDeleted.state)
+ .state;
}
if (mounted) {
@@ -511,43 +508,42 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
case FormInputStatus.empty:
color = Theme.of(context).extension<StackColors>()!.textFieldDefaultBG;
prefixColor = Theme.of(context).extension<StackColors>()!.textSubtitle2;
- borderColor =
- Theme.of(context).extension<StackColors>()!.textFieldDefaultBG;
+ borderColor = Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldDefaultBG;
break;
case FormInputStatus.invalid:
color = Theme.of(context).extension<StackColors>()!.textFieldErrorBG;
- prefixColor =
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldErrorSearchIconLeft;
- borderColor =
- Theme.of(context).extension<StackColors>()!.textFieldErrorBorder;
+ prefixColor = Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldErrorSearchIconLeft;
+ borderColor = Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldErrorBorder;
suffixIcon = SvgPicture.asset(
Assets.svg.alertCircle,
width: 16,
height: 16,
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldErrorSearchIconRight,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldErrorSearchIconRight,
);
break;
case FormInputStatus.valid:
color = Theme.of(context).extension<StackColors>()!.textFieldSuccessBG;
- prefixColor =
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldSuccessSearchIconLeft;
- borderColor =
- Theme.of(context).extension<StackColors>()!.textFieldSuccessBorder;
+ prefixColor = Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldSuccessSearchIconLeft;
+ borderColor = Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldSuccessBorder;
suffixIcon = SvgPicture.asset(
Assets.svg.checkCircle,
width: 16,
height: 16,
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldSuccessSearchIconRight,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldSuccessSearchIconRight,
);
break;
}
@@ -706,90 +702,85 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
final isDesktop = Util.isDesktop;
return MasterScaffold(
isDesktop: isDesktop,
- appBar:
- isDesktop
- ? const DesktopAppBar(
- isCompactHeight: false,
- leading: AppBarBackButton(),
- trailing: ExitToMyStackButton(),
- )
- : AppBar(
- leading: AppBarBackButton(
- onPressed: () async {
- if (FocusScope.of(context).hasFocus) {
- FocusScope.of(context).unfocus();
- await Future<void>.delayed(
- const Duration(milliseconds: 50),
- );
- }
- if (context.mounted) {
- Navigator.of(context).pop();
- }
- },
- ),
- actions: [
- Padding(
- padding: const EdgeInsets.only(
- top: 10,
- bottom: 10,
- right: 10,
- ),
- child: AspectRatio(
- aspectRatio: 1,
- child: AppBarIconButton(
- semanticsLabel:
- "View QR Code Button. Opens Camera To Scan QR Code For Restoring Wallet.",
- key: const Key("restoreWalletViewQrCodeButton"),
- size: 36,
- shadows: const [],
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.background,
- icon: QrCodeIcon(
- width: 20,
- height: 20,
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.accentColorDark,
- ),
- onPressed: scanMnemonicQr,
+ appBar: isDesktop
+ ? const DesktopAppBar(
+ isCompactHeight: false,
+ leading: AppBarBackButton(),
+ trailing: ExitToMyStackButton(),
+ )
+ : AppBar(
+ leading: AppBarBackButton(
+ onPressed: () async {
+ if (FocusScope.of(context).hasFocus) {
+ FocusScope.of(context).unfocus();
+ await Future<void>.delayed(
+ const Duration(milliseconds: 50),
+ );
+ }
+ if (context.mounted) {
+ Navigator.of(context).pop();
+ }
+ },
+ ),
+ actions: [
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 10,
+ bottom: 10,
+ right: 10,
+ ),
+ child: AspectRatio(
+ aspectRatio: 1,
+ child: AppBarIconButton(
+ semanticsLabel:
+ "View QR Code Button. Opens Camera To Scan QR Code For Restoring Wallet.",
+ key: const Key("restoreWalletViewQrCodeButton"),
+ size: 36,
+ shadows: const [],
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.background,
+ icon: QrCodeIcon(
+ width: 20,
+ height: 20,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.accentColorDark,
),
+ onPressed: scanMnemonicQr,
),
),
- Padding(
- padding: const EdgeInsets.only(
- top: 10,
- bottom: 10,
- right: 10,
- ),
- child: AspectRatio(
- aspectRatio: 1,
- child: AppBarIconButton(
- semanticsLabel:
- "Paste Button. Pastes From Clipboard For Restoring Wallet.",
- key: const Key("restoreWalletPasteButton"),
- size: 36,
- shadows: const [],
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.background,
- icon: ClipboardIcon(
- width: 20,
- height: 20,
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.accentColorDark,
- ),
- onPressed: pasteMnemonic,
+ ),
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 10,
+ bottom: 10,
+ right: 10,
+ ),
+ child: AspectRatio(
+ aspectRatio: 1,
+ child: AppBarIconButton(
+ semanticsLabel:
+ "Paste Button. Pastes From Clipboard For Restoring Wallet.",
+ key: const Key("restoreWalletPasteButton"),
+ size: 36,
+ shadows: const [],
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.background,
+ icon: ClipboardIcon(
+ width: 20,
+ height: 20,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.accentColorDark,
),
+ onPressed: pasteMnemonic,
),
),
- ],
- ),
+ ),
+ ],
+ ),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
@@ -810,18 +801,16 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
SizedBox(height: isDesktop ? 0 : 4),
Text(
"Recovery phrase",
- style:
- isDesktop
- ? STextStyles.desktopH2(context)
- : STextStyles.pageTitleH1(context),
+ style: isDesktop
+ ? STextStyles.desktopH2(context)
+ : STextStyles.pageTitleH1(context),
),
SizedBox(height: isDesktop ? 16 : 8),
Text(
"Enter your $_seedWordCount-word recovery phrase.",
- style:
- isDesktop
- ? STextStyles.desktopSubtitleH2(context)
- : STextStyles.subtitle(context),
+ style: isDesktop
+ ? STextStyles.desktopSubtitleH2(context)
+ : STextStyles.subtitle(context),
),
SizedBox(height: isDesktop ? 16 : 10),
if (isDesktop)
@@ -841,10 +830,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
Assets.svg.clipboard,
width: 22,
height: 22,
- color:
- Theme.of(context)
- .extension<StackColors>()!
- .buttonTextSecondary,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.buttonTextSecondary,
),
const SizedBox(width: 8),
Text(
@@ -910,8 +898,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
.onUserInteraction,
selectionControls:
i * 4 + j - 1 == 1
- ? textSelectionControls
- : null,
+ ? textSelectionControls
+ : null,
// focusNode:
// _focusNodes[i * 4 + j - 1],
onChanged: (value) {
@@ -957,18 +945,19 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
_controllers[i * 4 +
j -
1],
- style: STextStyles.field(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style:
+ STextStyles.field(
+ context,
+ ).copyWith(
+ color: Theme.of(context)
.extension<
StackColors
>()!
.textRestore,
- fontSize:
- isDesktop ? 16 : 14,
- ),
+ fontSize: isDesktop
+ ? 16
+ : 14,
+ ),
),
if (_inputStatuses[i * 4 +
j -
@@ -987,16 +976,19 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
"Please check spelling",
textAlign:
TextAlign.left,
- style: STextStyles.label(
- context,
- ).copyWith(
- color:
- Theme.of(context)
- .extension<
- StackColors
- >()!
- .textError,
- ),
+ style:
+ STextStyles.label(
+ context,
+ ).copyWith(
+ color:
+ Theme.of(
+ context,
+ )
+ .extension<
+ StackColors
+ >()!
+ .textError,
+ ),
),
),
),
@@ -1048,10 +1040,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
autovalidateMode:
AutovalidateMode
.onUserInteraction,
- selectionControls:
- i == 1
- ? textSelectionControls
- : null,
+ selectionControls: i == 1
+ ? textSelectionControls
+ : null,
onChanged: (value) {
final FormInputStatus
formInputStatus;
@@ -1078,18 +1069,19 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
});
},
controller: _controllers[i],
- style: STextStyles.field(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style:
+ STextStyles.field(
+ context,
+ ).copyWith(
+ color: Theme.of(context)
.extension<
StackColors
>()!
.overlay,
- fontSize:
- isDesktop ? 16 : 14,
- ),
+ fontSize: isDesktop
+ ? 16
+ : 14,
+ ),
),
if (_inputStatuses[i] ==
FormInputStatus.invalid)
@@ -1106,16 +1098,19 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
"Please check spelling",
textAlign:
TextAlign.left,
- style: STextStyles.label(
- context,
- ).copyWith(
- color:
- Theme.of(context)
- .extension<
- StackColors
- >()!
- .textError,
- ),
+ style:
+ STextStyles.label(
+ context,
+ ).copyWith(
+ color:
+ Theme.of(
+ context,
+ )
+ .extension<
+ StackColors
+ >()!
+ .textError,
+ ),
),
),
),
@@ -1181,8 +1176,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
),
autovalidateMode:
AutovalidateMode.onUserInteraction,
- selectionControls:
- i == 1 ? textSelectionControls : null,
+ selectionControls: i == 1
+ ? textSelectionControls
+ : null,
// focusNode: _focusNodes[i - 1],
onChanged: (value) {
final FormInputStatus formInputStatus;
@@ -1212,10 +1208,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
},
controller: _controllers[i - 1],
style: STextStyles.field(context).copyWith(
- color:
- Theme.of(context)
- .extension<StackColors>()!
- .textRestore,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textRestore,
fontSize: isDesktop ? 16 : 14,
),
),
@@ -1232,14 +1227,12 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
child: Text(
"Please check spelling",
textAlign: TextAlign.left,
- style: STextStyles.label(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.label(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.textError,
- ),
+ ),
),
),
),
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index 1577e56..855d1bd 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -11,7 +11,6 @@
import 'dart:async';
import 'dart:io';
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -76,6 +75,7 @@ import '../../widgets/rounded_white_container.dart';
import '../../widgets/stack_dialog.dart';
import '../../widgets/stack_text_field.dart';
import '../../widgets/textfield_icon_button.dart';
+import '../../wl_gen/interfaces/cs_monero_interface.dart';
import '../address_book_views/address_book_view.dart';
import '../coin_control/coin_control_view.dart';
import 'confirm_transaction_view.dart';
@@ -345,18 +345,19 @@ class _SendViewState extends ConsumerState<SendView> {
);
final Amount? amount;
if (baseAmount != null) {
- final _price =
- ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin)?.value;
+ final _price = ref
+ .read(priceAnd24hChangeNotifierProvider)
+ .getPrice(coin)
+ ?.value;
if (_price == null || _price == Decimal.zero) {
amount = 0.toAmountAsRaw(fractionDigits: coin.fractionDigits);
} else {
- amount =
- baseAmount <= Amount.zero
- ? 0.toAmountAsRaw(fractionDigits: coin.fractionDigits)
- : (baseAmount.decimal / _price)
- .toDecimal(scaleOnInfinitePrecision: coin.fractionDigits)
- .toAmount(fractionDigits: coin.fractionDigits);
+ amount = baseAmount <= Amount.zero
+ ? 0.toAmountAsRaw(fractionDigits: coin.fractionDigits)
+ : (baseAmount.decimal / _price)
+ .toDecimal(scaleOnInfinitePrecision: coin.fractionDigits)
+ .toAmount(fractionDigits: coin.fractionDigits);
}
if (_cachedAmountToSend != null && _cachedAmountToSend == amount) {
return;
@@ -397,8 +398,10 @@ class _SendViewState extends ConsumerState<SendView> {
}
_cachedAmountToSend = amount;
- final price =
- ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin)?.value;
+ final price = ref
+ .read(priceAnd24hChangeNotifierProvider)
+ .getPrice(coin)
+ ?.value;
if (price != null && price > Decimal.zero) {
baseAmountController.text = (amount.decimal * price)
@@ -463,12 +466,11 @@ class _SendViewState extends ConsumerState<SendView> {
fee = fee.split(" ").first;
}
- final value =
- fee.contains(",")
- ? Decimal.parse(
- fee.replaceFirst(",", "."),
- ).toAmount(fractionDigits: coin.fractionDigits)
- : Decimal.parse(fee).toAmount(fractionDigits: coin.fractionDigits);
+ final value = fee.contains(",")
+ ? Decimal.parse(
+ fee.replaceFirst(",", "."),
+ ).toAmount(fractionDigits: coin.fractionDigits)
+ : Decimal.parse(fee).toAmount(fractionDigits: coin.fractionDigits);
if (shouldSetState) {
setState(() => _currentFee = value);
@@ -559,25 +561,22 @@ class _SendViewState extends ConsumerState<SendView> {
Amount fee;
if (coin is Monero) {
- lib_monero.TransactionPriority specialMoneroId;
+ final int specialMoneroId;
switch (ref.read(feeRateTypeMobileStateProvider.state).state) {
case FeeRateType.fast:
- specialMoneroId = lib_monero.TransactionPriority.high;
+ specialMoneroId = csMonero.getTxPriorityHigh();
break;
case FeeRateType.average:
- specialMoneroId = lib_monero.TransactionPriority.medium;
+ specialMoneroId = csMonero.getTxPriorityMedium();
break;
case FeeRateType.slow:
- specialMoneroId = lib_monero.TransactionPriority.normal;
+ specialMoneroId = csMonero.getTxPriorityNormal();
break;
default:
throw ArgumentError("custom fee not available for monero");
}
- fee = await wallet.estimateFeeFor(
- amount,
- BigInt.from(specialMoneroId.value),
- );
+ fee = await wallet.estimateFeeFor(amount, BigInt.from(specialMoneroId));
cachedFees[amount] = ref
.read(pAmountFormatter(coin))
.format(fee, withUnitName: true, indicatePrecisionLoss: false);
@@ -629,10 +628,9 @@ class _SendViewState extends ConsumerState<SendView> {
amount: amount,
recipientAddress: null,
// No specific recipient for manual slatepack.
- message:
- onChainNoteController.text.isNotEmpty == true
- ? onChainNoteController.text
- : null,
+ message: onChainNoteController.text.isNotEmpty == true
+ ? onChainNoteController.text
+ : null,
encrypt: false, // No encryption without recipient address.
);
}
@@ -672,10 +670,9 @@ class _SendViewState extends ConsumerState<SendView> {
await showDialog<void>(
context: context,
barrierDismissible: false,
- builder:
- (context) => StackDialogBase(
- child: MwcSlatepackDialog(slatepackResult: slatepackResult),
- ),
+ builder: (context) => StackDialogBase(
+ child: MwcSlatepackDialog(slatepackResult: slatepackResult),
+ ),
);
// Clear form after slatepack dialog is closed.
@@ -692,11 +689,10 @@ class _SendViewState extends ConsumerState<SendView> {
if (mounted) {
await showDialog<void>(
context: context,
- builder:
- (context) => StackOkDialog(
- title: "Slatepack Creation Failed",
- message: e.toString(),
- ),
+ builder: (context) => StackOkDialog(
+ title: "Slatepack Creation Failed",
+ message: e.toString(),
+ ),
);
}
}
@@ -716,18 +712,18 @@ class _SendViewState extends ConsumerState<SendView> {
availableBalance = wallet.info.cachedBalance.spendable;
break;
case BalanceType.private:
- availableBalance =
- isFiro
- ? wallet.info.cachedBalanceTertiary.spendable
- : wallet.info.cachedBalanceSecondary.spendable;
+ availableBalance = isFiro
+ ? wallet.info.cachedBalanceTertiary.spendable
+ : wallet.info.cachedBalanceSecondary.spendable;
break;
}
} else {
availableBalance = ref.read(pWalletBalance(walletId)).spendable;
}
- final coinControlEnabled =
- ref.read(prefsChangeNotifierProvider).enableCoinControl;
+ final coinControlEnabled = ref
+ .read(prefsChangeNotifierProvider)
+ .enableCoinControl;
if (coin is! Ethereum &&
!(wallet is CoinControlInterface && coinControlEnabled) ||
@@ -754,10 +750,9 @@ class _SendViewState extends ConsumerState<SendView> {
child: Text(
"Cancel",
style: STextStyles.button(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.accentColorDark,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.accentColorDark,
),
),
onPressed: () {
@@ -833,10 +828,10 @@ class _SendViewState extends ConsumerState<SendView> {
feeRateType: feeRate,
utxos:
(wallet is CoinControlInterface &&
- coinControlEnabled &&
- selectedUTXOs.isNotEmpty)
- ? selectedUTXOs
- : null,
+ coinControlEnabled &&
+ selectedUTXOs.isNotEmpty)
+ ? selectedUTXOs
+ : null,
),
);
} else if (wallet is FiroWallet) {
@@ -855,10 +850,9 @@ class _SendViewState extends ConsumerState<SendView> {
],
feeRateType: ref.read(feeRateTypeMobileStateProvider),
satsPerVByte: isCustomFee.value ? customFeeRate : null,
- utxos:
- (coinControlEnabled && selectedUTXOs.isNotEmpty)
- ? selectedUTXOs
- : null,
+ utxos: (coinControlEnabled && selectedUTXOs.isNotEmpty)
+ ? selectedUTXOs
+ : null,
),
);
} else {
@@ -869,16 +863,16 @@ class _SendViewState extends ConsumerState<SendView> {
address: _address!,
amount: amount,
isChange: false,
- addressType:
- wallet.cryptoCurrency.getAddressType(_address!)!,
+ addressType: wallet.cryptoCurrency.getAddressType(
+ _address!,
+ )!,
),
],
feeRateType: ref.read(feeRateTypeMobileStateProvider),
satsPerVByte: isCustomFee.value ? customFeeRate : null,
- utxos:
- (coinControlEnabled && selectedUTXOs.isNotEmpty)
- ? selectedUTXOs
- : null,
+ utxos: (coinControlEnabled && selectedUTXOs.isNotEmpty)
+ ? selectedUTXOs
+ : null,
),
);
}
@@ -887,31 +881,28 @@ class _SendViewState extends ConsumerState<SendView> {
case BalanceType.private:
txDataFuture = wallet.prepareSendSpark(
txData: TxData(
- recipients:
- ref.read(pValidSparkSendToAddress)
- ? null
- : [
- TxRecipient(
- address: _address!,
- amount: amount,
- isChange: false,
- addressType:
- wallet.cryptoCurrency.getAddressType(
- _address!,
- )!,
- ),
- ],
- sparkRecipients:
- ref.read(pValidSparkSendToAddress)
- ? [
- (
- address: _address!,
- amount: amount,
- memo: memoController.text,
- isChange: false,
- ),
- ]
- : null,
+ recipients: ref.read(pValidSparkSendToAddress)
+ ? null
+ : [
+ TxRecipient(
+ address: _address!,
+ amount: amount,
+ isChange: false,
+ addressType: wallet.cryptoCurrency.getAddressType(
+ _address!,
+ )!,
+ ),
+ ],
+ sparkRecipients: ref.read(pValidSparkSendToAddress)
+ ? [
+ (
+ address: _address!,
+ amount: amount,
+ memo: memoController.text,
+ isChange: false,
+ ),
+ ]
+ : null,
),
);
break;
@@ -959,10 +950,10 @@ class _SendViewState extends ConsumerState<SendView> {
ethEIP1559Fee: ethFee,
utxos:
(wallet is CoinControlInterface &&
- coinControlEnabled &&
- selectedUTXOs.isNotEmpty)
- ? selectedUTXOs
- : null,
+ coinControlEnabled &&
+ selectedUTXOs.isNotEmpty)
+ ? selectedUTXOs
+ : null,
),
);
}
@@ -975,10 +966,9 @@ class _SendViewState extends ConsumerState<SendView> {
if (isPaynymSend) {
txData = txData.copyWith(
paynymAccountLite: widget.accountLite!,
- note:
- noteController.text.isNotEmpty
- ? noteController.text
- : "PayNym send",
+ note: noteController.text.isNotEmpty
+ ? noteController.text
+ : "PayNym send",
);
} else {
txData = txData.copyWith(note: noteController.text);
@@ -992,13 +982,12 @@ class _SendViewState extends ConsumerState<SendView> {
Navigator.of(context).push(
RouteGenerator.getRoute(
shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
- builder:
- (_) => ConfirmTransactionView(
- txData: txData,
- walletId: walletId,
- isPaynymTransaction: isPaynymSend,
- onSuccess: clearSendForm,
- ),
+ builder: (_) => ConfirmTransactionView(
+ txData: txData,
+ walletId: walletId,
+ isPaynymTransaction: isPaynymSend,
+ onSuccess: clearSendForm,
+ ),
settings: const RouteSettings(
name: ConfirmTransactionView.routeName,
),
@@ -1028,10 +1017,9 @@ class _SendViewState extends ConsumerState<SendView> {
child: Text(
"Ok",
style: STextStyles.button(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.accentColorDark,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.accentColorDark,
),
),
onPressed: () {
@@ -1089,10 +1077,9 @@ class _SendViewState extends ConsumerState<SendView> {
break;
case BalanceType.private:
- amount =
- isFiro
- ? ref.read(pWalletBalanceTertiary(walletId)).spendable
- : ref.read(pWalletBalanceSecondary(walletId)).spendable;
+ amount = isFiro
+ ? ref.read(pWalletBalanceTertiary(walletId)).spendable
+ : ref.read(pWalletBalanceSecondary(walletId)).spendable;
break;
}
} else {
@@ -1153,32 +1140,32 @@ class _SendViewState extends ConsumerState<SendView> {
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
- builder:
- (_) => TransactionFeeSelectionSheet(
- walletId: walletId,
- amount: (Decimal.tryParse(cryptoAmountController.text) ??
+ builder: (_) => TransactionFeeSelectionSheet(
+ walletId: walletId,
+ amount:
+ (Decimal.tryParse(cryptoAmountController.text) ??
ref.watch(pSendAmount)?.decimal ??
Decimal.zero)
.toAmount(fractionDigits: coin.fractionDigits),
- updateChosen: (String fee) {
- if (fee == "custom") {
- if (!isCustomFee.value) {
- setState(() {
- isCustomFee.value = true;
- });
- }
- return;
- }
-
- _setCurrentFee(fee, true);
+ updateChosen: (String fee) {
+ if (fee == "custom") {
+ if (!isCustomFee.value) {
setState(() {
- _calculateFeesFuture = Future(() => fee);
- if (isCustomFee.value) {
- isCustomFee.value = false;
- }
+ isCustomFee.value = true;
});
- },
- ),
+ }
+ return;
+ }
+
+ _setCurrentFee(fee, true);
+ setState(() {
+ _calculateFeesFuture = Future(() => fee);
+ if (isCustomFee.value) {
+ isCustomFee.value = false;
+ }
+ });
+ },
+ ),
);
}
@@ -1433,10 +1420,9 @@ class _SendViewState extends ConsumerState<SendView> {
children: [
Container(
decoration: BoxDecoration(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.popupBG,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@@ -1489,38 +1475,31 @@ class _SendViewState extends ConsumerState<SendView> {
if (showPrivateBalance) {
switch (balType) {
case BalanceType.public:
- amount =
- ref
- .read(
- pWalletBalance(
- walletId,
- ),
- )
- .spendable;
+ amount = ref
+ .read(
+ pWalletBalance(walletId),
+ )
+ .spendable;
break;
case BalanceType.private:
- amount =
- ref
- .read(
- isMwebEnabled
- ? pWalletBalanceSecondary(
- walletId,
- )
- : pWalletBalanceTertiary(
- walletId,
- ),
- )
- .spendable;
- break;
- }
- } else {
- amount =
- ref
+ amount = ref
.read(
- pWalletBalance(walletId),
+ isMwebEnabled
+ ? pWalletBalanceSecondary(
+ walletId,
+ )
+ : pWalletBalanceTertiary(
+ walletId,
+ ),
)
.spendable;
+ break;
+ }
+ } else {
+ amount = ref
+ .read(pWalletBalance(walletId))
+ .spendable;
}
return GestureDetector(
@@ -1672,95 +1651,103 @@ class _SendViewState extends ConsumerState<SendView> {
},
focusNode: _addressFocusNode,
style: STextStyles.field(context),
- decoration: standardInputDecoration(
- isMwcSlatepack
- ? "Enter ${coin.ticker} address (optional)"
- : "Enter ${coin.ticker} address",
- _addressFocusNode,
- context,
- ).copyWith(
- contentPadding: const EdgeInsets.only(
- left: 16,
- top: 6,
- bottom: 8,
- right: 5,
- ),
- suffixIcon: Padding(
- padding:
- sendToController.text.isEmpty
+ decoration:
+ standardInputDecoration(
+ isMwcSlatepack
+ ? "Enter ${coin.ticker} address (optional)"
+ : "Enter ${coin.ticker} address",
+ _addressFocusNode,
+ context,
+ ).copyWith(
+ contentPadding: const EdgeInsets.only(
+ left: 16,
+ top: 6,
+ bottom: 8,
+ right: 5,
+ ),
+ suffixIcon: Padding(
+ padding: sendToController.text.isEmpty
? const EdgeInsets.only(right: 8)
: const EdgeInsets.only(right: 0),
- child: UnconstrainedBox(
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceAround,
- children: [
- _addressToggleFlag
- ? TextFieldIconButton(
- semanticsLabel:
- "Clear Button. Clears The Address Field Input.",
- key: const Key(
- "sendViewClearAddressFieldButtonKey",
+ child: UnconstrainedBox(
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceAround,
+ children: [
+ _addressToggleFlag
+ ? TextFieldIconButton(
+ semanticsLabel:
+ "Clear Button. Clears The Address Field Input.",
+ key: const Key(
+ "sendViewClearAddressFieldButtonKey",
+ ),
+ onTap: () {
+ sendToController
+ .text =
+ "";
+ _address = "";
+ _setValidAddressProviders(
+ _address,
+ );
+ setState(() {
+ _addressToggleFlag =
+ false;
+ });
+ },
+ child: const XIcon(),
+ )
+ : TextFieldIconButton(
+ semanticsLabel:
+ "Paste Button. Pastes From Clipboard To Address Field Input.",
+ key: const Key(
+ "sendViewPasteAddressFieldButtonKey",
+ ),
+ onTap: _pasteAddress,
+ child:
+ sendToController
+ .text
+ .isEmpty
+ ? const ClipboardIcon()
+ : const XIcon(),
+ ),
+ if (sendToController
+ .text
+ .isEmpty)
+ TextFieldIconButton(
+ semanticsLabel:
+ "Address Book Button. Opens Address Book For Address Field.",
+ key: const Key(
+ "sendViewAddressBookButtonKey",
+ ),
+ onTap: () {
+ Navigator.of(
+ context,
+ ).pushNamed(
+ AddressBookView
+ .routeName,
+ arguments: widget.coin,
+ );
+ },
+ child:
+ const AddressBookIcon(),
),
- onTap: () {
- sendToController.text = "";
- _address = "";
- _setValidAddressProviders(
- _address,
- );
- setState(() {
- _addressToggleFlag =
- false;
- });
- },
- child: const XIcon(),
- )
- : TextFieldIconButton(
- semanticsLabel:
- "Paste Button. Pastes From Clipboard To Address Field Input.",
- key: const Key(
- "sendViewPasteAddressFieldButtonKey",
+ if (sendToController
+ .text
+ .isEmpty)
+ TextFieldIconButton(
+ semanticsLabel:
+ "Scan QR Button. Opens Camera For Scanning QR Code.",
+ key: const Key(
+ "sendViewScanQrButtonKey",
+ ),
+ onTap: _scanQr,
+ child: const QrCodeIcon(),
),
- onTap: _pasteAddress,
- child:
- sendToController
- .text
- .isEmpty
- ? const ClipboardIcon()
- : const XIcon(),
- ),
- if (sendToController.text.isEmpty)
- TextFieldIconButton(
- semanticsLabel:
- "Address Book Button. Opens Address Book For Address Field.",
- key: const Key(
- "sendViewAddressBookButtonKey",
- ),
- onTap: () {
- Navigator.of(
- context,
- ).pushNamed(
- AddressBookView.routeName,
- arguments: widget.coin,
- );
- },
- child: const AddressBookIcon(),
- ),
- if (sendToController.text.isEmpty)
- TextFieldIconButton(
- semanticsLabel:
- "Scan QR Button. Opens Camera For Scanning QR Code.",
- key: const Key(
- "sendViewScanQrButtonKey",
- ),
- onTap: _scanQr,
- child: const QrCodeIcon(),
- ),
- ],
+ ],
+ ),
+ ),
),
),
- ),
- ),
),
),
const SizedBox(height: 10),
@@ -1782,72 +1769,79 @@ class _SendViewState extends ConsumerState<SendView> {
onChanged: (_) {
setState(() {});
},
- decoration: standardInputDecoration(
- "Enter memo (optional)",
- _memoFocus,
- context,
- ).copyWith(
- counterText: '',
- contentPadding: const EdgeInsets.only(
- left: 16,
- top: 6,
- bottom: 8,
- right: 5,
- ),
- suffixIcon: Padding(
- padding:
- memoController.text.isEmpty
+ decoration:
+ standardInputDecoration(
+ "Enter memo (optional)",
+ _memoFocus,
+ context,
+ ).copyWith(
+ counterText: '',
+ contentPadding: const EdgeInsets.only(
+ left: 16,
+ top: 6,
+ bottom: 8,
+ right: 5,
+ ),
+ suffixIcon: Padding(
+ padding: memoController.text.isEmpty
? const EdgeInsets.only(right: 8)
: const EdgeInsets.only(right: 0),
- child: UnconstrainedBox(
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceAround,
- children: [
- memoController.text.isNotEmpty
- ? TextFieldIconButton(
- semanticsLabel:
- "Clear Button. Clears The Memo Field Input.",
- key: const Key(
- "sendViewClearMemoFieldButtonKey",
- ),
- onTap: () {
- memoController.text = "";
- setState(() {});
- },
- child: const XIcon(),
- )
- : TextFieldIconButton(
- semanticsLabel:
- "Paste Button. Pastes From Clipboard To Memo Field Input.",
- key: const Key(
- "sendViewPasteMemoFieldButtonKey",
- ),
- onTap: () async {
- final ClipboardData? data =
- await clipboard.getData(
- Clipboard.kTextPlain,
- );
- if (data?.text != null &&
- data!
- .text!
- .isNotEmpty) {
- final String content =
- data.text!.trim();
-
- memoController.text =
- content.trim();
-
- setState(() {});
- }
- },
- child: const ClipboardIcon(),
- ),
- ],
+ child: UnconstrainedBox(
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceAround,
+ children: [
+ memoController.text.isNotEmpty
+ ? TextFieldIconButton(
+ semanticsLabel:
+ "Clear Button. Clears The Memo Field Input.",
+ key: const Key(
+ "sendViewClearMemoFieldButtonKey",
+ ),
+ onTap: () {
+ memoController.text =
+ "";
+ setState(() {});
+ },
+ child: const XIcon(),
+ )
+ : TextFieldIconButton(
+ semanticsLabel:
+ "Paste Button. Pastes From Clipboard To Memo Field Input.",
+ key: const Key(
+ "sendViewPasteMemoFieldButtonKey",
+ ),
+ onTap: () async {
+ final ClipboardData?
+ data = await clipboard
+ .getData(
+ Clipboard
+ .kTextPlain,
+ );
+ if (data?.text !=
+ null &&
+ data!
+ .text!
+ .isNotEmpty) {
+ final String
+ content = data.text!
+ .trim();
+
+ memoController
+ .text = content
+ .trim();
+
+ setState(() {});
+ }
+ },
+ child:
+ const ClipboardIcon(),
+ ),
+ ],
+ ),
+ ),
),
),
- ),
- ),
),
),
Builder(
@@ -1890,14 +1884,12 @@ class _SendViewState extends ConsumerState<SendView> {
child: Text(
error,
textAlign: TextAlign.left,
- style: STextStyles.label(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.label(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.textError,
- ),
+ ),
),
),
);
@@ -1919,8 +1911,9 @@ class _SendViewState extends ConsumerState<SendView> {
children: [
TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
readOnly: true,
textInputAction: TextInputAction.none,
),
@@ -1929,10 +1922,9 @@ class _SendViewState extends ConsumerState<SendView> {
horizontal: 12,
),
child: RawMaterialButton(
- splashColor:
- Theme.of(
- context,
- ).extension<StackColors>()!.highlight,
+ splashColor: Theme.of(
+ context,
+ ).extension<StackColors>()!.highlight,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
@@ -1947,8 +1939,8 @@ class _SendViewState extends ConsumerState<SendView> {
top: Radius.circular(20),
),
),
- builder:
- (_) => DualBalanceSelectionSheet(
+ builder: (_) =>
+ DualBalanceSelectionSheet(
walletId: walletId,
),
);
@@ -1977,28 +1969,26 @@ class _SendViewState extends ConsumerState<SendView> {
)
.state) {
case BalanceType.public:
- amount =
- ref
- .watch(
- pWalletBalance(
- walletId,
- ),
- )
- .spendable;
+ amount = ref
+ .watch(
+ pWalletBalance(
+ walletId,
+ ),
+ )
+ .spendable;
break;
case BalanceType.private:
- amount =
- ref
- .watch(
- isFiro
- ? pWalletBalanceTertiary(
- walletId,
- )
- : pWalletBalanceSecondary(
- walletId,
- ),
- )
- .spendable;
+ amount = ref
+ .watch(
+ isFiro
+ ? pWalletBalanceTertiary(
+ walletId,
+ )
+ : pWalletBalanceSecondary(
+ walletId,
+ ),
+ )
+ .spendable;
break;
}
@@ -2023,10 +2013,9 @@ class _SendViewState extends ConsumerState<SendView> {
Assets.svg.chevronDown,
width: 8,
height: 4,
- color:
- Theme.of(context)
- .extension<StackColors>()!
- .textSubtitle2,
+ color: Theme.of(context)
+ .extension<StackColors>()!
+ .textSubtitle2,
),
],
),
@@ -2049,8 +2038,8 @@ class _SendViewState extends ConsumerState<SendView> {
showCoinControl,
selectedUTXOs,
),
- onTap:
- () => _sendAllTapped(showCoinControl),
+ onTap: () =>
+ _sendAllTapped(showCoinControl),
),
],
),
@@ -2059,23 +2048,21 @@ class _SendViewState extends ConsumerState<SendView> {
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
style: STextStyles.smallMed14(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textDark,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textDark,
),
key: const Key(
"amountInputFieldCryptoTextFieldKey",
),
controller: cryptoAmountController,
focusNode: _cryptoFocus,
- keyboardType:
- Util.isDesktop
- ? null
- : const TextInputType.numberWithOptions(
- signed: false,
- decimal: true,
- ),
+ keyboardType: Util.isDesktop
+ ? null
+ : const TextInputType.numberWithOptions(
+ signed: false,
+ decimal: true,
+ ),
textAlign: TextAlign.right,
inputFormatters: [
AmountInputFormatter(
@@ -2111,14 +2098,12 @@ class _SendViewState extends ConsumerState<SendView> {
ref
.watch(pAmountUnit(coin))
.unitForCoin(coin),
- style: STextStyles.smallMed14(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.smallMed14(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
- ),
+ ),
),
),
),
@@ -2129,26 +2114,25 @@ class _SendViewState extends ConsumerState<SendView> {
if (Prefs.instance.externalCalls)
TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
style: STextStyles.smallMed14(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textDark,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textDark,
),
key: const Key(
"amountInputFieldFiatTextFieldKey",
),
controller: baseAmountController,
focusNode: _baseFocus,
- keyboardType:
- Util.isDesktop
- ? null
- : const TextInputType.numberWithOptions(
- signed: false,
- decimal: true,
- ),
+ keyboardType: Util.isDesktop
+ ? null
+ : const TextInputType.numberWithOptions(
+ signed: false,
+ decimal: true,
+ ),
textAlign: TextAlign.right,
inputFormatters: [
AmountInputFormatter(
@@ -2184,14 +2168,12 @@ class _SendViewState extends ConsumerState<SendView> {
(value) => value.currency,
),
),
- style: STextStyles.smallMed14(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.smallMed14(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
- ),
+ ),
),
),
),
@@ -2206,20 +2188,17 @@ class _SendViewState extends ConsumerState<SendView> {
children: [
Text(
"Coin control",
- style: STextStyles.w500_14(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.w500_14(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
- ),
+ ),
),
CustomTextButton(
- text:
- selectedUTXOs.isEmpty
- ? "Select coins"
- : "Selected coins (${selectedUTXOs.length})",
+ text: selectedUTXOs.isEmpty
+ ? "Select coins"
+ : "Selected coins (${selectedUTXOs.length})",
onTap: () async {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
@@ -2229,12 +2208,9 @@ class _SendViewState extends ConsumerState<SendView> {
}
if (context.mounted) {
- final spendable =
- ref
- .read(
- pWalletBalance(walletId),
- )
- .spendable;
+ final spendable = ref
+ .read(pWalletBalance(walletId))
+ .spendable;
Amount? amount;
if (ref.read(pSendAmount) != null) {
@@ -2247,28 +2223,26 @@ class _SendViewState extends ConsumerState<SendView> {
}
}
- final result = await Navigator.of(
- context,
- ).pushNamed(
- CoinControlView.routeName,
- arguments: Tuple4(
- walletId,
- CoinControlViewType.use,
- amount,
- selectedUTXOs
- .map((e) => e.utxo)
- .toSet(),
- ),
- );
+ final result =
+ await Navigator.of(
+ context,
+ ).pushNamed(
+ CoinControlView.routeName,
+ arguments: Tuple4(
+ walletId,
+ CoinControlViewType.use,
+ amount,
+ selectedUTXOs
+ .map((e) => e.utxo)
+ .toSet(),
+ ),
+ );
if (result is Set<UTXO>) {
setState(() {
- selectedUTXOs =
- result
- .map(
- (e) => StandardInput(e),
- )
- .toSet();
+ selectedUTXOs = result
+ .map((e) => StandardInput(e))
+ .toSet();
});
}
}
@@ -2292,42 +2266,47 @@ class _SendViewState extends ConsumerState<SendView> {
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
maxLength: 256,
controller: onChainNoteController,
focusNode: _onChainNoteFocusNode,
style: STextStyles.field(context),
onChanged: (_) => setState(() {}),
- decoration: standardInputDecoration(
- "Type something...",
- _onChainNoteFocusNode,
- context,
- ).copyWith(
- suffixIcon:
- onChainNoteController.text.isNotEmpty
+ decoration:
+ standardInputDecoration(
+ "Type something...",
+ _onChainNoteFocusNode,
+ context,
+ ).copyWith(
+ suffixIcon:
+ onChainNoteController
+ .text
+ .isNotEmpty
? Padding(
- padding: const EdgeInsets.only(
- right: 0,
- ),
- child: UnconstrainedBox(
- child: Row(
- children: [
- TextFieldIconButton(
- child: const XIcon(),
- onTap: () async {
- setState(() {
- onChainNoteController
- .text = "";
- });
- },
- ),
- ],
+ padding: const EdgeInsets.only(
+ right: 0,
),
- ),
- )
+ child: UnconstrainedBox(
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ onChainNoteController
+ .text =
+ "";
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ )
: null,
- ),
+ ),
),
),
if (coin is Epiccash || coin is Mimblewimblecoin)
@@ -2348,41 +2327,44 @@ class _SendViewState extends ConsumerState<SendView> {
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
controller: noteController,
focusNode: _noteFocusNode,
style: STextStyles.field(context),
onChanged: (_) => setState(() {}),
- decoration: standardInputDecoration(
- "Type something...",
- _noteFocusNode,
- context,
- ).copyWith(
- suffixIcon:
- noteController.text.isNotEmpty
+ decoration:
+ standardInputDecoration(
+ "Type something...",
+ _noteFocusNode,
+ context,
+ ).copyWith(
+ suffixIcon:
+ noteController.text.isNotEmpty
? Padding(
- padding: const EdgeInsets.only(
- right: 0,
- ),
- child: UnconstrainedBox(
- child: Row(
- children: [
- TextFieldIconButton(
- child: const XIcon(),
- onTap: () async {
- setState(() {
- noteController.text =
- "";
- });
- },
- ),
- ],
+ padding: const EdgeInsets.only(
+ right: 0,
),
- ),
- )
+ child: UnconstrainedBox(
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ noteController
+ .text =
+ "";
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ )
: null,
- ),
+ ),
),
),
if (coin is Epiccash || coin is Mimblewimblecoin)
@@ -2401,41 +2383,42 @@ class _SendViewState extends ConsumerState<SendView> {
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
controller: noteController,
focusNode: _noteFocusNode,
style: STextStyles.field(context),
onChanged: (_) => setState(() {}),
- decoration: standardInputDecoration(
- "Type something...",
- _noteFocusNode,
- context,
- ).copyWith(
- suffixIcon:
- noteController.text.isNotEmpty
+ decoration:
+ standardInputDecoration(
+ "Type something...",
+ _noteFocusNode,
+ context,
+ ).copyWith(
+ suffixIcon: noteController.text.isNotEmpty
? Padding(
- padding: const EdgeInsets.only(
- right: 0,
- ),
- child: UnconstrainedBox(
- child: Row(
- children: [
- TextFieldIconButton(
- child: const XIcon(),
- onTap: () async {
- setState(() {
- noteController.text =
- "";
- });
- },
- ),
- ],
+ padding: const EdgeInsets.only(
+ right: 0,
),
- ),
- )
+ child: UnconstrainedBox(
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ noteController.text =
+ "";
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ )
: null,
- ),
+ ),
),
),
const SizedBox(height: 12),
@@ -2461,8 +2444,9 @@ class _SendViewState extends ConsumerState<SendView> {
children: [
TextField(
autocorrect: Util.isDesktop ? false : true,
- enableSuggestions:
- Util.isDesktop ? false : true,
+ enableSuggestions: Util.isDesktop
+ ? false
+ : true,
controller: feeController,
readOnly: true,
textInputAction: TextInputAction.none,
@@ -2476,10 +2460,9 @@ class _SendViewState extends ConsumerState<SendView> {
horizontal: 12,
),
child: RawMaterialButton(
- splashColor:
- Theme.of(context)
- .extension<StackColors>()!
- .highlight,
+ splashColor: Theme.of(
+ context,
+ ).extension<StackColors>()!.highlight,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
@@ -2487,138 +2470,128 @@ class _SendViewState extends ConsumerState<SendView> {
),
onPressed:
isFiro &&
- ref
- .watch(
- publicPrivateBalanceStateProvider
- .state,
- )
- .state !=
- BalanceType.public
- ? null
- : _onFeeSelectPressed,
+ ref
+ .watch(
+ publicPrivateBalanceStateProvider
+ .state,
+ )
+ .state !=
+ BalanceType.public
+ ? null
+ : _onFeeSelectPressed,
child:
(isFiro &&
- ref
- .watch(
- publicPrivateBalanceStateProvider
- .state,
- )
- .state !=
- BalanceType.public)
- ? Row(
- children: [
- FutureBuilder(
- future:
- _calculateFeesFuture,
- builder: (
- context,
- snapshot,
- ) {
- if (snapshot.connectionState ==
- ConnectionState
- .done &&
- snapshot.hasData) {
- _setCurrentFee(
- snapshot.data!,
- false,
- );
- return Text(
- "~${snapshot.data!}",
- style:
- STextStyles.itemSubtitle(
- context,
- ),
- );
- } else {
- return AnimatedText(
- stringsToLoopThrough:
- stringsToLoopThrough,
- style:
- STextStyles.itemSubtitle(
- context,
- ),
- );
- }
- },
- ),
- ],
- )
- : Row(
- mainAxisAlignment:
- MainAxisAlignment
- .spaceBetween,
- children: [
- Row(
- children: [
- Text(
- ref
- .watch(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state
- .prettyName,
+ ref
+ .watch(
+ publicPrivateBalanceStateProvider
+ .state,
+ )
+ .state !=
+ BalanceType.public)
+ ? Row(
+ children: [
+ FutureBuilder(
+ future:
+ _calculateFeesFuture,
+ builder: (context, snapshot) {
+ if (snapshot.connectionState ==
+ ConnectionState
+ .done &&
+ snapshot.hasData) {
+ _setCurrentFee(
+ snapshot.data!,
+ false,
+ );
+ return Text(
+ "~${snapshot.data!}",
style:
- STextStyles.itemSubtitle12(
+ STextStyles.itemSubtitle(
context,
),
- ),
- const SizedBox(
- width: 10,
- ),
- FutureBuilder(
- future:
- _calculateFeesFuture,
- builder: (
- context,
- snapshot,
- ) {
- if (snapshot.connectionState ==
- ConnectionState
- .done &&
- snapshot
- .hasData) {
- _setCurrentFee(
- snapshot.data!,
- false,
- );
- return Text(
- isCustomFee
- .value
- ? ""
- : "~${snapshot.data!}",
- style:
- STextStyles.itemSubtitle(
- context,
- ),
- );
- } else {
- return AnimatedText(
- stringsToLoopThrough:
- stringsToLoopThrough,
- style:
- STextStyles.itemSubtitle(
- context,
- ),
- );
- }
- },
- ),
- ],
- ),
- SvgPicture.asset(
- Assets.svg.chevronDown,
- width: 8,
- height: 4,
- color:
- Theme.of(context)
- .extension<
- StackColors
- >()!
- .textSubtitle2,
- ),
- ],
- ),
+ );
+ } else {
+ return AnimatedText(
+ stringsToLoopThrough:
+ stringsToLoopThrough,
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ }
+ },
+ ),
+ ],
+ )
+ : Row(
+ mainAxisAlignment:
+ MainAxisAlignment
+ .spaceBetween,
+ children: [
+ Row(
+ children: [
+ Text(
+ ref
+ .watch(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state
+ .prettyName,
+ style:
+ STextStyles.itemSubtitle12(
+ context,
+ ),
+ ),
+ const SizedBox(width: 10),
+ FutureBuilder(
+ future:
+ _calculateFeesFuture,
+ builder: (context, snapshot) {
+ if (snapshot.connectionState ==
+ ConnectionState
+ .done &&
+ snapshot
+ .hasData) {
+ _setCurrentFee(
+ snapshot.data!,
+ false,
+ );
+ return Text(
+ isCustomFee.value
+ ? ""
+ : "~${snapshot.data!}",
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ } else {
+ return AnimatedText(
+ stringsToLoopThrough:
+ stringsToLoopThrough,
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ }
+ },
+ ),
+ ],
+ ),
+ SvgPicture.asset(
+ Assets.svg.chevronDown,
+ width: 8,
+ height: 4,
+ color: Theme.of(context)
+ .extension<
+ StackColors
+ >()!
+ .textSubtitle2,
+ ),
+ ],
+ ),
),
),
),
@@ -2649,23 +2622,18 @@ class _SendViewState extends ConsumerState<SendView> {
TextButton(
onPressed:
ref.watch(pPreviewTxButtonEnabled(coin))
- ? ref.watch(
- pSelectedMwcTransactionMethod,
- ) ==
- MwcTransactionMethod.slatepack
- ? _createSlatepack
- : _previewTransaction
- : null,
- style:
- ref.watch(pPreviewTxButtonEnabled(coin))
- ? Theme.of(context)
- .extension<StackColors>()!
- .getPrimaryEnabledButtonStyle(context)
- : Theme.of(context)
- .extension<StackColors>()!
- .getPrimaryDisabledButtonStyle(
- context,
- ),
+ ? ref.watch(pSelectedMwcTransactionMethod) ==
+ MwcTransactionMethod.slatepack
+ ? _createSlatepack
+ : _previewTransaction
+ : null,
+ style: ref.watch(pPreviewTxButtonEnabled(coin))
+ ? Theme.of(context)
+ .extension<StackColors>()!
+ .getPrimaryEnabledButtonStyle(context)
+ : Theme.of(context)
+ .extension<StackColors>()!
+ .getPrimaryDisabledButtonStyle(context),
child: Text(
ref.watch(pSelectedMwcTransactionMethod) ==
MwcTransactionMethod.slatepack
diff --git a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
index 3ec7048..8c05fa9 100644
--- a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
+++ b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
@@ -8,7 +8,6 @@
*
*/
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -29,6 +28,7 @@ import '../../../wallets/isar/providers/wallet_info_provider.dart';
import '../../../wallets/wallet/impl/firo_wallet.dart';
import '../../../wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
import '../../../widgets/animated_text.dart';
+import '../../../wl_gen/interfaces/cs_monero_interface.dart';
final feeSheetSessionCacheProvider =
ChangeNotifierProvider<FeeSheetSessionCache>((ref) {
@@ -91,7 +91,7 @@ class _TransactionFeeSelectionSheetState
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.high.value),
+ BigInt.from(csMonero.getTxPriorityHigh()),
);
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
} else if (coin is Firo) {
@@ -128,7 +128,7 @@ class _TransactionFeeSelectionSheetState
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.medium.value),
+ BigInt.from(csMonero.getTxPriorityMedium()),
);
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
} else if (coin is Firo) {
@@ -164,7 +164,7 @@ class _TransactionFeeSelectionSheetState
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.normal.value),
+ BigInt.from(csMonero.getTxPriorityNormal()),
);
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
} else if (coin is Firo) {
@@ -254,10 +254,9 @@ class _TransactionFeeSelectionSheetState
Center(
child: Container(
decoration: BoxDecoration(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldDefaultBG,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@@ -268,10 +267,9 @@ class _TransactionFeeSelectionSheetState
),
const SizedBox(height: 36),
FutureBuilder(
- future:
- widget.isToken
- ? ref.read(pCurrentTokenWallet)!.fees
- : wallet.fees,
+ future: widget.isToken
+ ? ref.read(pCurrentTokenWallet)!.fees
+ : wallet.fees,
builder: (context, AsyncSnapshot<FeeObject> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
@@ -289,10 +287,9 @@ class _TransactionFeeSelectionSheetState
const SizedBox(height: 16),
GestureDetector(
onTap: () {
- final state =
- ref
- .read(feeRateTypeMobileStateProvider.state)
- .state;
+ final state = ref
+ .read(feeRateTypeMobileStateProvider.state)
+ .state;
if (state != FeeRateType.fast) {
ref.read(feeRateTypeMobileStateProvider.state).state =
FeeRateType.fast;
@@ -318,25 +315,23 @@ class _TransactionFeeSelectionSheetState
width: 20,
height: 20,
child: Radio(
- activeColor:
- Theme.of(context)
- .extension<StackColors>()!
- .radioButtonIconEnabled,
+ activeColor: Theme.of(context)
+ .extension<StackColors>()!
+ .radioButtonIconEnabled,
value: FeeRateType.fast,
- groupValue:
- ref
- .watch(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state,
+ groupValue: ref
+ .watch(
+ feeRateTypeMobileStateProvider.state,
+ )
+ .state,
onChanged: (x) {
ref
- .read(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state = FeeRateType.fast;
+ .read(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state =
+ FeeRateType.fast;
Navigator.of(context).pop();
},
@@ -373,30 +368,33 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.fast,
amount: amount,
),
- builder: (
- _,
- AsyncSnapshot<Amount> snapshot,
- ) {
- if (snapshot.connectionState ==
- ConnectionState.done &&
- snapshot.hasData) {
- return Text(
- "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
- style: STextStyles.itemSubtitle(
- context,
- ),
- textAlign: TextAlign.left,
- );
- } else {
- return AnimatedText(
- stringsToLoopThrough:
- stringsToLoopThrough,
- style: STextStyles.itemSubtitle(
- context,
- ),
- );
- }
- },
+ builder:
+ (
+ _,
+ AsyncSnapshot<Amount> snapshot,
+ ) {
+ if (snapshot.connectionState ==
+ ConnectionState.done &&
+ snapshot.hasData) {
+ return Text(
+ "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ textAlign: TextAlign.left,
+ );
+ } else {
+ return AnimatedText(
+ stringsToLoopThrough:
+ stringsToLoopThrough,
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ }
+ },
),
],
),
@@ -426,10 +424,9 @@ class _TransactionFeeSelectionSheetState
const SizedBox(height: 16),
GestureDetector(
onTap: () {
- final state =
- ref
- .read(feeRateTypeMobileStateProvider.state)
- .state;
+ final state = ref
+ .read(feeRateTypeMobileStateProvider.state)
+ .state;
if (state != FeeRateType.average) {
ref.read(feeRateTypeMobileStateProvider.state).state =
FeeRateType.average;
@@ -454,25 +451,23 @@ class _TransactionFeeSelectionSheetState
width: 20,
height: 20,
child: Radio(
- activeColor:
- Theme.of(context)
- .extension<StackColors>()!
- .radioButtonIconEnabled,
+ activeColor: Theme.of(context)
+ .extension<StackColors>()!
+ .radioButtonIconEnabled,
value: FeeRateType.average,
- groupValue:
- ref
- .watch(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state,
+ groupValue: ref
+ .watch(
+ feeRateTypeMobileStateProvider.state,
+ )
+ .state,
onChanged: (x) {
ref
- .read(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state = FeeRateType.average;
+ .read(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state =
+ FeeRateType.average;
Navigator.of(context).pop();
},
),
@@ -508,30 +503,33 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.medium,
amount: amount,
),
- builder: (
- _,
- AsyncSnapshot<Amount> snapshot,
- ) {
- if (snapshot.connectionState ==
- ConnectionState.done &&
- snapshot.hasData) {
- return Text(
- "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
- style: STextStyles.itemSubtitle(
- context,
- ),
- textAlign: TextAlign.left,
- );
- } else {
- return AnimatedText(
- stringsToLoopThrough:
- stringsToLoopThrough,
- style: STextStyles.itemSubtitle(
- context,
- ),
- );
- }
- },
+ builder:
+ (
+ _,
+ AsyncSnapshot<Amount> snapshot,
+ ) {
+ if (snapshot.connectionState ==
+ ConnectionState.done &&
+ snapshot.hasData) {
+ return Text(
+ "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ textAlign: TextAlign.left,
+ );
+ } else {
+ return AnimatedText(
+ stringsToLoopThrough:
+ stringsToLoopThrough,
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ }
+ },
),
],
),
@@ -561,10 +559,9 @@ class _TransactionFeeSelectionSheetState
const SizedBox(height: 16),
GestureDetector(
onTap: () {
- final state =
- ref
- .read(feeRateTypeMobileStateProvider.state)
- .state;
+ final state = ref
+ .read(feeRateTypeMobileStateProvider.state)
+ .state;
if (state != FeeRateType.slow) {
ref.read(feeRateTypeMobileStateProvider.state).state =
FeeRateType.slow;
@@ -586,25 +583,23 @@ class _TransactionFeeSelectionSheetState
width: 20,
height: 20,
child: Radio(
- activeColor:
- Theme.of(context)
- .extension<StackColors>()!
- .radioButtonIconEnabled,
+ activeColor: Theme.of(context)
+ .extension<StackColors>()!
+ .radioButtonIconEnabled,
value: FeeRateType.slow,
- groupValue:
- ref
- .watch(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state,
+ groupValue: ref
+ .watch(
+ feeRateTypeMobileStateProvider.state,
+ )
+ .state,
onChanged: (x) {
ref
- .read(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state = FeeRateType.slow;
+ .read(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state =
+ FeeRateType.slow;
Navigator.of(context).pop();
},
),
@@ -640,30 +635,33 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.slow,
amount: amount,
),
- builder: (
- _,
- AsyncSnapshot<Amount> snapshot,
- ) {
- if (snapshot.connectionState ==
- ConnectionState.done &&
- snapshot.hasData) {
- return Text(
- "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
- style: STextStyles.itemSubtitle(
- context,
- ),
- textAlign: TextAlign.left,
- );
- } else {
- return AnimatedText(
- stringsToLoopThrough:
- stringsToLoopThrough,
- style: STextStyles.itemSubtitle(
- context,
- ),
- );
- }
- },
+ builder:
+ (
+ _,
+ AsyncSnapshot<Amount> snapshot,
+ ) {
+ if (snapshot.connectionState ==
+ ConnectionState.done &&
+ snapshot.hasData) {
+ return Text(
+ "(~${ref.watch(pAmountFormatter(coin)).format(snapshot.data!, indicatePrecisionLoss: false)})",
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ textAlign: TextAlign.left,
+ );
+ } else {
+ return AnimatedText(
+ stringsToLoopThrough:
+ stringsToLoopThrough,
+ style:
+ STextStyles.itemSubtitle(
+ context,
+ ),
+ );
+ }
+ },
),
],
),
@@ -694,14 +692,14 @@ class _TransactionFeeSelectionSheetState
if (wallet is ElectrumXInterface || coin is Ethereum)
GestureDetector(
onTap: () {
- final state =
- ref
- .read(feeRateTypeMobileStateProvider.state)
- .state;
+ final state = ref
+ .read(feeRateTypeMobileStateProvider.state)
+ .state;
if (state != FeeRateType.custom) {
ref
- .read(feeRateTypeMobileStateProvider.state)
- .state = FeeRateType.custom;
+ .read(feeRateTypeMobileStateProvider.state)
+ .state =
+ FeeRateType.custom;
}
widget.updateChosen("custom");
@@ -718,25 +716,24 @@ class _TransactionFeeSelectionSheetState
width: 20,
height: 20,
child: Radio(
- activeColor:
- Theme.of(context)
- .extension<StackColors>()!
- .radioButtonIconEnabled,
+ activeColor: Theme.of(context)
+ .extension<StackColors>()!
+ .radioButtonIconEnabled,
value: FeeRateType.custom,
- groupValue:
- ref
- .watch(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state,
+ groupValue: ref
+ .watch(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state,
onChanged: (x) {
ref
- .read(
- feeRateTypeMobileStateProvider
- .state,
- )
- .state = FeeRateType.custom;
+ .read(
+ feeRateTypeMobileStateProvider
+ .state,
+ )
+ .state =
+ FeeRateType.custom;
Navigator.of(context).pop();
},
),
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/edit_refresh_height_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/edit_refresh_height_view.dart
index f1d0aa5..47ce7d2 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/edit_refresh_height_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/edit_refresh_height_view.dart
@@ -5,12 +5,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../notifications/show_flush_bar.dart';
import '../../../../providers/db/main_db_provider.dart';
-import '../../../../providers/global/wallets_provider.dart';
import '../../../../themes/stack_colors.dart';
import '../../../../utilities/constants.dart';
import '../../../../utilities/text_styles.dart';
import '../../../../utilities/util.dart';
-import '../../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
+import '../../../../wallets/isar/providers/wallet_info_provider.dart';
import '../../../../widgets/background.dart';
import '../../../../widgets/conditional_parent.dart';
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
@@ -20,6 +19,7 @@ import '../../../../widgets/desktop/primary_button.dart';
import '../../../../widgets/icon_widgets/x_icon.dart';
import '../../../../widgets/stack_text_field.dart';
import '../../../../widgets/textfield_icon_button.dart';
+import '../../../../wl_gen/interfaces/cs_monero_interface.dart';
class EditRefreshHeightView extends ConsumerStatefulWidget {
const EditRefreshHeightView({super.key, required this.walletId});
@@ -34,7 +34,6 @@ class EditRefreshHeightView extends ConsumerStatefulWidget {
}
class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
- late final LibMoneroWallet _wallet;
late final TextEditingController _controller;
final _focusNode = FocusNode();
@@ -48,11 +47,13 @@ class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
try {
final newHeight = int.tryParse(_controller.text);
if (newHeight != null && newHeight >= 0) {
- await _wallet.info.updateRestoreHeight(
- newRestoreHeight: newHeight,
- isar: ref.read(mainDBProvider).isar,
- );
- _wallet.libMoneroWallet!.setRefreshFromBlockHeight(newHeight);
+ await ref
+ .read(pWalletInfo(widget.walletId))
+ .updateRestoreHeight(
+ newRestoreHeight: newHeight,
+ isar: ref.read(mainDBProvider).isar,
+ );
+ csMonero.setRefreshFromBlockHeight(widget.walletId, newHeight);
} else {
errMessage = "Invalid height: ${_controller.text}";
}
@@ -88,11 +89,8 @@ class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
@override
void initState() {
super.initState();
- _wallet = ref.read(pWallets).getWallet(widget.walletId) as LibMoneroWallet;
- _controller =
- TextEditingController()
- ..text =
- _wallet.libMoneroWallet!.getRefreshFromBlockHeight().toString();
+ _controller = TextEditingController()
+ ..text = csMonero.getRefreshFromBlockHeight(widget.walletId).toString();
}
@override
@@ -118,8 +116,10 @@ class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
mainAxisAlignment: MainAxisAlignment.end,
children: [
DesktopDialogCloseButton(
- onPressedOverride:
- Navigator.of(context, rootNavigator: true).pop,
+ onPressedOverride: Navigator.of(
+ context,
+ rootNavigator: true,
+ ).pop,
),
],
),
@@ -137,8 +137,9 @@ class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
builder: (child) {
return Background(
child: Scaffold(
- backgroundColor:
- Theme.of(context).extension<StackColors>()!.background,
+ backgroundColor: Theme.of(
+ context,
+ ).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
@@ -167,51 +168,47 @@ class _EditRefreshHeightViewState extends ConsumerState<EditRefreshHeightView> {
key: const Key("restoreHeightFieldKey"),
controller: _controller,
focusNode: _focusNode,
- style:
- Util.isDesktop
- ? STextStyles.desktopTextMedium(
- context,
- ).copyWith(height: 2)
- : STextStyles.field(context),
+ style: Util.isDesktop
+ ? STextStyles.desktopTextMedium(context).copyWith(height: 2)
+ : STextStyles.field(context),
enableSuggestions: false,
autocorrect: false,
autofocus: true,
onSubmitted: (_) => _save(),
onChanged: (_) => setState(() {}),
- decoration: standardInputDecoration(
- "Restore height",
- _focusNode,
- context,
- ).copyWith(
- suffixIcon:
- _controller.text.isNotEmpty
+ decoration:
+ standardInputDecoration(
+ "Restore height",
+ _focusNode,
+ context,
+ ).copyWith(
+ suffixIcon: _controller.text.isNotEmpty
? Padding(
- padding: const EdgeInsets.only(right: 0),
- child: UnconstrainedBox(
- child: ConditionalParent(
- condition: Util.isDesktop,
- builder:
- (child) =>
- SizedBox(height: 70, child: child),
- child: Row(
- children: [
- TextFieldIconButton(
- child: const XIcon(),
- onTap: () async {
- setState(() {
- _controller.text = "";
- });
- },
- ),
- ],
+ padding: const EdgeInsets.only(right: 0),
+ child: UnconstrainedBox(
+ child: ConditionalParent(
+ condition: Util.isDesktop,
+ builder: (child) =>
+ SizedBox(height: 70, child: child),
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ _controller.text = "";
+ });
+ },
+ ),
+ ],
+ ),
),
),
- ),
- )
+ )
: Util.isDesktop
? const SizedBox(height: 70)
: null,
- ),
+ ),
),
),
Util.isDesktop ? const SizedBox(height: 32) : const Spacer(),
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send_fee_form.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send_fee_form.dart
index 69757ac..462262d 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send_fee_form.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send_fee_form.dart
@@ -1,4 +1,3 @@
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -22,6 +21,7 @@ import '../../../../widgets/custom_buttons/blue_text_button.dart';
import '../../../../widgets/desktop/desktop_fee_dialog.dart';
import '../../../../widgets/eth_fee_form.dart';
import '../../../../widgets/fee_slider.dart';
+import '../../../../wl_gen/interfaces/cs_monero_interface.dart';
class DesktopSendFeeForm extends ConsumerStatefulWidget {
const DesktopSendFeeForm({
@@ -86,47 +86,44 @@ class _DesktopSendFeeFormState extends ConsumerState<DesktopSendFeeForm> {
children: [
ConditionalParent(
condition: canEditFees,
- builder:
- (child) => Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- child,
- CustomTextButton(
- text: "Edit",
- onTap: () async {
- feeSelectionResult =
- await showDialog<(FeeRateType, String?, String?)?>(
- context: context,
- builder:
- (_) => DesktopFeeDialog(
- walletId: widget.walletId,
- isToken: widget.isToken,
- ),
- );
+ builder: (child) => Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ child,
+ CustomTextButton(
+ text: "Edit",
+ onTap: () async {
+ feeSelectionResult =
+ await showDialog<(FeeRateType, String?, String?)?>(
+ context: context,
+ builder: (_) => DesktopFeeDialog(
+ walletId: widget.walletId,
+ isToken: widget.isToken,
+ ),
+ );
- if (feeSelectionResult != null) {
- if (_isCustomFee &&
- feeSelectionResult!.$1 != FeeRateType.custom) {
- _isCustomFee = false;
- } else if (!_isCustomFee &&
- feeSelectionResult!.$1 == FeeRateType.custom) {
- _isCustomFee = true;
- }
- }
+ if (feeSelectionResult != null) {
+ if (_isCustomFee &&
+ feeSelectionResult!.$1 != FeeRateType.custom) {
+ _isCustomFee = false;
+ } else if (!_isCustomFee &&
+ feeSelectionResult!.$1 == FeeRateType.custom) {
+ _isCustomFee = true;
+ }
+ }
- setState(() {});
- },
- ),
- ],
+ setState(() {});
+ },
),
+ ],
+ ),
child: Text(
"Transaction fee"
"${_isCustomFee ? "" : " (${isEth ? "max" : "estimated"})"}",
style: STextStyles.desktopTextExtraSmall(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldActiveSearchIconRight,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldActiveSearchIconRight,
),
textAlign: TextAlign.left,
),
@@ -135,162 +132,155 @@ class _DesktopSendFeeFormState extends ConsumerState<DesktopSendFeeForm> {
if (!_isCustomFee)
Padding(
padding: const EdgeInsets.all(10),
- child:
- (feeSelectionResult?.$2 == null)
- ? FutureBuilder(
- future: ref.watch(
- pWallets.select(
- (value) => value.getWallet(widget.walletId).fees,
- ),
+ child: (feeSelectionResult?.$2 == null)
+ ? FutureBuilder(
+ future: ref.watch(
+ pWallets.select(
+ (value) => value.getWallet(widget.walletId).fees,
),
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.done &&
- snapshot.hasData) {
- return DesktopFeeItem(
- feeObject: snapshot.data,
- feeRateType: FeeRateType.average,
- walletId: widget.walletId,
- isButton: false,
- feeFor: ({
- required Amount amount,
- required FeeRateType feeRateType,
- required BigInt feeRate,
- required CryptoCurrency coin,
- }) async {
- if (ref
- .read(
- widget.isToken
- ? tokenFeeSessionCacheProvider
- : feeSheetSessionCacheProvider,
- )
- .average[amount] ==
- null) {
- if (widget.isToken == false) {
- final wallet = ref
- .read(pWallets)
- .getWallet(widget.walletId);
+ ),
+ builder: (context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.done &&
+ snapshot.hasData) {
+ return DesktopFeeItem(
+ feeObject: snapshot.data,
+ feeRateType: FeeRateType.average,
+ walletId: widget.walletId,
+ isButton: false,
+ feeFor:
+ ({
+ required Amount amount,
+ required FeeRateType feeRateType,
+ required BigInt feeRate,
+ required CryptoCurrency coin,
+ }) async {
+ if (ref
+ .read(
+ widget.isToken
+ ? tokenFeeSessionCacheProvider
+ : feeSheetSessionCacheProvider,
+ )
+ .average[amount] ==
+ null) {
+ if (widget.isToken == false) {
+ final wallet = ref
+ .read(pWallets)
+ .getWallet(widget.walletId);
- if (coin is Monero || coin is Wownero) {
- final fee = await wallet.estimateFeeFor(
- amount,
- BigInt.from(
- lib_monero
- .TransactionPriority
- .medium
- .value,
- ),
- );
- ref
- .read(feeSheetSessionCacheProvider)
- .average[amount] =
- fee;
- } else if ((coin is Firo) &&
+ if (coin is Monero || coin is Wownero) {
+ final fee = await wallet.estimateFeeFor(
+ amount,
+ BigInt.from(
+ csMonero.getTxPriorityMedium(),
+ ),
+ );
ref
+ .read(
+ feeSheetSessionCacheProvider,
+ )
+ .average[amount] =
+ fee;
+ } else if ((coin is Firo) &&
+ ref
+ .read(
+ publicPrivateBalanceStateProvider
+ .state,
+ )
+ .state !=
+ BalanceType.public) {
+ final firoWallet = wallet as FiroWallet;
+
+ if (ref
.read(
publicPrivateBalanceStateProvider
.state,
)
- .state !=
- BalanceType.public) {
- final firoWallet = wallet as FiroWallet;
-
- if (ref
- .read(
- publicPrivateBalanceStateProvider
- .state,
- )
- .state ==
- BalanceType.private) {
+ .state ==
+ BalanceType.private) {
+ ref
+ .read(feeSheetSessionCacheProvider)
+ .average[amount] = await firoWallet
+ .estimateFeeForSpark(amount);
+ }
+ } else {
ref
.read(feeSheetSessionCacheProvider)
- .average[amount] = await firoWallet
- .estimateFeeForSpark(amount);
+ .average[amount] = await wallet
+ .estimateFeeFor(amount, feeRate);
}
} else {
- ref
- .read(feeSheetSessionCacheProvider)
- .average[amount] = await wallet
+ final tokenWallet = ref.read(
+ pCurrentTokenWallet,
+ )!;
+ final fee = await tokenWallet
.estimateFeeFor(amount, feeRate);
+ ref
+ .read(tokenFeeSessionCacheProvider)
+ .average[amount] =
+ fee;
}
- } else {
- final tokenWallet =
- ref.read(pCurrentTokenWallet)!;
- final fee = await tokenWallet.estimateFeeFor(
- amount,
- feeRate,
- );
- ref
- .read(tokenFeeSessionCacheProvider)
- .average[amount] =
- fee;
}
- }
- return ref
- .read(
- widget.isToken
- ? tokenFeeSessionCacheProvider
- : feeSheetSessionCacheProvider,
- )
- .average[amount]!;
- },
- isSelected: true,
- );
- } else {
- return Row(
- children: [
- AnimatedText(
- stringsToLoopThrough: stringsToLoopThrough,
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(context)
- .extension<StackColors>()!
- .textFieldActiveText,
- ),
- ),
- ],
- );
- }
- },
- )
- : Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- feeSelectionResult?.$2 ?? "",
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldActiveText,
- ),
- textAlign: TextAlign.left,
- ),
- Text(
- feeSelectionResult?.$3 ?? "",
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(context)
- .extension<StackColors>()!
- .textFieldActiveSearchIconRight,
- ),
- ),
- ],
- ),
+ return ref
+ .read(
+ widget.isToken
+ ? tokenFeeSessionCacheProvider
+ : feeSheetSessionCacheProvider,
+ )
+ .average[amount]!;
+ },
+ isSelected: true,
+ );
+ } else {
+ return Row(
+ children: [
+ AnimatedText(
+ stringsToLoopThrough: stringsToLoopThrough,
+ style:
+ STextStyles.desktopTextExtraExtraSmall(
+ context,
+ ).copyWith(
+ color: Theme.of(context)
+ .extension<StackColors>()!
+ .textFieldActiveText,
+ ),
+ ),
+ ],
+ );
+ }
+ },
+ )
+ : Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ feeSelectionResult?.$2 ?? "",
+ style: STextStyles.desktopTextExtraExtraSmall(context)
+ .copyWith(
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldActiveText,
+ ),
+ textAlign: TextAlign.left,
+ ),
+ Text(
+ feeSelectionResult?.$3 ?? "",
+ style: STextStyles.desktopTextExtraExtraSmall(context)
+ .copyWith(
+ color: Theme.of(context)
+ .extension<StackColors>()!
+ .textFieldActiveSearchIconRight,
+ ),
+ ),
+ ],
+ ),
),
if (_isCustomFee && isEth)
EthFeeForm(
- minGasLimit:
- widget.isToken
- ? kEthereumTokenMinGasLimit
- : kEthereumMinGasLimit,
- stateChanged:
- (value) => widget.onCustomEip1559FeeOptionChanged?.call(value),
+ minGasLimit: widget.isToken
+ ? kEthereumTokenMinGasLimit
+ : kEthereumMinGasLimit,
+ stateChanged: (value) =>
+ widget.onCustomEip1559FeeOptionChanged?.call(value),
),
if (_isCustomFee && !isEth)
Padding(
diff --git a/lib/services/churning_service.dart b/lib/services/churning_service.dart
index 0aecefe..1e18850 100644
--- a/lib/services/churning_service.dart
+++ b/lib/services/churning_service.dart
@@ -1,18 +1,14 @@
import 'dart:async';
import 'dart:math';
-import 'package:cs_monero/cs_monero.dart';
import 'package:flutter/cupertino.dart';
import 'package:mutex/mutex.dart';
+import '../utilities/logger.dart';
import '../wallets/wallet/intermediate/lib_monero_wallet.dart';
+import '../wl_gen/interfaces/cs_monero_interface.dart';
-enum ChurnStatus {
- waiting,
- running,
- failed,
- success;
-}
+enum ChurnStatus { waiting, running, failed, success }
class ChurningService extends ChangeNotifier {
// stack only uses account 0 at this point in time
@@ -21,7 +17,7 @@ class ChurningService extends ChangeNotifier {
ChurningService({required this.wallet});
final LibMoneroWallet wallet;
- Wallet get csWallet => wallet.libMoneroWallet!;
+ String get walletId => wallet.walletId;
int rounds = 1; // default
bool ignoreErrors = false; // default
@@ -36,7 +32,9 @@ class ChurningService extends ChangeNotifier {
Object? lastSeenError;
bool _canChurn() {
- if (csWallet.getUnlockedBalance(accountIndex: kAccount) > BigInt.zero) {
+ if (csMonero.walletInstanceExists(walletId) &&
+ csMonero.getUnlockedBalance(walletId, accountIndex: kAccount)! >
+ BigInt.zero) {
return true;
} else {
return false;
@@ -50,7 +48,7 @@ class ChurningService extends ChangeNotifier {
return;
}
- final outputs = await csWallet.getOutputs(refresh: true);
+ final outputs = await csMonero.getOutputs(walletId, refresh: true);
final required = wallet.cryptoCurrency.minConfirms;
int lowestNumberOfConfirms = required;
@@ -127,14 +125,14 @@ class ChurningService extends ChangeNotifier {
try {
_stopConfirmsTimer();
- Logging.log?.i("Doing churn #${roundsCompleted + 1}");
+ Logging.instance.i("Doing churn #${roundsCompleted + 1}");
await _churnTxSimple();
waitingForUnlockedBalance = ChurnStatus.success;
makingChurnTransaction = ChurnStatus.success;
roundsCompleted++;
notifyListeners();
} catch (e, s) {
- Logging.log?.e(
+ Logging.instance.e(
"Churning round #${roundsCompleted + 1} failed",
error: e,
stackTrace: s,
@@ -154,7 +152,7 @@ class ChurningService extends ChangeNotifier {
}
}
} else {
- Logging.log?.i("Can't churn yet, waiting...");
+ Logging.instance.i("Can't churn yet, waiting...");
}
if (!complete() && _running) {
@@ -174,7 +172,7 @@ class ChurningService extends ChangeNotifier {
done = true;
_running = false;
notifyListeners();
- Logging.log?.i("Churning complete");
+ Logging.instance.i("Churning complete");
}
void stopChurning() {
@@ -184,24 +182,28 @@ class ChurningService extends ChangeNotifier {
unpause();
}
- Future<void> _churnTxSimple({
- final TransactionPriority priority = TransactionPriority.normal,
- }) async {
- final address = csWallet.getAddress(
+ Future<void> _churnTxSimple() async {
+ final address = csMonero.getAddress(
+ walletId,
accountIndex: kAccount,
addressIndex: 0,
);
- final pending = await csWallet.createTx(
- output: Recipient(
- address: address.value,
- amount: BigInt.zero, // Doesn't matter if `sweep` is true
+ final height = await wallet.chainHeight;
+
+ final pending = await csMonero.createTx(
+ walletId,
+ output: CsRecipient(
+ address,
+ BigInt.zero, // Doesn't matter if `sweep` is true
),
- priority: priority,
+ priority: csMonero.getTxPriorityNormal(),
accountIndex: kAccount,
sweep: true,
+ minConfirms: wallet.cryptoCurrency.minConfirms,
+ currentHeight: height,
);
- await csWallet.commitTx(pending);
+ await csMonero.commitTx(walletId, pending);
}
}
diff --git a/lib/wallets/models/tx_data.dart b/lib/wallets/models/tx_data.dart
index 9a8dffd..8ebed1e 100644
--- a/lib/wallets/models/tx_data.dart
+++ b/lib/wallets/models/tx_data.dart
@@ -1,4 +1,3 @@
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:cs_salvium/cs_salvium.dart' as lib_salvium;
import 'package:tezart/tezart.dart' as tezart;
import 'package:web3dart/web3dart.dart' as web3dart;
@@ -10,6 +9,8 @@ import '../../models/paynym/paynym_account_lite.dart';
import '../../utilities/amount/amount.dart';
import '../../utilities/enums/fee_rate_type_enum.dart';
import '../../widgets/eth_fee_form.dart';
+import '../../wl_gen/interfaces/cs_monero_interface.dart'
+ show CsPendingTransaction;
import '../isar/models/spark_coin.dart';
import 'name_op_state.dart';
import 'tx_recipient.dart';
@@ -67,7 +68,7 @@ class TxData {
final int? nonce;
final BigInt? chainId;
// wownero and monero specific
- final lib_monero.PendingTransaction? pendingTransaction;
+ final CsPendingTransaction? pendingTransaction;
// salvium
final lib_salvium.PendingTransaction? pendingSalviumTransaction;
@@ -169,10 +170,10 @@ class TxData {
Amount? get amountSpark =>
sparkRecipients != null && sparkRecipients!.isNotEmpty
- ? sparkRecipients!
- .map((e) => e.amount)
- .reduce((total, amount) => total += amount)
- : null;
+ ? sparkRecipients!
+ .map((e) => e.amount)
+ .reduce((total, amount) => total += amount)
+ : null;
Amount? get amountWithoutChange {
if (recipients != null && recipients!.isNotEmpty) {
@@ -230,10 +231,9 @@ class TxData {
}
}
- int? get estimatedSatsPerVByte =>
- fee != null && vSize != null
- ? (fee!.raw ~/ BigInt.from(vSize!)).toInt()
- : null;
+ int? get estimatedSatsPerVByte => fee != null && vSize != null
+ ? (fee!.raw ~/ BigInt.from(vSize!)).toInt()
+ : null;
TxData copyWith({
FeeRateType? feeRateType,
@@ -259,7 +259,7 @@ class TxData {
web3dart.Transaction? web3dartTransaction,
int? nonce,
BigInt? chainId,
- lib_monero.PendingTransaction? pendingTransaction,
+ CsPendingTransaction? pendingTransaction,
lib_salvium.PendingTransaction? pendingSalviumTransaction,
int? jMintValue,
List<int>? spendCoinIndexes,
diff --git a/lib/wallets/wallet/impl/monero_wallet.dart b/lib/wallets/wallet/impl/monero_wallet.dart
index 03bbfd5..e250192 100644
--- a/lib/wallets/wallet/impl/monero_wallet.dart
+++ b/lib/wallets/wallet/impl/monero_wallet.dart
@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:compat/compat.dart' as lib_monero_compat;
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import '../../../utilities/amount/amount.dart';
+import '../../../wl_gen/interfaces/cs_monero_interface.dart';
import '../../crypto_currency/crypto_currency.dart';
import '../intermediate/lib_monero_wallet.dart';
@@ -13,36 +13,17 @@ class MoneroWallet extends LibMoneroWallet {
@override
Future<Amount> estimateFeeFor(Amount amount, BigInt feeRate) async {
- if (libMoneroWallet == null ||
+ if (!csMonero.walletInstanceExists(walletId) ||
syncStatus is! lib_monero_compat.SyncedSyncStatus) {
return Amount.zeroWith(fractionDigits: cryptoCurrency.fractionDigits);
}
- lib_monero.TransactionPriority priority;
- switch (feeRate.toInt()) {
- case 1:
- priority = lib_monero.TransactionPriority.low;
- break;
- case 2:
- priority = lib_monero.TransactionPriority.medium;
- break;
- case 3:
- priority = lib_monero.TransactionPriority.high;
- break;
- case 4:
- priority = lib_monero.TransactionPriority.last;
- break;
- case 0:
- default:
- priority = lib_monero.TransactionPriority.normal;
- break;
- }
-
int approximateFee = 0;
await estimateFeeMutex.protect(() async {
- approximateFee = await libMoneroWallet!.estimateFee(
- priority,
- amount.raw.toInt(),
+ approximateFee = await csMonero.estimateFee(
+ feeRate.toInt(),
+ amount.raw,
+ walletId: walletId,
);
});
@@ -53,76 +34,67 @@ class MoneroWallet extends LibMoneroWallet {
}
@override
- bool walletExists(String path) => lib_monero.MoneroWallet.isWalletExist(path);
+ bool walletExists(String path) =>
+ csMonero.walletExists(path, csCoin: CsCoin.monero);
@override
- Future<void> loadWallet({
- required String path,
- required String password,
- }) async {
- libMoneroWallet = await lib_monero.MoneroWallet.loadWallet(
- path: path,
- password: password,
- );
- }
+ Future<void> loadWallet({required String path, required String password}) =>
+ csMonero.loadWallet(
+ walletId,
+ path: path,
+ password: password,
+ csCoin: CsCoin.monero,
+ );
@override
- Future<lib_monero.Wallet> getCreatedWallet({
+ Future<void> getCreatedWallet({
required String path,
required String password,
required int wordCount,
required String seedOffset,
- }) async {
- final lib_monero.MoneroSeedType type;
- switch (wordCount) {
- case 16:
- type = lib_monero.MoneroSeedType.sixteen;
- break;
-
- case 25:
- type = lib_monero.MoneroSeedType.twentyFive;
- break;
-
- default:
- throw Exception("Invalid mnemonic word count: $wordCount");
- }
-
- return await lib_monero.MoneroWallet.create(
- path: path,
- password: password,
- seedType: type,
- seedOffset: seedOffset,
- );
- }
+ required final void Function(int refreshFromBlockHeight, String seed)
+ onCreated,
+ }) => csMonero.getCreatedWallet(
+ csCoin: CsCoin.monero,
+ path: path,
+ password: password,
+ wordCount: wordCount,
+ seedOffset: seedOffset,
+ onCreated: onCreated,
+ );
@override
- Future<lib_monero.Wallet> getRestoredWallet({
+ Future<void> getRestoredWallet({
required String path,
required String password,
required String mnemonic,
required String seedOffset,
int height = 0,
- }) async => await lib_monero.MoneroWallet.restoreWalletFromSeed(
+ }) => csMonero.getRestoredWallet(
path: path,
password: password,
- seed: mnemonic,
- restoreHeight: height,
+ mnemonic: mnemonic,
+ height: height,
seedOffset: seedOffset,
+ csCoin: CsCoin.monero,
+ walletId: walletId,
);
@override
- Future<lib_monero.Wallet> getRestoredFromViewKeyWallet({
+ Future<void> getRestoredFromViewKeyWallet({
required String path,
required String password,
required String address,
required String privateViewKey,
int height = 0,
- }) async => lib_monero.MoneroWallet.createViewOnlyWallet(
+ }) => csMonero.getRestoredFromViewKeyWallet(
+ walletId: walletId,
+ csCoin: CsCoin.monero,
path: path,
password: password,
address: address,
- viewKey: privateViewKey,
- restoreHeight: height,
+ privateViewKey: privateViewKey,
+ height: height,
);
@override
diff --git a/lib/wallets/wallet/impl/wownero_wallet.dart b/lib/wallets/wallet/impl/wownero_wallet.dart
index a8d5e1c..5605971 100644
--- a/lib/wallets/wallet/impl/wownero_wallet.dart
+++ b/lib/wallets/wallet/impl/wownero_wallet.dart
@@ -1,11 +1,11 @@
import 'dart:async';
import 'package:compat/compat.dart' as lib_monero_compat;
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import '../../../models/isar/models/blockchain_data/address.dart';
import '../../../utilities/amount/amount.dart';
import '../../../utilities/enums/fee_rate_type_enum.dart';
+import '../../../wl_gen/interfaces/cs_monero_interface.dart';
import '../../crypto_currency/crypto_currency.dart';
import '../../models/tx_data.dart';
import '../intermediate/lib_monero_wallet.dart';
@@ -16,33 +16,27 @@ class WowneroWallet extends LibMoneroWallet {
@override
Future<Amount> estimateFeeFor(Amount amount, BigInt feeRate) async {
- if (libMoneroWallet == null ||
+ if (!csMonero.walletInstanceExists(walletId) ||
syncStatus is! lib_monero_compat.SyncedSyncStatus) {
return Amount.zeroWith(fractionDigits: cryptoCurrency.fractionDigits);
}
- lib_monero.TransactionPriority priority;
FeeRateType feeRateType = FeeRateType.slow;
switch (feeRate.toInt()) {
case 1:
- priority = lib_monero.TransactionPriority.low;
feeRateType = FeeRateType.average;
break;
case 2:
- priority = lib_monero.TransactionPriority.medium;
feeRateType = FeeRateType.average;
break;
case 3:
- priority = lib_monero.TransactionPriority.high;
feeRateType = FeeRateType.fast;
break;
case 4:
- priority = lib_monero.TransactionPriority.last;
feeRateType = FeeRateType.fast;
break;
case 0:
default:
- priority = lib_monero.TransactionPriority.normal;
feeRateType = FeeRateType.slow;
break;
}
@@ -71,9 +65,10 @@ class WowneroWallet extends LibMoneroWallet {
// unsure why this delay?
await Future<void>.delayed(const Duration(milliseconds: 500));
} catch (e) {
- approximateFee = libMoneroWallet!.estimateFee(
- priority,
- amount.raw.toInt(),
+ approximateFee = await csMonero.estimateFee(
+ feeRate.toInt(),
+ amount.raw,
+ walletId: walletId,
);
}
}
@@ -91,77 +86,66 @@ class WowneroWallet extends LibMoneroWallet {
@override
bool walletExists(String path) =>
- lib_monero.WowneroWallet.isWalletExist(path);
+ csMonero.walletExists(path, csCoin: CsCoin.wownero);
@override
- Future<void> loadWallet({
- required String path,
- required String password,
- }) async {
- libMoneroWallet = await lib_monero.WowneroWallet.loadWallet(
- path: path,
- password: password,
- );
- }
+ Future<void> loadWallet({required String path, required String password}) =>
+ csMonero.loadWallet(
+ walletId,
+ path: path,
+ password: password,
+ csCoin: CsCoin.wownero,
+ );
@override
- Future<lib_monero.Wallet> getCreatedWallet({
+ Future<void> getCreatedWallet({
required String path,
required String password,
required int wordCount,
required String seedOffset,
- }) async {
- final lib_monero.WowneroSeedType type;
- switch (wordCount) {
- case 16:
- type = lib_monero.WowneroSeedType.sixteen;
- break;
-
- case 25:
- type = lib_monero.WowneroSeedType.twentyFive;
- break;
-
- default:
- throw Exception("Invalid mnemonic word count: $wordCount");
- }
-
- return await lib_monero.WowneroWallet.create(
- path: path,
- password: password,
- seedType: type,
- overrideDeprecated14WordSeedException: true,
- seedOffset: seedOffset,
- );
- }
+ required final void Function(int refreshFromBlockHeight, String seed)
+ onCreated,
+ }) => csMonero.getCreatedWallet(
+ csCoin: CsCoin.wownero,
+ path: path,
+ password: password,
+ wordCount: wordCount,
+ seedOffset: seedOffset,
+ onCreated: onCreated,
+ );
@override
- Future<lib_monero.Wallet> getRestoredWallet({
+ Future<void> getRestoredWallet({
required String path,
required String password,
required String mnemonic,
required String seedOffset,
int height = 0,
- }) async => await lib_monero.WowneroWallet.restoreWalletFromSeed(
+ }) => csMonero.getRestoredWallet(
path: path,
password: password,
- seed: mnemonic,
- restoreHeight: height,
+ mnemonic: mnemonic,
+ height: height,
seedOffset: seedOffset,
+ csCoin: CsCoin.wownero,
+ walletId: walletId,
);
@override
- Future<lib_monero.Wallet> getRestoredFromViewKeyWallet({
+ Future<void> getRestoredFromViewKeyWallet({
required String path,
required String password,
required String address,
required String privateViewKey,
int height = 0,
- }) async => lib_monero.WowneroWallet.createViewOnlyWallet(
+ }) => csMonero.getRestoredFromViewKeyWallet(
+ walletId: walletId,
+ csCoin: CsCoin.wownero,
path: path,
password: password,
address: address,
- viewKey: privateViewKey,
- restoreHeight: height,
+ privateViewKey: privateViewKey,
+ height: height,
);
@override
diff --git a/lib/wallets/wallet/intermediate/lib_monero_wallet.dart b/lib/wallets/wallet/intermediate/lib_monero_wallet.dart
index a25b236..943de13 100644
--- a/lib/wallets/wallet/intermediate/lib_monero_wallet.dart
+++ b/lib/wallets/wallet/intermediate/lib_monero_wallet.dart
@@ -4,7 +4,6 @@ import 'dart:io';
import 'dart:math';
import 'package:compat/compat.dart' as lib_monero_compat;
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:isar_community/isar.dart';
import 'package:mutex/mutex.dart';
import 'package:stack_wallet_backup/generate_password.dart';
@@ -34,6 +33,7 @@ import '../../../utilities/amount/amount.dart';
import '../../../utilities/enums/fee_rate_type_enum.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/stack_file_system.dart';
+import '../../../wl_gen/interfaces/cs_monero_interface.dart';
import '../../crypto_currency/intermediate/cryptonote_currency.dart';
import '../../isar/models/wallet_info.dart';
import '../../models/tx_data.dart';
@@ -99,14 +99,13 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
await onUTXOsChanged(utxos);
await updateBalance(shouldUpdateUtxos: false);
} catch (e, s) {
- lib_monero.Logging.log?.i("_startInit", error: e, stackTrace: s);
+ Logging.instance.e("_startInit", error: e, stackTrace: s);
}
});
});
}
final lib_monero_compat.WalletType compatType;
- lib_monero.Wallet? libMoneroWallet;
lib_monero_compat.SyncStatus? get syncStatus => _syncStatus;
lib_monero_compat.SyncStatus? _syncStatus;
@@ -137,14 +136,16 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Future<void> loadWallet({required String path, required String password});
- Future<lib_monero.Wallet> getCreatedWallet({
+ Future<void> getCreatedWallet({
required String path,
required String password,
required int wordCount,
required String seedOffset,
+ required final void Function(int refreshFromBlockHeight, String seed)
+ onCreated,
});
- Future<lib_monero.Wallet> getRestoredWallet({
+ Future<void> getRestoredWallet({
required String path,
required String password,
required String mnemonic,
@@ -152,7 +153,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
int height = 0,
});
- Future<lib_monero.Wallet> getRestoredFromViewKeyWallet({
+ Future<void> getRestoredFromViewKeyWallet({
required String path,
required String password,
required String address,
@@ -165,16 +166,18 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
bool walletExists(String path);
String getTxKeyFor({required String txid}) {
- if (libMoneroWallet == null) {
+ if (!csMonero.walletInstanceExists(walletId)) {
throw Exception("Cannot get tx key in uninitialized libMoneroWallet");
}
- return libMoneroWallet!.getTxKey(txid);
+ return csMonero.getTxKey(walletId, txid);
}
void _setListener() {
- if (libMoneroWallet != null && libMoneroWallet!.getListeners().isEmpty) {
- libMoneroWallet?.addListener(
- lib_monero.WalletListener(
+ if (csMonero.walletInstanceExists(walletId) &&
+ !csMonero.hasListeners(walletId)) {
+ csMonero.addListener(
+ walletId,
+ CsMoneroWalletListener(
onSyncingUpdate: onSyncingUpdate,
onNewBlock: onNewBlock,
onBalancesChanged: onBalancesChanged,
@@ -190,17 +193,16 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Future<void> open() async {
bool wasNull = false;
- if (libMoneroWallet == null) {
+ if (!csMonero.walletInstanceExists(walletId)) {
wasNull = true;
// libMoneroWalletT?.close();
final path = await pathForWallet(name: walletId, type: compatType);
final String password;
try {
- password =
- (await secureStorageInterface.read(
- key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
- ))!;
+ password = (await secureStorageInterface.read(
+ key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
+ ))!;
} catch (e, s) {
throw Exception("Password not found $e, $s");
}
@@ -227,15 +229,15 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
if (wasNull) {
try {
_setSyncStatus(lib_monero_compat.ConnectingSyncStatus());
- libMoneroWallet?.startSyncing();
+ csMonero.startSyncing(walletId);
} catch (_) {
_setSyncStatus(lib_monero_compat.FailedSyncStatus());
// TODO log
}
}
_setListener();
- libMoneroWallet?.startListeners();
- libMoneroWallet?.startAutoSaving();
+ csMonero.startListeners(walletId);
+ csMonero.startAutoSaving(walletId);
unawaited(refresh());
}
@@ -260,16 +262,17 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
appRoot: appRoot,
);
}
- await libMoneroWallet!.save();
+ await csMonero.save(walletId);
}
Address addressFor({required int index, int account = 0}) {
- final address = libMoneroWallet!.getAddress(
+ final address = csMonero.getAddress(
+ walletId,
accountIndex: account,
addressIndex: index,
);
- if (address.value.contains("111")) {
+ if (address.contains("111")) {
throw Exception("111 address found!");
}
@@ -277,7 +280,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
walletId: walletId,
derivationIndex: index,
derivationPath: null,
- value: address.value,
+ value: address,
publicKey: [],
type: AddressType.cryptonote,
subType: AddressSubType.receiving,
@@ -287,19 +290,18 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
}
Future<CWKeyData?> getKeys() async {
- final base = libMoneroWallet;
-
final oldInfo = getLibMoneroWalletInfo(walletId);
- if (base == null || (oldInfo != null && oldInfo.name != walletId)) {
+ if (!csMonero.walletInstanceExists(walletId) ||
+ (oldInfo != null && oldInfo.name != walletId)) {
return null;
}
try {
return CWKeyData(
walletId: walletId,
- publicViewKey: base.getPublicViewKey(),
- privateViewKey: base.getPrivateViewKey(),
- publicSpendKey: base.getPublicSpendKey(),
- privateSpendKey: base.getPrivateSpendKey(),
+ publicViewKey: csMonero.getPublicViewKey(walletId),
+ privateViewKey: csMonero.getPrivateViewKey(walletId),
+ publicSpendKey: csMonero.getPublicSpendKey(walletId),
+ privateSpendKey: csMonero.getPrivateSpendKey(walletId),
);
} catch (e, s) {
Logging.instance.f("getKeys failed: ", error: e, stackTrace: s);
@@ -318,16 +320,17 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
final path = await pathForWallet(name: walletId, type: compatType);
final String password;
try {
- password =
- (await secureStorageInterface.read(
- key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
- ))!;
+ password = (await secureStorageInterface.read(
+ key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
+ ))!;
} catch (e, s) {
throw Exception("Password not found $e, $s");
}
await loadWallet(path: path, password: password);
- final wallet = libMoneroWallet!;
- return (wallet.getAddress().value, wallet.getPrivateViewKey());
+ return (
+ csMonero.getAddress(walletId),
+ csMonero.getPrivateViewKey(walletId),
+ );
}
@override
@@ -343,17 +346,23 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
value: password,
);
- final wallet = await getCreatedWallet(
+
+ late final int refreshFromBlockHeight;
+ late final String seedPhrase;
+
+ await getCreatedWallet(
path: path,
password: password,
wordCount: wordCount,
seedOffset: "", // default for non restored wallets for now
+ onCreated: (height, seed) {
+ refreshFromBlockHeight = height;
+ seedPhrase = seed;
+ },
);
- final height = wallet.getRefreshFromBlockHeight();
-
await info.updateRestoreHeight(
- newRestoreHeight: height,
+ newRestoreHeight: refreshFromBlockHeight,
isar: mainDB.isar,
);
@@ -361,7 +370,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
// before wallet.init() is called
await secureStorageInterface.write(
key: Wallet.mnemonicKey(walletId: walletId),
- value: wallet.getSeed().trim(),
+ value: seedPhrase,
);
await secureStorageInterface.write(
key: Wallet.mnemonicPassphraseKey(walletId: walletId),
@@ -384,8 +393,8 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
await mainDB.deleteWalletBlockchainData(walletId);
highestPercentCached = 0;
- unawaited(libMoneroWallet?.rescanBlockchain());
- libMoneroWallet?.startSyncing();
+ unawaited(csMonero.rescanBlockchain(walletId));
+ csMonero.startSyncing(walletId);
// unawaited(save());
});
unawaited(refresh());
@@ -422,7 +431,12 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
value: password,
);
- final wallet = await getRestoredWallet(
+
+ if (!csMonero.walletInstanceExists(walletId)) {
+ await exit();
+ }
+
+ await getRestoredWallet(
path: path,
password: password,
mnemonic: mnemonic,
@@ -430,12 +444,6 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
seedOffset: seedOffset,
);
- if (libMoneroWallet != null) {
- await exit();
- }
-
- libMoneroWallet = wallet;
-
_setListener();
final newReceivingAddress =
@@ -444,7 +452,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
walletId: walletId,
derivationIndex: 0,
derivationPath: null,
- value: wallet.getAddress().value,
+ value: csMonero.getAddress(walletId),
publicKey: [],
type: AddressType.cryptonote,
subType: AddressSubType.receiving,
@@ -463,12 +471,12 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
_setListener();
// libMoneroWallet?.setRecoveringFromSeed(isRecovery: true);
- unawaited(libMoneroWallet?.rescanBlockchain());
- libMoneroWallet?.startSyncing();
+ unawaited(csMonero.rescanBlockchain(walletId));
+ csMonero.startSyncing(walletId);
// await save();
- libMoneroWallet?.startListeners();
- libMoneroWallet?.startAutoSaving();
+ csMonero.startListeners(walletId);
+ csMonero.startAutoSaving(walletId);
} catch (e, s) {
Logging.instance.e(
"Exception rethrown from recoverFromMnemonic(): ",
@@ -484,11 +492,11 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
bool _canPing = false;
@override
- Future<bool> pingCheck() async {
+ Future<bool> pingCheck() {
if (_canPing) {
- return (await libMoneroWallet?.isConnectedToDaemon()) ?? false;
+ return csMonero.isConnectedToDaemon(walletId);
} else {
- return false;
+ return Future.value(false);
}
}
@@ -500,50 +508,50 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
throw Exception("TOR – clearnet mismatch");
}
- final host =
- node.host.endsWith(".onion") ? node.host : Uri.parse(node.host).host;
+ final host = node.host.endsWith(".onion")
+ ? node.host
+ : Uri.parse(node.host).host;
({InternetAddress host, int port})? proxy;
- proxy =
- prefs.useTor && !node.forceNoTor
- ? TorService.sharedInstance.getProxyInfo()
- : null;
+ proxy = prefs.useTor && !node.forceNoTor
+ ? TorService.sharedInstance.getProxyInfo()
+ : null;
_setSyncStatus(lib_monero_compat.ConnectingSyncStatus());
try {
if (_requireMutex) {
await _torConnectingLock.protect(() async {
- await libMoneroWallet?.connect(
+ await csMonero.connect(
+ walletId,
daemonAddress: "$host:${node.port}",
daemonUsername: node.loginName,
daemonPassword: await node.getPassword(secureStorageInterface),
trusted: node.trusted ?? false,
useSSL: node.useSSL,
- socksProxyAddress:
- node.forceNoTor
- ? null
- : proxy == null
- ? null
- : "${proxy.host.address}:${proxy.port}",
+ socksProxyAddress: node.forceNoTor
+ ? null
+ : proxy == null
+ ? null
+ : "${proxy.host.address}:${proxy.port}",
);
});
} else {
- await libMoneroWallet?.connect(
+ await csMonero.connect(
+ walletId,
daemonAddress: "$host:${node.port}",
daemonUsername: node.loginName,
daemonPassword: await node.getPassword(secureStorageInterface),
trusted: node.trusted ?? false,
useSSL: node.useSSL,
- socksProxyAddress:
- node.forceNoTor
- ? null
- : proxy == null
- ? null
- : "${proxy.host.address}:${proxy.port}",
+ socksProxyAddress: node.forceNoTor
+ ? null
+ : proxy == null
+ ? null
+ : "${proxy.host.address}:${proxy.port}",
);
}
- libMoneroWallet?.startSyncing();
- libMoneroWallet?.startListeners();
- libMoneroWallet?.startAutoSaving();
+ csMonero.startSyncing(walletId);
+ csMonero.startListeners(walletId);
+ csMonero.startAutoSaving(walletId);
_setSyncStatus(lib_monero_compat.ConnectedSyncStatus());
} catch (e, s) {
@@ -560,22 +568,19 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
@override
Future<void> updateTransactions() async {
- final base = libMoneroWallet;
-
- if (base == null) {
+ if (!csMonero.walletInstanceExists(walletId)) {
return;
}
- final localTxids =
- await mainDB.isar.transactionV2s
- .where()
- .walletIdEqualTo(walletId)
- .filter()
- .heightGreaterThan(0)
- .txidProperty()
- .findAll();
+ final localTxids = await mainDB.isar.transactionV2s
+ .where()
+ .walletIdEqualTo(walletId)
+ .filter()
+ .heightGreaterThan(0)
+ .txidProperty()
+ .findAll();
- final allTxids = await base.getAllTxids(refresh: true);
+ final allTxids = await csMonero.getAllTxids(walletId, refresh: true);
final txidsToFetch = allTxids.toSet().difference(localTxids.toSet());
@@ -583,9 +588,17 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
return;
}
- final transactions = await base.getTxs(txids: txidsToFetch, refresh: false);
+ final transactions = await csMonero.getTxs(
+ walletId,
+ txids: txidsToFetch,
+ refresh: false,
+ );
- final allOutputs = await base.getOutputs(includeSpent: true, refresh: true);
+ final allOutputs = await csMonero.getOutputs(
+ walletId,
+ includeSpent: true,
+ refresh: true,
+ );
// final cachedTransactions =
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
@@ -671,16 +684,14 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
type: type,
subType: TransactionSubType.none,
otherData: jsonEncode({
- TxV2OdKeys.overrideFee:
- Amount(
- rawValue: tx.fee,
- fractionDigits: cryptoCurrency.fractionDigits,
- ).toJsonString(),
- TxV2OdKeys.moneroAmount:
- Amount(
- rawValue: tx.amount,
- fractionDigits: cryptoCurrency.fractionDigits,
- ).toJsonString(),
+ TxV2OdKeys.overrideFee: Amount(
+ rawValue: tx.fee,
+ fractionDigits: cryptoCurrency.fractionDigits,
+ ).toJsonString(),
+ TxV2OdKeys.moneroAmount: Amount(
+ rawValue: tx.amount,
+ fractionDigits: cryptoCurrency.fractionDigits,
+ ).toJsonString(),
TxV2OdKeys.moneroAccountIndex: tx.accountIndex,
TxV2OdKeys.isMoneroTransaction: true,
}),
@@ -695,7 +706,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Future<Amount> get availableBalance async {
try {
return Amount(
- rawValue: libMoneroWallet!.getUnlockedBalance(),
+ rawValue: csMonero.getUnlockedBalance(walletId)!,
fractionDigits: cryptoCurrency.fractionDigits,
);
} catch (_) {
@@ -705,14 +716,14 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Future<Amount> get totalBalance async {
try {
- final full = libMoneroWallet?.getBalance();
+ final full = csMonero.getBalance(walletId);
if (full != null) {
return Amount(
rawValue: full,
fractionDigits: cryptoCurrency.fractionDigits,
);
} else {
- final transactions = await libMoneroWallet!.getAllTxs(refresh: true);
+ final transactions = await csMonero.getAllTxs(walletId, refresh: true);
BigInt transactionBalance = BigInt.zero;
for (final tx in transactions) {
if (!tx.isSpend) {
@@ -735,10 +746,10 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
@override
Future<void> exit() async {
Logging.instance.i("exit called on $walletId");
- libMoneroWallet?.stopAutoSaving();
- libMoneroWallet?.stopListeners();
- libMoneroWallet?.stopSyncing();
- await libMoneroWallet?.save();
+ csMonero.stopAutoSaving(walletId);
+ csMonero.stopListeners(walletId);
+ csMonero.stopSyncing(walletId);
+ await csMonero.save(walletId);
}
Future<String> pathForWalletDir({
@@ -820,7 +831,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
final _utxosUpdateLock = Mutex();
Future<void> onUTXOsChanged(List<UTXO> utxos) async {
await _utxosUpdateLock.protect(() async {
- final cwUtxos = await libMoneroWallet?.getOutputs(refresh: true) ?? [];
+ final cwUtxos = await csMonero.getOutputs(walletId, refresh: true);
// bool changed = false;
@@ -837,12 +848,12 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
if (u.isBlocked) {
if (!cw.isFrozen) {
- await libMoneroWallet?.freezeOutput(cw.keyImage);
+ await csMonero.freezeOutput(walletId, cw.keyImage);
// changed = true;
}
} else {
if (cw.isFrozen) {
- await libMoneroWallet?.thawOutput(cw.keyImage);
+ await csMonero.thawOutput(walletId, cw.keyImage);
// changed = true;
}
}
@@ -999,9 +1010,9 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
if (mismatch) {
_canPing = false;
- libMoneroWallet?.stopAutoSaving();
- libMoneroWallet?.stopListeners();
- libMoneroWallet?.stopSyncing();
+ csMonero.stopAutoSaving(walletId);
+ csMonero.stopListeners(walletId);
+ csMonero.stopSyncing(walletId);
_setSyncStatus(lib_monero_compat.FailedSyncStatus());
}
@@ -1019,27 +1030,23 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
@override
Future<bool> updateUTXOs() async {
final List<UTXO> outputArray = [];
- final utxos =
- await libMoneroWallet?.getOutputs(refresh: true) ??
- <lib_monero.Output>[];
+ final utxos = await csMonero.getOutputs(walletId, refresh: true);
for (final rawUTXO in utxos) {
if (!rawUTXO.spent) {
- final current =
- await mainDB.isar.utxos
- .where()
- .walletIdEqualTo(walletId)
- .filter()
- .voutEqualTo(rawUTXO.vout)
- .and()
- .txidEqualTo(rawUTXO.hash)
- .findFirst();
- final tx =
- await mainDB.isar.transactionV2s
- .where()
- .walletIdEqualTo(walletId)
- .filter()
- .txidEqualTo(rawUTXO.hash)
- .findFirst();
+ final current = await mainDB.isar.utxos
+ .where()
+ .walletIdEqualTo(walletId)
+ .filter()
+ .voutEqualTo(rawUTXO.vout)
+ .and()
+ .txidEqualTo(rawUTXO.hash)
+ .findFirst();
+ final tx = await mainDB.isar.transactionV2s
+ .where()
+ .walletIdEqualTo(walletId)
+ .filter()
+ .txidEqualTo(rawUTXO.hash)
+ .findFirst();
final otherDataMap = {
UTXOOtherDataKeys.keyImage: rawUTXO.keyImage,
@@ -1112,7 +1119,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
// Slight possibility of race but should be irrelevant
await refreshMutex.acquire();
- libMoneroWallet?.startSyncing();
+ csMonero.startSyncing(walletId);
_setSyncStatus(lib_monero_compat.StartingSyncStatus());
await updateTransactions();
@@ -1126,9 +1133,9 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
refreshMutex.release();
}
- final synced = await libMoneroWallet?.isSynced();
+ final synced = await csMonero.isSynced(walletId);
- if (synced == true) {
+ if (synced) {
_setSyncStatus(lib_monero_compat.SyncedSyncStatus());
}
}
@@ -1138,8 +1145,9 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
try {
final currentReceiving = await getCurrentReceivingAddress();
- final newReceivingIndex =
- currentReceiving == null ? 0 : currentReceiving.derivationIndex + 1;
+ final newReceivingIndex = currentReceiving == null
+ ? 0
+ : currentReceiving.derivationIndex + 1;
final newReceivingAddress = addressFor(index: newReceivingIndex);
@@ -1174,17 +1182,14 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
try {
int highestIndex = -1;
- final entries = await libMoneroWallet?.getAllTxs(refresh: true);
- if (entries != null) {
- for (final element in entries) {
- if (!element.isSpend) {
- final int curAddressIndex =
- element.addressIndexes.isEmpty
- ? 0
- : element.addressIndexes.reduce(max);
- if (curAddressIndex > highestIndex) {
- highestIndex = curAddressIndex;
- }
+ final entries = await csMonero.getAllTxs(walletId, refresh: true);
+ for (final element in entries) {
+ if (!element.isSpend) {
+ final int curAddressIndex = element.addressIndexes.isEmpty
+ ? 0
+ : element.addressIndexes.reduce(max);
+ if (curAddressIndex > highestIndex) {
+ highestIndex = curAddressIndex;
}
}
}
@@ -1200,12 +1205,11 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
// Use new index to derive a new receiving address
final newReceivingAddress = addressFor(index: newReceivingIndex);
- final existing =
- await mainDB
- .getAddresses(walletId)
- .filter()
- .valueEqualTo(newReceivingAddress.value)
- .findFirst();
+ final existing = await mainDB
+ .getAddresses(walletId)
+ .filter()
+ .valueEqualTo(newReceivingAddress.value)
+ .findFirst();
if (existing == null) {
// Add that new change address
await mainDB.putAddress(newReceivingAddress);
@@ -1241,9 +1245,9 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
numberOfBlocksFast: 10,
numberOfBlocksAverage: 15,
numberOfBlocksSlow: 20,
- fast: BigInt.from(lib_monero.TransactionPriority.high.value),
- medium: BigInt.from(lib_monero.TransactionPriority.medium.value),
- slow: BigInt.from(lib_monero.TransactionPriority.normal.value),
+ fast: BigInt.from(csMonero.getTxPriorityHigh()),
+ medium: BigInt.from(csMonero.getTxPriorityMedium()),
+ slow: BigInt.from(csMonero.getTxPriorityNormal()),
);
@override
@@ -1269,16 +1273,16 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
try {
final feeRate = txData.feeRateType;
if (feeRate is FeeRateType) {
- lib_monero.TransactionPriority feePriority;
+ final int feePriority;
switch (feeRate) {
case FeeRateType.fast:
- feePriority = lib_monero.TransactionPriority.high;
+ feePriority = csMonero.getTxPriorityHigh();
break;
case FeeRateType.average:
- feePriority = lib_monero.TransactionPriority.medium;
+ feePriority = csMonero.getTxPriorityMedium();
break;
case FeeRateType.slow:
- feePriority = lib_monero.TransactionPriority.normal;
+ feePriority = csMonero.getTxPriorityNormal();
break;
default:
throw ArgumentError("Invalid use of custom fee");
@@ -1303,12 +1307,9 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
throw Exception("Send all not supported with multiple recipients");
}
- final List<lib_monero.Recipient> outputs = [];
+ final List<CsRecipient> outputs = [];
for (final recipient in txData.recipients!) {
- final output = lib_monero.Recipient(
- address: recipient.address,
- amount: recipient.amount.raw,
- );
+ final output = CsRecipient(recipient.address, recipient.amount.raw);
outputs.add(output);
}
@@ -1318,44 +1319,27 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
}
final height = await chainHeight;
- final inputs =
- txData.utxos
- ?.whereType<StandardInput>()
- .map(
- (e) => lib_monero.Output(
- address: e.address!,
- hash: e.utxo.txid,
- keyImage: e.utxo.keyImage!,
- value: e.value,
- isFrozen: e.utxo.isBlocked,
- isUnlocked:
- e.utxo.blockHeight != null &&
- (height - (e.utxo.blockHeight ?? 0)) >=
- cryptoCurrency.minConfirms,
- height: e.utxo.blockHeight ?? 0,
- vout: e.utxo.vout,
- spent: e.utxo.used ?? false,
- spentHeight: null, // doesn't matter here
- coinbase: e.utxo.isCoinbase,
- ),
- )
- .toList();
+ final inputs = txData.utxos?.whereType<StandardInput>().toList();
return await prepareSendMutex.protect(() async {
- final lib_monero.PendingTransaction pendingTransaction;
+ final CsPendingTransaction pendingTransaction;
if (outputs.length == 1) {
- pendingTransaction = await libMoneroWallet!.createTx(
+ pendingTransaction = await csMonero.createTx(
+ walletId,
+ minConfirms: cryptoCurrency.minConfirms,
+ currentHeight: height,
output: outputs.first,
- paymentId: "",
sweep: sweep,
priority: feePriority,
preferredInputs: inputs,
accountIndex: 0, // sw only uses account 0 at this time
);
} else {
- pendingTransaction = await libMoneroWallet!.createTxMultiDest(
+ pendingTransaction = await csMonero.createTxMultiDest(
+ walletId,
+ minConfirms: cryptoCurrency.minConfirms,
+ currentHeight: height,
outputs: outputs,
- paymentId: "",
priority: feePriority,
preferredInputs: inputs,
sweep: sweep,
@@ -1398,7 +1382,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Future<TxData> confirmSend({required TxData txData}) async {
try {
try {
- await libMoneroWallet!.commitTx(txData.pendingTransaction!);
+ await csMonero.commitTx(walletId, txData.pendingTransaction!);
Logging.instance.d(
"transaction ${txData.pendingTransaction!.txid} has been sent",
@@ -1447,7 +1431,11 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
key: lib_monero_compat.libMoneroWalletPasswordKey(walletId),
value: password,
);
- final wallet = await getRestoredFromViewKeyWallet(
+
+ if (csMonero.walletInstanceExists(walletId)) {
+ await exit();
+ }
+ await getRestoredFromViewKeyWallet(
path: path,
password: password,
address: data.address,
@@ -1455,12 +1443,6 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
height: height,
);
- if (libMoneroWallet != null) {
- await exit();
- }
-
- libMoneroWallet = wallet;
-
_setListener();
final newReceivingAddress =
@@ -1469,7 +1451,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
walletId: walletId,
derivationIndex: 0,
derivationPath: null,
- value: wallet.getAddress().value,
+ value: csMonero.getAddress(walletId),
publicKey: [],
type: AddressType.cryptonote,
subType: AddressSubType.receiving,
@@ -1484,12 +1466,12 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
await updateNode();
_setListener();
- unawaited(libMoneroWallet?.rescanBlockchain());
- libMoneroWallet?.startSyncing();
+ unawaited(csMonero.rescanBlockchain(walletId));
+ csMonero.startSyncing(walletId);
// await save();
- libMoneroWallet?.startListeners();
- libMoneroWallet?.startAutoSaving();
+ csMonero.startListeners(walletId);
+ csMonero.startAutoSaving(walletId);
} catch (e, s) {
Logging.instance.e(
"Exception rethrown from recoverViewOnly(): ",
diff --git a/lib/widgets/desktop/desktop_fee_dialog.dart b/lib/widgets/desktop/desktop_fee_dialog.dart
index 82cc82e..82f92a5 100644
--- a/lib/widgets/desktop/desktop_fee_dialog.dart
+++ b/lib/widgets/desktop/desktop_fee_dialog.dart
@@ -1,4 +1,3 @@
-import 'package:cs_monero/cs_monero.dart' as lib_monero;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -16,6 +15,7 @@ import '../../utilities/text_styles.dart';
import '../../wallets/crypto_currency/crypto_currency.dart';
import '../../wallets/isar/providers/eth/current_token_wallet_provider.dart';
import '../../wallets/wallet/impl/firo_wallet.dart';
+import '../../wl_gen/interfaces/cs_monero_interface.dart';
import '../animated_text.dart';
import '../conditional_parent.dart';
import 'desktop_dialog.dart';
@@ -63,7 +63,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.high.value),
+ BigInt.from(csMonero.getTxPriorityHigh()),
);
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
} else if (coin is Firo) {
@@ -113,7 +113,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.medium.value),
+ BigInt.from(csMonero.getTxPriorityMedium()),
);
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
} else if (coin is Firo) {
@@ -163,7 +163,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
if (coin is Monero || coin is Wownero) {
final fee = await wallet.estimateFeeFor(
amount,
- BigInt.from(lib_monero.TransactionPriority.normal.value),
+ BigInt.from(csMonero.getTxPriorityNormal()),
);
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
} else if (coin is Firo) {
@@ -335,18 +335,17 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
return ConditionalParent(
condition: widget.isButton,
- builder:
- (child) => MaterialButton(
- materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
- onPressed: () {
- ref.read(feeRateTypeDesktopStateProvider.state).state =
- widget.feeRateType;
- Navigator.of(
- context,
- ).pop((widget.feeRateType, feeString, timeString));
- },
- child: child,
- ),
+ builder: (child) => MaterialButton(
+ materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+ onPressed: () {
+ ref.read(feeRateTypeDesktopStateProvider.state).state =
+ widget.feeRateType;
+ Navigator.of(
+ context,
+ ).pop((widget.feeRateType, feeString, timeString));
+ },
+ child: child,
+ ),
child: Builder(
builder: (_) {
if (widget.feeRateType == FeeRateType.custom) {
@@ -355,14 +354,12 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
children: [
Text(
widget.feeRateType.prettyName,
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(
+ style: STextStyles.desktopTextExtraExtraSmall(context)
+ .copyWith(
+ color: Theme.of(
context,
).extension<StackColors>()!.textFieldActiveText,
- ),
+ ),
textAlign: TextAlign.left,
),
],
@@ -377,10 +374,9 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
return AnimatedText(
stringsToLoopThrough: stringsToLoopThrough,
style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
- color:
- Theme.of(
- context,
- ).extension<StackColors>()!.textFieldActiveText,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldActiveText,
),
);
} else {
@@ -388,12 +384,11 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
future: widget.feeFor(
coin: wallet.info.coin,
feeRateType: widget.feeRateType,
- feeRate:
- widget.feeRateType == FeeRateType.fast
- ? widget.feeObject!.fast
- : widget.feeRateType == FeeRateType.slow
- ? widget.feeObject!.slow
- : widget.feeObject!.medium,
+ feeRate: widget.feeRateType == FeeRateType.fast
+ ? widget.feeObject!.fast
+ : widget.feeRateType == FeeRateType.slow
+ ? widget.feeObject!.slow
+ : widget.feeObject!.medium,
amount: ref.watch(sendAmountProvider.state).state,
),
builder: (_, AsyncSnapshot<Amount> snapshot) {
@@ -403,58 +398,51 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
"${widget.feeRateType.prettyName} "
"(~${ref.watch(pAmountFormatter(wallet.info.coin)).format(snapshot.data!, indicatePrecisionLoss: false)})";
- timeString =
- wallet.info.coin is Ethereum
- ? ""
- : estimatedTimeToBeIncludedInNextBlock(
- wallet.info.coin.targetBlockTimeSeconds,
- widget.feeRateType == FeeRateType.fast
- ? widget.feeObject!.numberOfBlocksFast
- : widget.feeRateType == FeeRateType.slow
- ? widget.feeObject!.numberOfBlocksSlow
- : widget.feeObject!.numberOfBlocksAverage,
- );
+ timeString = wallet.info.coin is Ethereum
+ ? ""
+ : estimatedTimeToBeIncludedInNextBlock(
+ wallet.info.coin.targetBlockTimeSeconds,
+ widget.feeRateType == FeeRateType.fast
+ ? widget.feeObject!.numberOfBlocksFast
+ : widget.feeRateType == FeeRateType.slow
+ ? widget.feeObject!.numberOfBlocksSlow
+ : widget.feeObject!.numberOfBlocksAverage,
+ );
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
feeString!,
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(
+ style: STextStyles.desktopTextExtraExtraSmall(context)
+ .copyWith(
+ color: Theme.of(
context,
).extension<StackColors>()!.textFieldActiveText,
- ),
+ ),
textAlign: TextAlign.left,
),
if (widget.feeObject != null)
Text(
timeString!,
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(context)
+ style: STextStyles.desktopTextExtraExtraSmall(context)
+ .copyWith(
+ color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconRight,
- ),
+ ),
),
],
);
} else {
return AnimatedText(
stringsToLoopThrough: stringsToLoopThrough,
- style: STextStyles.desktopTextExtraExtraSmall(
- context,
- ).copyWith(
- color:
- Theme.of(
+ style: STextStyles.desktopTextWhy this scored 33/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.