From f31d47f1235b41d1fab9827f7b048f7c720c60a6 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 13 Jun 2024 12:00:03 -0600 Subject: [PATCH 01/15] wownero restore tweaks --- lib/wallets/wallet/impl/wownero_wallet.dart | 27 ++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/wallets/wallet/impl/wownero_wallet.dart b/lib/wallets/wallet/impl/wownero_wallet.dart index ced514aa3..69f42a57d 100644 --- a/lib/wallets/wallet/impl/wownero_wallet.dart +++ b/lib/wallets/wallet/impl/wownero_wallet.dart @@ -12,6 +12,7 @@ import 'package:cw_core/wallet_credentials.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; +import 'package:cw_wownero/api/account_list.dart'; import 'package:cw_wownero/pending_wownero_transaction.dart'; import 'package:cw_wownero/wownero_wallet.dart'; import 'package:decimal/decimal.dart'; @@ -20,6 +21,7 @@ import 'package:flutter_libmonero/view_model/send/output.dart' as wownero_output; import 'package:flutter_libmonero/wownero/wownero.dart' as wow_dart; import 'package:isar/isar.dart'; +import 'package:monero/wownero.dart' as wownerodart; import 'package:mutex/mutex.dart'; import 'package:tuple/tuple.dart'; @@ -383,19 +385,11 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { _walletCreationService.type = WalletType.wownero; // To restore from a seed final wallet = await _walletCreationService.create(credentials); - // - // final bufferedCreateHeight = (seedWordsLength == 14) - // ? getSeedHeightSync(wallet?.seed.trim() as String) - // : wownero.getHeightByDate( - // date: DateTime.now().subtract(const Duration( - // days: - // 2))); // subtract a couple days to ensure we have a buffer for SWB - // TODO(mrcyjanek): implement - const bufferedCreateHeight = - 1; //getSeedHeightSync(wallet!.seed.trim()); + + final height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!); await info.updateRestoreHeight( - newRestoreHeight: bufferedCreateHeight, + newRestoreHeight: height, isar: mainDB.isar, ); @@ -410,7 +404,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { value: "", ); - walletInfo.restoreHeight = bufferedCreateHeight; + walletInfo.restoreHeight = height; walletInfo.address = wallet.walletAddresses.address; await DB.instance @@ -515,8 +509,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { // extract seed height from 14 word seed if (seedLength == 14) { - // TODO(mrcyjanek): implement - height = 1; // getSeedHeightSync(mnemonic.trim()); + height = 0; } else { height = max(height, 0); } @@ -563,7 +556,13 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { // To restore from a seed final wallet = await cwWalletCreationService .restoreFromSeed(credentials) as WowneroWalletBase; + height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!); walletInfo.address = wallet.walletAddresses.address; + walletInfo.restoreHeight = height; + await info.updateRestoreHeight( + newRestoreHeight: height, + isar: mainDB.isar, + ); await DB.instance .add(boxName: WalletInfo.boxName, value: walletInfo); CwBasedInterface.cwWalletBase?.close(); From 87405bc1ddae0fd96474d0ef2d76647e771b8317 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 13 Jun 2024 12:05:59 -0600 Subject: [PATCH 02/15] call `exit(0)` instead of `SystemNavigator.pop()` if xmr or wow is enabled hack to "fix" the native lib code from causing a complete app lockup on attempting to quit gracefully --- lib/pages_desktop_specific/desktop_menu.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/pages_desktop_specific/desktop_menu.dart b/lib/pages_desktop_specific/desktop_menu.dart index 2b4524bf0..81b99fd8f 100644 --- a/lib/pages_desktop_specific/desktop_menu.dart +++ b/lib/pages_desktop_specific/desktop_menu.dart @@ -20,6 +20,7 @@ import '../providers/desktop/current_desktop_menu_item.dart'; import '../themes/stack_colors.dart'; import '../utilities/assets.dart'; import '../utilities/text_styles.dart'; +import '../wallets/crypto_currency/crypto_currency.dart'; import '../widgets/desktop/desktop_tor_status_button.dart'; import '../widgets/desktop/living_stack_icon.dart'; import 'desktop_menu_item.dart'; @@ -278,8 +279,14 @@ class _DesktopMenuState extends ConsumerState { value: 7, onChanged: (_) { // todo: save stuff/ notify before exit? - // exit(0); - SystemNavigator.pop(); + if (AppConfig.coins + .where((e) => e is Monero || e is Wownero) + .isNotEmpty) { + // hack to insta kill because xmr/wow native lib code sucks + exit(0); + } else { + SystemNavigator.pop(); + } }, controller: controllers[8], ), From fc180dd8c1ab8ee8892c25acac007e51fb940f42 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 13 Jun 2024 14:46:22 -0600 Subject: [PATCH 03/15] simple async queue to write logs to db without holding up the logger to wait for it to complete --- lib/utilities/logger.dart | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/utilities/logger.dart b/lib/utilities/logger.dart index 6af09473a..83949ec5b 100644 --- a/lib/utilities/logger.dart +++ b/lib/utilities/logger.dart @@ -14,6 +14,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; + import '../models/isar/models/log.dart'; import 'constants.dart'; import 'enums/log_level_enum.dart'; @@ -30,8 +31,10 @@ class Logging { static const core.int defaultPrintLength = 1020; late final Isar? isar; + late final _AsyncLogWriterQueue _queue; Future init(Isar isar) async { + _queue = _AsyncLogWriterQueue(); this.isar = isar; } @@ -62,7 +65,11 @@ class Logging { printFullLength = true; } - isar!.writeTxnSync(() => log.id = isar!.logs.putSync(log)); + _queue.add( + () async => isar!.writeTxn( + () async => await isar!.logs.put(log), + ), + ); if (printToConsole) { final core.String logStr = "Log: ${log.toString()}"; @@ -129,3 +136,33 @@ abstract class Logger { } } } + +/// basic async queue for writing logs in the [Logging] to isar +class _AsyncLogWriterQueue { + final List Function()> _queue = []; + bool _runningLock = false; + + void add(Future Function() futureFunction) { + _queue.add(futureFunction); + _run(); + } + + void _run() async { + if (_runningLock) { + return; + } + _runningLock = true; + try { + while (_queue.isNotEmpty) { + final futureFunction = _queue.removeAt(0); + try { + await futureFunction.call(); + } catch (e, s) { + debugPrint("$e\n$s"); + } + } + } finally { + _runningLock = false; + } + } +} From 65879670ad15612dc7d3aa72e7ac686d789af361 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 13 Jun 2024 17:35:40 -0600 Subject: [PATCH 04/15] desktop swap navigation fix --- lib/pages/exchange_view/confirm_change_now_send.dart | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart index 09aac4df9..1b52dfdbe 100644 --- a/lib/pages/exchange_view/confirm_change_now_send.dart +++ b/lib/pages/exchange_view/confirm_change_now_send.dart @@ -147,17 +147,15 @@ class _ConfirmChangeNowSendViewState ); // pop back to wallet - if (mounted) { + if (context.mounted) { if (Util.isDesktop) { + // pop sending dialog Navigator.of(context, rootNavigator: true).pop(); - // stupid hack + // one day we'll do routing right + Navigator.of(context, rootNavigator: true).pop(); if (widget.fromDesktopStep4) { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context, rootNavigator: true).pop(); } } From 98960cac7729ab303cf9c4fb966c7bf25be7f5a6 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 08:41:16 -0600 Subject: [PATCH 05/15] WIP less cryptic errors in gui --- .../exchange_step_views/step_3_view.dart | 19 ++++++++++++++++--- .../exchange_steps/step_scaffold.dart | 12 +++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/pages/exchange_view/exchange_step_views/step_3_view.dart b/lib/pages/exchange_view/exchange_step_views/step_3_view.dart index 93856486e..545e2d41a 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_3_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_3_view.dart @@ -285,17 +285,30 @@ class _Step3ViewState extends ConsumerState { ); if (response.value == null) { - if (mounted) { + if (context.mounted) { Navigator.of(context).pop(); + // TODO: better errors + String? message; + if (response.exception != null) { + message = + response.exception!.toString(); + if (message.startsWith( + "FormatException:", + ) && + message.contains("")) { + message = + "${ref.read(efExchangeProvider).name} server error"; + } + } + unawaited( showDialog( context: context, barrierDismissible: true, builder: (_) => StackDialog( title: "Failed to create trade", - message: response.exception - ?.toString(), + message: message ?? "", ), ), ); diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart index 3c0688166..19eea020b 100644 --- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart +++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart @@ -117,13 +117,23 @@ class _StepScaffoldState extends ConsumerState { if (mounted) { Navigator.of(context).pop(); + String? message; + if (response.exception != null) { + message = response.exception!.toString(); + // TODO: better errors + if (message.startsWith("FormatException:") && + message.contains("")) { + message = "${ref.read(efExchangeProvider).name} server error"; + } + } + unawaited( showDialog( context: context, barrierDismissible: true, builder: (_) => SimpleDesktopDialog( title: "Failed to create trade", - message: response.exception?.toString() ?? "", + message: message ?? "", ), ), ); From 0b95afc62f72720023630f60df82c2ab8e9654e4 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 10:04:02 -0600 Subject: [PATCH 06/15] wrap long trade payin addresses in trade details view --- .../exchange_view/trade_details_view.dart | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart index 68a75704a..e64c1154b 100644 --- a/lib/pages/exchange_view/trade_details_view.dart +++ b/lib/pages/exchange_view/trade_details_view.dart @@ -669,21 +669,29 @@ class _TradeDetailsViewState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "${trade.exchangeName} address", - style: STextStyles.itemSubtitle(context), - ), - const SizedBox( - height: 4, - ), - SelectableText( - trade.payInAddress, - style: STextStyles.itemSubtitle12(context), - ), - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "${trade.exchangeName} address", + style: STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 4, + ), + Row( + children: [ + Flexible( + child: SelectableText( + trade.payInAddress, + style: STextStyles.itemSubtitle12(context), + ), + ), + ], + ), + ], + ), ), if (isDesktop) IconCopyButton( @@ -760,9 +768,15 @@ class _TradeDetailsViewState extends ConsumerState { const SizedBox( height: 4, ), - SelectableText( - trade.payInAddress, - style: STextStyles.itemSubtitle12(context), + Row( + children: [ + Expanded( + child: SelectableText( + trade.payInAddress, + style: STextStyles.itemSubtitle12(context), + ), + ), + ], ), const SizedBox( height: 10, From dcdad38ec7cb28f7b3b010d4e7fdc872a81aac66 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 10:18:11 -0600 Subject: [PATCH 07/15] fix desktop wallet network settings layout --- .../wallet_network_settings_view.dart | 15 ++++----- .../sub_widgets/network_info_button.dart | 31 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart index da50b6208..22566804a 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart @@ -15,11 +15,9 @@ import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import '../../global_settings_view/manage_nodes_views/add_edit_node_view.dart'; -import '../../global_settings_view/tor_settings/tor_settings_view.dart'; -import '../../sub_widgets/nodes_list.dart'; -import 'sub_widgets/confirm_full_rescan.dart'; -import 'sub_widgets/rescanning_dialog.dart'; +import 'package:tuple/tuple.dart'; +import 'package:wakelock/wakelock.dart'; + import '../../../../providers/providers.dart'; import '../../../../route_generator.dart'; import '../../../../services/event_bus/events/global/blocks_remaining_event.dart'; @@ -53,8 +51,11 @@ import '../../../../widgets/rounded_container.dart'; import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/stack_dialog.dart'; import '../../../../widgets/tor_subscription.dart'; -import 'package:tuple/tuple.dart'; -import 'package:wakelock/wakelock.dart'; +import '../../global_settings_view/manage_nodes_views/add_edit_node_view.dart'; +import '../../global_settings_view/tor_settings/tor_settings_view.dart'; +import '../../sub_widgets/nodes_list.dart'; +import 'sub_widgets/confirm_full_rescan.dart'; +import 'sub_widgets/rescanning_dialog.dart'; /// [eventBus] should only be set during testing class WalletNetworkSettingsView extends ConsumerStatefulWidget { diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/network_info_button.dart index b84332c01..7fbcef510 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/network_info_button.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/network_info_button.dart @@ -14,6 +14,8 @@ import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:tuple/tuple.dart'; + import '../../../../pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart'; import '../../../../providers/providers.dart'; import '../../../../route_generator.dart'; @@ -26,7 +28,6 @@ import '../../../../utilities/text_styles.dart'; import '../../../../utilities/util.dart'; import '../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../widgets/desktop/desktop_dialog_close_button.dart'; -import 'package:tuple/tuple.dart'; class NetworkInfoButton extends ConsumerStatefulWidget { const NetworkInfoButton({ @@ -226,7 +227,7 @@ class _NetworkInfoButtonState extends ConsumerState { return [ FadePageRoute( DesktopDialog( - maxHeight: MediaQuery.of(context).size.height - 64, + maxHeight: null, maxWidth: 580, child: Column( mainAxisSize: MainAxisSize.min, @@ -251,17 +252,21 @@ class _NetworkInfoButtonState extends ConsumerState { ], ), ), - Padding( - padding: const EdgeInsets.only( - top: 16, - left: 32, - right: 32, - bottom: 32, - ), - child: WalletNetworkSettingsView( - walletId: walletId, - initialSyncStatus: _currentSyncStatus, - initialNodeStatus: _currentNodeStatus, + Flexible( + child: Padding( + padding: const EdgeInsets.only( + top: 16, + left: 32, + right: 32, + bottom: 32, + ), + child: SingleChildScrollView( + child: WalletNetworkSettingsView( + walletId: walletId, + initialSyncStatus: _currentSyncStatus, + initialNodeStatus: _currentNodeStatus, + ), + ), ), ), ], From 8510fea4476c2a0bfa9b7161191f9eea338956bf Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 10:49:43 -0600 Subject: [PATCH 08/15] patch applied --- crypto_plugins/flutter_libmonero | 2 +- ios/MoneroWallet.framework/.gitignore | 1 + ios/MoneroWallet.framework/Info.plist | Bin 0 -> 793 bytes ios/WowneroWallet.framework/.gitignore | 1 + ios/WowneroWallet.framework/Info.plist | Bin 0 -> 793 bytes scripts/app_config/templates/pubspec.template | 8 ++++---- 6 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 ios/MoneroWallet.framework/.gitignore create mode 100644 ios/MoneroWallet.framework/Info.plist create mode 100644 ios/WowneroWallet.framework/.gitignore create mode 100644 ios/WowneroWallet.framework/Info.plist diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 4b87151d4..09a59d938 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 4b87151d4914606b911f738a8236a6e54a6d8ecb +Subproject commit 09a59d9381e24224ebe545fc9d96dcf51185b7a4 diff --git a/ios/MoneroWallet.framework/.gitignore b/ios/MoneroWallet.framework/.gitignore new file mode 100644 index 000000000..38de9b351 --- /dev/null +++ b/ios/MoneroWallet.framework/.gitignore @@ -0,0 +1 @@ +MoneroWallet \ No newline at end of file diff --git a/ios/MoneroWallet.framework/Info.plist b/ios/MoneroWallet.framework/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..8858589f7070c754a01b0519387f9cab5f664005 GIT binary patch literal 793 zcmZXQ&rcIU6vtUcNFuadk3vEj@Mp#?9$l6SH&kckVuTD5sjMYb$}%;&g-9bW<~Q zZM}D^YevHoE&4RdtOSg=OldOi)#x7O!nLX6S7?U`$CO6nT8(<$D3gq+BC&RuLrZ$} z+R}_NCw^OacJCKcO2$~3Si7V{jeR%FrsAx=BRs!9QTILObWRro*A2_G6_4zi(o{?q zoVL)I<%d#;xBpMnSX|G)pjP0MZQfgPRoE`$)H9`YwNRnY1Lo0IxFoaaDsjm+HkkGv_d;rn^AA8S~!N+h|T!EDJ4$U?sLt)zkO#Du`Hc+9O4IFXu{|T z6m>O=!l9n16V9pMWbRJ*6kT;$&Km0Cf>O(<`HZSmsPjavWft<8Otuj>8EeJ*x~|H~ z;Y@>-dtgb|mt@71W-MXL#C189!&_uRSLS@rmMu=4j;xx>;q5B%?4|IRh)DH_w(tcP z)~+X?7WL`geF;lo^fcAg#e7D|5UcNFuadk3vEj@Mp#?9$l6SH&kckVuTD5sjMYb$}%;&g-9bW<~Q zZM}D^YevHoE&4RdtOSg=OldOi)#x7O!nLX6S7?U`$CO6nT8(<$D3gq+BC&RuLrZ$} z+R}_NCw^OacJCKcO2$~3Si7V{jeR%FrsAx=BRs!9QTILObWRro*A2_G6_4zi(o{?q zoVL)I<%d#;xBpMnSX|G)pjP0MZQfgPRoE`$)H9`YwNRnY1Lo0IxFoaaDsjm+HkkGv_d;rn^AA8S~!N+h|T!EDJ4$U?sLt)zkO#Du`Hc+9O4IFXu{|T z6m>O=!l9n16V9pMWbRJ*6kT;$&Km0Cf>O(<`HZSmsPjavWft<8Otuj>8EeJ*x~|H~ z;Y@>-dtgb|mt@71W-MXL#C189!&_uRSLS@rmMu=4j;xx>;q5B%?4|IRh)DH_w(tcP z)~+X?7WL`geF;lo^fcAg#e7D|5 Date: Fri, 14 Jun 2024 12:28:06 -0600 Subject: [PATCH 09/15] update ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 09a59d938..f29b2dced 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 09a59d9381e24224ebe545fc9d96dcf51185b7a4 +Subproject commit f29b2dceddc61ec5e97194c393ab7c0e9ba4eb8b From 2ada78e4b025b45d58264246288a8d7610d9a162 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 13:33:27 -0600 Subject: [PATCH 10/15] spark mempool electrumx calls --- lib/electrumx_rpc/electrumx_client.dart | 43 +++++++++++++++++++------ 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/electrumx_rpc/electrumx_client.dart b/lib/electrumx_rpc/electrumx_client.dart index 442281532..a49d7675a 100644 --- a/lib/electrumx_rpc/electrumx_client.dart +++ b/lib/electrumx_rpc/electrumx_client.dart @@ -26,12 +26,20 @@ import '../services/event_bus/events/global/tor_status_changed_event.dart'; import '../services/event_bus/global_event_bus.dart'; import '../services/tor_service.dart'; import '../utilities/amount/amount.dart'; +import '../utilities/extensions/impl/string.dart'; import '../utilities/logger.dart'; import '../utilities/prefs.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/interfaces/electrumx_currency_interface.dart'; import 'client_manager.dart'; +typedef SparkMempoolData = ({ + String txid, + List serialContext, + List lTags, + List coins, +}); + class WifiOnlyException implements Exception {} class ElectrumXNode { @@ -1038,10 +1046,9 @@ class ElectrumXClient { command: "spark.getmempooltxids", ); - // TODO verify once server is live - final txids = List.from(response as List).toSet(); - // final map = Map.from(response as Map); - // final txids = List.from(map["tags"] as List).toSet(); + final txids = List.from(response as List) + .map((e) => e.toHexReversedFromBase64) + .toSet(); Logging.instance.log( "Finished ElectrumXClient.getMempoolTxids(). " @@ -1057,7 +1064,7 @@ class ElectrumXClient { } /// Returns the txids of the current transactions found in the mempool - Future> getMempoolSparkData({ + Future> getMempoolSparkData({ String? requestID, required List txids, }) async { @@ -1066,11 +1073,27 @@ class ElectrumXClient { final response = await request( requestID: requestID, command: "spark.getmempooltxs", - args: txids, + args: [ + { + "txids": txids, + }, + ], ); - // TODO verify once server is live final map = Map.from(response as Map); + final List result = []; + for (final entry in map.entries) { + result.add( + ( + txid: entry.key, + serialContext: + List.from(entry.value["Serial_context"] as List), + // the space after lTags is required lol + lTags: List.from(entry.value["lTags "] as List), + coins: List.from(entry.value["Coins"] as List), + ), + ); + } Logging.instance.log( "Finished ElectrumXClient.getMempoolSparkData(txids: $txids). " @@ -1078,9 +1101,9 @@ class ElectrumXClient { level: LogLevel.Info, ); - return map; - } catch (e) { - Logging.instance.log(e, level: LogLevel.Error); + return result; + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Error); rethrow; } } From d1a236be3330e3b7d1b282da185b21af254a3014 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 14 Jun 2024 14:52:01 -0600 Subject: [PATCH 11/15] spark mempool check during refresh --- .../spark_interface.dart | 474 +++++++++++------- 1 file changed, 283 insertions(+), 191 deletions(-) diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart index 5ac6ade90..496147da1 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart @@ -635,7 +635,9 @@ mixin SparkInterface // been marked as isUsed. // TODO: [prio=med] Could (probably should) throw an exception here if txData.usedSparkCoins is null or empty if (txData.usedSparkCoins != null && txData.usedSparkCoins!.isNotEmpty) { - await _addOrUpdateSparkCoins(txData.usedSparkCoins!); + await mainDB.isar.writeTxn(() async { + await mainDB.isar.sparkCoins.putAll(txData.usedSparkCoins!); + }); } return await updateSentCachedTxData(txData: txData); @@ -648,7 +650,88 @@ mixin SparkInterface } } + // in mem cache + Set _mempoolTxids = {}; + Set _mempoolTxidsChecked = {}; + + Future> _refreshSparkCoinsMempoolCheck({ + required Set privateKeyHexSet, + required int groupId, + }) async { + final start = DateTime.now(); + try { + // update cache + _mempoolTxids = await electrumXClient.getMempoolTxids(); + + // remove any checked txids that are not in the mempool anymore + _mempoolTxidsChecked = _mempoolTxidsChecked.intersection(_mempoolTxids); + + // get all unchecked txids currently in mempool + final txidsToCheck = _mempoolTxids.difference(_mempoolTxidsChecked); + if (txidsToCheck.isEmpty) { + return []; + } + + // fetch spark data to scan if we own any unconfirmed spark coins + final sparkDataToCheck = await electrumXClient.getMempoolSparkData( + txids: txidsToCheck.toList(), + ); + + final Set checkedTxids = {}; + final List> rawCoins = []; + + for (final data in sparkDataToCheck) { + for (int i = 0; i < data.coins.length; i++) { + rawCoins.add([ + data.coins[i], + data.txid, + data.serialContext.first, + ]); + } + + checkedTxids.add(data.txid); + } + + final result = []; + + // if there is new data we try and identify the coins + if (rawCoins.isNotEmpty) { + // run identify off main isolate + final myCoins = await compute( + _identifyCoins, + ( + anonymitySetCoins: rawCoins, + groupId: groupId, + privateKeyHexSet: privateKeyHexSet, + walletId: walletId, + isTestNet: cryptoCurrency.network == CryptoCurrencyNetwork.test, + ), + ); + + // add checked txids after identification + _mempoolTxidsChecked.addAll(checkedTxids); + + result.addAll(myCoins); + } + + return result; + } catch (e) { + Logging.instance.log( + "refreshSparkMempoolData() failed: $e", + level: LogLevel.Error, + ); + return []; + } finally { + Logging.instance.log( + "$walletId ${info.name} refreshSparkCoinsMempoolCheck() run " + "duration: ${DateTime.now().difference(start)}", + level: LogLevel.Debug, + ); + } + } + Future refreshSparkData() async { + final start = DateTime.now(); try { // start by checking if any previous sets are missing from db and add the // missing groupIds to the list if sets to check and update @@ -684,15 +767,210 @@ mixin SparkInterface ), ]); - await _checkAndUpdateCoins(); - // refresh spark balance - await refreshSparkBalance(); + // Get cached timestamps per groupId. These timestamps are used to check + // and try to id coins that were added to the spark anon set cache + // after that timestamp. + final groupIdTimestampUTCMap = + info.otherData[WalletInfoKeys.firoSparkCacheSetTimestampCache] + as Map? ?? + {}; + + // iterate through the cache, fetching spark coin data that hasn't been + // processed by this wallet yet + final Map>> rawCoinsBySetId = {}; + for (int i = 1; i <= latestGroupId; i++) { + final lastCheckedTimeStampUTC = + groupIdTimestampUTCMap[i.toString()] as int? ?? 0; + final info = await FiroCacheCoordinator.getLatestSetInfoForGroupId( + i, + ); + final anonymitySetResult = + await FiroCacheCoordinator.getSetCoinsForGroupId( + i, + newerThanTimeStamp: lastCheckedTimeStampUTC, + ); + final coinsRaw = anonymitySetResult + .map( + (e) => [ + e.serialized, + e.txHash, + e.context, + ], + ) + .toList(); + + if (coinsRaw.isNotEmpty) { + rawCoinsBySetId[i] = coinsRaw; + } + + // update last checked timestamp data + groupIdTimestampUTCMap[i.toString()] = max( + lastCheckedTimeStampUTC, + info?.timestampUTC ?? lastCheckedTimeStampUTC, + ); + } + + // get address(es) to get the private key hex strings required for + // identifying spark coins + final sparkAddresses = await mainDB.isar.addresses + .where() + .walletIdEqualTo(walletId) + .filter() + .typeEqualTo(AddressType.spark) + .findAll(); + final root = await getRootHDNode(); + final Set privateKeyHexSet = sparkAddresses + .map( + (e) => + root.derivePath(e.derivationPath!.value).privateKey.data.toHex, + ) + .toSet(); + + // try to identify any coins in the unchecked set data + final List newlyIdCoins = []; + for (final groupId in rawCoinsBySetId.keys) { + final myCoins = await compute( + _identifyCoins, + ( + anonymitySetCoins: rawCoinsBySetId[groupId]!, + groupId: groupId, + privateKeyHexSet: privateKeyHexSet, + walletId: walletId, + isTestNet: cryptoCurrency.network == CryptoCurrencyNetwork.test, + ), + ); + newlyIdCoins.addAll(myCoins); + } + // if any were found, add to database + if (newlyIdCoins.isNotEmpty) { + await mainDB.isar.writeTxn(() async { + await mainDB.isar.sparkCoins.putAll(newlyIdCoins); + }); + } + + // finally update the cached timestamps in the database + await info.updateOtherData( + newEntries: { + WalletInfoKeys.firoSparkCacheSetTimestampCache: + groupIdTimestampUTCMap, + }, + isar: mainDB.isar, + ); + + // check for spark coins in mempool + final mempoolMyCoins = await _refreshSparkCoinsMempoolCheck( + privateKeyHexSet: privateKeyHexSet, + groupId: latestGroupId, + ); + // if any were found, add to database + if (mempoolMyCoins.isNotEmpty) { + await mainDB.isar.writeTxn(() async { + await mainDB.isar.sparkCoins.putAll(mempoolMyCoins); + }); + } + + // get unused and or unconfirmed coins from db + final coinsToCheck = await mainDB.isar.sparkCoins + .where() + .walletIdEqualToAnyLTagHash(walletId) + .filter() + .heightIsNull() + .or() + .isUsedEqualTo(false) + .findAll(); + + Set? spentCoinTags; + // only fetch tags from db if we need them to compare against any items + // in coinsToCheck + if (coinsToCheck.isNotEmpty) { + spentCoinTags = await FiroCacheCoordinator.getUsedCoinTags(0); + } + + // check and update coins if required + final List updatedCoins = []; + for (final coin in coinsToCheck) { + SparkCoin updated = coin; + + if (updated.height == null) { + final tx = await electrumXCachedClient.getTransaction( + txHash: updated.txHash, + cryptoCurrency: info.coin, + ); + if (tx["height"] is int) { + updated = updated.copyWith(height: tx["height"] as int); + } + } + + if (updated.height != null && + spentCoinTags!.contains(updated.lTagHash)) { + updated = coin.copyWith(isUsed: true); + } + + updatedCoins.add(updated); + } + // update in db if any have changed + if (updatedCoins.isNotEmpty) { + await mainDB.isar.writeTxn(() async { + await mainDB.isar.sparkCoins.putAll(updatedCoins); + }); + } + + // used to check if balance is spendable or total + final currentHeight = await chainHeight; + + // get all unused coins to update wallet spark balance + final unusedCoins = await mainDB.isar.sparkCoins + .where() + .walletIdEqualToAnyLTagHash(walletId) + .filter() + .isUsedEqualTo(false) + .findAll(); + + final total = Amount( + rawValue: unusedCoins + .map((e) => e.value) + .fold(BigInt.zero, (prev, e) => prev + e), + fractionDigits: cryptoCurrency.fractionDigits, + ); + final spendable = Amount( + rawValue: unusedCoins + .where( + (e) => + e.height != null && + e.height! + cryptoCurrency.minConfirms <= currentHeight, + ) + .map((e) => e.value) + .fold(BigInt.zero, (prev, e) => prev + e), + fractionDigits: cryptoCurrency.fractionDigits, + ); + + final sparkBalance = Balance( + total: total, + spendable: spendable, + blockedTotal: Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ), + pendingSpendable: total - spendable, + ); + + // finally update balance in db + await info.updateBalanceTertiary( + newBalance: sparkBalance, + isar: mainDB.isar, + ); } catch (e, s) { Logging.instance.log( "$runtimeType $walletId ${info.name}: $e\n$s", level: LogLevel.Error, ); rethrow; + } finally { + Logging.instance.log( + "${info.name} refreshSparkData() duration:" + " ${DateTime.now().difference(start)}", + level: LogLevel.Debug, + ); } } @@ -722,49 +1000,6 @@ mixin SparkInterface return pairs.toSet(); } - Future refreshSparkBalance() async { - final currentHeight = await chainHeight; - final unusedCoins = await mainDB.isar.sparkCoins - .where() - .walletIdEqualToAnyLTagHash(walletId) - .filter() - .isUsedEqualTo(false) - .findAll(); - - final total = Amount( - rawValue: unusedCoins - .map((e) => e.value) - .fold(BigInt.zero, (prev, e) => prev + e), - fractionDigits: cryptoCurrency.fractionDigits, - ); - final spendable = Amount( - rawValue: unusedCoins - .where( - (e) => - e.height != null && - e.height! + cryptoCurrency.minConfirms <= currentHeight, - ) - .map((e) => e.value) - .fold(BigInt.zero, (prev, e) => prev + e), - fractionDigits: cryptoCurrency.fractionDigits, - ); - - final sparkBalance = Balance( - total: total, - spendable: spendable, - blockedTotal: Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ), - pendingSpendable: total - spendable, - ); - - await info.updateBalanceTertiary( - newBalance: sparkBalance, - isar: mainDB.isar, - ); - } - /// Should only be called within the standard wallet [recover] function due to /// mutex locking. Otherwise behaviour MAY be undefined. Future recoverSparkWallet({ @@ -777,10 +1012,7 @@ mixin SparkInterface } try { - await _checkAndUpdateCoins(); - - // refresh spark balance - await refreshSparkBalance(); + await refreshSparkData(); } catch (e, s) { Logging.instance.log( "$runtimeType $walletId ${info.name}: $e\n$s", @@ -790,115 +1022,6 @@ mixin SparkInterface } } - Future _checkAndUpdateCoins() async { - final sparkAddresses = await mainDB.isar.addresses - .where() - .walletIdEqualTo(walletId) - .filter() - .typeEqualTo(AddressType.spark) - .findAll(); - final root = await getRootHDNode(); - final Set privateKeyHexSet = sparkAddresses - .map( - (e) => root.derivePath(e.derivationPath!.value).privateKey.data.toHex, - ) - .toSet(); - - final Map>> rawCoinsBySetId = {}; - - final groupIdTimestampUTCMap = - info.otherData[WalletInfoKeys.firoSparkCacheSetTimestampCache] - as Map? ?? - {}; - - final latestSparkCoinId = await electrumXClient.getSparkLatestCoinId(); - for (int i = 1; i <= latestSparkCoinId; i++) { - final lastCheckedTimeStampUTC = - groupIdTimestampUTCMap[i.toString()] as int? ?? 0; - final info = await FiroCacheCoordinator.getLatestSetInfoForGroupId( - i, - ); - final anonymitySetResult = - await FiroCacheCoordinator.getSetCoinsForGroupId( - i, - newerThanTimeStamp: lastCheckedTimeStampUTC, - ); - final coinsRaw = anonymitySetResult - .map( - (e) => [ - e.serialized, - e.txHash, - e.context, - ], - ) - .toList(); - - if (coinsRaw.isNotEmpty) { - rawCoinsBySetId[i] = coinsRaw; - } - - groupIdTimestampUTCMap[i.toString()] = max( - lastCheckedTimeStampUTC, - info?.timestampUTC ?? lastCheckedTimeStampUTC, - ); - } - - await info.updateOtherData( - newEntries: { - WalletInfoKeys.firoSparkCacheSetTimestampCache: groupIdTimestampUTCMap, - }, - isar: mainDB.isar, - ); - - final List newlyIdCoins = []; - for (final groupId in rawCoinsBySetId.keys) { - final myCoins = await compute( - _identifyCoins, - ( - anonymitySetCoins: rawCoinsBySetId[groupId]!, - groupId: groupId, - privateKeyHexSet: privateKeyHexSet, - walletId: walletId, - isTestNet: cryptoCurrency.network == CryptoCurrencyNetwork.test, - ), - ); - newlyIdCoins.addAll(myCoins); - } - - await _checkAndMarkCoinsUsedInDB(coinsNotInDbYet: newlyIdCoins); - } - - Future _checkAndMarkCoinsUsedInDB({ - List coinsNotInDbYet = const [], - }) async { - final List coins = await mainDB.isar.sparkCoins - .where() - .walletIdEqualToAnyLTagHash(walletId) - .filter() - .isUsedEqualTo(false) - .findAll(); - - final List coinsToWrite = []; - - final spentCoinTags = await FiroCacheCoordinator.getUsedCoinTags(0); - - for (final coin in coins) { - if (spentCoinTags.contains(coin.lTagHash)) { - coinsToWrite.add(coin.copyWith(isUsed: true)); - } - } - for (final coin in coinsNotInDbYet) { - if (spentCoinTags.contains(coin.lTagHash)) { - coinsToWrite.add(coin.copyWith(isUsed: true)); - } else { - coinsToWrite.add(coin); - } - } - - // update wallet spark coins in isar - await _addOrUpdateSparkCoins(coinsToWrite); - } - // modelled on CSparkWallet::CreateSparkMintTransactions https://github.com/firoorg/firo/blob/39c41e5e7ec634ced3700fe3f4f5509dc2e480d0/src/spark/sparkwallet.cpp#L752 Future> _createSparkMintTransactions({ required List availableUtxos, @@ -1698,37 +1821,6 @@ mixin SparkInterface // ====================== Private ============================================ - Future _addOrUpdateSparkCoins(List coins) async { - if (coins.isNotEmpty) { - await mainDB.isar.writeTxn(() async { - await mainDB.isar.sparkCoins.putAll(coins); - }); - } - - // update wallet spark coin height - final coinsToCheck = await mainDB.isar.sparkCoins - .where() - .walletIdEqualToAnyLTagHash(walletId) - .filter() - .heightIsNull() - .findAll(); - final List updatedCoins = []; - for (final coin in coinsToCheck) { - final tx = await electrumXCachedClient.getTransaction( - txHash: coin.txHash, - cryptoCurrency: info.coin, - ); - if (tx["height"] is int) { - updatedCoins.add(coin.copyWith(height: tx["height"] as int)); - } - } - if (updatedCoins.isNotEmpty) { - await mainDB.isar.writeTxn(() async { - await mainDB.isar.sparkCoins.putAll(updatedCoins); - }); - } - } - btc.NetworkType get _bitcoinDartNetwork => btc.NetworkType( messagePrefix: cryptoCurrency.networkParams.messagePrefix, bech32: cryptoCurrency.networkParams.bech32Hrp, From 91f4b97cd7bd91640203c91bd318b2aad03fd97c Mon Sep 17 00:00:00 2001 From: Julian Date: Tue, 18 Jun 2024 07:46:35 -0600 Subject: [PATCH 12/15] fix plists and convert to xml --- ios/MoneroWallet.framework/Info.plist | Bin 793 -> 1526 bytes ios/WowneroWallet.framework/Info.plist | Bin 793 -> 1529 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ios/MoneroWallet.framework/Info.plist b/ios/MoneroWallet.framework/Info.plist index 8858589f7070c754a01b0519387f9cab5f664005..de2be3211f8d9a3b7870502df299bc1c588e9cdf 100644 GIT binary patch literal 1526 zcmbVMU6YzH6n(D0g7PjA_M@E+t5XGMoYj?Cu-iU$vT()B29k!L%fD|xv5Mfdeapu^ z_ndq0N$k;kLbWZ3jIi`UH;sX=K^n4%r168k3a0(f`e@j*KRU}v@WXR8PDv&;Z#ACJ zCYs(y=qu+G5OM-X^X4-@&{PhD+$UYrH&XI12<>(|1D8=o$dWQJL!Mw9ge>MNSziH+ zNJhG%*=IkKqfR3d%3<$={RYKwoD&)?aJV5UEd6R{qw+%CXHqEHL+i%1tXmr$wg=#3 zI?mIGf&*Kij3{8ts85{P363Vs2fE?yqH===>6 z@}SbM#?;iRT+j(7af)RwE*M9nQ70znTv0;gQ7qR?B-xP=3xP|&91TOfjhf%mKh1^e zsLFMCe`oY3}JA0I;%kr|Y3l>sPDW5fJ;(FG@{OK5ky>00I$P}`sh zFAHX>CFe%}L)BI2C*$H_If3sy{*yEne@&IyO7dNON*4w&?`~R3uR>cDnRl)=xW&!7 z7bGP~o-F;YvRfX~YNmb?62cTGgcdF4BB_KJ#88=|UY4G#*VgH=eQvka>=}OLL_oCX gm|%`y2_=%i6&qub+@DRSPHLn54{D?8e;xLI1Bbl(yZ`_I literal 793 zcmZXQ&rcIU6vtUcNFuadk3vEj@Mp#?9$l6SH&kckVuTD5sjMYb$}%;&g-9bW<~Q zZM}D^YevHoE&4RdtOSg=OldOi)#x7O!nLX6S7?U`$CO6nT8(<$D3gq+BC&RuLrZ$} z+R}_NCw^OacJCKcO2$~3Si7V{jeR%FrsAx=BRs!9QTILObWRro*A2_G6_4zi(o{?q zoVL)I<%d#;xBpMnSX|G)pjP0MZQfgPRoE`$)H9`YwNRnY1Lo0IxFoaaDsjm+HkkGv_d;rn^AA8S~!N+h|T!EDJ4$U?sLt)zkO#Du`Hc+9O4IFXu{|T z6m>O=!l9n16V9pMWbRJ*6kT;$&Km0Cf>O(<`HZSmsPjavWft<8Otuj>8EeJ*x~|H~ z;Y@>-dtgb|mt@71W-MXL#C189!&_uRSLS@rmMu=4j;xx>;q5B%?4|IRh)DH_w(tcP z)~+X?7WL`geF;lo^fcAg#e7D|57Ahg@<3|vMTAxp}@40(ca5VCku$@&Ul zL^9G9%|82?9CaFzP!4+^>^CTe8Q}Vc}Oh887usr}L z({Y|g6dc$BWjujYzCf(1Zo)yGv_su@2y=;FDKs%Fwo5^<6{Zwq7km~ePO>H-nsC(@ zBP{qvjX~n@&G@@?>6$sJGpYnEif{W7HZ$KFgDyGGIQhRiJS7pw5ET3ZKb@~0yZHPK z6Y?O_uO`(LtBlYICUJ^oE-n~HqfsX&=Uh=jIHB#+KE8)4A~Pu6Dhp7Y#)kRxq6JX!c%Ww*SflX=xj&muozzDAPt-=$7d!0z2C(h@KL7v# literal 793 zcmZXQ&rcIU6vtUcNFuadk3vEj@Mp#?9$l6SH&kckVuTD5sjMYb$}%;&g-9bW<~Q zZM}D^YevHoE&4RdtOSg=OldOi)#x7O!nLX6S7?U`$CO6nT8(<$D3gq+BC&RuLrZ$} z+R}_NCw^OacJCKcO2$~3Si7V{jeR%FrsAx=BRs!9QTILObWRro*A2_G6_4zi(o{?q zoVL)I<%d#;xBpMnSX|G)pjP0MZQfgPRoE`$)H9`YwNRnY1Lo0IxFoaaDsjm+HkkGv_d;rn^AA8S~!N+h|T!EDJ4$U?sLt)zkO#Du`Hc+9O4IFXu{|T z6m>O=!l9n16V9pMWbRJ*6kT;$&Km0Cf>O(<`HZSmsPjavWft<8Otuj>8EeJ*x~|H~ z;Y@>-dtgb|mt@71W-MXL#C189!&_uRSLS@rmMu=4j;xx>;q5B%?4|IRh)DH_w(tcP z)~+X?7WL`geF;lo^fcAg#e7D|5 Date: Tue, 18 Jun 2024 07:48:44 -0600 Subject: [PATCH 13/15] update ios project template file with manually added xmr and wow frameworks --- .../ios/Runner.xcodeproj/project.pbxproj | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj b/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj index fdfcd1bfa..4b521cca2 100644 --- a/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj +++ b/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj @@ -18,8 +18,8 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; B49D91439948369648AB0603 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51604430FD0FD1FA5C4767A0 /* Pods_Runner.framework */; }; - CE6B5DF12BF26AAA00CF1F44 /* monero_libwallet2_api_c.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE6B5DEF2BF26AAA00CF1F44 /* monero_libwallet2_api_c.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - CE6B5DF22BF26AAA00CF1F44 /* wownero_libwallet2_api_c.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE6B5DF02BF26AAA00CF1F44 /* wownero_libwallet2_api_c.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + CEFE41202C20387E00086DB4 /* WowneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE4F88332C202CF4007A8C67 /* WowneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + CEFE41212C20387E00086DB4 /* MoneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE4F88302C202CEE007A8C67 /* MoneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -40,8 +40,8 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - CE6B5DF12BF26AAA00CF1F44 /* monero_libwallet2_api_c.dylib in CopyFiles */, - CE6B5DF22BF26AAA00CF1F44 /* wownero_libwallet2_api_c.dylib in CopyFiles */, + CEFE41202C20387E00086DB4 /* WowneroWallet.framework in CopyFiles */, + CEFE41212C20387E00086DB4 /* MoneroWallet.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -75,8 +75,8 @@ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B999088F2ABE1E170012A442 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; - CE6B5DEF2BF26AAA00CF1F44 /* monero_libwallet2_api_c.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = monero_libwallet2_api_c.dylib; sourceTree = ""; }; - CE6B5DF02BF26AAA00CF1F44 /* wownero_libwallet2_api_c.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = wownero_libwallet2_api_c.dylib; sourceTree = ""; }; + CE4F88302C202CEE007A8C67 /* MoneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MoneroWallet.framework; sourceTree = ""; }; + CE4F88332C202CF4007A8C67 /* WowneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WowneroWallet.framework; sourceTree = ""; }; E6F536731AC506735EB76340 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -137,8 +137,8 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( - CE6B5DEF2BF26AAA00CF1F44 /* monero_libwallet2_api_c.dylib */, - CE6B5DF02BF26AAA00CF1F44 /* wownero_libwallet2_api_c.dylib */, + CE4F88332C202CF4007A8C67 /* WowneroWallet.framework */, + CE4F88302C202CEE007A8C67 /* MoneroWallet.framework */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, @@ -192,9 +192,9 @@ 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, + CE6B5DEA2BF26A3300CF1F44 /* CopyFiles */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, FD1CA371131604E6658D4146 /* [CP] Embed Pods Frameworks */, - CE6B5DEA2BF26A3300CF1F44 /* CopyFiles */, ); buildRules = ( ); @@ -341,6 +341,8 @@ "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", + "${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework", + "${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework", "${BUILT_PRODUCTS_DIR}/stack_wallet_backup/stack_wallet_backup.framework", "${BUILT_PRODUCTS_DIR}/tor_ffi_plugin/tor_ffi_plugin.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", @@ -374,6 +376,8 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3_flutter_libs.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/stack_wallet_backup.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tor_ffi_plugin.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", @@ -486,6 +490,7 @@ "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus", "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios", + "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -677,6 +682,7 @@ "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus", "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**", + "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -760,6 +766,7 @@ "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios", + "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( "$(inherited)", From 6b368e334c911a52beb4e5d3a4b611e627b2a454 Mon Sep 17 00:00:00 2001 From: Julian Date: Tue, 18 Jun 2024 07:49:10 -0600 Subject: [PATCH 14/15] update ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index f29b2dced..b954d52b3 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit f29b2dceddc61ec5e97194c393ab7c0e9ba4eb8b +Subproject commit b954d52b32939eeb98a870b80b50d14fd83a65b6 From 1735fc194395489abc85fe19fbdafad82ab89f8f Mon Sep 17 00:00:00 2001 From: Julian Date: Tue, 18 Jun 2024 08:46:24 -0600 Subject: [PATCH 15/15] update ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index b954d52b3..adc7bf50a 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit b954d52b32939eeb98a870b80b50d14fd83a65b6 +Subproject commit adc7bf50abe4bbe90d5050b82fb5751937cbae4e