mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-22 11:29:23 +00:00
WIP migrate flutter_libmonero to cs_monero
This commit is contained in:
parent
4109e7ed9f
commit
16b9254761
67 changed files with 1728 additions and 2529 deletions
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -101,21 +101,7 @@ pubspec.yaml
|
||||||
# FVM Version Cache
|
# FVM Version Cache
|
||||||
.fvm/
|
.fvm/
|
||||||
|
|
||||||
android/app/src/main/jniLibs/arm64-v8a/libwownero_wallet2_api_c.so
|
scripts/linux/build/libsecret/subprojects/gi-docgen/.meson-subproject-wrap-hash.txt
|
||||||
android/app/src/main/jniLibs/arm64-v8a/libmonero_wallet2_api_c.so
|
|
||||||
android/app/src/main/jniLibs/armeabi-v7a/libmonero_wallet2_api_c.so
|
crypto_plugins/cs_monero/built_outputs
|
||||||
android/app/src/main/jniLibs/armeabi-v7a/libwownero_wallet2_api_c.so
|
crypto_plugins/cs_monero/build
|
||||||
android/app/src/main/jniLibs/x86_64/libmonero_wallet2_api_c.so
|
|
||||||
android/app/src/main/jniLibs/x86_64/libwownero_wallet2_api_c.so
|
|
||||||
macos/monero_wallet2_api_c.dylib
|
|
||||||
macos/wownero_wallet2_api_c.dylib
|
|
||||||
/macos/monero_libwallet2_api_c.dylib
|
|
||||||
/macos/wownero_libwallet2_api_c.dylib
|
|
||||||
/ios/monero_libwallet2_api_c.dylib
|
|
||||||
/ios/wownero_libwallet2_api_c.dylib
|
|
||||||
/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so
|
|
||||||
/android/app/src/main/jniLibs/armeabi-v7a/libmonero_libwallet2_api_c.so
|
|
||||||
/android/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.so
|
|
||||||
/android/app/src/main/jniLibs/arm64-v8a/libwownero_libwallet2_api_c.so
|
|
||||||
/android/app/src/main/jniLibs/armeabi-v7a/libwownero_libwallet2_api_c.so
|
|
||||||
/android/app/src/main/jniLibs/x86_64/libwownero_libwallet2_api_c.so
|
|
||||||
|
|
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -1,12 +1,12 @@
|
||||||
[submodule "crypto_plugins/flutter_libepiccash"]
|
[submodule "crypto_plugins/flutter_libepiccash"]
|
||||||
path = crypto_plugins/flutter_libepiccash
|
path = crypto_plugins/flutter_libepiccash
|
||||||
url = https://github.com/cypherstack/flutter_libepiccash.git
|
url = https://github.com/cypherstack/flutter_libepiccash.git
|
||||||
[submodule "crypto_plugins/flutter_libmonero"]
|
|
||||||
path = crypto_plugins/flutter_libmonero
|
|
||||||
url = https://github.com/cypherstack/flutter_libmonero.git
|
|
||||||
[submodule "crypto_plugins/flutter_liblelantus"]
|
[submodule "crypto_plugins/flutter_liblelantus"]
|
||||||
path = crypto_plugins/flutter_liblelantus
|
path = crypto_plugins/flutter_liblelantus
|
||||||
url = https://github.com/cypherstack/flutter_liblelantus.git
|
url = https://github.com/cypherstack/flutter_liblelantus.git
|
||||||
[submodule "crypto_plugins/frostdart"]
|
[submodule "crypto_plugins/frostdart"]
|
||||||
path = crypto_plugins/frostdart
|
path = crypto_plugins/frostdart
|
||||||
url = https://github.com/cypherstack/frostdart
|
url = https://github.com/cypherstack/frostdart
|
||||||
|
[submodule "crypto_plugins/cs_monero"]
|
||||||
|
path = crypto_plugins/cs_monero
|
||||||
|
url = https://github.com/cypherstack/cs_monero
|
||||||
|
|
1
crypto_plugins/cs_monero
Submodule
1
crypto_plugins/cs_monero
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fee51e29e97ee8c1f57082b126173eeaf39a79f1
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 66369ef5b432e4d58e76b6cc4f91a5e24eb6b1ea
|
|
1
ios/MoneroWallet.framework/.gitignore
vendored
1
ios/MoneroWallet.framework/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
MoneroWallet
|
|
|
@ -1,57 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>BuildMachineOSBuild</key>
|
|
||||||
<string>23E224</string>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>MoneroWallet</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.cypherstack.MoneroWallet</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>MoneroWallet</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>???</string>
|
|
||||||
<key>CFBundleSupportedPlatforms</key>
|
|
||||||
<array>
|
|
||||||
<string>iPhoneOS</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>DTCompiler</key>
|
|
||||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
|
||||||
<key>DTPlatformBuild</key>
|
|
||||||
<string>21E210</string>
|
|
||||||
<key>DTPlatformName</key>
|
|
||||||
<string>iphoneos</string>
|
|
||||||
<key>DTPlatformVersion</key>
|
|
||||||
<string>17.4</string>
|
|
||||||
<key>DTSDKBuild</key>
|
|
||||||
<string>21E210</string>
|
|
||||||
<key>DTSDKName</key>
|
|
||||||
<string>iphoneos17.4</string>
|
|
||||||
<key>DTXcode</key>
|
|
||||||
<string>1530</string>
|
|
||||||
<key>DTXcodeBuild</key>
|
|
||||||
<string>15E204a</string>
|
|
||||||
<key>MinimumOSVersion</key>
|
|
||||||
<string>16.0</string>
|
|
||||||
<key>UIDeviceFamily</key>
|
|
||||||
<array>
|
|
||||||
<integer>1</integer>
|
|
||||||
<integer>2</integer>
|
|
||||||
</array>
|
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
|
||||||
<array>
|
|
||||||
<string>arm64</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
1
ios/WowneroWallet.framework/.gitignore
vendored
1
ios/WowneroWallet.framework/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
WowneroWallet
|
|
|
@ -1,57 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>BuildMachineOSBuild</key>
|
|
||||||
<string>23E224</string>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>WowneroWallet</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.cypherstack.WowneroWallet</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>WowneroWallet</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>???</string>
|
|
||||||
<key>CFBundleSupportedPlatforms</key>
|
|
||||||
<array>
|
|
||||||
<string>iPhoneOS</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>DTCompiler</key>
|
|
||||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
|
||||||
<key>DTPlatformBuild</key>
|
|
||||||
<string>21E210</string>
|
|
||||||
<key>DTPlatformName</key>
|
|
||||||
<string>iphoneos</string>
|
|
||||||
<key>DTPlatformVersion</key>
|
|
||||||
<string>17.4</string>
|
|
||||||
<key>DTSDKBuild</key>
|
|
||||||
<string>21E210</string>
|
|
||||||
<key>DTSDKName</key>
|
|
||||||
<string>iphoneos17.4</string>
|
|
||||||
<key>DTXcode</key>
|
|
||||||
<string>1530</string>
|
|
||||||
<key>DTXcodeBuild</key>
|
|
||||||
<string>15E204a</string>
|
|
||||||
<key>MinimumOSVersion</key>
|
|
||||||
<string>16.0</string>
|
|
||||||
<key>UIDeviceFamily</key>
|
|
||||||
<array>
|
|
||||||
<integer>1</integer>
|
|
||||||
<integer>2</integer>
|
|
||||||
</array>
|
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
|
||||||
<array>
|
|
||||||
<string>arm64</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:cw_core/wallet_info.dart' as xmr;
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
import 'package:hive/hive.dart' show Box;
|
import 'package:hive/hive.dart' show Box;
|
||||||
import 'package:hive/src/hive_impl.dart';
|
import 'package:hive/src/hive_impl.dart';
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
|
@ -71,7 +71,7 @@ class DB {
|
||||||
Box<Trade>? _boxTradesV2;
|
Box<Trade>? _boxTradesV2;
|
||||||
Box<String>? _boxTradeNotes;
|
Box<String>? _boxTradeNotes;
|
||||||
Box<String>? _boxFavoriteWallets;
|
Box<String>? _boxFavoriteWallets;
|
||||||
Box<xmr.WalletInfo>? _walletInfoSource;
|
Box<lib_monero_compat.WalletInfo>? _walletInfoSource;
|
||||||
Box<dynamic>? _boxPrefs;
|
Box<dynamic>? _boxPrefs;
|
||||||
Box<TradeWalletLookup>? _boxTradeLookup;
|
Box<TradeWalletLookup>? _boxTradeLookup;
|
||||||
Box<dynamic>? _boxDBInfo;
|
Box<dynamic>? _boxDBInfo;
|
||||||
|
@ -85,7 +85,8 @@ class DB {
|
||||||
final Map<String, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {};
|
final Map<String, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {};
|
||||||
|
|
||||||
// exposed for monero
|
// exposed for monero
|
||||||
Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource!;
|
Box<lib_monero_compat.WalletInfo> get moneroWalletInfoBox =>
|
||||||
|
_walletInfoSource!;
|
||||||
|
|
||||||
// mutex for stack backup
|
// mutex for stack backup
|
||||||
final mutex = Mutex();
|
final mutex = Mutex();
|
||||||
|
@ -147,8 +148,8 @@ class DB {
|
||||||
_boxTradesV2 = await hive.openBox<Trade>(boxNameTradesV2);
|
_boxTradesV2 = await hive.openBox<Trade>(boxNameTradesV2);
|
||||||
_boxTradeNotes = await hive.openBox<String>(boxNameTradeNotes);
|
_boxTradeNotes = await hive.openBox<String>(boxNameTradeNotes);
|
||||||
_boxTradeLookup = await hive.openBox<TradeWalletLookup>(boxNameTradeLookup);
|
_boxTradeLookup = await hive.openBox<TradeWalletLookup>(boxNameTradeLookup);
|
||||||
_walletInfoSource =
|
_walletInfoSource = await hive.openBox<lib_monero_compat.WalletInfo>(
|
||||||
await hive.openBox<xmr.WalletInfo>(xmr.WalletInfo.boxName);
|
lib_monero_compat.WalletInfo.boxName);
|
||||||
_boxFavoriteWallets = await hive.openBox<String>(boxNameFavoriteWallets);
|
_boxFavoriteWallets = await hive.openBox<String>(boxNameFavoriteWallets);
|
||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
|
|
|
@ -13,11 +13,8 @@ import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:coinlib_flutter/coinlib_flutter.dart';
|
import 'package:coinlib_flutter/coinlib_flutter.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
|
||||||
import 'package:cw_core/wallet_info.dart';
|
|
||||||
import 'package:cw_core/wallet_type.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
@ -92,10 +89,11 @@ void main(List<String> args) async {
|
||||||
StackFileSystem.setDesktopOverrideDir(args.last);
|
StackFileSystem.setDesktopOverrideDir(args.last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell flutter_libmonero how to get access to the application dir
|
// no longer requried
|
||||||
FS.setApplicationRootDirectoryFunction(
|
// // Tell flutter_libmonero how to get access to the application dir
|
||||||
StackFileSystem.applicationRootDirectory,
|
// FS.setApplicationRootDirectoryFunction(
|
||||||
);
|
// StackFileSystem.applicationRootDirectory,
|
||||||
|
// );
|
||||||
// TODO set any other external libs file paths (bad external lib design workaround)
|
// TODO set any other external libs file paths (bad external lib design workaround)
|
||||||
|
|
||||||
final loadCoinlibFuture = loadCoinlib();
|
final loadCoinlibFuture = loadCoinlib();
|
||||||
|
@ -170,15 +168,18 @@ void main(List<String> args) async {
|
||||||
// node model adapter
|
// node model adapter
|
||||||
DB.instance.hive.registerAdapter(NodeModelAdapter());
|
DB.instance.hive.registerAdapter(NodeModelAdapter());
|
||||||
|
|
||||||
DB.instance.hive.registerAdapter(NodeAdapter());
|
// DB.instance.hive.registerAdapter(NodeAdapter());
|
||||||
|
|
||||||
if (!DB.instance.hive.isAdapterRegistered(WalletInfoAdapter().typeId)) {
|
if (!DB.instance.hive
|
||||||
DB.instance.hive.registerAdapter(WalletInfoAdapter());
|
.isAdapterRegistered(lib_monero_compat.WalletInfoAdapter().typeId)) {
|
||||||
|
DB.instance.hive.registerAdapter(lib_monero_compat.WalletInfoAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.instance.hive.registerAdapter(WalletTypeAdapter());
|
DB.instance.hive.registerAdapter(lib_monero_compat.WalletTypeAdapter());
|
||||||
|
|
||||||
DB.instance.hive.registerAdapter(UnspentCoinsInfoAdapter());
|
// DB.instance.hive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||||
|
|
||||||
|
lib_monero.Logging.useLogger = true;
|
||||||
|
|
||||||
DB.instance.hive.init(
|
DB.instance.hive.init(
|
||||||
(await StackFileSystem.applicationHiveDirectory()).path,
|
(await StackFileSystem.applicationHiveDirectory()).path,
|
||||||
|
|
|
@ -67,7 +67,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
|
||||||
late final TextEditingController passwordController;
|
late final TextEditingController passwordController;
|
||||||
|
|
||||||
final bool _nextEnabled = true;
|
final bool _nextEnabled = true;
|
||||||
DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0);
|
DateTime? _restoreFromDate;
|
||||||
bool hidePassword = true;
|
bool hidePassword = true;
|
||||||
bool _expandedAdavnced = false;
|
bool _expandedAdavnced = false;
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:bip39/bip39.dart' as bip39;
|
import 'package:bip39/bip39.dart' as bip39;
|
||||||
import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
|
import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
|
||||||
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_libmonero/monero/monero.dart' as libxmr;
|
|
||||||
import 'package:flutter_libmonero/wownero/wownero.dart' as libwow;
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
@ -86,7 +86,7 @@ class RestoreWalletView extends ConsumerStatefulWidget {
|
||||||
final CryptoCurrency coin;
|
final CryptoCurrency coin;
|
||||||
final String mnemonicPassphrase;
|
final String mnemonicPassphrase;
|
||||||
final int seedWordsLength;
|
final int seedWordsLength;
|
||||||
final DateTime restoreFromDate;
|
final DateTime? restoreFromDate;
|
||||||
final bool enableLelantusScanning;
|
final bool enableLelantusScanning;
|
||||||
|
|
||||||
final BarcodeScannerInterface barcodeScanner;
|
final BarcodeScannerInterface barcodeScanner;
|
||||||
|
@ -181,7 +181,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
||||||
if (widget.coin is Monero) {
|
if (widget.coin is Monero) {
|
||||||
switch (widget.seedWordsLength) {
|
switch (widget.seedWordsLength) {
|
||||||
case 25:
|
case 25:
|
||||||
return libxmr.monero.getMoneroWordList("English").contains(word);
|
return lib_monero.getMoneroWordList("English").contains(word);
|
||||||
case 16:
|
case 16:
|
||||||
return Monero.sixteenWordsWordList.contains(word);
|
return Monero.sixteenWordsWordList.contains(word);
|
||||||
default:
|
default:
|
||||||
|
@ -189,7 +189,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (widget.coin is Wownero) {
|
if (widget.coin is Wownero) {
|
||||||
final wowneroWordList = libwow.wownero.getWowneroWordList(
|
final wowneroWordList = lib_monero.getWowneroWordList(
|
||||||
"English",
|
"English",
|
||||||
seedWordsLength: widget.seedWordsLength,
|
seedWordsLength: widget.seedWordsLength,
|
||||||
);
|
);
|
||||||
|
@ -219,29 +219,35 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
||||||
int height = 0;
|
int height = 0;
|
||||||
String? otherDataJsonString;
|
String? otherDataJsonString;
|
||||||
|
|
||||||
|
if (widget.restoreFromDate != null) {
|
||||||
if (widget.coin is Monero) {
|
if (widget.coin is Monero) {
|
||||||
height = libxmr.monero.getHeigthByDate(date: widget.restoreFromDate);
|
height = lib_monero_compat.getMoneroHeigthByDate(
|
||||||
} else if (widget.coin is Wownero) {
|
date: widget.restoreFromDate!,
|
||||||
height = libwow.wownero.getHeightByDate(date: widget.restoreFromDate);
|
);
|
||||||
|
}
|
||||||
|
if (widget.coin is Wownero) {
|
||||||
|
height = lib_monero_compat.getWowneroHeightByDate(
|
||||||
|
date: widget.restoreFromDate!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (height < 0) {
|
||||||
|
height = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// todo: wait until this implemented
|
|
||||||
// else if (widget.coin is Wownero) {
|
|
||||||
// height = wownero.getHeightByDate(date: widget.restoreFromDate);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
|
// TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
|
||||||
if (widget.coin is Epiccash) {
|
if (widget.coin is Epiccash) {
|
||||||
|
if (widget.restoreFromDate != null) {
|
||||||
final int secondsSinceEpoch =
|
final int secondsSinceEpoch =
|
||||||
widget.restoreFromDate.millisecondsSinceEpoch ~/ 1000;
|
widget.restoreFromDate!.millisecondsSinceEpoch ~/ 1000;
|
||||||
const int epicCashFirstBlock = 1565370278;
|
const int epicCashFirstBlock = 1565370278;
|
||||||
const double overestimateSecondsPerBlock = 61;
|
const double overestimateSecondsPerBlock = 61;
|
||||||
final int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock;
|
final int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock;
|
||||||
final int approximateHeight =
|
final int approximateHeight =
|
||||||
chosenSeconds ~/ overestimateSecondsPerBlock;
|
chosenSeconds ~/ overestimateSecondsPerBlock;
|
||||||
//todo: check if print needed
|
|
||||||
// debugPrint(
|
|
||||||
// "approximate height: $approximateHeight chosen_seconds: $chosenSeconds");
|
|
||||||
height = approximateHeight;
|
height = approximateHeight;
|
||||||
|
}
|
||||||
if (height < 0) {
|
if (height < 0) {
|
||||||
height = 0;
|
height = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ import '../../wallets/crypto_currency/crypto_currency.dart';
|
||||||
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
||||||
import '../../wallets/models/tx_data.dart';
|
import '../../wallets/models/tx_data.dart';
|
||||||
import '../../wallets/wallet/impl/firo_wallet.dart';
|
import '../../wallets/wallet/impl/firo_wallet.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../widgets/background.dart';
|
import '../../widgets/background.dart';
|
||||||
import '../../widgets/conditional_parent.dart';
|
import '../../widgets/conditional_parent.dart';
|
||||||
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
|
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
@ -277,7 +277,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
||||||
// access to this screen but this is needed to get past an error that
|
// access to this screen but this is needed to get past an error that
|
||||||
// would occur only to lead to another error which is why xmr/wow wallets
|
// would occur only to lead to another error which is why xmr/wow wallets
|
||||||
// don't have access to this screen currently
|
// don't have access to this screen currently
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
await wallet.open();
|
await wallet.open();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import '../../utilities/biometrics.dart';
|
||||||
import '../../utilities/flutter_secure_storage_interface.dart';
|
import '../../utilities/flutter_secure_storage_interface.dart';
|
||||||
import '../../utilities/show_loading.dart';
|
import '../../utilities/show_loading.dart';
|
||||||
import '../../utilities/text_styles.dart';
|
import '../../utilities/text_styles.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../widgets/background.dart';
|
import '../../widgets/background.dart';
|
||||||
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
|
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import '../../widgets/custom_buttons/blue_text_button.dart';
|
import '../../widgets/custom_buttons/blue_text_button.dart';
|
||||||
|
@ -102,7 +102,7 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> {
|
||||||
|
|
||||||
final wallet = ref.read(pWallets).getWallet(walletId);
|
final wallet = ref.read(pWallets).getWallet(walletId);
|
||||||
final Future<void> loadFuture;
|
final Future<void> loadFuture;
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
loadFuture =
|
loadFuture =
|
||||||
wallet.init().then((value) async => await (wallet).open());
|
wallet.init().then((value) async => await (wallet).open());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
@ -470,22 +470,22 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
|
|
||||||
Amount fee;
|
Amount fee;
|
||||||
if (coin is Monero) {
|
if (coin is Monero) {
|
||||||
MoneroTransactionPriority specialMoneroId;
|
lib_monero.TransactionPriority specialMoneroId;
|
||||||
switch (ref.read(feeRateTypeStateProvider.state).state) {
|
switch (ref.read(feeRateTypeStateProvider.state).state) {
|
||||||
case FeeRateType.fast:
|
case FeeRateType.fast:
|
||||||
specialMoneroId = MoneroTransactionPriority.fast;
|
specialMoneroId = lib_monero.TransactionPriority.high;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.average:
|
case FeeRateType.average:
|
||||||
specialMoneroId = MoneroTransactionPriority.regular;
|
specialMoneroId = lib_monero.TransactionPriority.medium;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.slow:
|
case FeeRateType.slow:
|
||||||
specialMoneroId = MoneroTransactionPriority.slow;
|
specialMoneroId = lib_monero.TransactionPriority.normal;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError("custom fee not available for monero");
|
throw ArgumentError("custom fee not available for monero");
|
||||||
}
|
}
|
||||||
|
|
||||||
fee = await wallet.estimateFeeFor(amount, specialMoneroId.raw!);
|
fee = await wallet.estimateFeeFor(amount, specialMoneroId.value);
|
||||||
cachedFees[amount] = ref.read(pAmountFormatter(coin)).format(
|
cachedFees[amount] = ref.read(pAmountFormatter(coin)).format(
|
||||||
fee,
|
fee,
|
||||||
withUnitName: true,
|
withUnitName: true,
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import '../../../models/paymint/fee_object_model.dart';
|
import '../../../models/paymint/fee_object_model.dart';
|
||||||
import '../../../providers/providers.dart';
|
import '../../../providers/providers.dart';
|
||||||
import '../../../providers/ui/fee_rate_type_state_provider.dart';
|
import '../../../providers/ui/fee_rate_type_state_provider.dart';
|
||||||
|
@ -90,7 +91,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.fast.raw!,
|
lib_monero.TransactionPriority.high.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -127,7 +128,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.regular.raw!,
|
lib_monero.TransactionPriority.medium.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -163,7 +164,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.slow.raw!,
|
lib_monero.TransactionPriority.normal.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
|
|
@ -272,48 +272,48 @@ class AboutView extends ConsumerWidget {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 12,
|
height: 12,
|
||||||
),
|
),
|
||||||
if (AppConfig.coins.whereType<Monero>().isNotEmpty)
|
// if (AppConfig.coins.whereType<Monero>().isNotEmpty)
|
||||||
FutureBuilder(
|
// FutureBuilder(
|
||||||
future: GitStatus.getMoneroCommitStatus(),
|
// future: GitStatus.getMoneroCommitStatus(),
|
||||||
builder: (
|
// builder: (
|
||||||
context,
|
// context,
|
||||||
AsyncSnapshot<CommitStatus> snapshot,
|
// AsyncSnapshot<CommitStatus> snapshot,
|
||||||
) {
|
// ) {
|
||||||
CommitStatus stateOfCommit =
|
// CommitStatus stateOfCommit =
|
||||||
CommitStatus.notLoaded;
|
// CommitStatus.notLoaded;
|
||||||
|
//
|
||||||
if (snapshot.connectionState ==
|
// if (snapshot.connectionState ==
|
||||||
ConnectionState.done &&
|
// ConnectionState.done &&
|
||||||
snapshot.hasData) {
|
// snapshot.hasData) {
|
||||||
stateOfCommit = snapshot.data!;
|
// stateOfCommit = snapshot.data!;
|
||||||
}
|
// }
|
||||||
return RoundedWhiteContainer(
|
// return RoundedWhiteContainer(
|
||||||
child: Column(
|
// child: Column(
|
||||||
crossAxisAlignment:
|
// crossAxisAlignment:
|
||||||
CrossAxisAlignment.stretch,
|
// CrossAxisAlignment.stretch,
|
||||||
children: [
|
// children: [
|
||||||
Text(
|
// Text(
|
||||||
"Monero Build Commit",
|
// "Monero Build Commit",
|
||||||
style: STextStyles.titleBold12(context),
|
// style: STextStyles.titleBold12(context),
|
||||||
),
|
// ),
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 4,
|
// height: 4,
|
||||||
),
|
// ),
|
||||||
SelectableText(
|
// SelectableText(
|
||||||
GitStatus.moneroCommit,
|
// GitStatus.moneroCommit,
|
||||||
style: GitStatus.styleForStatus(
|
// style: GitStatus.styleForStatus(
|
||||||
stateOfCommit,
|
// stateOfCommit,
|
||||||
context,
|
// context,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 12,
|
// height: 12,
|
||||||
),
|
// ),
|
||||||
RoundedWhiteContainer(
|
RoundedWhiteContainer(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
|
import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
|
||||||
import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
|
// import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
|
import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
|
||||||
|
@ -313,8 +313,8 @@ class _DebugViewState extends ConsumerState<DebugView> {
|
||||||
FIRO_VERSIONS.getPluginVersion();
|
FIRO_VERSIONS.getPluginVersion();
|
||||||
final String epicCashCommit =
|
final String epicCashCommit =
|
||||||
EPIC_VERSIONS.getPluginVersion();
|
EPIC_VERSIONS.getPluginVersion();
|
||||||
final String moneroCommit =
|
// final String moneroCommit =
|
||||||
MONERO_VERSIONS.getPluginVersion();
|
// MONERO_VERSIONS.getPluginVersion();
|
||||||
final DeviceInfoPlugin deviceInfoPlugin =
|
final DeviceInfoPlugin deviceInfoPlugin =
|
||||||
DeviceInfoPlugin();
|
DeviceInfoPlugin();
|
||||||
final deviceInfo =
|
final deviceInfo =
|
||||||
|
@ -347,7 +347,7 @@ class _DebugViewState extends ConsumerState<DebugView> {
|
||||||
"appName": appName,
|
"appName": appName,
|
||||||
"firoCommit": firoCommit,
|
"firoCommit": firoCommit,
|
||||||
"epicCashCommit": epicCashCommit,
|
"epicCashCommit": epicCashCommit,
|
||||||
"moneroCommit": moneroCommit,
|
// "moneroCommit": moneroCommit,
|
||||||
"deviceInfoMap": deviceInfoMap,
|
"deviceInfoMap": deviceInfoMap,
|
||||||
"errorLogs": errorLogs,
|
"errorLogs": errorLogs,
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../utilities/util.dart';
|
import '../../../../utilities/util.dart';
|
||||||
import '../../../../wallets/crypto_currency/crypto_currency.dart';
|
import '../../../../wallets/crypto_currency/crypto_currency.dart';
|
||||||
import '../../../../wallets/crypto_currency/intermediate/cryptonote_currency.dart';
|
import '../../../../wallets/crypto_currency/intermediate/cryptonote_currency.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../../widgets/background.dart';
|
import '../../../../widgets/background.dart';
|
||||||
import '../../../../widgets/conditional_parent.dart';
|
import '../../../../widgets/conditional_parent.dart';
|
||||||
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
|
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
@ -222,7 +222,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
|
||||||
|
|
||||||
// strip unused path
|
// strip unused path
|
||||||
String address = formData.host!;
|
String address = formData.host!;
|
||||||
if (coin is CwBasedInterface) {
|
if (coin is LibMoneroWallet) {
|
||||||
if (address.startsWith("http")) {
|
if (address.startsWith("http")) {
|
||||||
final uri = Uri.parse(address);
|
final uri = Uri.parse(address);
|
||||||
address = "${uri.scheme}://${uri.host}";
|
address = "${uri.scheme}://${uri.host}";
|
||||||
|
@ -837,7 +837,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
||||||
} else {
|
} else {
|
||||||
enableSSLCheckbox = true;
|
enableSSLCheckbox = true;
|
||||||
}
|
}
|
||||||
} else if (widget.coin is CwBasedInterface) {
|
} else if (widget.coin is LibMoneroWallet) {
|
||||||
if (newValue.startsWith("https://")) {
|
if (newValue.startsWith("https://")) {
|
||||||
_useSSL = true;
|
_useSSL = true;
|
||||||
} else if (newValue.startsWith("http://")) {
|
} else if (newValue.startsWith("http://")) {
|
||||||
|
@ -1052,7 +1052,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (widget.coin is CwBasedInterface)
|
if (widget.coin is LibMoneroWallet)
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
|
|
|
@ -54,8 +54,8 @@ import '../../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
||||||
import '../../../../../wallets/wallet/impl/epiccash_wallet.dart';
|
import '../../../../../wallets/wallet/impl/epiccash_wallet.dart';
|
||||||
import '../../../../../wallets/wallet/impl/monero_wallet.dart';
|
import '../../../../../wallets/wallet/impl/monero_wallet.dart';
|
||||||
import '../../../../../wallets/wallet/impl/wownero_wallet.dart';
|
import '../../../../../wallets/wallet/impl/wownero_wallet.dart';
|
||||||
|
import '../../../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../../../wallets/wallet/wallet.dart';
|
import '../../../../../wallets/wallet/wallet.dart';
|
||||||
import '../../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
|
||||||
import '../../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../../../../wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
|
import '../../../../../wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ abstract class SWB {
|
||||||
|
|
||||||
Future<void>? restoringFuture;
|
Future<void>? restoringFuture;
|
||||||
|
|
||||||
if (!(wallet is CwBasedInterface || wallet is EpiccashWallet)) {
|
if (!(wallet is LibMoneroWallet || wallet is EpiccashWallet)) {
|
||||||
if (wallet is BitcoinFrostWallet) {
|
if (wallet is BitcoinFrostWallet) {
|
||||||
restoringFuture = wallet.recover(
|
restoringFuture = wallet.recover(
|
||||||
isRescan: false,
|
isRescan: false,
|
||||||
|
|
|
@ -36,7 +36,7 @@ import '../../../wallets/crypto_currency/intermediate/frost_currency.dart';
|
||||||
import '../../../wallets/crypto_currency/intermediate/nano_currency.dart';
|
import '../../../wallets/crypto_currency/intermediate/nano_currency.dart';
|
||||||
import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
||||||
import '../../../wallets/wallet/impl/epiccash_wallet.dart';
|
import '../../../wallets/wallet/impl/epiccash_wallet.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../../widgets/background.dart';
|
import '../../../widgets/background.dart';
|
||||||
|
@ -307,7 +307,7 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
|
||||||
KeyDataInterface? keyData;
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
keyData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
} else if (wallet is CwBasedInterface) {
|
} else if (wallet is LibMoneroWallet) {
|
||||||
keyData = await wallet.getKeys();
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import '../../utilities/assets.dart';
|
||||||
import '../../utilities/text_styles.dart';
|
import '../../utilities/text_styles.dart';
|
||||||
import '../../utilities/util.dart';
|
import '../../utilities/util.dart';
|
||||||
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../widgets/background.dart';
|
import '../../widgets/background.dart';
|
||||||
|
@ -270,7 +270,7 @@ class _FiroRescanRecoveryErrorViewState
|
||||||
KeyDataInterface? keyData;
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
keyData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
} else if (wallet is CwBasedInterface) {
|
} else if (wallet is LibMoneroWallet) {
|
||||||
keyData = await wallet.getKeys();
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import '../../wallet_view/wallet_view.dart';
|
|
||||||
import '../../../pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart';
|
import '../../../pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart';
|
||||||
import '../../../providers/providers.dart';
|
import '../../../providers/providers.dart';
|
||||||
import '../../../themes/coin_icon_provider.dart';
|
import '../../../themes/coin_icon_provider.dart';
|
||||||
|
@ -26,9 +26,10 @@ import '../../../utilities/text_styles.dart';
|
||||||
import '../../../utilities/util.dart';
|
import '../../../utilities/util.dart';
|
||||||
import '../../../wallets/crypto_currency/coins/firo.dart';
|
import '../../../wallets/crypto_currency/coins/firo.dart';
|
||||||
import '../../../wallets/isar/providers/wallet_info_provider.dart';
|
import '../../../wallets/isar/providers/wallet_info_provider.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../widgets/coin_card.dart';
|
import '../../../widgets/coin_card.dart';
|
||||||
import '../../../widgets/conditional_parent.dart';
|
import '../../../widgets/conditional_parent.dart';
|
||||||
|
import '../../wallet_view/wallet_view.dart';
|
||||||
|
|
||||||
class FavoriteCard extends ConsumerStatefulWidget {
|
class FavoriteCard extends ConsumerStatefulWidget {
|
||||||
const FavoriteCard({
|
const FavoriteCard({
|
||||||
|
@ -117,7 +118,7 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
|
||||||
final wallet = ref.read(pWallets).getWallet(walletId);
|
final wallet = ref.read(pWallets).getWallet(walletId);
|
||||||
|
|
||||||
final Future<void> loadFuture;
|
final Future<void> loadFuture;
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
loadFuture =
|
loadFuture =
|
||||||
wallet.init().then((value) async => await (wallet).open());
|
wallet.init().then((value) async => await (wallet).open());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import '../../../utilities/show_loading.dart';
|
||||||
import '../../../utilities/text_styles.dart';
|
import '../../../utilities/text_styles.dart';
|
||||||
import '../../../utilities/util.dart';
|
import '../../../utilities/util.dart';
|
||||||
import '../../../wallets/crypto_currency/crypto_currency.dart';
|
import '../../../wallets/crypto_currency/crypto_currency.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../widgets/dialogs/tor_warning_dialog.dart';
|
import '../../../widgets/dialogs/tor_warning_dialog.dart';
|
||||||
import '../../../widgets/rounded_white_container.dart';
|
import '../../../widgets/rounded_white_container.dart';
|
||||||
import '../../wallet_view/wallet_view.dart';
|
import '../../wallet_view/wallet_view.dart';
|
||||||
|
@ -84,7 +84,7 @@ class WalletListItem extends ConsumerWidget {
|
||||||
.wallets
|
.wallets
|
||||||
.firstWhere((e) => e.info.coin == coin);
|
.firstWhere((e) => e.info.coin == coin);
|
||||||
final Future<void> loadFuture;
|
final Future<void> loadFuture;
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
loadFuture =
|
loadFuture =
|
||||||
wallet.init().then((value) async => await (wallet).open());
|
wallet.init().then((value) async => await (wallet).open());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'wallet_view/desktop_wallet_view.dart';
|
|
||||||
import '../../providers/global/active_wallet_provider.dart';
|
import '../../providers/global/active_wallet_provider.dart';
|
||||||
import '../../providers/global/wallets_provider.dart';
|
import '../../providers/global/wallets_provider.dart';
|
||||||
import '../../themes/stack_colors.dart';
|
import '../../themes/stack_colors.dart';
|
||||||
|
@ -18,9 +18,10 @@ import '../../utilities/constants.dart';
|
||||||
import '../../utilities/show_loading.dart';
|
import '../../utilities/show_loading.dart';
|
||||||
import '../../utilities/util.dart';
|
import '../../utilities/util.dart';
|
||||||
import '../../wallets/crypto_currency/crypto_currency.dart';
|
import '../../wallets/crypto_currency/crypto_currency.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../widgets/rounded_container.dart';
|
import '../../widgets/rounded_container.dart';
|
||||||
import '../../widgets/wallet_info_row/wallet_info_row.dart';
|
import '../../widgets/wallet_info_row/wallet_info_row.dart';
|
||||||
|
import 'wallet_view/desktop_wallet_view.dart';
|
||||||
|
|
||||||
class CoinWalletsTable extends ConsumerWidget {
|
class CoinWalletsTable extends ConsumerWidget {
|
||||||
const CoinWalletsTable({
|
const CoinWalletsTable({
|
||||||
|
@ -81,7 +82,7 @@ class CoinWalletsTable extends ConsumerWidget {
|
||||||
final wallet =
|
final wallet =
|
||||||
ref.read(pWallets).getWallet(walletIds[i]);
|
ref.read(pWallets).getWallet(walletIds[i]);
|
||||||
final Future<void> loadFuture;
|
final Future<void> loadFuture;
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
loadFuture = wallet
|
loadFuture = wallet
|
||||||
.init()
|
.init()
|
||||||
.then((value) async => await (wallet).open());
|
.then((value) async => await (wallet).open());
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.fast.raw!,
|
lib_monero.TransactionPriority.high.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -136,7 +136,7 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.regular.raw!,
|
lib_monero.TransactionPriority.medium.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -186,7 +186,7 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.slow.raw!,
|
lib_monero.TransactionPriority.normal.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
@ -1860,7 +1860,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.regular.raw!,
|
lib_monero.TransactionPriority.medium.value,
|
||||||
);
|
);
|
||||||
ref
|
ref
|
||||||
.read(feeSheetSessionCacheProvider)
|
.read(feeSheetSessionCacheProvider)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import '../../../../utilities/assets.dart';
|
||||||
import '../../../../utilities/constants.dart';
|
import '../../../../utilities/constants.dart';
|
||||||
import '../../../../utilities/text_styles.dart';
|
import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
import '../../../../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../../../widgets/desktop/desktop_dialog.dart';
|
import '../../../../widgets/desktop/desktop_dialog.dart';
|
||||||
|
@ -106,7 +106,7 @@ class _UnlockWalletKeysDesktopState
|
||||||
KeyDataInterface? keyData;
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
keyData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
} else if (wallet is CwBasedInterface) {
|
} else if (wallet is LibMoneroWallet) {
|
||||||
keyData = await wallet.getKeys();
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ class _UnlockWalletKeysDesktopState
|
||||||
KeyDataInterface? keyData;
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
keyData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
} else if (wallet is CwBasedInterface) {
|
} else if (wallet is LibMoneroWallet) {
|
||||||
keyData = await wallet.getKeys();
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,63 +434,63 @@ class DesktopAboutView extends ConsumerWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (AppConfig.coins
|
// if (AppConfig.coins
|
||||||
.whereType<Monero>()
|
// .whereType<Monero>()
|
||||||
.isNotEmpty)
|
// .isNotEmpty)
|
||||||
FutureBuilder(
|
// FutureBuilder(
|
||||||
future: GitStatus
|
// future: GitStatus
|
||||||
.getMoneroCommitStatus(),
|
// .getMoneroCommitStatus(),
|
||||||
builder: (
|
// builder: (
|
||||||
context,
|
// context,
|
||||||
AsyncSnapshot<CommitStatus>
|
// AsyncSnapshot<CommitStatus>
|
||||||
snapshot,
|
// snapshot,
|
||||||
) {
|
// ) {
|
||||||
CommitStatus stateOfCommit =
|
// CommitStatus stateOfCommit =
|
||||||
CommitStatus.notLoaded;
|
// CommitStatus.notLoaded;
|
||||||
|
//
|
||||||
if (snapshot.connectionState ==
|
// if (snapshot.connectionState ==
|
||||||
ConnectionState
|
// ConnectionState
|
||||||
.done &&
|
// .done &&
|
||||||
snapshot.hasData) {
|
// snapshot.hasData) {
|
||||||
stateOfCommit =
|
// stateOfCommit =
|
||||||
snapshot.data!;
|
// snapshot.data!;
|
||||||
}
|
// }
|
||||||
return Column(
|
// return Column(
|
||||||
mainAxisSize:
|
// mainAxisSize:
|
||||||
MainAxisSize.min,
|
// MainAxisSize.min,
|
||||||
crossAxisAlignment:
|
// crossAxisAlignment:
|
||||||
CrossAxisAlignment
|
// CrossAxisAlignment
|
||||||
.start,
|
// .start,
|
||||||
children: [
|
// children: [
|
||||||
Text(
|
// Text(
|
||||||
"Monero Build Commit",
|
// "Monero Build Commit",
|
||||||
style: STextStyles
|
// style: STextStyles
|
||||||
.desktopTextExtraExtraSmall(
|
// .desktopTextExtraExtraSmall(
|
||||||
context,
|
// context,
|
||||||
).copyWith(
|
// ).copyWith(
|
||||||
color: Theme.of(
|
// color: Theme.of(
|
||||||
context,
|
// context,
|
||||||
)
|
// )
|
||||||
.extension<
|
// .extension<
|
||||||
StackColors>()!
|
// StackColors>()!
|
||||||
.textDark,
|
// .textDark,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 2,
|
// height: 2,
|
||||||
),
|
// ),
|
||||||
SelectableText(
|
// SelectableText(
|
||||||
GitStatus.moneroCommit,
|
// GitStatus.moneroCommit,
|
||||||
style: GitStatus
|
// style: GitStatus
|
||||||
.styleForStatus(
|
// .styleForStatus(
|
||||||
stateOfCommit,
|
// stateOfCommit,
|
||||||
context,
|
// context,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 35),
|
const SizedBox(height: 35),
|
||||||
|
|
|
@ -1456,7 +1456,7 @@ class RouteGenerator {
|
||||||
|
|
||||||
case RestoreWalletView.routeName:
|
case RestoreWalletView.routeName:
|
||||||
if (args
|
if (args
|
||||||
is Tuple6<String, CryptoCurrency, int, DateTime, String, bool>) {
|
is Tuple6<String, CryptoCurrency, int, DateTime?, String, bool>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => RestoreWalletView(
|
builder: (_) => RestoreWalletView(
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_libmonero/monero/monero.dart' as monero;
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
import 'package:flutter_libmonero/wownero/wownero.dart' as wownero;
|
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
import '../app_config.dart';
|
import '../app_config.dart';
|
||||||
|
@ -21,11 +20,12 @@ import '../utilities/enums/sync_type_enum.dart';
|
||||||
import '../utilities/flutter_secure_storage_interface.dart';
|
import '../utilities/flutter_secure_storage_interface.dart';
|
||||||
import '../utilities/logger.dart';
|
import '../utilities/logger.dart';
|
||||||
import '../utilities/prefs.dart';
|
import '../utilities/prefs.dart';
|
||||||
|
import '../utilities/stack_file_system.dart';
|
||||||
import '../wallets/crypto_currency/crypto_currency.dart';
|
import '../wallets/crypto_currency/crypto_currency.dart';
|
||||||
import '../wallets/isar/models/wallet_info.dart';
|
import '../wallets/isar/models/wallet_info.dart';
|
||||||
import '../wallets/wallet/impl/epiccash_wallet.dart';
|
import '../wallets/wallet/impl/epiccash_wallet.dart';
|
||||||
|
import '../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../wallets/wallet/wallet.dart';
|
import '../wallets/wallet/wallet.dart';
|
||||||
import '../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
|
||||||
import 'event_bus/events/wallet_added_event.dart';
|
import 'event_bus/events/wallet_added_event.dart';
|
||||||
import 'event_bus/global_event_bus.dart';
|
import 'event_bus/global_event_bus.dart';
|
||||||
import 'node_service.dart';
|
import 'node_service.dart';
|
||||||
|
@ -86,15 +86,19 @@ class Wallets {
|
||||||
await secureStorage.delete(key: Wallet.privateKeyKey(walletId: walletId));
|
await secureStorage.delete(key: Wallet.privateKeyKey(walletId: walletId));
|
||||||
|
|
||||||
if (info.coin is Wownero) {
|
if (info.coin is Wownero) {
|
||||||
final wowService = wownero.wownero
|
await lib_monero_compat.deleteWalletFiles(
|
||||||
.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
|
name: walletId,
|
||||||
await wowService.remove(walletId);
|
type: lib_monero_compat.WalletType.wownero,
|
||||||
|
appRoot: await StackFileSystem.applicationRootDirectory(),
|
||||||
|
);
|
||||||
Logging.instance
|
Logging.instance
|
||||||
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
|
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
|
||||||
} else if (info.coin is Monero) {
|
} else if (info.coin is Monero) {
|
||||||
final xmrService = monero.monero
|
await lib_monero_compat.deleteWalletFiles(
|
||||||
.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
|
name: walletId,
|
||||||
await xmrService.remove(walletId);
|
type: lib_monero_compat.WalletType.monero,
|
||||||
|
appRoot: await StackFileSystem.applicationRootDirectory(),
|
||||||
|
);
|
||||||
Logging.instance
|
Logging.instance
|
||||||
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
|
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
|
||||||
} else if (info.coin is Epiccash) {
|
} else if (info.coin is Epiccash) {
|
||||||
|
@ -220,7 +224,7 @@ class Wallets {
|
||||||
final shouldSetAutoSync = shouldAutoSyncAll ||
|
final shouldSetAutoSync = shouldAutoSyncAll ||
|
||||||
walletIdsToEnableAutoSync.contains(walletInfo.walletId);
|
walletIdsToEnableAutoSync.contains(walletInfo.walletId);
|
||||||
|
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
} else {
|
} else {
|
||||||
walletInitFutures.add(
|
walletInitFutures.add(
|
||||||
|
@ -327,7 +331,7 @@ class Wallets {
|
||||||
nodeService: nodeService,
|
nodeService: nodeService,
|
||||||
prefs: prefs,
|
prefs: prefs,
|
||||||
).then((wallet) {
|
).then((wallet) {
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
|
|
||||||
walletIdCompleter.complete("dummy_ignore");
|
walletIdCompleter.complete("dummy_ignore");
|
||||||
|
@ -457,7 +461,7 @@ class Wallets {
|
||||||
nodeService: nodeService,
|
nodeService: nodeService,
|
||||||
prefs: prefs,
|
prefs: prefs,
|
||||||
).then((wallet) {
|
).then((wallet) {
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
|
|
||||||
walletIdCompleter.complete("dummy_ignore");
|
walletIdCompleter.complete("dummy_ignore");
|
||||||
|
@ -577,7 +581,7 @@ class Wallets {
|
||||||
walletIdsToEnableAutoSync.contains(wallet.walletId);
|
walletIdsToEnableAutoSync.contains(wallet.walletId);
|
||||||
|
|
||||||
if (isDesktop) {
|
if (isDesktop) {
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
} else {
|
} else {
|
||||||
walletInitFutures.add(
|
walletInitFutures.add(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_libepiccash/git_versions.dart' as epic_versions;
|
import 'package:flutter_libepiccash/git_versions.dart' as epic_versions;
|
||||||
import 'package:flutter_libmonero/git_versions.dart' as monero_versions;
|
// import 'package:flutter_libmonero/git_versions.dart' as monero_versions;
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:lelantus/git_versions.dart' as firo_versions;
|
import 'package:lelantus/git_versions.dart' as firo_versions;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded }
|
||||||
abstract class GitStatus {
|
abstract class GitStatus {
|
||||||
static String get firoCommit => firo_versions.getPluginVersion();
|
static String get firoCommit => firo_versions.getPluginVersion();
|
||||||
static String get epicCashCommit => epic_versions.getPluginVersion();
|
static String get epicCashCommit => epic_versions.getPluginVersion();
|
||||||
static String get moneroCommit => monero_versions.getPluginVersion();
|
// static String get moneroCommit => monero_versions.getPluginVersion();
|
||||||
|
|
||||||
static String get appCommitHash => AppConfig.commitHash;
|
static String get appCommitHash => AppConfig.commitHash;
|
||||||
|
|
||||||
|
@ -78,31 +78,31 @@ abstract class GitStatus {
|
||||||
|
|
||||||
return _cachedEpicStatus!;
|
return _cachedEpicStatus!;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
static CommitStatus? _cachedMoneroStatus;
|
// static CommitStatus? _cachedMoneroStatus;
|
||||||
static Future<CommitStatus> getMoneroCommitStatus() async {
|
// static Future<CommitStatus> getMoneroCommitStatus() async {
|
||||||
if (_cachedMoneroStatus != null) {
|
// if (_cachedMoneroStatus != null) {
|
||||||
return _cachedMoneroStatus!;
|
// return _cachedMoneroStatus!;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
final List<bool> results = await Future.wait([
|
// final List<bool> results = await Future.wait([
|
||||||
_doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
|
// _doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
|
||||||
_isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
|
// _isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
|
||||||
]);
|
// ]);
|
||||||
|
//
|
||||||
final commitExists = results[0];
|
// final commitExists = results[0];
|
||||||
final commitIsHead = results[1];
|
// final commitIsHead = results[1];
|
||||||
|
//
|
||||||
if (commitExists && commitIsHead) {
|
// if (commitExists && commitIsHead) {
|
||||||
_cachedMoneroStatus = CommitStatus.isHead;
|
// _cachedMoneroStatus = CommitStatus.isHead;
|
||||||
} else if (commitExists) {
|
// } else if (commitExists) {
|
||||||
_cachedMoneroStatus = CommitStatus.isOldCommit;
|
// _cachedMoneroStatus = CommitStatus.isOldCommit;
|
||||||
} else {
|
// } else {
|
||||||
_cachedMoneroStatus = CommitStatus.notACommit;
|
// _cachedMoneroStatus = CommitStatus.notACommit;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return _cachedMoneroStatus!;
|
// return _cachedMoneroStatus!;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static TextStyle styleForStatus(CommitStatus status, BuildContext context) {
|
static TextStyle styleForStatus(CommitStatus status, BuildContext context) {
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:cw_monero/pending_monero_transaction.dart';
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:cw_wownero/pending_wownero_transaction.dart';
|
|
||||||
import 'package:tezart/tezart.dart' as tezart;
|
import 'package:tezart/tezart.dart' as tezart;
|
||||||
import 'package:web3dart/web3dart.dart' as web3dart;
|
import 'package:web3dart/web3dart.dart' as web3dart;
|
||||||
|
|
||||||
|
@ -49,11 +48,8 @@ class TxData {
|
||||||
final BigInt? chainId;
|
final BigInt? chainId;
|
||||||
final BigInt? feeInWei;
|
final BigInt? feeInWei;
|
||||||
|
|
||||||
// wownero specific
|
// wownero and monero specific
|
||||||
final PendingWowneroTransaction? pendingWowneroTransaction;
|
final lib_monero.PendingTransaction? pendingTransaction;
|
||||||
|
|
||||||
// monero specific
|
|
||||||
final PendingMoneroTransaction? pendingMoneroTransaction;
|
|
||||||
|
|
||||||
// firo lelantus specific
|
// firo lelantus specific
|
||||||
final int? jMintValue;
|
final int? jMintValue;
|
||||||
|
@ -104,8 +100,7 @@ class TxData {
|
||||||
this.nonce,
|
this.nonce,
|
||||||
this.chainId,
|
this.chainId,
|
||||||
this.feeInWei,
|
this.feeInWei,
|
||||||
this.pendingWowneroTransaction,
|
this.pendingTransaction,
|
||||||
this.pendingMoneroTransaction,
|
|
||||||
this.jMintValue,
|
this.jMintValue,
|
||||||
this.spendCoinIndexes,
|
this.spendCoinIndexes,
|
||||||
this.height,
|
this.height,
|
||||||
|
@ -196,8 +191,7 @@ class TxData {
|
||||||
int? nonce,
|
int? nonce,
|
||||||
BigInt? chainId,
|
BigInt? chainId,
|
||||||
BigInt? feeInWei,
|
BigInt? feeInWei,
|
||||||
PendingWowneroTransaction? pendingWowneroTransaction,
|
lib_monero.PendingTransaction? pendingTransaction,
|
||||||
PendingMoneroTransaction? pendingMoneroTransaction,
|
|
||||||
int? jMintValue,
|
int? jMintValue,
|
||||||
List<int>? spendCoinIndexes,
|
List<int>? spendCoinIndexes,
|
||||||
int? height,
|
int? height,
|
||||||
|
@ -241,10 +235,7 @@ class TxData {
|
||||||
nonce: nonce ?? this.nonce,
|
nonce: nonce ?? this.nonce,
|
||||||
chainId: chainId ?? this.chainId,
|
chainId: chainId ?? this.chainId,
|
||||||
feeInWei: feeInWei ?? this.feeInWei,
|
feeInWei: feeInWei ?? this.feeInWei,
|
||||||
pendingWowneroTransaction:
|
pendingTransaction: pendingTransaction ?? this.pendingTransaction,
|
||||||
pendingWowneroTransaction ?? this.pendingWowneroTransaction,
|
|
||||||
pendingMoneroTransaction:
|
|
||||||
pendingMoneroTransaction ?? this.pendingMoneroTransaction,
|
|
||||||
jMintValue: jMintValue ?? this.jMintValue,
|
jMintValue: jMintValue ?? this.jMintValue,
|
||||||
spendCoinIndexes: spendCoinIndexes ?? this.spendCoinIndexes,
|
spendCoinIndexes: spendCoinIndexes ?? this.spendCoinIndexes,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
|
@ -284,8 +275,7 @@ class TxData {
|
||||||
'nonce: $nonce, '
|
'nonce: $nonce, '
|
||||||
'chainId: $chainId, '
|
'chainId: $chainId, '
|
||||||
'feeInWei: $feeInWei, '
|
'feeInWei: $feeInWei, '
|
||||||
'pendingWowneroTransaction: $pendingWowneroTransaction, '
|
'pendingTransaction: $pendingTransaction, '
|
||||||
'pendingMoneroTransaction: $pendingMoneroTransaction, '
|
|
||||||
'jMintValue: $jMintValue, '
|
'jMintValue: $jMintValue, '
|
||||||
'spendCoinIndexes: $spendCoinIndexes, '
|
'spendCoinIndexes: $spendCoinIndexes, '
|
||||||
'height: $height, '
|
'height: $height, '
|
||||||
|
|
|
@ -1,206 +1,51 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
|
||||||
import 'package:cw_core/sync_status.dart';
|
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
|
||||||
import 'package:cw_core/utxo.dart' as cw;
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
|
||||||
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_monero/monero_wallet.dart';
|
|
||||||
import 'package:cw_monero/monero_wallet_service.dart';
|
|
||||||
import 'package:cw_monero/pending_monero_transaction.dart';
|
|
||||||
import 'package:decimal/decimal.dart';
|
|
||||||
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
|
||||||
import 'package:flutter_libmonero/monero/monero.dart' as xmr_dart;
|
|
||||||
import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output;
|
|
||||||
import 'package:isar/isar.dart';
|
|
||||||
import 'package:mutex/mutex.dart';
|
|
||||||
import 'package:tuple/tuple.dart';
|
|
||||||
|
|
||||||
import '../../../db/hive/db.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/utxo.dart';
|
|
||||||
import '../../../models/keys/cw_key_data.dart';
|
|
||||||
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
|
||||||
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/amount/amount.dart';
|
||||||
import '../../../utilities/enums/fee_rate_type_enum.dart';
|
|
||||||
import '../../../utilities/logger.dart';
|
|
||||||
import '../../crypto_currency/crypto_currency.dart';
|
import '../../crypto_currency/crypto_currency.dart';
|
||||||
import '../../models/tx_data.dart';
|
import '../intermediate/lib_monero_wallet.dart';
|
||||||
import '../intermediate/cryptonote_wallet.dart';
|
|
||||||
import '../wallet.dart';
|
|
||||||
import '../wallet_mixin_interfaces/cw_based_interface.dart';
|
|
||||||
|
|
||||||
class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
class MoneroWallet extends LibMoneroWallet {
|
||||||
MoneroWallet(CryptoCurrencyNetwork network) : super(Monero(network)) {
|
MoneroWallet(CryptoCurrencyNetwork network)
|
||||||
final bus = GlobalEventBus.instance;
|
: super(
|
||||||
|
Monero(network),
|
||||||
// Listen for tor status changes.
|
lib_monero_compat.WalletType.monero,
|
||||||
_torStatusListener = bus.on<TorConnectionStatusChangedEvent>().listen(
|
|
||||||
(event) async {
|
|
||||||
switch (event.newStatus) {
|
|
||||||
case TorConnectionStatus.connecting:
|
|
||||||
if (!_torConnectingLock.isLocked) {
|
|
||||||
await _torConnectingLock.acquire();
|
|
||||||
}
|
|
||||||
_requireMutex = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TorConnectionStatus.connected:
|
|
||||||
case TorConnectionStatus.disconnected:
|
|
||||||
if (_torConnectingLock.isLocked) {
|
|
||||||
_torConnectingLock.release();
|
|
||||||
}
|
|
||||||
_requireMutex = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Listen for tor preference changes.
|
|
||||||
_torPreferenceListener = bus.on<TorPreferenceChangedEvent>().listen(
|
|
||||||
(event) async {
|
|
||||||
await updateNode();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Potentially dangerous hack. See comments in _startInit()
|
|
||||||
_startInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cw based wallet listener to handle synchronization of utxo frozen states
|
|
||||||
late final StreamSubscription<List<UTXO>> _streamSub;
|
|
||||||
Future<void> _startInit() async {
|
|
||||||
// Delay required as `mainDB` is not initialized in constructor.
|
|
||||||
// This is a hack and could lead to a race condition.
|
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
|
||||||
_streamSub = mainDB.isar.utxos
|
|
||||||
.where()
|
|
||||||
.walletIdEqualTo(walletId)
|
|
||||||
.watch(fireImmediately: true)
|
|
||||||
.listen((utxos) async {
|
|
||||||
await onUTXOsCHanged(utxos);
|
|
||||||
await updateBalance(shouldUpdateUtxos: false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
MoneroWalletBase? cwWalletBase;
|
|
||||||
|
|
||||||
@override
|
|
||||||
MoneroWalletService? cwWalletService;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Address addressFor({required int index, int account = 0}) {
|
|
||||||
final String address = (cwWalletBase as MoneroWalletBase)
|
|
||||||
.getTransactionAddress(account, index);
|
|
||||||
|
|
||||||
final newReceivingAddress = Address(
|
|
||||||
walletId: walletId,
|
|
||||||
derivationIndex: index,
|
|
||||||
derivationPath: null,
|
|
||||||
value: address,
|
|
||||||
publicKey: [],
|
|
||||||
type: AddressType.cryptonote,
|
|
||||||
subType: AddressSubType.receiving,
|
|
||||||
);
|
|
||||||
|
|
||||||
return newReceivingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> open() async {
|
|
||||||
String? password;
|
|
||||||
try {
|
|
||||||
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
|
||||||
} catch (e, s) {
|
|
||||||
throw Exception("Password not found $e, $s");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wasNull = false;
|
|
||||||
|
|
||||||
if (cwWalletBase == null) {
|
|
||||||
wasNull = true;
|
|
||||||
// cwWalletBaseT?.close();
|
|
||||||
cwWalletBase ??= (await cwWalletService!.openWallet(walletId, password))
|
|
||||||
as MoneroWalletBase;
|
|
||||||
|
|
||||||
cwWalletBase?.onNewBlock ??= onNewBlock;
|
|
||||||
cwWalletBase?.onNewTransaction ??= onNewTransaction;
|
|
||||||
cwWalletBase?.syncStatusChanged ??= syncStatusChanged;
|
|
||||||
|
|
||||||
await updateNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
Address? currentAddress = await getCurrentReceivingAddress();
|
|
||||||
if (currentAddress == null) {
|
|
||||||
currentAddress = addressFor(index: 0);
|
|
||||||
await mainDB.updateOrPutAddresses([currentAddress]);
|
|
||||||
}
|
|
||||||
if (info.cachedReceivingAddress != currentAddress.value) {
|
|
||||||
await info.updateReceivingAddress(
|
|
||||||
newAddress: currentAddress.value,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wasNull) {
|
|
||||||
await cwWalletBase?.startSync();
|
|
||||||
} else {
|
|
||||||
cwWalletBase?.wallet.startListeners();
|
|
||||||
}
|
|
||||||
unawaited(refresh());
|
|
||||||
|
|
||||||
autoSaveTimer?.cancel();
|
|
||||||
autoSaveTimer = Timer.periodic(
|
|
||||||
const Duration(seconds: 193),
|
|
||||||
(_) async => await cwWalletBase?.save(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||||
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
if (libMoneroWallet == null ||
|
||||||
|
syncStatus is! lib_monero_compat.SyncedSyncStatus) {
|
||||||
return Amount.zeroWith(
|
return Amount.zeroWith(
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroTransactionPriority priority;
|
lib_monero.TransactionPriority priority;
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case 1:
|
case 1:
|
||||||
priority = MoneroTransactionPriority.regular;
|
priority = lib_monero.TransactionPriority.low;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
priority = MoneroTransactionPriority.medium;
|
priority = lib_monero.TransactionPriority.medium;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
priority = MoneroTransactionPriority.fast;
|
priority = lib_monero.TransactionPriority.high;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
priority = MoneroTransactionPriority.fastest;
|
priority = lib_monero.TransactionPriority.last;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
priority = MoneroTransactionPriority.slow;
|
priority = lib_monero.TransactionPriority.normal;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int approximateFee = 0;
|
int approximateFee = 0;
|
||||||
await estimateFeeMutex.protect(() async {
|
await estimateFeeMutex.protect(() async {
|
||||||
approximateFee = cwWalletBase!.calculateEstimatedFee(
|
approximateFee = await libMoneroWallet!.estimateFee(
|
||||||
priority,
|
priority,
|
||||||
amount.raw.toInt(),
|
amount.raw.toInt(),
|
||||||
);
|
);
|
||||||
|
@ -213,573 +58,49 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> pingCheck() async {
|
bool walletExists(String path) => lib_monero.MoneroWallet.isWalletExist(path);
|
||||||
return await cwWalletBase?.isConnected() ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateNode() async {
|
void loadWallet({
|
||||||
final node = getCurrentNode();
|
required String path,
|
||||||
|
required String password,
|
||||||
String host = Uri.parse(node.host).host;
|
}) {
|
||||||
if (host.isEmpty) {
|
libMoneroWallet = lib_monero.MoneroWallet.loadWallet(
|
||||||
host = node.host;
|
|
||||||
}
|
|
||||||
({InternetAddress host, int port})? proxy;
|
|
||||||
if (prefs.useTor) {
|
|
||||||
proxy = TorService.sharedInstance.getProxyInfo();
|
|
||||||
}
|
|
||||||
if (_requireMutex) {
|
|
||||||
await _torConnectingLock.protect(() async {
|
|
||||||
await cwWalletBase?.connectToNode(
|
|
||||||
node: Node(
|
|
||||||
uri: "$host:${node.port}",
|
|
||||||
type: WalletType.monero,
|
|
||||||
trusted: node.trusted ?? false,
|
|
||||||
useSSL: node.useSSL,
|
|
||||||
),
|
|
||||||
socksProxyAddress:
|
|
||||||
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await cwWalletBase?.connectToNode(
|
|
||||||
node: Node(
|
|
||||||
uri: "$host:${node.port}",
|
|
||||||
type: WalletType.monero,
|
|
||||||
trusted: node.trusted ?? false,
|
|
||||||
useSSL: node.useSSL,
|
|
||||||
),
|
|
||||||
socksProxyAddress:
|
|
||||||
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CWKeyData?> getKeys() async {
|
|
||||||
final base = cwWalletBase;
|
|
||||||
|
|
||||||
if (base == null || base.walletInfo.name != walletId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CWKeyData(
|
|
||||||
walletId: walletId,
|
|
||||||
publicViewKey: base.keys.publicViewKey,
|
|
||||||
privateViewKey: base.keys.privateViewKey,
|
|
||||||
publicSpendKey: base.keys.publicSpendKey,
|
|
||||||
privateSpendKey: base.keys.privateSpendKey,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateTransactions() async {
|
|
||||||
final base = cwWalletBase;
|
|
||||||
|
|
||||||
if (base == null || base.walletInfo.name != walletId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await base.updateTransactions();
|
|
||||||
final transactions = base.transactionHistory?.transactions;
|
|
||||||
|
|
||||||
// final cachedTransactions =
|
|
||||||
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
|
|
||||||
// as TransactionData?;
|
|
||||||
// int latestTxnBlockHeight =
|
|
||||||
// DB.instance.get<dynamic>(boxName: walletId, key: "storedTxnDataHeight")
|
|
||||||
// as int? ??
|
|
||||||
// 0;
|
|
||||||
//
|
|
||||||
// final txidsList = DB.instance
|
|
||||||
// .get<dynamic>(boxName: walletId, key: "cachedTxids") as List? ??
|
|
||||||
// [];
|
|
||||||
//
|
|
||||||
// final Set<String> cachedTxids = Set<String>.from(txidsList);
|
|
||||||
|
|
||||||
// TODO: filter to skip cached + confirmed txn processing in next step
|
|
||||||
// final unconfirmedCachedTransactions =
|
|
||||||
// cachedTransactions?.getAllTransactions() ?? {};
|
|
||||||
// unconfirmedCachedTransactions
|
|
||||||
// .removeWhere((key, value) => value.confirmedStatus);
|
|
||||||
//
|
|
||||||
// if (cachedTransactions != null) {
|
|
||||||
// for (final tx in allTxHashes.toList(growable: false)) {
|
|
||||||
// final txHeight = tx["height"] as int;
|
|
||||||
// if (txHeight > 0 &&
|
|
||||||
// txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
|
|
||||||
// if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
|
|
||||||
// allTxHashes.remove(tx);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
final List<Tuple2<Transaction, Address?>> txnsData = [];
|
|
||||||
|
|
||||||
if (transactions != null) {
|
|
||||||
for (final tx in transactions.entries) {
|
|
||||||
Address? address;
|
|
||||||
TransactionType type;
|
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
|
||||||
final addressInfo = tx.value.additionalInfo;
|
|
||||||
|
|
||||||
final addressString = cwWalletBase?.getTransactionAddress(
|
|
||||||
addressInfo!['accountIndex'] as int,
|
|
||||||
addressInfo['addressIndex'] as int,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (addressString != null) {
|
|
||||||
address = await mainDB
|
|
||||||
.getAddresses(walletId)
|
|
||||||
.filter()
|
|
||||||
.valueEqualTo(addressString)
|
|
||||||
.findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
type = TransactionType.incoming;
|
|
||||||
} else {
|
|
||||||
// txn.address = "";
|
|
||||||
type = TransactionType.outgoing;
|
|
||||||
}
|
|
||||||
|
|
||||||
final txn = Transaction(
|
|
||||||
walletId: walletId,
|
|
||||||
txid: tx.value.id,
|
|
||||||
timestamp: (tx.value.date.millisecondsSinceEpoch ~/ 1000),
|
|
||||||
type: type,
|
|
||||||
subType: TransactionSubType.none,
|
|
||||||
amount: tx.value.amount ?? 0,
|
|
||||||
amountString: Amount(
|
|
||||||
rawValue: BigInt.from(tx.value.amount ?? 0),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
).toJsonString(),
|
|
||||||
fee: tx.value.fee ?? 0,
|
|
||||||
height: tx.value.height,
|
|
||||||
isCancelled: false,
|
|
||||||
isLelantus: false,
|
|
||||||
slateId: null,
|
|
||||||
otherData: null,
|
|
||||||
nonce: null,
|
|
||||||
inputs: [],
|
|
||||||
outputs: [],
|
|
||||||
numberOfMessages: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
txnsData.add(Tuple2(txn, address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await mainDB.isar.writeTxn(() async {
|
|
||||||
await mainDB.isar.transactions
|
|
||||||
.where()
|
|
||||||
.walletIdEqualTo(walletId)
|
|
||||||
.deleteAll();
|
|
||||||
for (final data in txnsData) {
|
|
||||||
final tx = data.item1;
|
|
||||||
|
|
||||||
// save transaction
|
|
||||||
await mainDB.isar.transactions.put(tx);
|
|
||||||
|
|
||||||
if (data.item2 != null) {
|
|
||||||
final address = await mainDB.getAddress(walletId, data.item2!.value);
|
|
||||||
|
|
||||||
// check if address exists in db and add if it does not
|
|
||||||
if (address == null) {
|
|
||||||
await mainDB.isar.addresses.put(data.item2!);
|
|
||||||
}
|
|
||||||
|
|
||||||
// link and save address
|
|
||||||
tx.address.value = address ?? data.item2!;
|
|
||||||
await tx.address.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> init({bool? isRestore}) async {
|
|
||||||
cwWalletService ??= xmr_dart.monero
|
|
||||||
.createMoneroWalletService(DB.instance.moneroWalletInfoBox)
|
|
||||||
as MoneroWalletService;
|
|
||||||
|
|
||||||
if (!(await cwWalletService!.isWalletExist(walletId)) &&
|
|
||||||
isRestore != true) {
|
|
||||||
WalletInfo walletInfo;
|
|
||||||
WalletCredentials credentials;
|
|
||||||
try {
|
|
||||||
final dirPath =
|
|
||||||
await pathForWalletDir(name: walletId, type: WalletType.monero);
|
|
||||||
final path =
|
|
||||||
await pathForWallet(name: walletId, type: WalletType.monero);
|
|
||||||
credentials = xmr_dart.monero.createMoneroNewWalletCredentials(
|
|
||||||
name: walletId,
|
|
||||||
language: "English",
|
|
||||||
);
|
|
||||||
|
|
||||||
walletInfo = WalletInfo.external(
|
|
||||||
id: WalletBase.idFor(walletId, WalletType.monero),
|
|
||||||
name: walletId,
|
|
||||||
type: WalletType.monero,
|
|
||||||
isRecovery: false,
|
|
||||||
restoreHeight: credentials.height ?? 0,
|
|
||||||
date: DateTime.now(),
|
|
||||||
path: path,
|
path: path,
|
||||||
dirPath: dirPath,
|
password: password,
|
||||||
address: '',
|
|
||||||
);
|
);
|
||||||
credentials.walletInfo = walletInfo;
|
|
||||||
|
|
||||||
final _walletCreationService = WalletCreationService(
|
|
||||||
secureStorage: secureStorageInterface,
|
|
||||||
walletService: cwWalletService!,
|
|
||||||
keyService: cwKeysStorage,
|
|
||||||
type: WalletType.monero,
|
|
||||||
);
|
|
||||||
// To restore from a seed
|
|
||||||
final wallet = await _walletCreationService.create(credentials);
|
|
||||||
|
|
||||||
// subtract a couple days to ensure we have a buffer for SWB
|
|
||||||
final bufferedCreateHeight = xmr_dart.monero.getHeigthByDate(
|
|
||||||
date: DateTime.now().subtract(const Duration(days: 2)),
|
|
||||||
);
|
|
||||||
|
|
||||||
await info.updateRestoreHeight(
|
|
||||||
newRestoreHeight: bufferedCreateHeight,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
|
|
||||||
// special case for xmr/wow. Normally mnemonic + passphrase is saved
|
|
||||||
// before wallet.init() is called
|
|
||||||
await secureStorageInterface.write(
|
|
||||||
key: Wallet.mnemonicKey(walletId: walletId),
|
|
||||||
value: wallet.seed.trim(),
|
|
||||||
);
|
|
||||||
await secureStorageInterface.write(
|
|
||||||
key: Wallet.mnemonicPassphraseKey(walletId: walletId),
|
|
||||||
value: "",
|
|
||||||
);
|
|
||||||
|
|
||||||
walletInfo.restoreHeight = bufferedCreateHeight;
|
|
||||||
|
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
|
||||||
await DB.instance
|
|
||||||
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
|
||||||
|
|
||||||
wallet.close();
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
|
||||||
cwWalletBase?.close();
|
|
||||||
}
|
|
||||||
await updateNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> recover({required bool isRescan}) async {
|
Future<lib_monero.Wallet> getCreatedWallet({
|
||||||
if (isRescan) {
|
required String path,
|
||||||
await refreshMutex.protect(() async {
|
required String password,
|
||||||
// clear blockchain info
|
}) async =>
|
||||||
await mainDB.deleteWalletBlockchainData(walletId);
|
await lib_monero.MoneroWallet.create(
|
||||||
|
|
||||||
final restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
|
|
||||||
highestPercentCached = 0;
|
|
||||||
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
|
||||||
});
|
|
||||||
unawaited(refresh());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await refreshMutex.protect(() async {
|
|
||||||
final mnemonic = await getMnemonic();
|
|
||||||
final seedLength = mnemonic.trim().split(" ").length;
|
|
||||||
|
|
||||||
if (seedLength != 25 && seedLength != 16) {
|
|
||||||
throw Exception("Invalid monero mnemonic length found: $seedLength");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final height = max(info.restoreHeight, 0);
|
|
||||||
|
|
||||||
await info.updateRestoreHeight(
|
|
||||||
newRestoreHeight: height,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
|
|
||||||
cwWalletService = xmr_dart.monero
|
|
||||||
.createMoneroWalletService(DB.instance.moneroWalletInfoBox)
|
|
||||||
as MoneroWalletService;
|
|
||||||
WalletInfo walletInfo;
|
|
||||||
WalletCredentials credentials;
|
|
||||||
final String name = walletId;
|
|
||||||
final dirPath =
|
|
||||||
await pathForWalletDir(name: name, type: WalletType.monero);
|
|
||||||
final path = await pathForWallet(name: name, type: WalletType.monero);
|
|
||||||
credentials =
|
|
||||||
xmr_dart.monero.createMoneroRestoreWalletFromSeedCredentials(
|
|
||||||
name: name,
|
|
||||||
height: height,
|
|
||||||
mnemonic: mnemonic.trim(),
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
walletInfo = WalletInfo.external(
|
|
||||||
id: WalletBase.idFor(name, WalletType.monero),
|
|
||||||
name: name,
|
|
||||||
type: WalletType.monero,
|
|
||||||
isRecovery: false,
|
|
||||||
restoreHeight: credentials.height ?? 0,
|
|
||||||
date: DateTime.now(),
|
|
||||||
path: path,
|
path: path,
|
||||||
dirPath: dirPath,
|
password: password,
|
||||||
address: '',
|
seedType: lib_monero.MoneroSeedType
|
||||||
|
.sixteen, // TODO: check we want to actually use 16 here
|
||||||
);
|
);
|
||||||
credentials.walletInfo = walletInfo;
|
|
||||||
|
|
||||||
final cwWalletCreationService = WalletCreationService(
|
|
||||||
secureStorage: secureStorageInterface,
|
|
||||||
walletService: cwWalletService!,
|
|
||||||
keyService: cwKeysStorage,
|
|
||||||
type: WalletType.monero,
|
|
||||||
);
|
|
||||||
// To restore from a seed
|
|
||||||
final wallet =
|
|
||||||
await cwWalletCreationService.restoreFromSeed(credentials);
|
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
|
||||||
await DB.instance
|
|
||||||
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
|
||||||
cwWalletBase?.close();
|
|
||||||
cwWalletBase = wallet as MoneroWalletBase;
|
|
||||||
cwWalletBase?.onNewBlock = onNewBlock;
|
|
||||||
cwWalletBase?.onNewTransaction = onNewTransaction;
|
|
||||||
cwWalletBase?.syncStatusChanged = syncStatusChanged;
|
|
||||||
if (walletInfo.address != null) {
|
|
||||||
final newReceivingAddress = await getCurrentReceivingAddress() ??
|
|
||||||
Address(
|
|
||||||
walletId: walletId,
|
|
||||||
derivationIndex: 0,
|
|
||||||
derivationPath: null,
|
|
||||||
value: walletInfo.address!,
|
|
||||||
publicKey: [],
|
|
||||||
type: AddressType.cryptonote,
|
|
||||||
subType: AddressSubType.receiving,
|
|
||||||
);
|
|
||||||
|
|
||||||
await mainDB.updateOrPutAddresses([newReceivingAddress]);
|
|
||||||
await info.updateReceivingAddress(
|
|
||||||
newAddress: newReceivingAddress.value,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
|
||||||
}
|
|
||||||
await updateNode();
|
|
||||||
|
|
||||||
await cwWalletBase?.rescan(height: credentials.height);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TxData> prepareSend({required TxData txData}) async {
|
Future<lib_monero.Wallet> getRestoredWallet({
|
||||||
try {
|
required String path,
|
||||||
final feeRate = txData.feeRateType;
|
required String password,
|
||||||
if (feeRate is FeeRateType) {
|
required String mnemonic,
|
||||||
MoneroTransactionPriority feePriority;
|
int height = 0,
|
||||||
switch (feeRate) {
|
}) async =>
|
||||||
case FeeRateType.fast:
|
await lib_monero.MoneroWallet.restoreWalletFromSeed(
|
||||||
feePriority = MoneroTransactionPriority.fast;
|
path: path,
|
||||||
break;
|
password: password,
|
||||||
case FeeRateType.average:
|
seed: mnemonic,
|
||||||
feePriority = MoneroTransactionPriority.regular;
|
restoreHeight: height,
|
||||||
break;
|
|
||||||
case FeeRateType.slow:
|
|
||||||
feePriority = MoneroTransactionPriority.slow;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw ArgumentError("Invalid use of custom fee");
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<PendingTransaction>? awaitPendingTransaction;
|
|
||||||
try {
|
|
||||||
// check for send all
|
|
||||||
bool isSendAll = false;
|
|
||||||
final balance = await availableBalance;
|
|
||||||
if (txData.amount! == balance &&
|
|
||||||
txData.recipients!.first.amount == balance) {
|
|
||||||
isSendAll = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<monero_output.Output> outputs = [];
|
|
||||||
for (final recipient in txData.recipients!) {
|
|
||||||
final output = monero_output.Output(cwWalletBase!);
|
|
||||||
output.address = recipient.address;
|
|
||||||
output.sendAll = isSendAll;
|
|
||||||
final String amountToSend = recipient.amount.decimal.toString();
|
|
||||||
output.setCryptoAmount(amountToSend);
|
|
||||||
outputs.add(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
final tmp =
|
|
||||||
xmr_dart.monero.createMoneroTransactionCreationCredentials(
|
|
||||||
outputs: outputs,
|
|
||||||
priority: feePriority,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final height = await chainHeight;
|
|
||||||
final inputs = txData.utxos
|
|
||||||
?.map(
|
|
||||||
(e) => cw.UTXO(
|
|
||||||
address: e.address!,
|
|
||||||
hash: e.txid,
|
|
||||||
keyImage: e.keyImage!,
|
|
||||||
value: e.value,
|
|
||||||
isFrozen: e.isBlocked,
|
|
||||||
isUnlocked: e.blockHeight != null &&
|
|
||||||
(height - (e.blockHeight ?? 0)) >=
|
|
||||||
cryptoCurrency.minConfirms,
|
|
||||||
height: e.blockHeight ?? 0,
|
|
||||||
vout: e.vout,
|
|
||||||
spent: e.used ?? false,
|
|
||||||
coinbase: e.isCoinbase,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
await prepareSendMutex.protect(() async {
|
|
||||||
awaitPendingTransaction = cwWalletBase!.createTransaction(
|
|
||||||
tmp,
|
|
||||||
inputs: inputs,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from prepareSend(): $e\n$s",
|
|
||||||
level: LogLevel.Warning,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final PendingMoneroTransaction pendingMoneroTransaction =
|
|
||||||
await (awaitPendingTransaction!) as PendingMoneroTransaction;
|
|
||||||
final realFee = Amount.fromDecimal(
|
|
||||||
Decimal.parse(pendingMoneroTransaction.feeFormatted),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
|
|
||||||
return txData.copyWith(
|
|
||||||
fee: realFee,
|
|
||||||
pendingMoneroTransaction: pendingMoneroTransaction,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
throw ArgumentError("Invalid fee rate argument provided!");
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from prepare send(): $e\n$s",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (e.toString().contains("Incorrect unlocked balance")) {
|
|
||||||
throw Exception("Insufficient balance!");
|
|
||||||
} else if (e is CreationTransactionException) {
|
|
||||||
throw Exception("Insufficient funds to pay for transaction fee!");
|
|
||||||
} else {
|
|
||||||
throw Exception("Transaction failed with error code $e");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TxData> confirmSend({required TxData txData}) async {
|
void invalidSeedLengthCheck(int length) {
|
||||||
try {
|
if (length != 25 && length != 16) {
|
||||||
try {
|
throw Exception("Invalid monero mnemonic length found: $length");
|
||||||
await txData.pendingMoneroTransaction!.commit();
|
|
||||||
Logging.instance.log(
|
|
||||||
"transaction ${txData.pendingMoneroTransaction!.id} has been sent",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
return txData.copyWith(txid: txData.pendingMoneroTransaction!.id);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"${info.name} monero confirmSend: $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from confirmSend(): $e\n$s",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Amount> get availableBalance async {
|
|
||||||
try {
|
|
||||||
int runningBalance = 0;
|
|
||||||
for (final entry in cwWalletBase!.balance!.entries) {
|
|
||||||
runningBalance += entry.value.unlockedBalance;
|
|
||||||
}
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(runningBalance),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
} catch (_) {
|
|
||||||
return info.cachedBalance.spendable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Amount> get totalBalance async {
|
|
||||||
try {
|
|
||||||
final balanceEntries = cwWalletBase?.balance?.entries;
|
|
||||||
if (balanceEntries != null) {
|
|
||||||
int bal = 0;
|
|
||||||
for (final element in balanceEntries) {
|
|
||||||
bal = bal + element.value.fullBalance;
|
|
||||||
}
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(bal),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
final transactions = cwWalletBase!.transactionHistory!.transactions;
|
|
||||||
int transactionBalance = 0;
|
|
||||||
for (final tx in transactions!.entries) {
|
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
|
||||||
transactionBalance += tx.value.amount!;
|
|
||||||
} else {
|
|
||||||
transactionBalance += -tx.value.amount! - tx.value.fee!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(transactionBalance),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
return info.cachedBalance.total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============== Private ====================================================
|
|
||||||
|
|
||||||
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
|
|
||||||
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
|
|
||||||
|
|
||||||
final Mutex _torConnectingLock = Mutex();
|
|
||||||
bool _requireMutex = false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,157 +1,52 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
import 'package:compat/compat.dart' as lib_monero_compat;
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
|
||||||
import 'package:cw_core/sync_status.dart';
|
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
|
||||||
import 'package:cw_core/utxo.dart' as cw;
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
|
||||||
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/pending_wownero_transaction.dart';
|
|
||||||
import 'package:cw_wownero/wownero_wallet.dart';
|
|
||||||
import 'package:cw_wownero/wownero_wallet_service.dart';
|
|
||||||
import 'package:decimal/decimal.dart';
|
|
||||||
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
|
||||||
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';
|
|
||||||
|
|
||||||
import '../../../db/hive/db.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/utxo.dart';
|
|
||||||
import '../../../models/keys/cw_key_data.dart';
|
|
||||||
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
|
||||||
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/amount/amount.dart';
|
||||||
import '../../../utilities/enums/fee_rate_type_enum.dart';
|
import '../../../utilities/enums/fee_rate_type_enum.dart';
|
||||||
import '../../../utilities/logger.dart';
|
|
||||||
import '../../crypto_currency/crypto_currency.dart';
|
import '../../crypto_currency/crypto_currency.dart';
|
||||||
import '../../models/tx_data.dart';
|
import '../../models/tx_data.dart';
|
||||||
import '../intermediate/cryptonote_wallet.dart';
|
import '../intermediate/lib_monero_wallet.dart';
|
||||||
import '../wallet.dart';
|
|
||||||
import '../wallet_mixin_interfaces/cw_based_interface.dart';
|
|
||||||
|
|
||||||
class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
class WowneroWallet extends LibMoneroWallet {
|
||||||
WowneroWallet(CryptoCurrencyNetwork network) : super(Wownero(network)) {
|
WowneroWallet(CryptoCurrencyNetwork network)
|
||||||
final bus = GlobalEventBus.instance;
|
: super(
|
||||||
|
Wownero(network),
|
||||||
// Listen for tor status changes.
|
lib_monero_compat.WalletType.wownero,
|
||||||
_torStatusListener = bus.on<TorConnectionStatusChangedEvent>().listen(
|
|
||||||
(event) async {
|
|
||||||
switch (event.newStatus) {
|
|
||||||
case TorConnectionStatus.connecting:
|
|
||||||
if (!_torConnectingLock.isLocked) {
|
|
||||||
await _torConnectingLock.acquire();
|
|
||||||
}
|
|
||||||
_requireMutex = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TorConnectionStatus.connected:
|
|
||||||
case TorConnectionStatus.disconnected:
|
|
||||||
if (_torConnectingLock.isLocked) {
|
|
||||||
_torConnectingLock.release();
|
|
||||||
}
|
|
||||||
_requireMutex = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Listen for tor preference changes.
|
|
||||||
_torPreferenceListener = bus.on<TorPreferenceChangedEvent>().listen(
|
|
||||||
(event) async {
|
|
||||||
await updateNode();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Potentially dangerous hack. See comments in _startInit()
|
|
||||||
_startInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cw based wallet listener to handle synchronization of utxo frozen states
|
|
||||||
late final StreamSubscription<List<UTXO>> _streamSub;
|
|
||||||
Future<void> _startInit() async {
|
|
||||||
// Delay required as `mainDB` is not initialized in constructor.
|
|
||||||
// This is a hack and could lead to a race condition.
|
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
|
||||||
_streamSub = mainDB.isar.utxos
|
|
||||||
.where()
|
|
||||||
.walletIdEqualTo(walletId)
|
|
||||||
.watch(fireImmediately: true)
|
|
||||||
.listen((utxos) async {
|
|
||||||
await onUTXOsCHanged(utxos);
|
|
||||||
await updateBalance(shouldUpdateUtxos: false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
WowneroWalletBase? cwWalletBase;
|
|
||||||
|
|
||||||
@override
|
|
||||||
WowneroWalletService? cwWalletService;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Address addressFor({required int index, int account = 0}) {
|
|
||||||
final String address = (cwWalletBase as WowneroWalletBase)
|
|
||||||
.getTransactionAddress(account, index);
|
|
||||||
|
|
||||||
final newReceivingAddress = Address(
|
|
||||||
walletId: walletId,
|
|
||||||
derivationIndex: index,
|
|
||||||
derivationPath: null,
|
|
||||||
value: address,
|
|
||||||
publicKey: [],
|
|
||||||
type: AddressType.cryptonote,
|
|
||||||
subType: AddressSubType.receiving,
|
|
||||||
);
|
|
||||||
|
|
||||||
return newReceivingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||||
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
if (libMoneroWallet == null ||
|
||||||
|
syncStatus is! lib_monero_compat.SyncedSyncStatus) {
|
||||||
return Amount.zeroWith(
|
return Amount.zeroWith(
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroTransactionPriority priority;
|
lib_monero.TransactionPriority priority;
|
||||||
FeeRateType feeRateType = FeeRateType.slow;
|
FeeRateType feeRateType = FeeRateType.slow;
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case 1:
|
case 1:
|
||||||
priority = MoneroTransactionPriority.regular;
|
priority = lib_monero.TransactionPriority.low;
|
||||||
feeRateType = FeeRateType.average;
|
feeRateType = FeeRateType.average;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
priority = MoneroTransactionPriority.medium;
|
priority = lib_monero.TransactionPriority.medium;
|
||||||
feeRateType = FeeRateType.average;
|
feeRateType = FeeRateType.average;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
priority = MoneroTransactionPriority.fast;
|
priority = lib_monero.TransactionPriority.high;
|
||||||
feeRateType = FeeRateType.fast;
|
feeRateType = FeeRateType.fast;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
priority = MoneroTransactionPriority.fastest;
|
priority = lib_monero.TransactionPriority.last;
|
||||||
feeRateType = FeeRateType.fast;
|
feeRateType = FeeRateType.fast;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
priority = MoneroTransactionPriority.slow;
|
priority = lib_monero.TransactionPriority.normal;
|
||||||
feeRateType = FeeRateType.slow;
|
feeRateType = FeeRateType.slow;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +74,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
// unsure why this delay?
|
// unsure why this delay?
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
approximateFee = cwWalletBase!.calculateEstimatedFee(
|
approximateFee = libMoneroWallet!.estimateFee(
|
||||||
priority,
|
priority,
|
||||||
amount.raw.toInt(),
|
amount.raw.toInt(),
|
||||||
);
|
);
|
||||||
|
@ -198,634 +93,51 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> pingCheck() async {
|
bool walletExists(String path) =>
|
||||||
return await cwWalletBase?.isConnected() ?? false;
|
lib_monero.WowneroWallet.isWalletExist(path);
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateNode() async {
|
void loadWallet({
|
||||||
final node = getCurrentNode();
|
required String path,
|
||||||
|
required String password,
|
||||||
final host = Uri.parse(node.host).host;
|
}) {
|
||||||
({InternetAddress host, int port})? proxy;
|
libMoneroWallet = lib_monero.WowneroWallet.loadWallet(
|
||||||
if (prefs.useTor) {
|
|
||||||
proxy = TorService.sharedInstance.getProxyInfo();
|
|
||||||
}
|
|
||||||
if (_requireMutex) {
|
|
||||||
await _torConnectingLock.protect(() async {
|
|
||||||
await cwWalletBase?.connectToNode(
|
|
||||||
node: Node(
|
|
||||||
uri: "$host:${node.port}",
|
|
||||||
type: WalletType.wownero,
|
|
||||||
trusted: node.trusted ?? false,
|
|
||||||
useSSL: node.useSSL,
|
|
||||||
),
|
|
||||||
socksProxyAddress:
|
|
||||||
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await cwWalletBase?.connectToNode(
|
|
||||||
node: Node(
|
|
||||||
uri: "$host:${node.port}",
|
|
||||||
type: WalletType.wownero,
|
|
||||||
trusted: node.trusted ?? false,
|
|
||||||
useSSL: node.useSSL,
|
|
||||||
),
|
|
||||||
socksProxyAddress:
|
|
||||||
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CWKeyData?> getKeys() async {
|
|
||||||
final base = cwWalletBase;
|
|
||||||
|
|
||||||
if (base == null || base.walletInfo.name != walletId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CWKeyData(
|
|
||||||
walletId: walletId,
|
|
||||||
publicViewKey: base.keys.publicViewKey,
|
|
||||||
privateViewKey: base.keys.privateViewKey,
|
|
||||||
publicSpendKey: base.keys.publicSpendKey,
|
|
||||||
privateSpendKey: base.keys.privateSpendKey,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateTransactions() async {
|
|
||||||
final base = cwWalletBase;
|
|
||||||
|
|
||||||
if (base == null || base.walletInfo.name != walletId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await base.updateTransactions();
|
|
||||||
final transactions = base.transactionHistory?.transactions;
|
|
||||||
|
|
||||||
// final cachedTransactions =
|
|
||||||
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
|
|
||||||
// as TransactionData?;
|
|
||||||
// int latestTxnBlockHeight =
|
|
||||||
// DB.instance.get<dynamic>(boxName: walletId, key: "storedTxnDataHeight")
|
|
||||||
// as int? ??
|
|
||||||
// 0;
|
|
||||||
//
|
|
||||||
// final txidsList = DB.instance
|
|
||||||
// .get<dynamic>(boxName: walletId, key: "cachedTxids") as List? ??
|
|
||||||
// [];
|
|
||||||
//
|
|
||||||
// final Set<String> cachedTxids = Set<String>.from(txidsList);
|
|
||||||
|
|
||||||
// TODO: filter to skip cached + confirmed txn processing in next step
|
|
||||||
// final unconfirmedCachedTransactions =
|
|
||||||
// cachedTransactions?.getAllTransactions() ?? {};
|
|
||||||
// unconfirmedCachedTransactions
|
|
||||||
// .removeWhere((key, value) => value.confirmedStatus);
|
|
||||||
//
|
|
||||||
// if (cachedTransactions != null) {
|
|
||||||
// for (final tx in allTxHashes.toList(growable: false)) {
|
|
||||||
// final txHeight = tx["height"] as int;
|
|
||||||
// if (txHeight > 0 &&
|
|
||||||
// txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
|
|
||||||
// if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
|
|
||||||
// allTxHashes.remove(tx);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
final List<Tuple2<Transaction, Address?>> txnsData = [];
|
|
||||||
|
|
||||||
if (transactions != null) {
|
|
||||||
for (final tx in transactions.entries) {
|
|
||||||
Address? address;
|
|
||||||
TransactionType type;
|
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
|
||||||
final addressInfo = tx.value.additionalInfo;
|
|
||||||
|
|
||||||
final addressString = cwWalletBase?.getTransactionAddress(
|
|
||||||
addressInfo!['accountIndex'] as int,
|
|
||||||
addressInfo['addressIndex'] as int,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (addressString != null) {
|
|
||||||
address = await mainDB
|
|
||||||
.getAddresses(walletId)
|
|
||||||
.filter()
|
|
||||||
.valueEqualTo(addressString)
|
|
||||||
.findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
type = TransactionType.incoming;
|
|
||||||
} else {
|
|
||||||
// txn.address = "";
|
|
||||||
type = TransactionType.outgoing;
|
|
||||||
}
|
|
||||||
|
|
||||||
final txn = Transaction(
|
|
||||||
walletId: walletId,
|
|
||||||
txid: tx.value.id,
|
|
||||||
timestamp: (tx.value.date.millisecondsSinceEpoch ~/ 1000),
|
|
||||||
type: type,
|
|
||||||
subType: TransactionSubType.none,
|
|
||||||
amount: tx.value.amount ?? 0,
|
|
||||||
amountString: Amount(
|
|
||||||
rawValue: BigInt.from(tx.value.amount ?? 0),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
).toJsonString(),
|
|
||||||
fee: tx.value.fee ?? 0,
|
|
||||||
height: tx.value.height,
|
|
||||||
isCancelled: false,
|
|
||||||
isLelantus: false,
|
|
||||||
slateId: null,
|
|
||||||
otherData: null,
|
|
||||||
nonce: null,
|
|
||||||
inputs: [],
|
|
||||||
outputs: [],
|
|
||||||
numberOfMessages: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
txnsData.add(Tuple2(txn, address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await mainDB.isar.writeTxn(() async {
|
|
||||||
await mainDB.isar.transactions
|
|
||||||
.where()
|
|
||||||
.walletIdEqualTo(walletId)
|
|
||||||
.deleteAll();
|
|
||||||
for (final data in txnsData) {
|
|
||||||
final tx = data.item1;
|
|
||||||
|
|
||||||
// save transaction
|
|
||||||
await mainDB.isar.transactions.put(tx);
|
|
||||||
|
|
||||||
if (data.item2 != null) {
|
|
||||||
final address = await mainDB.getAddress(walletId, data.item2!.value);
|
|
||||||
|
|
||||||
// check if address exists in db and add if it does not
|
|
||||||
if (address == null) {
|
|
||||||
await mainDB.isar.addresses.put(data.item2!);
|
|
||||||
}
|
|
||||||
|
|
||||||
// link and save address
|
|
||||||
tx.address.value = address ?? data.item2!;
|
|
||||||
await tx.address.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> init({bool? isRestore}) async {
|
|
||||||
cwWalletService = wow_dart.wownero
|
|
||||||
.createWowneroWalletService(DB.instance.moneroWalletInfoBox)
|
|
||||||
as WowneroWalletService;
|
|
||||||
|
|
||||||
if (!(await cwWalletService!.isWalletExist(walletId)) &&
|
|
||||||
isRestore != true) {
|
|
||||||
WalletInfo walletInfo;
|
|
||||||
WalletCredentials credentials;
|
|
||||||
try {
|
|
||||||
final dirPath =
|
|
||||||
await pathForWalletDir(name: walletId, type: WalletType.wownero);
|
|
||||||
final path =
|
|
||||||
await pathForWallet(name: walletId, type: WalletType.wownero);
|
|
||||||
credentials = wow_dart.wownero.createWowneroNewWalletCredentials(
|
|
||||||
name: walletId,
|
|
||||||
language: "English",
|
|
||||||
seedWordsLength: 14,
|
|
||||||
);
|
|
||||||
|
|
||||||
walletInfo = WalletInfo.external(
|
|
||||||
id: WalletBase.idFor(walletId, WalletType.wownero),
|
|
||||||
name: walletId,
|
|
||||||
type: WalletType.wownero,
|
|
||||||
isRecovery: false,
|
|
||||||
restoreHeight: credentials.height ?? 0,
|
|
||||||
date: DateTime.now(),
|
|
||||||
path: path,
|
path: path,
|
||||||
dirPath: dirPath,
|
password: password,
|
||||||
address: '',
|
|
||||||
);
|
|
||||||
credentials.walletInfo = walletInfo;
|
|
||||||
|
|
||||||
final _walletCreationService = WalletCreationService(
|
|
||||||
secureStorage: secureStorageInterface,
|
|
||||||
walletService: cwWalletService!,
|
|
||||||
keyService: cwKeysStorage,
|
|
||||||
type: WalletType.wownero,
|
|
||||||
);
|
|
||||||
// To restore from a seed
|
|
||||||
final wallet = await _walletCreationService.create(credentials)
|
|
||||||
as WowneroWalletBase;
|
|
||||||
|
|
||||||
final height =
|
|
||||||
wownerodart.Wallet_getRefreshFromBlockHeight(wallet.wallet.wptr);
|
|
||||||
|
|
||||||
await info.updateRestoreHeight(
|
|
||||||
newRestoreHeight: height,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
|
|
||||||
// special case for xmr/wow. Normally mnemonic + passphrase is saved
|
|
||||||
// before wallet.init() is called
|
|
||||||
await secureStorageInterface.write(
|
|
||||||
key: Wallet.mnemonicKey(walletId: walletId),
|
|
||||||
value: wallet.seed.trim(),
|
|
||||||
);
|
|
||||||
await secureStorageInterface.write(
|
|
||||||
key: Wallet.mnemonicPassphraseKey(walletId: walletId),
|
|
||||||
value: "",
|
|
||||||
);
|
|
||||||
|
|
||||||
walletInfo.restoreHeight = height;
|
|
||||||
|
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
|
||||||
await DB.instance
|
|
||||||
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
|
||||||
|
|
||||||
wallet.close();
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
|
||||||
cwWalletBase?.close();
|
|
||||||
}
|
|
||||||
await updateNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> open() async {
|
|
||||||
String? password;
|
|
||||||
try {
|
|
||||||
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
|
||||||
} catch (e, s) {
|
|
||||||
throw Exception("Password not found $e, $s");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wasNull = false;
|
|
||||||
|
|
||||||
if (cwWalletBase == null) {
|
|
||||||
wasNull = true;
|
|
||||||
// cwWalletBaseT?.close();
|
|
||||||
cwWalletBase = (await cwWalletService!.openWallet(walletId, password))
|
|
||||||
as WowneroWalletBase;
|
|
||||||
|
|
||||||
cwWalletBase?.onNewBlock = onNewBlock;
|
|
||||||
cwWalletBase?.onNewTransaction = onNewTransaction;
|
|
||||||
cwWalletBase?.syncStatusChanged = syncStatusChanged;
|
|
||||||
|
|
||||||
await updateNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
Address? currentAddress = await getCurrentReceivingAddress();
|
|
||||||
if (currentAddress == null) {
|
|
||||||
currentAddress = addressFor(index: 0);
|
|
||||||
await mainDB.updateOrPutAddresses([currentAddress]);
|
|
||||||
}
|
|
||||||
if (info.cachedReceivingAddress != currentAddress.value) {
|
|
||||||
await info.updateReceivingAddress(
|
|
||||||
newAddress: currentAddress.value,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wasNull) {
|
|
||||||
await cwWalletBase?.startSync();
|
|
||||||
} else {
|
|
||||||
cwWalletBase?.wallet.startListeners();
|
|
||||||
}
|
|
||||||
unawaited(refresh());
|
|
||||||
|
|
||||||
autoSaveTimer = Timer.periodic(
|
|
||||||
const Duration(seconds: 193),
|
|
||||||
(_) async => await cwWalletBase?.save(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> recover({required bool isRescan}) async {
|
Future<lib_monero.Wallet> getCreatedWallet({
|
||||||
if (isRescan) {
|
required String path,
|
||||||
await refreshMutex.protect(() async {
|
required String password,
|
||||||
// clear blockchain info
|
}) async =>
|
||||||
await mainDB.deleteWalletBlockchainData(walletId);
|
await lib_monero.WowneroWallet.create(
|
||||||
|
|
||||||
final restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
|
|
||||||
highestPercentCached = 0;
|
|
||||||
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
|
||||||
});
|
|
||||||
unawaited(refresh());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await refreshMutex.protect(() async {
|
|
||||||
final mnemonic = await getMnemonic();
|
|
||||||
final seedLength = mnemonic.trim().split(" ").length;
|
|
||||||
|
|
||||||
if (!(seedLength == 14 || seedLength == 25)) {
|
|
||||||
throw Exception("Invalid wownero mnemonic length found: $seedLength");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
int height = info.restoreHeight;
|
|
||||||
|
|
||||||
// extract seed height from 14 word seed
|
|
||||||
if (seedLength == 14) {
|
|
||||||
height = 0;
|
|
||||||
} else {
|
|
||||||
height = max(height, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
await info.updateRestoreHeight(
|
|
||||||
newRestoreHeight: height,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
|
|
||||||
cwWalletService = wow_dart.wownero
|
|
||||||
.createWowneroWalletService(DB.instance.moneroWalletInfoBox)
|
|
||||||
as WowneroWalletService;
|
|
||||||
WalletInfo walletInfo;
|
|
||||||
WalletCredentials credentials;
|
|
||||||
final String name = walletId;
|
|
||||||
final dirPath =
|
|
||||||
await pathForWalletDir(name: name, type: WalletType.wownero);
|
|
||||||
final path = await pathForWallet(name: name, type: WalletType.wownero);
|
|
||||||
credentials =
|
|
||||||
wow_dart.wownero.createWowneroRestoreWalletFromSeedCredentials(
|
|
||||||
name: name,
|
|
||||||
height: height,
|
|
||||||
mnemonic: mnemonic.trim(),
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
walletInfo = WalletInfo.external(
|
|
||||||
id: WalletBase.idFor(name, WalletType.wownero),
|
|
||||||
name: name,
|
|
||||||
type: WalletType.wownero,
|
|
||||||
isRecovery: false,
|
|
||||||
restoreHeight: credentials.height ?? 0,
|
|
||||||
date: DateTime.now(),
|
|
||||||
path: path,
|
path: path,
|
||||||
dirPath: dirPath,
|
password: password,
|
||||||
// TODO: find out what to put for address
|
seedType: lib_monero.WowneroSeedType
|
||||||
address: '',
|
.fourteen, // TODO: check we want to actually use 14 here
|
||||||
|
overrideDeprecated14WordSeedException: true,
|
||||||
);
|
);
|
||||||
credentials.walletInfo = walletInfo;
|
|
||||||
|
|
||||||
final cwWalletCreationService = WalletCreationService(
|
|
||||||
secureStorage: secureStorageInterface,
|
|
||||||
walletService: cwWalletService!,
|
|
||||||
keyService: cwKeysStorage,
|
|
||||||
type: WalletType.wownero,
|
|
||||||
);
|
|
||||||
// To restore from a seed
|
|
||||||
final wallet = await cwWalletCreationService
|
|
||||||
.restoreFromSeed(credentials) as WowneroWalletBase;
|
|
||||||
height =
|
|
||||||
wownerodart.Wallet_getRefreshFromBlockHeight(wallet.wallet.wptr);
|
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
|
||||||
walletInfo.restoreHeight = height;
|
|
||||||
await info.updateRestoreHeight(
|
|
||||||
newRestoreHeight: height,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
await DB.instance
|
|
||||||
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
|
||||||
cwWalletBase?.close();
|
|
||||||
cwWalletBase = wallet;
|
|
||||||
cwWalletBase?.onNewBlock = onNewBlock;
|
|
||||||
cwWalletBase?.onNewTransaction = onNewTransaction;
|
|
||||||
cwWalletBase?.syncStatusChanged = syncStatusChanged;
|
|
||||||
if (walletInfo.address != null) {
|
|
||||||
final newReceivingAddress = await getCurrentReceivingAddress() ??
|
|
||||||
Address(
|
|
||||||
walletId: walletId,
|
|
||||||
derivationIndex: 0,
|
|
||||||
derivationPath: null,
|
|
||||||
value: walletInfo.address!,
|
|
||||||
publicKey: [],
|
|
||||||
type: AddressType.cryptonote,
|
|
||||||
subType: AddressSubType.receiving,
|
|
||||||
);
|
|
||||||
|
|
||||||
await mainDB.updateOrPutAddresses([newReceivingAddress]);
|
|
||||||
await info.updateReceivingAddress(
|
|
||||||
newAddress: newReceivingAddress.value,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
|
||||||
}
|
|
||||||
await updateNode();
|
|
||||||
|
|
||||||
await cwWalletBase?.rescan(height: credentials.height);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TxData> prepareSend({required TxData txData}) async {
|
Future<lib_monero.Wallet> getRestoredWallet({
|
||||||
try {
|
required String path,
|
||||||
final feeRate = txData.feeRateType;
|
required String password,
|
||||||
if (feeRate is FeeRateType) {
|
required String mnemonic,
|
||||||
MoneroTransactionPriority feePriority;
|
int height = 0,
|
||||||
switch (feeRate) {
|
}) async =>
|
||||||
case FeeRateType.fast:
|
await lib_monero.WowneroWallet.restoreWalletFromSeed(
|
||||||
feePriority = MoneroTransactionPriority.fast;
|
path: path,
|
||||||
break;
|
password: password,
|
||||||
case FeeRateType.average:
|
seed: mnemonic,
|
||||||
feePriority = MoneroTransactionPriority.regular;
|
restoreHeight: height,
|
||||||
break;
|
|
||||||
case FeeRateType.slow:
|
|
||||||
feePriority = MoneroTransactionPriority.slow;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw ArgumentError("Invalid use of custom fee");
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<PendingTransaction>? awaitPendingTransaction;
|
|
||||||
try {
|
|
||||||
// check for send all
|
|
||||||
bool isSendAll = false;
|
|
||||||
final balance = await availableBalance;
|
|
||||||
if (txData.amount! == balance &&
|
|
||||||
txData.recipients!.first.amount == balance) {
|
|
||||||
isSendAll = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<wownero_output.Output> outputs = [];
|
|
||||||
for (final recipient in txData.recipients!) {
|
|
||||||
final output = wownero_output.Output(cwWalletBase!);
|
|
||||||
output.address = recipient.address;
|
|
||||||
output.sendAll = isSendAll;
|
|
||||||
final String amountToSend = recipient.amount.decimal.toString();
|
|
||||||
output.setCryptoAmount(amountToSend);
|
|
||||||
outputs.add(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
final tmp =
|
|
||||||
wow_dart.wownero.createWowneroTransactionCreationCredentials(
|
|
||||||
outputs: outputs,
|
|
||||||
priority: feePriority,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final height = await chainHeight;
|
|
||||||
final inputs = txData.utxos
|
|
||||||
?.map(
|
|
||||||
(e) => cw.UTXO(
|
|
||||||
address: e.address!,
|
|
||||||
hash: e.txid,
|
|
||||||
keyImage: e.keyImage!,
|
|
||||||
value: e.value,
|
|
||||||
isFrozen: e.isBlocked,
|
|
||||||
isUnlocked: e.blockHeight != null &&
|
|
||||||
(height - (e.blockHeight ?? 0)) >=
|
|
||||||
cryptoCurrency.minConfirms,
|
|
||||||
height: e.blockHeight ?? 0,
|
|
||||||
vout: e.vout,
|
|
||||||
spent: e.used ?? false,
|
|
||||||
coinbase: e.isCoinbase,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
await prepareSendMutex.protect(() async {
|
|
||||||
awaitPendingTransaction = cwWalletBase!.createTransaction(
|
|
||||||
tmp,
|
|
||||||
inputs: inputs,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from prepareSend(): $e\n$s",
|
|
||||||
level: LogLevel.Warning,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final PendingWowneroTransaction pendingWowneroTransaction =
|
|
||||||
await (awaitPendingTransaction!) as PendingWowneroTransaction;
|
|
||||||
final realFee = Amount.fromDecimal(
|
|
||||||
Decimal.parse(pendingWowneroTransaction.feeFormatted),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
|
|
||||||
return txData.copyWith(
|
|
||||||
fee: realFee,
|
|
||||||
pendingWowneroTransaction: pendingWowneroTransaction,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
throw ArgumentError("Invalid fee rate argument provided!");
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from prepare send(): $e\n$s",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (e.toString().contains("Incorrect unlocked balance")) {
|
|
||||||
throw Exception("Insufficient balance!");
|
|
||||||
} else if (e is CreationTransactionException) {
|
|
||||||
throw Exception("Insufficient funds to pay for transaction fee!");
|
|
||||||
} else {
|
|
||||||
throw Exception("Transaction failed with error code $e");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TxData> confirmSend({required TxData txData}) async {
|
void invalidSeedLengthCheck(int length) {
|
||||||
try {
|
if (!(length == 14 || length == 25)) {
|
||||||
try {
|
throw Exception("Invalid wownero mnemonic length found: $length");
|
||||||
await txData.pendingWowneroTransaction!.commit();
|
|
||||||
Logging.instance.log(
|
|
||||||
"transaction ${txData.pendingWowneroTransaction!.id} has been sent",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
return txData.copyWith(txid: txData.pendingWowneroTransaction!.id);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"${info.name} wownero confirmSend: $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from confirmSend(): $e\n$s",
|
|
||||||
level: LogLevel.Info,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Amount> get availableBalance async {
|
|
||||||
try {
|
|
||||||
int runningBalance = 0;
|
|
||||||
for (final entry in cwWalletBase!.balance!.entries) {
|
|
||||||
runningBalance += entry.value.unlockedBalance;
|
|
||||||
}
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(runningBalance),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
} catch (_) {
|
|
||||||
return info.cachedBalance.spendable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Amount> get totalBalance async {
|
|
||||||
try {
|
|
||||||
final balanceEntries = cwWalletBase?.balance?.entries;
|
|
||||||
if (balanceEntries != null) {
|
|
||||||
int bal = 0;
|
|
||||||
for (final element in balanceEntries) {
|
|
||||||
bal = bal + element.value.fullBalance;
|
|
||||||
}
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(bal),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
final transactions = cwWalletBase!.transactionHistory!.transactions;
|
|
||||||
int transactionBalance = 0;
|
|
||||||
for (final tx in transactions!.entries) {
|
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
|
||||||
transactionBalance += tx.value.amount!;
|
|
||||||
} else {
|
|
||||||
transactionBalance += -tx.value.amount! - tx.value.fee!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Amount(
|
|
||||||
rawValue: BigInt.from(transactionBalance),
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
return info.cachedBalance.total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============== Private ====================================================
|
|
||||||
|
|
||||||
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
|
|
||||||
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
|
|
||||||
|
|
||||||
final Mutex _torConnectingLock = Mutex();
|
|
||||||
bool _requireMutex = false;
|
|
||||||
}
|
}
|
||||||
|
|
1293
lib/wallets/wallet/intermediate/lib_monero_wallet.dart
Normal file
1293
lib/wallets/wallet/intermediate/lib_monero_wallet.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,532 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:cw_core/sync_status.dart';
|
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
|
||||||
import 'package:cw_core/utxo.dart' as cw;
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
|
||||||
import 'package:cw_core/wallet_service.dart';
|
|
||||||
import 'package:cw_core/wallet_type.dart';
|
|
||||||
import 'package:flutter_libmonero/core/key_service.dart';
|
|
||||||
import 'package:isar/isar.dart';
|
|
||||||
import 'package:mutex/mutex.dart';
|
|
||||||
|
|
||||||
import '../../../models/balance.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
|
||||||
import '../../../models/isar/models/blockchain_data/utxo.dart';
|
|
||||||
import '../../../models/keys/cw_key_data.dart';
|
|
||||||
import '../../../models/paymint/fee_object_model.dart';
|
|
||||||
import '../../../services/event_bus/events/global/blocks_remaining_event.dart';
|
|
||||||
import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart';
|
|
||||||
import '../../../services/event_bus/events/global/updated_in_background_event.dart';
|
|
||||||
import '../../../services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
|
||||||
import '../../../services/event_bus/global_event_bus.dart';
|
|
||||||
import '../../../utilities/amount/amount.dart';
|
|
||||||
import '../../../utilities/logger.dart';
|
|
||||||
import '../../../utilities/stack_file_system.dart';
|
|
||||||
import '../../crypto_currency/intermediate/cryptonote_currency.dart';
|
|
||||||
import '../../isar/models/wallet_info.dart';
|
|
||||||
import '../intermediate/cryptonote_wallet.dart';
|
|
||||||
import 'multi_address_interface.dart';
|
|
||||||
|
|
||||||
mixin CwBasedInterface<T extends CryptonoteCurrency, U extends WalletBase,
|
|
||||||
V extends WalletService> on CryptonoteWallet<T>
|
|
||||||
implements MultiAddressInterface<T> {
|
|
||||||
final prepareSendMutex = Mutex();
|
|
||||||
final estimateFeeMutex = Mutex();
|
|
||||||
|
|
||||||
KeyService? _cwKeysStorageCached;
|
|
||||||
KeyService get cwKeysStorage =>
|
|
||||||
_cwKeysStorageCached ??= KeyService(secureStorageInterface);
|
|
||||||
|
|
||||||
bool _txRefreshLock = false;
|
|
||||||
int _lastCheckedHeight = -1;
|
|
||||||
int _txCount = 0;
|
|
||||||
int currentKnownChainHeight = 0;
|
|
||||||
double highestPercentCached = 0;
|
|
||||||
|
|
||||||
Timer? autoSaveTimer;
|
|
||||||
Future<String> pathForWalletDir({
|
|
||||||
required String name,
|
|
||||||
required WalletType type,
|
|
||||||
}) async {
|
|
||||||
final Directory root = await StackFileSystem.applicationRootDirectory();
|
|
||||||
|
|
||||||
final prefix = walletTypeToString(type).toLowerCase();
|
|
||||||
final walletsDir = Directory('${root.path}/wallets');
|
|
||||||
final walletDire = Directory('${walletsDir.path}/$prefix/$name');
|
|
||||||
|
|
||||||
if (!walletDire.existsSync()) {
|
|
||||||
walletDire.createSync(recursive: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return walletDire.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> pathForWallet({
|
|
||||||
required String name,
|
|
||||||
required WalletType type,
|
|
||||||
}) async =>
|
|
||||||
await pathForWalletDir(name: name, type: type)
|
|
||||||
.then((path) => '$path/$name');
|
|
||||||
|
|
||||||
void onNewBlock({required int height, required int blocksLeft}) {
|
|
||||||
currentKnownChainHeight = height;
|
|
||||||
updateChainHeight();
|
|
||||||
_refreshTxDataHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
final _utxosUpdateLock = Mutex();
|
|
||||||
Future<void> onUTXOsCHanged(List<UTXO> utxos) async {
|
|
||||||
await _utxosUpdateLock.protect(() async {
|
|
||||||
final cwUtxos = cwWalletBase?.utxos ?? [];
|
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
for (final cw in cwUtxos) {
|
|
||||||
final match = utxos.where(
|
|
||||||
(e) =>
|
|
||||||
e.keyImage != null &&
|
|
||||||
e.keyImage!.isNotEmpty &&
|
|
||||||
e.keyImage == cw.keyImage,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (match.isNotEmpty) {
|
|
||||||
final u = match.first;
|
|
||||||
|
|
||||||
if (u.isBlocked) {
|
|
||||||
if (!cw.isFrozen) {
|
|
||||||
await cwWalletBase?.freeze(cw.keyImage);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (cw.isFrozen) {
|
|
||||||
await cwWalletBase?.thaw(cw.keyImage);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
await cwWalletBase?.updateUTXOs();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void onNewTransaction() {
|
|
||||||
// TODO: [prio=low] get rid of UpdatedInBackgroundEvent and move to
|
|
||||||
// adding the v2 tx to the db which would update ui automagically since the
|
|
||||||
// db is watched by the ui
|
|
||||||
// call this here?
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
UpdatedInBackgroundEvent(
|
|
||||||
"New data found in $walletId ${info.name} in background!",
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void syncStatusChanged() async {
|
|
||||||
final syncStatus = cwWalletBase?.syncStatus;
|
|
||||||
|
|
||||||
if (syncStatus != null) {
|
|
||||||
if (syncStatus.progress() == 1 && refreshMutex.isLocked) {
|
|
||||||
refreshMutex.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletSyncStatus? status;
|
|
||||||
xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(true);
|
|
||||||
|
|
||||||
if (syncStatus is SyncingSyncStatus) {
|
|
||||||
final int blocksLeft = syncStatus.blocksLeft;
|
|
||||||
|
|
||||||
// ensure at least 1 to prevent math errors
|
|
||||||
final int height = max(1, syncStatus.height);
|
|
||||||
|
|
||||||
final nodeHeight = height + blocksLeft;
|
|
||||||
currentKnownChainHeight = nodeHeight;
|
|
||||||
|
|
||||||
final percent = height / nodeHeight;
|
|
||||||
|
|
||||||
final highest = max(highestPercentCached, percent);
|
|
||||||
|
|
||||||
// update cached
|
|
||||||
if (highestPercentCached < percent) {
|
|
||||||
highestPercentCached = percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
RefreshPercentChangedEvent(
|
|
||||||
highest,
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
BlocksRemainingEvent(
|
|
||||||
blocksLeft,
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (syncStatus is SyncedSyncStatus) {
|
|
||||||
status = WalletSyncStatus.synced;
|
|
||||||
} else if (syncStatus is NotConnectedSyncStatus) {
|
|
||||||
status = WalletSyncStatus.unableToSync;
|
|
||||||
xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false);
|
|
||||||
} else if (syncStatus is StartingSyncStatus) {
|
|
||||||
status = WalletSyncStatus.syncing;
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
RefreshPercentChangedEvent(
|
|
||||||
highestPercentCached,
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (syncStatus is FailedSyncStatus) {
|
|
||||||
status = WalletSyncStatus.unableToSync;
|
|
||||||
xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false);
|
|
||||||
} else if (syncStatus is ConnectingSyncStatus) {
|
|
||||||
status = WalletSyncStatus.syncing;
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
RefreshPercentChangedEvent(
|
|
||||||
highestPercentCached,
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (syncStatus is ConnectedSyncStatus) {
|
|
||||||
status = WalletSyncStatus.syncing;
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
RefreshPercentChangedEvent(
|
|
||||||
highestPercentCached,
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (syncStatus is LostConnectionSyncStatus) {
|
|
||||||
status = WalletSyncStatus.unableToSync;
|
|
||||||
xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != null) {
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
WalletSyncStatusChangedEvent(
|
|
||||||
status,
|
|
||||||
walletId,
|
|
||||||
info.coin,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> checkSaveInitialReceivingAddress() async {
|
|
||||||
// this doesn't work without opening the wallet first which takes a while
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Interface ====================================================
|
|
||||||
|
|
||||||
U? get cwWalletBase;
|
|
||||||
V? get cwWalletService;
|
|
||||||
|
|
||||||
Future<Amount> get availableBalance;
|
|
||||||
Future<Amount> get totalBalance;
|
|
||||||
|
|
||||||
Future<void> open();
|
|
||||||
|
|
||||||
Address addressFor({required int index, int account = 0});
|
|
||||||
|
|
||||||
Future<CWKeyData?> getKeys();
|
|
||||||
|
|
||||||
// ============ Private ======================================================
|
|
||||||
Future<void> _refreshTxDataHelper() async {
|
|
||||||
if (_txRefreshLock) return;
|
|
||||||
_txRefreshLock = true;
|
|
||||||
|
|
||||||
final syncStatus = cwWalletBase?.syncStatus;
|
|
||||||
|
|
||||||
if (syncStatus != null && syncStatus is SyncingSyncStatus) {
|
|
||||||
final int blocksLeft = syncStatus.blocksLeft;
|
|
||||||
final tenKChange = blocksLeft ~/ 10000;
|
|
||||||
|
|
||||||
// only refresh transactions periodically during a sync
|
|
||||||
if (_lastCheckedHeight == -1 || tenKChange < _lastCheckedHeight) {
|
|
||||||
_lastCheckedHeight = tenKChange;
|
|
||||||
await _refreshTxData();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await _refreshTxData();
|
|
||||||
}
|
|
||||||
|
|
||||||
_txRefreshLock = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _refreshTxData() async {
|
|
||||||
await updateTransactions();
|
|
||||||
final count = await mainDB.getTransactions(walletId).count();
|
|
||||||
|
|
||||||
if (count > _txCount) {
|
|
||||||
_txCount = count;
|
|
||||||
await updateBalance();
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
UpdatedInBackgroundEvent(
|
|
||||||
"New transaction data found in $walletId ${info.name}!",
|
|
||||||
walletId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Overrides ====================================================
|
|
||||||
|
|
||||||
@override
|
|
||||||
FilterOperation? get changeAddressFilterOperation => null;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FilterOperation? get receivingAddressFilterOperation => null;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> updateUTXOs() async {
|
|
||||||
await cwWalletBase?.updateUTXOs();
|
|
||||||
|
|
||||||
final List<UTXO> outputArray = [];
|
|
||||||
for (final rawUTXO in (cwWalletBase?.utxos ?? <cw.UTXO>[])) {
|
|
||||||
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.transactions
|
|
||||||
.where()
|
|
||||||
.walletIdEqualTo(walletId)
|
|
||||||
.filter()
|
|
||||||
.txidEqualTo(rawUTXO.hash)
|
|
||||||
.findFirst();
|
|
||||||
|
|
||||||
final otherDataMap = {
|
|
||||||
"keyImage": rawUTXO.keyImage,
|
|
||||||
"spent": rawUTXO.spent,
|
|
||||||
};
|
|
||||||
|
|
||||||
final utxo = UTXO(
|
|
||||||
address: rawUTXO.address,
|
|
||||||
walletId: walletId,
|
|
||||||
txid: rawUTXO.hash,
|
|
||||||
vout: rawUTXO.vout,
|
|
||||||
value: rawUTXO.value,
|
|
||||||
name: current?.name ?? "",
|
|
||||||
isBlocked: current?.isBlocked ?? rawUTXO.isFrozen,
|
|
||||||
blockedReason: current?.blockedReason ?? "",
|
|
||||||
isCoinbase: rawUTXO.coinbase,
|
|
||||||
blockHash: "",
|
|
||||||
blockHeight:
|
|
||||||
tx?.height ?? (rawUTXO.height > 0 ? rawUTXO.height : null),
|
|
||||||
blockTime: tx?.timestamp,
|
|
||||||
otherData: jsonEncode(otherDataMap),
|
|
||||||
);
|
|
||||||
|
|
||||||
outputArray.add(utxo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await mainDB.updateUTXOs(walletId, outputArray);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateBalance({bool shouldUpdateUtxos = true}) async {
|
|
||||||
if (shouldUpdateUtxos) {
|
|
||||||
await updateUTXOs();
|
|
||||||
}
|
|
||||||
|
|
||||||
final total = await totalBalance;
|
|
||||||
final available = await availableBalance;
|
|
||||||
|
|
||||||
final balance = Balance(
|
|
||||||
total: total,
|
|
||||||
spendable: available,
|
|
||||||
blockedTotal: Amount(
|
|
||||||
rawValue: BigInt.zero,
|
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
|
||||||
),
|
|
||||||
pendingSpendable: total - available,
|
|
||||||
);
|
|
||||||
|
|
||||||
await info.updateBalance(newBalance: balance, isar: mainDB.isar);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> refresh() async {
|
|
||||||
// Awaiting this lock could be dangerous.
|
|
||||||
// Since refresh is periodic (generally)
|
|
||||||
if (refreshMutex.isLocked) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this acquire should be almost instant due to above check.
|
|
||||||
// Slight possibility of race but should be irrelevant
|
|
||||||
await refreshMutex.acquire();
|
|
||||||
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
WalletSyncStatusChangedEvent(
|
|
||||||
WalletSyncStatus.syncing,
|
|
||||||
walletId,
|
|
||||||
info.coin,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await updateTransactions();
|
|
||||||
await updateBalance();
|
|
||||||
|
|
||||||
if (info.otherData[WalletInfoKeys.reuseAddress] != true) {
|
|
||||||
await checkReceivingAddressForTransactions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cwWalletBase?.syncStatus is SyncedSyncStatus) {
|
|
||||||
refreshMutex.release();
|
|
||||||
GlobalEventBus.instance.fire(
|
|
||||||
WalletSyncStatusChangedEvent(
|
|
||||||
WalletSyncStatus.synced,
|
|
||||||
walletId,
|
|
||||||
info.coin,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> exit() async {
|
|
||||||
autoSaveTimer?.cancel();
|
|
||||||
await cwWalletBase?.save();
|
|
||||||
cwWalletBase?.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> generateNewReceivingAddress() async {
|
|
||||||
try {
|
|
||||||
final currentReceiving = await getCurrentReceivingAddress();
|
|
||||||
|
|
||||||
final newReceivingIndex =
|
|
||||||
currentReceiving == null ? 0 : currentReceiving.derivationIndex + 1;
|
|
||||||
|
|
||||||
final newReceivingAddress = addressFor(index: newReceivingIndex);
|
|
||||||
|
|
||||||
// Add that new receiving address
|
|
||||||
await mainDB.putAddress(newReceivingAddress);
|
|
||||||
await info.updateReceivingAddress(
|
|
||||||
newAddress: newReceivingAddress.value,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception in generateNewAddress(): $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> checkReceivingAddressForTransactions() async {
|
|
||||||
if (info.otherData[WalletInfoKeys.reuseAddress] == true) {
|
|
||||||
try {
|
|
||||||
throw Exception();
|
|
||||||
} catch (_, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"checkReceivingAddressForTransactions called but reuse address flag set: $s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
int highestIndex = -1;
|
|
||||||
final entries = cwWalletBase?.transactionHistory?.transactions?.entries;
|
|
||||||
if (entries != null) {
|
|
||||||
for (final element in entries) {
|
|
||||||
if (element.value.direction == TransactionDirection.incoming) {
|
|
||||||
final int curAddressIndex =
|
|
||||||
element.value.additionalInfo!['addressIndex'] as int;
|
|
||||||
if (curAddressIndex > highestIndex) {
|
|
||||||
highestIndex = curAddressIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the new receiving index
|
|
||||||
final currentReceiving = await getCurrentReceivingAddress();
|
|
||||||
final curIndex = currentReceiving?.derivationIndex ?? -1;
|
|
||||||
|
|
||||||
if (highestIndex >= curIndex) {
|
|
||||||
// First increment the receiving index
|
|
||||||
final newReceivingIndex = curIndex + 1;
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
if (existing == null) {
|
|
||||||
// Add that new change address
|
|
||||||
await mainDB.putAddress(newReceivingAddress);
|
|
||||||
} else {
|
|
||||||
// we need to update the address
|
|
||||||
await mainDB.updateAddress(existing, newReceivingAddress);
|
|
||||||
}
|
|
||||||
if (info.otherData[WalletInfoKeys.reuseAddress] != true) {
|
|
||||||
// keep checking until address with no tx history is set as current
|
|
||||||
await checkReceivingAddressForTransactions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} on SocketException catch (se, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"SocketException caught in _checkReceivingAddressForTransactions(): $se\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
} catch (e, s) {
|
|
||||||
Logging.instance.log(
|
|
||||||
"Exception rethrown from _checkReceivingAddressForTransactions(): $e\n$s",
|
|
||||||
level: LogLevel.Error,
|
|
||||||
);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<FeeObject> get fees async => FeeObject(
|
|
||||||
numberOfBlocksFast: 10,
|
|
||||||
numberOfBlocksAverage: 15,
|
|
||||||
numberOfBlocksSlow: 20,
|
|
||||||
fast: MoneroTransactionPriority.fast.raw!,
|
|
||||||
medium: MoneroTransactionPriority.regular.raw!,
|
|
||||||
slow: MoneroTransactionPriority.slow.raw!,
|
|
||||||
);
|
|
||||||
@override
|
|
||||||
Future<void> updateChainHeight() async {
|
|
||||||
await info.updateCachedChainHeight(
|
|
||||||
newHeight: currentKnownChainHeight,
|
|
||||||
isar: mainDB.isar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> checkChangeAddressForTransactions() async {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> generateNewChangeAddress() async {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cs_monero/cs_monero.dart' as lib_monero;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import '../../models/models.dart';
|
import '../../models/models.dart';
|
||||||
import '../../pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
|
import '../../pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
|
||||||
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart';
|
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart';
|
||||||
|
@ -61,7 +62,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.fast.raw!,
|
lib_monero.TransactionPriority.high.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -111,7 +112,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.regular.raw!,
|
lib_monero.TransactionPriority.medium.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
@ -161,7 +162,7 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
|
||||||
if (coin is Monero || coin is Wownero) {
|
if (coin is Monero || coin is Wownero) {
|
||||||
final fee = await wallet.estimateFeeFor(
|
final fee = await wallet.estimateFeeFor(
|
||||||
amount,
|
amount,
|
||||||
MoneroTransactionPriority.slow.raw!,
|
lib_monero.TransactionPriority.normal.value,
|
||||||
);
|
);
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
|
||||||
} else if (coin is Firo) {
|
} else if (coin is Firo) {
|
||||||
|
|
|
@ -27,8 +27,8 @@ import '../utilities/util.dart';
|
||||||
import '../wallets/isar/providers/eth/current_token_wallet_provider.dart';
|
import '../wallets/isar/providers/eth/current_token_wallet_provider.dart';
|
||||||
import '../wallets/wallet/impl/ethereum_wallet.dart';
|
import '../wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import '../wallets/wallet/impl/sub_wallets/eth_token_wallet.dart';
|
import '../wallets/wallet/impl/sub_wallets/eth_token_wallet.dart';
|
||||||
|
import '../wallets/wallet/intermediate/lib_monero_wallet.dart';
|
||||||
import '../wallets/wallet/wallet.dart';
|
import '../wallets/wallet/wallet.dart';
|
||||||
import '../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
|
||||||
import 'conditional_parent.dart';
|
import 'conditional_parent.dart';
|
||||||
import 'desktop/primary_button.dart';
|
import 'desktop/primary_button.dart';
|
||||||
import 'dialogs/basic_dialog.dart';
|
import 'dialogs/basic_dialog.dart';
|
||||||
|
@ -97,7 +97,7 @@ class SimpleWalletCard extends ConsumerWidget {
|
||||||
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
final Future<void> loadFuture;
|
final Future<void> loadFuture;
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is LibMoneroWallet) {
|
||||||
loadFuture = wallet.init().then((value) async => await (wallet).open());
|
loadFuture = wallet.init().then((value) async => await (wallet).open());
|
||||||
} else {
|
} else {
|
||||||
loadFuture = wallet.init();
|
loadFuture = wallet.init();
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <cs_monero_flutter_libs/cs_monero_flutter_libs_plugin.h>
|
||||||
#include <desktop_drop/desktop_drop_plugin.h>
|
#include <desktop_drop/desktop_drop_plugin.h>
|
||||||
#include <devicelocale/devicelocale_plugin.h>
|
#include <devicelocale/devicelocale_plugin.h>
|
||||||
#include <flutter_libepiccash/flutter_libepiccash_plugin.h>
|
#include <flutter_libepiccash/flutter_libepiccash_plugin.h>
|
||||||
#include <flutter_libmonero/flutter_libmonero_plugin.h>
|
|
||||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||||
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
||||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
|
@ -18,6 +18,9 @@
|
||||||
#include <window_size/window_size_plugin.h>
|
#include <window_size/window_size_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) cs_monero_flutter_libs_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "CsMoneroFlutterLibsPlugin");
|
||||||
|
cs_monero_flutter_libs_plugin_register_with_registrar(cs_monero_flutter_libs_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) desktop_drop_registrar =
|
g_autoptr(FlPluginRegistrar) desktop_drop_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin");
|
||||||
desktop_drop_plugin_register_with_registrar(desktop_drop_registrar);
|
desktop_drop_plugin_register_with_registrar(desktop_drop_registrar);
|
||||||
|
@ -27,9 +30,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) flutter_libepiccash_registrar =
|
g_autoptr(FlPluginRegistrar) flutter_libepiccash_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLibepiccashPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLibepiccashPlugin");
|
||||||
flutter_libepiccash_plugin_register_with_registrar(flutter_libepiccash_registrar);
|
flutter_libepiccash_plugin_register_with_registrar(flutter_libepiccash_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) flutter_libmonero_registrar =
|
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLibmoneroPlugin");
|
|
||||||
flutter_libmonero_plugin_register_with_registrar(flutter_libmonero_registrar);
|
|
||||||
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||||
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
cs_monero_flutter_libs
|
||||||
desktop_drop
|
desktop_drop
|
||||||
devicelocale
|
devicelocale
|
||||||
flutter_libepiccash
|
flutter_libepiccash
|
||||||
flutter_libmonero
|
|
||||||
flutter_secure_storage_linux
|
flutter_secure_storage_linux
|
||||||
isar_flutter_libs
|
isar_flutter_libs
|
||||||
sqlite3_flutter_libs
|
sqlite3_flutter_libs
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Foundation
|
||||||
|
|
||||||
import camera_macos
|
import camera_macos
|
||||||
import connectivity_plus
|
import connectivity_plus
|
||||||
|
import cs_monero_flutter_libs
|
||||||
import desktop_drop
|
import desktop_drop
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import devicelocale
|
import devicelocale
|
||||||
|
@ -28,6 +29,7 @@ import window_size
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
CameraMacosPlugin.register(with: registry.registrar(forPlugin: "CameraMacosPlugin"))
|
CameraMacosPlugin.register(with: registry.registrar(forPlugin: "CameraMacosPlugin"))
|
||||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||||
|
CsMoneroFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "CsMoneroFlutterLibsPlugin"))
|
||||||
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
|
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin"))
|
DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin"))
|
||||||
|
|
105
pubspec.lock
105
pubspec.lock
|
@ -54,14 +54,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.5.0"
|
||||||
asn1lib:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: asn1lib
|
|
||||||
sha256: "2ca377ad4d677bbadca278e0ba4da4e057b80a10b927bfc8f7d8bda8fe2ceb75"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.4"
|
|
||||||
async:
|
async:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -374,6 +366,13 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.18.0"
|
||||||
|
compat:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "crypto_plugins/cs_monero/compat"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "1.0.0"
|
||||||
connectivity_plus:
|
connectivity_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -430,6 +429,20 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
|
cs_monero:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "crypto_plugins/cs_monero/cs_monero"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "1.0.0"
|
||||||
|
cs_monero_flutter_libs:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "crypto_plugins/cs_monero/cs_monero_flutter_libs"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "1.0.0"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -438,27 +451,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
cw_core:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "crypto_plugins/flutter_libmonero/cw_core"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
cw_monero:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "crypto_plugins/flutter_libmonero/cw_monero"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
cw_wownero:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "crypto_plugins/flutter_libmonero/cw_wownero"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
dart_base_x:
|
dart_base_x:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -628,14 +620,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.9"
|
version: "0.9.9"
|
||||||
encrypt:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: encrypt
|
|
||||||
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.0.3"
|
|
||||||
equatable:
|
equatable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -750,13 +734,6 @@ packages:
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
flutter_libmonero:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "crypto_plugins/flutter_libmonero"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter_libsparkmobile:
|
flutter_libsparkmobile:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -798,14 +775,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.0"
|
version: "7.2.0"
|
||||||
flutter_mobx:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flutter_mobx
|
|
||||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.2.1+1"
|
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -1217,6 +1186,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.11"
|
version: "1.0.11"
|
||||||
|
logger:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: logger
|
||||||
|
sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1281,14 +1258,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.6"
|
||||||
mobx:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: mobx
|
|
||||||
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.3.3+2"
|
|
||||||
mockingjay:
|
mockingjay:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -1338,14 +1307,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
nested:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: nested
|
|
||||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
nm:
|
nm:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1578,14 +1539,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
provider:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: provider
|
|
||||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "6.1.2"
|
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -14,7 +14,7 @@ PLUGINS_DIR=../../crypto_plugins
|
||||||
|
|
||||||
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/cs_monero/tools/build_scripts && ./build_android.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ PLUGINS_DIR=../../crypto_plugins
|
||||||
|
|
||||||
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/cs_monero/tools/build_scripts && ./build_android.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ PLUGINS_DIR=../../crypto_plugins
|
||||||
|
|
||||||
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh )
|
||||||
(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/cs_monero/tools/build_scripts && ./build_android.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -45,14 +45,14 @@ android {
|
||||||
abiFilters "x86_64","armeabi-v7a", "arm64-v8a"
|
abiFilters "x86_64","armeabi-v7a", "arm64-v8a"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalNativeBuild {
|
// externalNativeBuild {
|
||||||
cmake {
|
// cmake {
|
||||||
arguments "-DANDROID_STL=c++_shared", '-DBUILD_TESTING=OFF', "-DANDROID_TOOLCHAIN=clang -v"
|
// arguments "-DANDROID_STL=c++_shared", '-DBUILD_TESTING=OFF', "-DANDROID_TOOLCHAIN=clang -v"
|
||||||
cppFlags "-frtti -fexceptions -v -DANDROID -std=c++17"
|
// cppFlags "-frtti -fexceptions -v -DANDROID -std=c++17"
|
||||||
// cppFlags "-std=c++11"
|
//// cppFlags "-std=c++11"
|
||||||
version "3.10.2"
|
// version "3.10.2"
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
|
|
@ -134,12 +134,6 @@ install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}
|
||||||
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
COMPONENT Runtime)
|
COMPONENT Runtime)
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/monero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "monero_libwallet2_api_c.so"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.so"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libepiccash/scripts/linux/build/rust/target/x86_64-unknown-linux-gnu/release/libepic_cash_wallet.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libepiccash/scripts/linux/build/rust/target/x86_64-unknown-linux-gnu/release/libepic_cash_wallet.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
COMPONENT Runtime)
|
COMPONENT Runtime)
|
||||||
|
|
||||||
|
|
|
@ -37,17 +37,14 @@ dependencies:
|
||||||
url: https://github.com/cypherstack/flutter_libsparkmobile.git
|
url: https://github.com/cypherstack/flutter_libsparkmobile.git
|
||||||
ref: cc7b43b731e4a7906dd25d4364a08e34554cee19
|
ref: cc7b43b731e4a7906dd25d4364a08e34554cee19
|
||||||
|
|
||||||
flutter_libmonero:
|
cs_monero:
|
||||||
path: ./crypto_plugins/flutter_libmonero
|
path: ./crypto_plugins/cs_monero/cs_monero
|
||||||
|
|
||||||
cw_monero:
|
compat:
|
||||||
path: ./crypto_plugins/flutter_libmonero/cw_monero
|
path: ./crypto_plugins/cs_monero/compat
|
||||||
|
|
||||||
cw_wownero:
|
cs_monero_flutter_libs:
|
||||||
path: ./crypto_plugins/flutter_libmonero/cw_wownero
|
path: ./crypto_plugins/cs_monero/cs_monero_flutter_libs
|
||||||
|
|
||||||
cw_core:
|
|
||||||
path: ./crypto_plugins/flutter_libmonero/cw_core
|
|
||||||
|
|
||||||
monero:
|
monero:
|
||||||
git:
|
git:
|
||||||
|
|
|
@ -86,27 +86,6 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libepiccash
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_liblelantus/scripts/windows/build/libmobileliblelantus.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_liblelantus/scripts/windows/build/libmobileliblelantus.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
COMPONENT Runtime)
|
COMPONENT Runtime)
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/monero/x86_64-w64-mingw32_libwallet2_api_c.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "monero_libwallet2_api_c.dll"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libwallet2_api_c.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.dll"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
#install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libgcc_s_seh-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libgcc_s_seh-1.dll"
|
|
||||||
# COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libpolyseed.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libpolyseed.dll"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libssp-0.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libssp-0.dll"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
#install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libstdc++-6.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libstdc++-6.dll"
|
|
||||||
# COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libwinpthread-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libwinpthread-1.dll"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
if(PLUGIN_BUNDLED_LIBRARIES)
|
if(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
||||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
|
|
|
@ -16,7 +16,7 @@ rustup target add x86_64-apple-ios
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_ios.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ rustup target add x86_64-apple-ios
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_ios.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ rustup target add x86_64-apple-ios
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_ios.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ mkdir -p build
|
||||||
./build_secure_storage_deps.sh
|
./build_secure_storage_deps.sh
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_linux.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ mkdir -p build
|
||||||
./build_secure_storage_deps.sh
|
./build_secure_storage_deps.sh
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_linux.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ mkdir -p build
|
||||||
./build_secure_storage_deps.sh &
|
./build_secure_storage_deps.sh &
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_linux.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ set_rust_to_1671
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_macos.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ set_rust_to_1671
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_macos.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ set_rust_to_1671
|
||||||
|
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh )
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_macos.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ set_rust_to_1671
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh)
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_windows.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ set_rust_to_1671
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh)
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_windows.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ set_rust_to_1671
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh )
|
||||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh)
|
(cd ../../crypto_plugins/cs_monero/tools/build_scripts && ./build_windows.sh )
|
||||||
set_rust_to_1720
|
set_rust_to_1720
|
||||||
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
(cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh )
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <camera_windows/camera_windows.h>
|
#include <camera_windows/camera_windows.h>
|
||||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||||
|
#include <cs_monero_flutter_libs/cs_monero_flutter_libs_plugin_c_api.h>
|
||||||
#include <desktop_drop/desktop_drop_plugin.h>
|
#include <desktop_drop/desktop_drop_plugin.h>
|
||||||
#include <flutter_libepiccash/flutter_libepiccash_plugin_c_api.h>
|
#include <flutter_libepiccash/flutter_libepiccash_plugin_c_api.h>
|
||||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||||
|
@ -25,6 +26,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
registry->GetRegistrarForPlugin("CameraWindows"));
|
registry->GetRegistrarForPlugin("CameraWindows"));
|
||||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||||
|
CsMoneroFlutterLibsPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("CsMoneroFlutterLibsPluginCApi"));
|
||||||
DesktopDropPluginRegisterWithRegistrar(
|
DesktopDropPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
|
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
|
||||||
FlutterLibepiccashPluginCApiRegisterWithRegistrar(
|
FlutterLibepiccashPluginCApiRegisterWithRegistrar(
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
camera_windows
|
camera_windows
|
||||||
connectivity_plus
|
connectivity_plus
|
||||||
|
cs_monero_flutter_libs
|
||||||
desktop_drop
|
desktop_drop
|
||||||
flutter_libepiccash
|
flutter_libepiccash
|
||||||
flutter_secure_storage_windows
|
flutter_secure_storage_windows
|
||||||
|
|
Loading…
Reference in a new issue