Merge pull request #876 from cypherstack/appConfig

App config
This commit is contained in:
Diego Salazar 2024-05-24 15:35:42 -06:00 committed by GitHub
commit 205b6408bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
864 changed files with 17236 additions and 15675 deletions

37
.gitignore vendored
View file

@ -46,6 +46,12 @@ test/services/coins/particl/particl_wallet_test_parameters.dart
# Exceptions to above rules. # Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
# asset symlinks
/assets/default_themes
/assets/icon
/assets/lottie
/assets/in_app_logo_icons
# other # other
coverage coverage
scripts/**/build scripts/**/build
@ -59,3 +65,34 @@ libtor_ffi.dll
flutter_libsparkmobile.dll flutter_libsparkmobile.dll
secp256k1.dll secp256k1.dll
/libisar.so /libisar.so
/lib/app_config.g.dart
/android/app/src/main/app_icon-playstore.png
## other generated project files
pubspec.yaml
/android/app/build.gradle
/android/app/src/debug/AndroidManifest.xml
/android/app/src/profile/AndroidManifest.xml
/android/app/src/main/AndroidManifest.xml
/android/app/src/main/profile/AndroidManifest.xml
/android/app/src/main/kotlin/com/cypherstack/stackwallet/MainActivity.kt
/android/app/src/main/res/**/ic_launcher.png
/ios/Runner/Info.plist
/ios/Runner.xcodeproj/project.pbxproj
/ios/Runner/Assets.xcassets/AppIcon.appiconset/*.png
/linux/CMakeLists.txt
/linux/my_application.cc
/macos/Runner/Configs/AppInfo.xcconfig
/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
/macos/Runner.xcodeproj/project.pbxproj
/macos/Runner/Assets.xcassets/AppIcon.appiconset/*.png
/windows/runner/Runner.rc
/windows/runner/main.cpp
/windows/CMakeLists.txt
/windows/runner/resources/app_icon.ico

View file

@ -82,7 +82,7 @@ linter:
# `// ignore_for_file: name_of_lint` syntax on the line or in the file # `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint. # producing the lint.
rules: rules:
always_use_package_imports: true prefer_relative_imports: true
avoid_relative_lib_imports: true avoid_relative_lib_imports: true
no_leading_underscores_for_local_identifiers: false no_leading_underscores_for_local_identifiers: false
no_leading_underscores_for_library_prefixes: false no_leading_underscores_for_library_prefixes: false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m256.77 256c0 30.12-20.56 55.43-48.4 62.67-10.43-18.52-16.38-39.9-16.38-62.67s5.95-44.15 16.38-62.67c27.84 7.24 48.4 32.55 48.4 62.67z"/><path d="m447.99 256c0 70.69-57.31 128-128 128-23.31 0-45.16-6.23-63.99-17.12 38.26-22.13 64.01-63.5 64.01-110.88s-25.75-88.75-64.01-110.88c18.83-10.89 40.68-17.12 63.99-17.12 70.69 0 128 57.31 128 128z"/><path d="m208.37 318.67c-5.22 1.37-10.71 2.09-16.36 2.09-35.77 0-64.77-28.99-64.77-64.76s29-64.76 64.77-64.76c5.65 0 11.14.72 16.36 2.09 11.26-20.03 27.76-36.72 47.63-48.21-18.83-10.89-40.68-17.12-63.99-17.12-70.7 0-128 57.31-128 128s57.3 128 128 128c23.31 0 45.16-6.23 63.99-17.12-19.87-11.49-36.37-28.18-47.63-48.21z" fill="#b3b3b3"/><path d="m320.01 256c0 47.38-25.75 88.75-64.01 110.88-19.87-11.49-36.37-28.18-47.63-48.21 27.84-7.24 48.4-32.55 48.4-62.67s-20.56-55.43-48.4-62.67c11.26-20.03 27.76-36.72 47.63-48.21 38.26 22.13 64.01 63.5 64.01 110.88z" fill="#666"/></svg>

After

Width:  |  Height:  |  Size: 989 B

View file

@ -0,0 +1 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m256.77 256c0 30.12-20.56 55.43-48.4 62.67-10.43-18.52-16.38-39.9-16.38-62.67s5.95-44.15 16.38-62.67c27.84 7.24 48.4 32.55 48.4 62.67z"/><path d="m447.99 256c0 70.69-57.31 128-128 128-23.31 0-45.16-6.23-63.99-17.12 38.26-22.13 64.01-63.5 64.01-110.88s-25.75-88.75-64.01-110.88c18.83-10.89 40.68-17.12 63.99-17.12 70.69 0 128 57.31 128 128z"/><path d="m208.37 318.67c-5.22 1.37-10.71 2.09-16.36 2.09-35.77 0-64.77-28.99-64.77-64.76s29-64.76 64.77-64.76c5.65 0 11.14.72 16.36 2.09 11.26-20.03 27.76-36.72 47.63-48.21-18.83-10.89-40.68-17.12-63.99-17.12-70.7 0-128 57.31-128 128s57.3 128 128 128c23.31 0 45.16-6.23 63.99-17.12-19.87-11.49-36.37-28.18-47.63-48.21z" fill="#b3b3b3"/><path d="m320.01 256c0 47.38-25.75 88.75-64.01 110.88-19.87-11.49-36.37-28.18-47.63-48.21 27.84-7.24 48.4-32.55 48.4-62.67s-20.56-55.43-48.4-62.67c11.26-20.03 27.76-36.72 47.63-48.21 38.26 22.13 64.01 63.5 64.01 110.88z" fill="#666"/></svg>

After

Width:  |  Height:  |  Size: 989 B

View file

@ -0,0 +1 @@
Dummy file to ensure dir structure is preserved. Stack app icon is in standard themes.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"v":"5.10.2","fr":30,"ip":0,"op":60,"w":30,"h":30,"nm":"arrow-rotate","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"arrow-rotate","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44,"s":[200]},{"t":60,"s":[360]}],"ix":10},"p":{"a":0,"k":[15,15,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.828],[0,0],[3.389,0],[1.441,-4.074],[-0.781,-0.277],[-0.276,0.778],[-3.22,0],[-1.369,-1.823],[0,0],[0,-0.83],[-0.83,0],[0,0],[-0.023,0],[0,0],[0,0.83],[0,0],[0.83,0]],"o":[[0,0],[-1.964,-2.437],[-4.533,0],[-0.276,0.741],[0.781,0.277],[1.031,-2.916],[2.494,0],[0,0],[-0.83,0],[0,0.83],[0,0],[0.023,0],[0,0],[0.83,0],[0,0],[0,-0.828],[-0.83,0]],"v":[[8.25,-8.25],[8.25,-6.497],[-0.042,-10.5],[-9.902,-3.502],[-8.988,-1.584],[-7.073,-2.498],[-0.042,-7.5],[6,-4.5],[4.5,-4.5],[3,-3],[4.5,-1.5],[8.452,-1.5],[8.522,-1.5],[9.75,-1.5],[11.25,-3],[11.25,-8.25],[9.75,-9.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.828,0],[0,0.83],[0,0],[-3.347,0],[-1.439,4.073],[0.783,0.277],[0.277,-0.778],[3.262,0],[1.411,1.823],[0,0],[0,0.83],[0.83,0],[0,0],[0,-0.83]],"o":[[0,0.83],[0.828,0],[0,0],[1.922,2.438],[4.575,0],[0.277,-0.783],[-0.778,-0.277],[-1.031,2.916],[-2.452,0],[0,0],[0.83,0],[0,-0.83],[0,0],[-0.828,0],[0,0]],"v":[[-11.25,8.25],[-9.75,9.75],[-8.25,8.25],[-8.25,6.497],[0,10.5],[9.9,3.502],[8.986,1.584],[7.073,2.498],[0,7.5],[-6.042,4.5],[-4.5,4.5],[-3,3],[-4.5,1.5],[-9.75,1.5],[-11.25,3]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.137254908681,0.137254908681,0.137254908681,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"ct":1,"bm":0}],"markers":[]}

View file

@ -0,0 +1 @@
{"v":"5.10.2","fr":30,"ip":0,"op":100,"w":24,"h":24,"nm":"icon-send","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"MASK","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0.125,0.125,0],"ix":1,"l":2},"s":{"a":0,"k":[87.368,87.368,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[23.75,23.75],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.125,0.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Arrow","tt":1,"tp":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[-1.009,25.009,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":33,"s":[11.695,12.306,0],"to":[0,0,0],"ti":[0,0,0]},{"t":53,"s":[24.398,-0.397,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-0.69],[-0.69,0],[0,0],[0,0],[-0.488,-0.488],[-0.488,0.488],[0,0],[0,0],[-0.69,0],[0,0.69],[0,0],[0.234,0.234],[0.332,0]],"o":[[-0.69,0],[0,0.69],[0,0],[0,0],[-0.488,0.488],[0.488,0.488],[0,0],[0,0],[0,0.69],[0.69,0],[0,0],[0,-0.332],[-0.234,-0.234],[0,0]],"v":[[-2,-5.25],[-3.25,-4],[-2,-2.75],[0.982,-2.75],[-4.884,3.116],[-4.884,4.884],[-3.116,4.884],[2.75,-0.982],[2.75,2],[4,3.25],[5.25,2],[5.25,-4],[4.884,-4.884],[4,-5.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.137254908681,0.137254908681,0.137254908681,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Outline","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[12,0.063,0],"ix":1,"l":2},"s":{"a":0,"k":[90.104,90.104,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.137254901961,0.137254901961,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[12,0.063],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":58,"s":[0]},{"t":97,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":58,"s":[100]},{"t":97,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":100,"st":0,"ct":1,"bm":0}],"markers":[{"tm":0,"cm":"{\r\n\"name\":\"SEGMENT 1\"\r\n}","dr":0},{"tm":53,"cm":"{\r\n\"name\":\"SEGMENT 2\"\r\n}","dr":0},{"tm":97,"cm":"{\r\n\"name\":\"SEGMENT 3\"\r\n}","dr":0}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

@ -1 +1 @@
Subproject commit 2c684cedba6c3d9353c7ea748cadb5a246008027 Subproject commit 6e71b956c3801f65a662c7f140e871c246166db3

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,011 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

72
lib/app_config.dart Normal file
View file

@ -0,0 +1,72 @@
import 'wallets/crypto_currency/crypto_currency.dart';
import 'wallets/crypto_currency/intermediate/frost_currency.dart';
part 'app_config.g.dart';
abstract class AppConfig {
static const appName = _prefix + _separator + suffix;
static const prefix = _prefix;
static const suffix = _suffix;
static String get appDefaultDataDirName => _appDataDirName;
static String get commitHash => _commitHash;
static ({String light, String dark})? get appIconAsset => _appIconAsset;
static List<CryptoCurrency> get coins => _supportedCoins;
static CryptoCurrency? getCryptoCurrencyFor(String coinIdentifier) {
try {
return coins.firstWhere((e) => e.identifier == coinIdentifier);
} catch (_) {
return null;
}
}
static CryptoCurrency? getCryptoCurrencyForTicker(
final String ticker, {
bool caseInsensitive = true,
}) {
final _ticker = caseInsensitive ? ticker.toLowerCase() : ticker;
try {
return coins.firstWhere(
caseInsensitive
? (e) => e.ticker.toLowerCase() == _ticker && e is! FrostCurrency
: (e) => e.ticker == _ticker && e is! FrostCurrency,
);
} catch (_) {
return null;
}
}
static bool isStackCoin(String? ticker) {
if (ticker == null) {
return false;
}
if (getCryptoCurrencyForTicker(ticker, caseInsensitive: false) != null) {
return true;
}
try {
getCryptoCurrencyByPrettyName(ticker);
return true;
} catch (_) {
return false;
}
}
/// Fuzzy logic. Use with caution!!
@Deprecated("dangerous")
static CryptoCurrency getCryptoCurrencyByPrettyName(final String prettyName) {
final name = prettyName.replaceAll(" ", "").toLowerCase();
try {
return coins.firstWhere(
(e) => e.identifier.toLowerCase() == name || e.prettyName == prettyName,
);
} catch (_) {
throw Exception("getCryptoCurrencyByPrettyName($prettyName) failed!");
}
}
}

View file

@ -10,33 +10,31 @@
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/db/isar/main_db.dart';
import 'package:stackwallet/db/migrate_wallets_to_isar.dart';
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
import 'package:stackwallet/models/isar/models/contact_entry.dart'
as isar_contact;
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/services/mixins/wallet_db.dart';
import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/services/wallets_service.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
import '../app_config.dart';
import '../electrumx_rpc/electrumx_client.dart';
import '../models/contact.dart';
import '../models/exchange/change_now/exchange_transaction.dart';
import '../models/exchange/response_objects/trade.dart';
import '../models/isar/models/blockchain_data/address.dart';
import '../models/isar/models/contact_entry.dart' as isar_contact;
import '../models/isar/models/isar_models.dart' as isar_models;
import '../models/models.dart';
import '../models/node_model.dart';
import '../services/mixins/wallet_db.dart';
import '../services/node_service.dart';
import '../services/wallets_service.dart';
import '../utilities/amount/amount.dart';
import '../utilities/constants.dart';
import '../utilities/flutter_secure_storage_interface.dart';
import '../utilities/logger.dart';
import '../utilities/prefs.dart';
import '../wallets/crypto_currency/crypto_currency.dart';
import 'hive/db.dart';
import 'isar/main_db.dart';
import 'migrate_wallets_to_isar.dart';
class DbVersionMigrator with WalletDB { class DbVersionMigrator with WalletDB {
Future<void> migrate( Future<void> migrate(
int fromVersion, { int fromVersion, {
@ -59,14 +57,16 @@ class DbVersionMigrator with WalletDB {
ElectrumXClient? client; ElectrumXClient? client;
int? latestSetId; int? latestSetId;
final firo = Firo(CryptoCurrencyNetwork.main);
// only instantiate client if there are firo wallets // only instantiate client if there are firo wallets
if (walletInfoList.values.any((element) => element.coin == Coin.firo)) { if (walletInfoList.values
.any((element) => element.coinIdentifier == firo.identifier)) {
await Hive.openBox<NodeModel>(DB.boxNameNodeModels); await Hive.openBox<NodeModel>(DB.boxNameNodeModels);
await Hive.openBox<NodeModel>(DB.boxNamePrimaryNodes); await Hive.openBox<NodeModel>(DB.boxNamePrimaryNodes);
final node = nodeService.getPrimaryNodeFor(coin: Coin.firo) ?? final node =
DefaultNodes.firo; nodeService.getPrimaryNodeFor(currency: firo) ?? firo.defaultNode;
List<ElectrumXNode> failovers = nodeService final List<ElectrumXNode> failovers = nodeService
.failoverNodesFor(coin: Coin.firo) .failoverNodesFor(currency: firo)
.map( .map(
(e) => ElectrumXNode( (e) => ElectrumXNode(
address: e.host, address: e.host,
@ -80,11 +80,12 @@ class DbVersionMigrator with WalletDB {
client = ElectrumXClient.from( client = ElectrumXClient.from(
node: ElectrumXNode( node: ElectrumXNode(
address: node.host, address: node.host,
port: node.port, port: node.port,
name: node.name, name: node.name,
id: node.id, id: node.id,
useSSL: node.useSSL), useSSL: node.useSSL,
),
prefs: prefs, prefs: prefs,
failovers: failovers, failovers: failovers,
cryptoCurrency: Firo(CryptoCurrencyNetwork.main), cryptoCurrency: Firo(CryptoCurrencyNetwork.main),
@ -96,26 +97,29 @@ class DbVersionMigrator with WalletDB {
// default to 2 for now // default to 2 for now
latestSetId = 2; latestSetId = 2;
Logging.instance.log( Logging.instance.log(
"Failed to fetch latest coin id during firo db migrate: $e \nUsing a default value of 2", "Failed to fetch latest coin id during firo db migrate: $e \nUsing a default value of 2",
level: LogLevel.Warning); level: LogLevel.Warning,
);
} }
} }
for (final walletInfo in walletInfoList.values) { for (final walletInfo in walletInfoList.values) {
// migrate each firo wallet's lelantus coins // migrate each firo wallet's lelantus coins
if (walletInfo.coin == Coin.firo) { if (walletInfo.coinIdentifier == firo.identifier) {
await Hive.openBox<dynamic>(walletInfo.walletId); await Hive.openBox<dynamic>(walletInfo.walletId);
final _lelantusCoins = DB.instance.get<dynamic>( final _lelantusCoins = DB.instance.get<dynamic>(
boxName: walletInfo.walletId, key: '_lelantus_coins') as List?; boxName: walletInfo.walletId,
key: '_lelantus_coins',
) as List?;
final List<Map<dynamic, LelantusCoin>> lelantusCoins = []; final List<Map<dynamic, LelantusCoin>> lelantusCoins = [];
for (var lCoin in _lelantusCoins ?? []) { for (final lCoin in _lelantusCoins ?? []) {
lelantusCoins lelantusCoins
.add({lCoin.keys.first: lCoin.values.first as LelantusCoin}); .add({lCoin.keys.first: lCoin.values.first as LelantusCoin});
} }
List<Map<dynamic, LelantusCoin>> coins = []; final List<Map<dynamic, LelantusCoin>> coins = [];
for (final element in lelantusCoins) { for (final element in lelantusCoins) {
LelantusCoin coin = element.values.first; final LelantusCoin coin = element.values.first;
int anonSetId = coin.anonymitySetId; int anonSetId = coin.anonymitySetId;
if (coin.anonymitySetId == 1 && if (coin.anonymitySetId == 1 &&
(coin.publicCoin == '' || (coin.publicCoin == '' ||
@ -123,21 +127,31 @@ class DbVersionMigrator with WalletDB {
anonSetId = latestSetId!; anonSetId = latestSetId!;
} }
coins.add({ coins.add({
element.keys.first: LelantusCoin(coin.index, coin.value, element.keys.first: LelantusCoin(
coin.publicCoin, coin.txId, anonSetId, coin.isUsed) coin.index,
coin.value,
coin.publicCoin,
coin.txId,
anonSetId,
coin.isUsed,
),
}); });
} }
Logger.print("newcoins $coins", normalLength: false); Logger.print("newcoins $coins", normalLength: false);
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: walletInfo.walletId, boxName: walletInfo.walletId,
key: '_lelantus_coins', key: '_lelantus_coins',
value: coins); value: coins,
);
} }
} }
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 1); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 1,
);
// try to continue migrating // try to continue migrating
return await migrate(1, secureStore: secureStore); return await migrate(1, secureStore: secureStore);
@ -161,7 +175,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 2); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 2,
);
// try to continue migrating // try to continue migrating
return await migrate(2, secureStore: secureStore); return await migrate(2, secureStore: secureStore);
@ -176,16 +193,26 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 3); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 3,
);
return await migrate(3, secureStore: secureStore); return await migrate(3, secureStore: secureStore);
case 3: case 3:
// clear possible broken firo cache // clear possible broken firo cache
await DB.instance.clearSharedTransactionCache(coin: Coin.firo); await DB.instance.clearSharedTransactionCache(
currency: Firo(
CryptoCurrencyNetwork.test,
),
);
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 4); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 4,
);
// try to continue migrating // try to continue migrating
return await migrate(4, secureStore: secureStore); return await migrate(4, secureStore: secureStore);
@ -196,7 +223,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 5); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 5,
);
// try to continue migrating // try to continue migrating
return await migrate(5, secureStore: secureStore); return await migrate(5, secureStore: secureStore);
@ -212,11 +242,17 @@ class DbVersionMigrator with WalletDB {
"light"; "light";
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs, key: "theme", value: themeName); boxName: DB.boxNamePrefs,
key: "theme",
value: themeName,
);
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 6); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 6,
);
// try to continue migrating // try to continue migrating
return await migrate(6, secureStore: secureStore); return await migrate(6, secureStore: secureStore);
@ -287,7 +323,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 7); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 7,
);
// try to continue migrating // try to continue migrating
return await migrate(7, secureStore: secureStore); return await migrate(7, secureStore: secureStore);
@ -298,7 +337,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 8); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 8,
);
// try to continue migrating // try to continue migrating
return await migrate(8, secureStore: secureStore); return await migrate(8, secureStore: secureStore);
@ -311,8 +353,10 @@ class DbVersionMigrator with WalletDB {
await MainDB.instance.initMainDB(); await MainDB.instance.initMainDB();
for (final walletId in walletInfoList.keys) { for (final walletId in walletInfoList.keys) {
final info = walletInfoList[walletId]!; final info = walletInfoList[walletId]!;
if (info.coin == Coin.bitcoincash || if (info.coinIdentifier ==
info.coin == Coin.bitcoincashTestnet) { Bitcoincash(CryptoCurrencyNetwork.main).identifier ||
info.coinIdentifier ==
Bitcoincash(CryptoCurrencyNetwork.test).identifier) {
final ids = await MainDB.instance final ids = await MainDB.instance
.getAddresses(walletId) .getAddresses(walletId)
.filter() .filter()
@ -328,7 +372,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 9); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 9,
);
// try to continue migrating // try to continue migrating
return await migrate(9, secureStore: secureStore); return await migrate(9, secureStore: secureStore);
@ -339,7 +386,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 10); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 10,
);
// try to continue migrating // try to continue migrating
return await migrate(10, secureStore: secureStore); return await migrate(10, secureStore: secureStore);
@ -350,7 +400,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 11); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 11,
);
// try to continue migrating // try to continue migrating
return await migrate(11, secureStore: secureStore); return await migrate(11, secureStore: secureStore);
@ -361,7 +414,10 @@ class DbVersionMigrator with WalletDB {
// update version // update version
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 12); boxName: DB.boxNameDBInfo,
key: "hive_data_version",
value: 12,
);
// try to continue migrating // try to continue migrating
return await migrate(12, secureStore: secureStore); return await migrate(12, secureStore: secureStore);
@ -392,7 +448,8 @@ class DbVersionMigrator with WalletDB {
// we need to manually migrate epic cash transactions as they are not // we need to manually migrate epic cash transactions as they are not
// stored on the epic cash blockchain // stored on the epic cash blockchain
if (info.coin == Coin.epicCash) { final epic = Epiccash(CryptoCurrencyNetwork.main);
if (info.coinIdentifier == epic.identifier) {
final txnData = walletBox.get("latest_tx_model") as TransactionData?; final txnData = walletBox.get("latest_tx_model") as TransactionData?;
// we ever only used index 0 in the past // we ever only used index 0 in the past
@ -404,7 +461,7 @@ class DbVersionMigrator with WalletDB {
final txns = txnData.getAllTransactions(); final txns = txnData.getAllTransactions();
for (final tx in txns.values) { for (final tx in txns.values) {
bool isIncoming = tx.txType == "Received"; final bool isIncoming = tx.txType == "Received";
final iTx = isar_models.Transaction( final iTx = isar_models.Transaction(
walletId: walletId, walletId: walletId,
@ -417,7 +474,7 @@ class DbVersionMigrator with WalletDB {
amount: tx.amount, amount: tx.amount,
amountString: Amount( amountString: Amount(
rawValue: BigInt.from(tx.amount), rawValue: BigInt.from(tx.amount),
fractionDigits: info.coin.decimals, fractionDigits: epic.fractionDigits,
).toJsonString(), ).toJsonString(),
fee: tx.fees, fee: tx.fees,
height: tx.height, height: tx.height,
@ -470,12 +527,14 @@ class DbVersionMigrator with WalletDB {
if ((await secureStore.read(key: '${walletId}_mnemonicPassphrase')) == if ((await secureStore.read(key: '${walletId}_mnemonicPassphrase')) ==
null) { null) {
await secureStore.write( await secureStore.write(
key: '${walletId}_mnemonicPassphrase', value: ""); key: '${walletId}_mnemonicPassphrase',
value: "",
);
} }
// doing this for epic cash will delete transaction history as it is not // doing this for epic cash will delete transaction history as it is not
// stored on the epic cash blockchain // stored on the epic cash blockchain
if (info.coin != Coin.epicCash) { if (info.coinIdentifier != epic.identifier) {
// set flag to initiate full rescan on opening wallet // set flag to initiate full rescan on opening wallet
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo, boxName: DB.boxNameDBInfo,
@ -498,6 +557,8 @@ class DbVersionMigrator with WalletDB {
final count = await MainDB.instance.getTransactions(walletId).count(); final count = await MainDB.instance.getTransactions(walletId).count();
final crypto = AppConfig.getCryptoCurrencyFor(info.coinIdentifier)!;
for (var i = 0; i < count; i += 50) { for (var i = 0; i < count; i += 50) {
final txns = await MainDB.instance final txns = await MainDB.instance
.getTransactions(walletId) .getTransactions(walletId)
@ -512,7 +573,7 @@ class DbVersionMigrator with WalletDB {
tx tx
..amountString = Amount( ..amountString = Amount(
rawValue: BigInt.from(tx.amount), rawValue: BigInt.from(tx.amount),
fractionDigits: info.coin.decimals, fractionDigits: crypto.fractionDigits,
).toJsonString(), ).toJsonString(),
tx.address.value, tx.address.value,
), ),
@ -531,11 +592,13 @@ class DbVersionMigrator with WalletDB {
final keys = List<String>.from(addressBookBox.keys); final keys = List<String>.from(addressBookBox.keys);
final contacts = keys final contacts = keys
.map((id) => Contact.fromJson( .map(
Map<String, dynamic>.from( (id) => Contact.fromJson(
addressBookBox.get(id) as Map, Map<String, dynamic>.from(
), addressBookBox.get(id) as Map,
)) ),
),
)
.toList(growable: false); .toList(growable: false);
final List<isar_contact.ContactEntry> newContacts = []; final List<isar_contact.ContactEntry> newContacts = [];
@ -547,7 +610,7 @@ class DbVersionMigrator with WalletDB {
for (final entry in contact.addresses) { for (final entry in contact.addresses) {
newContactAddressEntries.add( newContactAddressEntries.add(
isar_contact.ContactAddressEntry() isar_contact.ContactAddressEntry()
..coinName = entry.coin.name ..coinName = entry.coin.identifier
..address = entry.address ..address = entry.address
..label = entry.label ..label = entry.label
..other = entry.other, ..other = entry.other,
@ -580,11 +643,13 @@ class DbVersionMigrator with WalletDB {
await prefs.init(); await prefs.init();
await MainDB.instance.initMainDB(); await MainDB.instance.initMainDB();
final firo = Firo(CryptoCurrencyNetwork.main);
for (final walletId in walletInfoList.keys) { for (final walletId in walletInfoList.keys) {
final info = walletInfoList[walletId]!; final info = walletInfoList[walletId]!;
assert(info.walletId == walletId); assert(info.walletId == walletId);
if (info.coin == Coin.firo && if (info.coinIdentifier == firo.identifier &&
MainDB.instance.isar.lelantusCoins MainDB.instance.isar.lelantusCoins
.where() .where()
.walletIdEqualTo(walletId) .walletIdEqualTo(walletId)

View file

@ -13,13 +13,14 @@ import 'dart:isolate';
import 'package:cw_core/wallet_info.dart' as xmr; import 'package:cw_core/wallet_info.dart' as xmr;
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mutex/mutex.dart'; import 'package:mutex/mutex.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import '../../app_config.dart';
import 'package:stackwallet/models/node_model.dart'; import '../../models/exchange/response_objects/trade.dart';
import 'package:stackwallet/models/notification_model.dart'; import '../../models/node_model.dart';
import 'package:stackwallet/models/trade_wallet_lookup.dart'; import '../../models/notification_model.dart';
import 'package:stackwallet/services/wallets_service.dart'; import '../../models/trade_wallet_lookup.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../services/wallets_service.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../utilities/logger.dart';
import '../../wallets/crypto_currency/crypto_currency.dart';
class DB { class DB {
// legacy (required for migrations) // legacy (required for migrations)
@ -48,17 +49,18 @@ class DB {
static const String boxNamePrefs = "prefs"; static const String boxNamePrefs = "prefs";
static const String boxNameOneTimeDialogsShown = "oneTimeDialogsShown"; static const String boxNameOneTimeDialogsShown = "oneTimeDialogsShown";
String _boxNameTxCache({required Coin coin}) => "${coin.name}_txCache"; String _boxNameTxCache({required CryptoCurrency currency}) =>
"${currency.identifier}_txCache";
// firo only // firo only
String _boxNameSetCache({required Coin coin}) => String _boxNameSetCache({required CryptoCurrency currency}) =>
"${coin.name}_anonymitySetCache"; "${currency.identifier}_anonymitySetCache";
String _boxNameSetSparkCache({required Coin coin}) => String _boxNameSetSparkCache({required CryptoCurrency currency}) =>
"${coin.name}_anonymitySetSparkCache"; "${currency.identifier}_anonymitySetSparkCache";
String _boxNameUsedSerialsCache({required Coin coin}) => String _boxNameUsedSerialsCache({required CryptoCurrency currency}) =>
"${coin.name}_usedSerialsCache"; "${currency.identifier}_usedSerialsCache";
String _boxNameSparkUsedCoinsTagsCache({required Coin coin}) => String _boxNameSparkUsedCoinsTagsCache({required CryptoCurrency currency}) =>
"${coin.name}_sparkUsedCoinsTagsCache"; "${currency.identifier}_sparkUsedCoinsTagsCache";
Box<NodeModel>? _boxNodeModels; Box<NodeModel>? _boxNodeModels;
Box<NodeModel>? _boxPrimaryNodes; Box<NodeModel>? _boxPrimaryNodes;
@ -77,11 +79,11 @@ class DB {
final Map<String, Box<dynamic>> _walletBoxes = {}; final Map<String, Box<dynamic>> _walletBoxes = {};
final Map<Coin, Box<dynamic>> _txCacheBoxes = {}; final Map<String, Box<dynamic>> _txCacheBoxes = {};
final Map<Coin, Box<dynamic>> _setCacheBoxes = {}; final Map<String, Box<dynamic>> _setCacheBoxes = {};
final Map<Coin, Box<dynamic>> _setSparkCacheBoxes = {}; final Map<String, Box<dynamic>> _setSparkCacheBoxes = {};
final Map<Coin, Box<dynamic>> _usedSerialsCacheBoxes = {}; final Map<String, Box<dynamic>> _usedSerialsCacheBoxes = {};
final Map<Coin, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {}; final Map<String, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {};
// exposed for monero // exposed for monero
Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource!; Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource!;
@ -97,7 +99,8 @@ class DB {
// TODO: make sure this works properly // TODO: make sure this works properly
if (Isolate.current.debugName != "main") { if (Isolate.current.debugName != "main") {
throw Exception( throw Exception(
"DB.instance should not be accessed outside the main isolate!"); "DB.instance should not be accessed outside the main isolate!",
);
} }
return _instance; return _instance;
@ -160,17 +163,22 @@ class DB {
names.removeWhere((name, dyn) { names.removeWhere((name, dyn) {
final jsonObject = Map<String, dynamic>.from(dyn as Map); final jsonObject = Map<String, dynamic>.from(dyn as Map);
try { try {
Coin.values.byName(jsonObject["coin"] as String); AppConfig.getCryptoCurrencyFor(jsonObject["coin"] as String);
return false; return false;
} catch (e, s) { } catch (e, s) {
Logging.instance.log( Logging.instance.log(
"Error, ${jsonObject["coin"]} does not exist, $name wallet cannot be loaded", "Error, ${jsonObject["coin"]} does not exist, $name wallet cannot be loaded",
level: LogLevel.Error); level: LogLevel.Error,
);
return true; return true;
} }
}); });
final mapped = Map<String, dynamic>.from(names).map((name, dyn) => MapEntry( final mapped = Map<String, dynamic>.from(names).map(
name, WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map)))); (name, dyn) => MapEntry(
name,
WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map)),
),
);
for (final entry in mapped.entries) { for (final entry in mapped.entries) {
if (Hive.isBoxOpen(entry.value.walletId)) { if (Hive.isBoxOpen(entry.value.walletId)) {
@ -183,70 +191,90 @@ class DB {
} }
} }
Future<Box<dynamic>> getTxCacheBox({required Coin coin}) async { Future<Box<dynamic>> getTxCacheBox({required CryptoCurrency currency}) async {
if (_txCacheBoxes[coin]?.isOpen != true) { if (_txCacheBoxes[currency.identifier]?.isOpen != true) {
_txCacheBoxes.remove(coin); _txCacheBoxes.remove(currency.identifier);
} }
return _txCacheBoxes[coin] ??= return _txCacheBoxes[currency.identifier] ??=
await Hive.openBox<dynamic>(_boxNameTxCache(coin: coin)); await Hive.openBox<dynamic>(_boxNameTxCache(currency: currency));
} }
Future<void> closeTxCacheBox({required Coin coin}) async { Future<void> closeTxCacheBox({required CryptoCurrency currency}) async {
await _txCacheBoxes[coin]?.close(); await _txCacheBoxes[currency.identifier]?.close();
} }
Future<Box<dynamic>> getAnonymitySetCacheBox({required Coin coin}) async { Future<Box<dynamic>> getAnonymitySetCacheBox({
if (_setCacheBoxes[coin]?.isOpen != true) { required CryptoCurrency currency,
_setCacheBoxes.remove(coin); }) async {
if (_setCacheBoxes[currency.identifier]?.isOpen != true) {
_setCacheBoxes.remove(currency.identifier);
} }
return _setCacheBoxes[coin] ??= return _setCacheBoxes[currency.identifier] ??=
await Hive.openBox<dynamic>(_boxNameSetCache(coin: coin)); await Hive.openBox<dynamic>(_boxNameSetCache(currency: currency));
} }
Future<Box<dynamic>> getSparkAnonymitySetCacheBox( Future<Box<dynamic>> getSparkAnonymitySetCacheBox({
{required Coin coin}) async { required CryptoCurrency currency,
if (_setSparkCacheBoxes[coin]?.isOpen != true) { }) async {
_setSparkCacheBoxes.remove(coin); if (_setSparkCacheBoxes[currency.identifier]?.isOpen != true) {
_setSparkCacheBoxes.remove(currency.identifier);
} }
return _setSparkCacheBoxes[coin] ??= return _setSparkCacheBoxes[currency.identifier] ??=
await Hive.openBox<dynamic>(_boxNameSetSparkCache(coin: coin)); await Hive.openBox<dynamic>(_boxNameSetSparkCache(currency: currency));
} }
Future<void> closeAnonymitySetCacheBox({required Coin coin}) async { Future<void> closeAnonymitySetCacheBox({
await _setCacheBoxes[coin]?.close(); required CryptoCurrency currency,
}) async {
await _setCacheBoxes[currency.identifier]?.close();
} }
Future<Box<dynamic>> getUsedSerialsCacheBox({required Coin coin}) async { Future<Box<dynamic>> getUsedSerialsCacheBox({
if (_usedSerialsCacheBoxes[coin]?.isOpen != true) { required CryptoCurrency currency,
_usedSerialsCacheBoxes.remove(coin); }) async {
if (_usedSerialsCacheBoxes[currency.identifier]?.isOpen != true) {
_usedSerialsCacheBoxes.remove(currency.identifier);
} }
return _usedSerialsCacheBoxes[coin] ??= return _usedSerialsCacheBoxes[currency.identifier] ??=
await Hive.openBox<dynamic>(_boxNameUsedSerialsCache(coin: coin));
}
Future<Box<dynamic>> getSparkUsedCoinsTagsCacheBox(
{required Coin coin}) async {
if (_getSparkUsedCoinsTagsCacheBoxes[coin]?.isOpen != true) {
_getSparkUsedCoinsTagsCacheBoxes.remove(coin);
}
return _getSparkUsedCoinsTagsCacheBoxes[coin] ??=
await Hive.openBox<dynamic>( await Hive.openBox<dynamic>(
_boxNameSparkUsedCoinsTagsCache(coin: coin)); _boxNameUsedSerialsCache(currency: currency),
);
} }
Future<void> closeUsedSerialsCacheBox({required Coin coin}) async { Future<Box<dynamic>> getSparkUsedCoinsTagsCacheBox({
await _usedSerialsCacheBoxes[coin]?.close(); required CryptoCurrency currency,
}) async {
if (_getSparkUsedCoinsTagsCacheBoxes[currency.identifier]?.isOpen != true) {
_getSparkUsedCoinsTagsCacheBoxes.remove(currency.identifier);
}
return _getSparkUsedCoinsTagsCacheBoxes[currency.identifier] ??=
await Hive.openBox<dynamic>(
_boxNameSparkUsedCoinsTagsCache(currency: currency),
);
}
Future<void> closeUsedSerialsCacheBox({
required CryptoCurrency currency,
}) async {
await _usedSerialsCacheBoxes[currency.identifier]?.close();
} }
/// Clear all cached transactions for the specified coin /// Clear all cached transactions for the specified coin
Future<void> clearSharedTransactionCache({required Coin coin}) async { Future<void> clearSharedTransactionCache({
await deleteAll<dynamic>(boxName: _boxNameTxCache(coin: coin)); required CryptoCurrency currency,
if (coin == Coin.firo || coin == Coin.firoTestNet) { }) async {
await deleteAll<dynamic>(boxName: _boxNameSetCache(coin: coin)); await deleteAll<dynamic>(boxName: _boxNameTxCache(currency: currency));
await deleteAll<dynamic>(boxName: _boxNameSetSparkCache(coin: coin)); if (currency is Firo) {
await deleteAll<dynamic>(boxName: _boxNameUsedSerialsCache(coin: coin)); await deleteAll<dynamic>(boxName: _boxNameSetCache(currency: currency));
await deleteAll<dynamic>( await deleteAll<dynamic>(
boxName: _boxNameSparkUsedCoinsTagsCache(coin: coin)); boxName: _boxNameSetSparkCache(currency: currency),
);
await deleteAll<dynamic>(
boxName: _boxNameUsedSerialsCache(currency: currency),
);
await deleteAll<dynamic>(
boxName: _boxNameSparkUsedCoinsTagsCache(currency: currency),
);
} }
} }
@ -284,23 +312,28 @@ class DB {
// writes // writes
Future<void> put<T>( Future<void> put<T>({
{required String boxName, required String boxName,
required dynamic key, required dynamic key,
required T value}) async => required T value,
}) async =>
await mutex await mutex
.protect(() async => await Hive.box<T>(boxName).put(key, value)); .protect(() async => await Hive.box<T>(boxName).put(key, value));
Future<void> add<T>({required String boxName, required T value}) async => Future<void> add<T>({required String boxName, required T value}) async =>
await mutex.protect(() async => await Hive.box<T>(boxName).add(value)); await mutex.protect(() async => await Hive.box<T>(boxName).add(value));
Future<void> addAll<T>( Future<void> addAll<T>({
{required String boxName, required Iterable<T> values}) async => required String boxName,
required Iterable<T> values,
}) async =>
await mutex await mutex
.protect(() async => await Hive.box<T>(boxName).addAll(values)); .protect(() async => await Hive.box<T>(boxName).addAll(values));
Future<void> delete<T>( Future<void> delete<T>({
{required dynamic key, required String boxName}) async => required dynamic key,
required String boxName,
}) async =>
await mutex.protect(() async => await Hive.box<T>(boxName).delete(key)); await mutex.protect(() async => await Hive.box<T>(boxName).delete(key));
Future<void> deleteAll<T>({required String boxName}) async { Future<void> deleteAll<T>({required String boxName}) async {

View file

@ -11,21 +11,21 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_native_splash/cli_commands.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import '../../exceptions/main_db/main_db_exception.dart';
import 'package:stackwallet/models/isar/models/block_explorer.dart'; import '../../models/isar/models/block_explorer.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import '../../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import 'package:stackwallet/models/isar/models/contact_entry.dart'; import '../../models/isar/models/contact_entry.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart'; import '../../models/isar/models/isar_models.dart';
import 'package:stackwallet/models/isar/ordinal.dart'; import '../../models/isar/ordinal.dart';
import 'package:stackwallet/models/isar/stack_theme.dart'; import '../../models/isar/stack_theme.dart';
import 'package:stackwallet/utilities/amount/amount.dart'; import '../../utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../utilities/stack_file_system.dart';
import 'package:stackwallet/utilities/stack_file_system.dart'; import '../../wallets/crypto_currency/crypto_currency.dart';
import 'package:stackwallet/wallets/isar/models/frost_wallet_info.dart'; import '../../wallets/isar/models/frost_wallet_info.dart';
import 'package:stackwallet/wallets/isar/models/spark_coin.dart'; import '../../wallets/isar/models/spark_coin.dart';
import 'package:stackwallet/wallets/isar/models/token_wallet_info.dart'; import '../../wallets/isar/models/token_wallet_info.dart';
import 'package:stackwallet/wallets/isar/models/wallet_info.dart'; import '../../wallets/isar/models/wallet_info.dart';
import 'package:stackwallet/wallets/isar/models/wallet_info_meta.dart'; import '../../wallets/isar/models/wallet_info_meta.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
part '../queries/queries.dart'; part '../queries/queries.dart';
@ -149,15 +149,17 @@ class MainDB {
} }
// tx block explorers // tx block explorers
TransactionBlockExplorer? getTransactionBlockExplorer({required Coin coin}) { TransactionBlockExplorer? getTransactionBlockExplorer(
{required CryptoCurrency cryptoCurrency}) {
return isar.transactionBlockExplorers return isar.transactionBlockExplorers
.where() .where()
.tickerEqualTo(coin.ticker) .tickerEqualTo(cryptoCurrency.ticker)
.findFirstSync(); .findFirstSync();
} }
Future<int> putTransactionBlockExplorer( Future<int> putTransactionBlockExplorer(
TransactionBlockExplorer explorer) async { TransactionBlockExplorer explorer,
) async {
try { try {
return await isar.writeTxn(() async { return await isar.writeTxn(() async {
return await isar.transactionBlockExplorers.put(explorer); return await isar.transactionBlockExplorers.put(explorer);
@ -169,7 +171,8 @@ class MainDB {
// addresses // addresses
QueryBuilder<Address, Address, QAfterWhereClause> getAddresses( QueryBuilder<Address, Address, QAfterWhereClause> getAddresses(
String walletId) => String walletId,
) =>
isar.addresses.where().walletIdEqualTo(walletId); isar.addresses.where().walletIdEqualTo(walletId);
Future<int> putAddress(Address address) async { Future<int> putAddress(Address address) async {
@ -194,7 +197,7 @@ class MainDB {
Future<List<int>> updateOrPutAddresses(List<Address> addresses) async { Future<List<int>> updateOrPutAddresses(List<Address> addresses) async {
try { try {
List<int> ids = []; final List<int> ids = [];
await isar.writeTxn(() async { await isar.writeTxn(() async {
for (final address in addresses) { for (final address in addresses) {
final storedAddress = await isar.addresses final storedAddress = await isar.addresses
@ -239,13 +242,16 @@ class MainDB {
}); });
} catch (e) { } catch (e) {
throw MainDBException( throw MainDBException(
"failed updateAddress: from=$oldAddress to=$newAddress", e); "failed updateAddress: from=$oldAddress to=$newAddress",
e,
);
} }
} }
// transactions // transactions
QueryBuilder<Transaction, Transaction, QAfterWhereClause> getTransactions( QueryBuilder<Transaction, Transaction, QAfterWhereClause> getTransactions(
String walletId) => String walletId,
) =>
isar.transactions.where().walletIdEqualTo(walletId); isar.transactions.where().walletIdEqualTo(walletId);
Future<int> putTransaction(Transaction transaction) async { Future<int> putTransaction(Transaction transaction) async {
@ -284,7 +290,9 @@ class MainDB {
isar.utxos.where().walletIdEqualTo(walletId); isar.utxos.where().walletIdEqualTo(walletId);
QueryBuilder<UTXO, UTXO, QAfterFilterCondition> getUTXOsByAddress( QueryBuilder<UTXO, UTXO, QAfterFilterCondition> getUTXOsByAddress(
String walletId, String address) => String walletId,
String address,
) =>
isar.utxos isar.utxos
.where() .where()
.walletIdEqualTo(walletId) .walletIdEqualTo(walletId)
@ -357,7 +365,9 @@ class MainDB {
}); });
Future<TransactionNote?> getTransactionNote( Future<TransactionNote?> getTransactionNote(
String walletId, String txid) async { String walletId,
String txid,
) async {
return isar.transactionNotes.getByTxidWalletId( return isar.transactionNotes.getByTxidWalletId(
txid, txid,
walletId, walletId,
@ -374,7 +384,8 @@ class MainDB {
// address labels // address labels
QueryBuilder<AddressLabel, AddressLabel, QAfterWhereClause> getAddressLabels( QueryBuilder<AddressLabel, AddressLabel, QAfterWhereClause> getAddressLabels(
String walletId) => String walletId,
) =>
isar.addressLabels.where().walletIdEqualTo(walletId); isar.addressLabels.where().walletIdEqualTo(walletId);
Future<int> putAddressLabel(AddressLabel addressLabel) => Future<int> putAddressLabel(AddressLabel addressLabel) =>
@ -392,7 +403,9 @@ class MainDB {
}); });
Future<AddressLabel?> getAddressLabel( Future<AddressLabel?> getAddressLabel(
String walletId, String addressString) async { String walletId,
String addressString,
) async {
return isar.addressLabels.getByAddressStringWalletId( return isar.addressLabels.getByAddressStringWalletId(
addressString, addressString,
walletId, walletId,
@ -573,7 +586,7 @@ class MainDB {
List<TransactionV2> transactions, List<TransactionV2> transactions,
) async { ) async {
try { try {
List<int> ids = []; final List<int> ids = [];
await isar.writeTxn(() async { await isar.writeTxn(() async {
for (final tx in transactions) { for (final tx in transactions) {
final storedTx = await isar.transactionV2s final storedTx = await isar.transactionV2s
@ -595,7 +608,9 @@ class MainDB {
return ids; return ids;
} catch (e) { } catch (e) {
throw MainDBException( throw MainDBException(
"failed updateOrPutTransactionV2s: $transactions", e); "failed updateOrPutTransactionV2s: $transactions",
e,
);
} }
} }

View file

@ -2,16 +2,18 @@ import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/db/isar/main_db.dart'; import '../app_config.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import '../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart'; import '../models/isar/models/isar_models.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
import 'package:stackwallet/wallets/isar/models/token_wallet_info.dart'; import '../wallets/isar/models/token_wallet_info.dart';
import 'package:stackwallet/wallets/isar/models/wallet_info.dart'; import '../wallets/isar/models/wallet_info.dart';
import 'package:stackwallet/wallets/isar/models/wallet_info_meta.dart'; import '../wallets/isar/models/wallet_info_meta.dart';
import 'package:stackwallet/wallets/wallet/supporting/epiccash_wallet_info_extension.dart'; import '../wallets/wallet/supporting/epiccash_wallet_info_extension.dart';
import 'hive/db.dart';
import 'isar/main_db.dart';
Future<void> migrateWalletsToIsar({ Future<void> migrateWalletsToIsar({
required SecureStorageInterface secureStore, required SecureStorageInterface secureStore,
@ -37,13 +39,13 @@ Future<void> migrateWalletsToIsar({
// //
final List< final List<
({ ({
Coin coin, String coinIdentifier,
String name, String name,
String walletId, String walletId,
})> oldInfo = Map<String, dynamic>.from(names).values.map((e) { })> oldInfo = Map<String, dynamic>.from(names).values.map((e) {
final map = e as Map; final map = e as Map;
return ( return (
coin: Coin.values.byName(map["coin"] as String), coinIdentifier: map["coin"] as String,
walletId: map["id"] as String, walletId: map["id"] as String,
name: map["name"] as String, name: map["name"] as String,
); );
@ -93,16 +95,16 @@ Future<void> migrateWalletsToIsar({
} }
// reset stellar + tezos address type // reset stellar + tezos address type
if (old.coin == Coin.stellar || if (old.coinIdentifier == Stellar(CryptoCurrencyNetwork.main).identifier ||
old.coin == Coin.stellarTestnet || old.coinIdentifier == Stellar(CryptoCurrencyNetwork.test).identifier ||
old.coin == Coin.tezos) { old.coinIdentifier == Tezos(CryptoCurrencyNetwork.main).identifier) {
await MainDB.instance.deleteWalletBlockchainData(old.walletId); await MainDB.instance.deleteWalletBlockchainData(old.walletId);
} }
// //
// Set other data values // Set other data values
// //
Map<String, dynamic> otherData = {}; final Map<String, dynamic> otherData = {};
final List<String>? tokenContractAddresses = walletBox.get( final List<String>? tokenContractAddresses = walletBox.get(
"ethTokenContracts", "ethTokenContracts",
@ -129,7 +131,7 @@ Future<void> migrateWalletsToIsar({
} }
// epiccash specifics // epiccash specifics
if (old.coin == Coin.epicCash) { if (old.coinIdentifier == Epiccash(CryptoCurrencyNetwork.main)) {
final epicWalletInfo = ExtraEpiccashWalletInfo.fromMap({ final epicWalletInfo = ExtraEpiccashWalletInfo.fromMap({
"receivingIndex": walletBox.get("receivingIndex") as int? ?? 0, "receivingIndex": walletBox.get("receivingIndex") as int? ?? 0,
"changeIndex": walletBox.get("changeIndex") as int? ?? 0, "changeIndex": walletBox.get("changeIndex") as int? ?? 0,
@ -142,7 +144,9 @@ Future<void> migrateWalletsToIsar({
otherData[WalletInfoKeys.epiccashData] = jsonEncode( otherData[WalletInfoKeys.epiccashData] = jsonEncode(
epicWalletInfo.toMap(), epicWalletInfo.toMap(),
); );
} else if (old.coin == Coin.firo || old.coin == Coin.firoTestNet) { } else if (old.coinIdentifier ==
Firo(CryptoCurrencyNetwork.main).identifier ||
old.coinIdentifier == Firo(CryptoCurrencyNetwork.test).identifier) {
otherData[WalletInfoKeys.lelantusCoinIsarRescanRequired] = walletBox otherData[WalletInfoKeys.lelantusCoinIsarRescanRequired] = walletBox
.get(WalletInfoKeys.lelantusCoinIsarRescanRequired) as bool? ?? .get(WalletInfoKeys.lelantusCoinIsarRescanRequired) as bool? ??
true; true;
@ -161,10 +165,11 @@ Future<void> migrateWalletsToIsar({
); );
final info = WalletInfo( final info = WalletInfo(
coinName: old.coin.name, coinName: old.coinIdentifier,
walletId: old.walletId, walletId: old.walletId,
name: old.name, name: old.name,
mainAddressType: old.coin.primaryAddressType, mainAddressType: AppConfig.getCryptoCurrencyFor(old.coinIdentifier)!
.primaryAddressType,
favouriteOrderIndex: favourites.indexOf(old.walletId), favouriteOrderIndex: favourites.indexOf(old.walletId),
cachedChainHeight: walletBox.get( cachedChainHeight: walletBox.get(
DBKeys.storedChainHeight, DBKeys.storedChainHeight,

View file

@ -8,7 +8,7 @@
* *
*/ */
part of 'package:stackwallet/db/isar/main_db.dart'; part of '../isar/main_db.dart';
enum CCFilter { enum CCFilter {
all, all,
@ -42,7 +42,7 @@ extension MainDBQueries on MainDB {
required CCFilter filter, required CCFilter filter,
required CCSortDescriptor sort, required CCSortDescriptor sort,
required String searchTerm, required String searchTerm,
required Coin coin, required CryptoCurrency cryptoCurrency,
}) { }) {
var preSort = getUTXOs(walletId).filter().group((q) { var preSort = getUTXOs(walletId).filter().group((q) {
final qq = q.group( final qq = q.group(
@ -79,7 +79,7 @@ extension MainDBQueries on MainDB {
qq = qq.or().valueEqualTo( qq = qq.or().valueEqualTo(
Amount.fromDecimal( Amount.fromDecimal(
maybeDecimal, maybeDecimal,
fractionDigits: coin.decimals, fractionDigits: cryptoCurrency.fractionDigits,
).raw.toInt(), ).raw.toInt(),
); );
} }
@ -114,7 +114,7 @@ extension MainDBQueries on MainDB {
required CCFilter filter, required CCFilter filter,
required CCSortDescriptor sort, required CCSortDescriptor sort,
required String searchTerm, required String searchTerm,
required Coin coin, required CryptoCurrency cryptoCurrency,
}) { }) {
var preSort = getUTXOs(walletId).filter().group((q) { var preSort = getUTXOs(walletId).filter().group((q) {
final qq = q.group( final qq = q.group(
@ -151,7 +151,7 @@ extension MainDBQueries on MainDB {
qq = qq.or().valueEqualTo( qq = qq.or().valueEqualTo(
Amount.fromDecimal( Amount.fromDecimal(
maybeDecimal, maybeDecimal,
fractionDigits: coin.decimals, fractionDigits: cryptoCurrency.fractionDigits,
).raw.toInt(), ).raw.toInt(),
); );
} }

View file

@ -10,8 +10,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart'; import '../../utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../wallets/crypto_currency/coins/ethereum.dart';
import '../../wallets/crypto_currency/crypto_currency.dart';
class EthTokenTxExtraDTO { class EthTokenTxExtraDTO {
EthTokenTxExtraDTO({ EthTokenTxExtraDTO({
@ -42,7 +43,7 @@ class EthTokenTxExtraDTO {
to: map['to'] as String, to: map['to'] as String,
value: Amount( value: Amount(
rawValue: BigInt.parse(map['value'] as String), rawValue: BigInt.parse(map['value'] as String),
fractionDigits: Coin.ethereum.decimals, fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
), ),
gas: _amountFromJsonNum(map['gas']), gas: _amountFromJsonNum(map['gas']),
gasPrice: _amountFromJsonNum(map['gasPrice']), gasPrice: _amountFromJsonNum(map['gasPrice']),
@ -70,7 +71,7 @@ class EthTokenTxExtraDTO {
static Amount _amountFromJsonNum(dynamic json) { static Amount _amountFromJsonNum(dynamic json) {
return Amount( return Amount(
rawValue: BigInt.from(json as num), rawValue: BigInt.from(json as num),
fractionDigits: Coin.ethereum.decimals, fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
); );
} }

View file

@ -10,8 +10,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart'; import '../../utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../wallets/crypto_currency/coins/ethereum.dart';
import '../../wallets/crypto_currency/crypto_currency.dart';
class EthTxDTO { class EthTxDTO {
EthTxDTO({ EthTxDTO({
@ -75,7 +76,7 @@ class EthTxDTO {
} }
return Amount( return Amount(
rawValue: BigInt.parse(json.toString()), rawValue: BigInt.parse(json.toString()),
fractionDigits: Coin.ethereum.decimals, fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
); );
} }

View file

@ -1,5 +1,5 @@
import 'package:stackwallet/dto/ordinals/litescribe_response.dart'; import 'litescribe_response.dart';
import 'package:stackwallet/dto/ordinals/inscription_data.dart'; import 'inscription_data.dart';
class AddressInscriptionResponse extends LitescribeResponse<AddressInscriptionResponse> { class AddressInscriptionResponse extends LitescribeResponse<AddressInscriptionResponse> {
final int status; final int status;

View file

@ -11,10 +11,10 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:stackwallet/db/hive/db.dart'; import '../db/hive/db.dart';
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart'; import 'electrumx_client.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../utilities/logger.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
import 'package:string_validator/string_validator.dart'; import 'package:string_validator/string_validator.dart';
class CachedElectrumXClient { class CachedElectrumXClient {
@ -34,10 +34,11 @@ class CachedElectrumXClient {
Future<Map<String, dynamic>> getAnonymitySet({ Future<Map<String, dynamic>> getAnonymitySet({
required String groupId, required String groupId,
String blockhash = "", String blockhash = "",
required Coin coin, required CryptoCurrency cryptoCurrency,
}) async { }) async {
try { try {
final box = await DB.instance.getAnonymitySetCacheBox(coin: coin); final box =
await DB.instance.getAnonymitySetCacheBox(currency: cryptoCurrency);
final cachedSet = box.get(groupId) as Map?; final cachedSet = box.get(groupId) as Map?;
Map<String, dynamic> set; Map<String, dynamic> set;
@ -68,30 +69,38 @@ class CachedElectrumXClient {
? base64ToReverseHex(newSet["blockHash"] as String) ? base64ToReverseHex(newSet["blockHash"] as String)
: newSet["blockHash"]; : newSet["blockHash"];
for (int i = (newSet["coins"] as List).length - 1; i >= 0; i--) { for (int i = (newSet["coins"] as List).length - 1; i >= 0; i--) {
dynamic newCoin = newSet["coins"][i]; final dynamic newCoin = newSet["coins"][i];
List<dynamic> translatedCoin = []; final List<dynamic> translatedCoin = [];
translatedCoin.add(!isHexadecimal(newCoin[0] as String) translatedCoin.add(
? base64ToHex(newCoin[0] as String) !isHexadecimal(newCoin[0] as String)
: newCoin[0]); ? base64ToHex(newCoin[0] as String)
translatedCoin.add(!isHexadecimal(newCoin[1] as String) : newCoin[0],
? base64ToReverseHex(newCoin[1] as String) );
: newCoin[1]); translatedCoin.add(
!isHexadecimal(newCoin[1] as String)
? base64ToReverseHex(newCoin[1] as String)
: newCoin[1],
);
try { try {
translatedCoin.add(!isHexadecimal(newCoin[2] as String) translatedCoin.add(
? base64ToHex(newCoin[2] as String) !isHexadecimal(newCoin[2] as String)
: newCoin[2]); ? base64ToHex(newCoin[2] as String)
: newCoin[2],
);
} catch (e) { } catch (e) {
translatedCoin.add(newCoin[2]); translatedCoin.add(newCoin[2]);
} }
translatedCoin.add(!isHexadecimal(newCoin[3] as String) translatedCoin.add(
? base64ToReverseHex(newCoin[3] as String) !isHexadecimal(newCoin[3] as String)
: newCoin[3]); ? base64ToReverseHex(newCoin[3] as String)
: newCoin[3],
);
set["coins"].insert(0, translatedCoin); set["coins"].insert(0, translatedCoin);
} }
// save set to db // save set to db
await box.put(groupId, set); await box.put(groupId, set);
Logging.instance.log( Logging.instance.log(
"Updated current anonymity set for ${coin.name} with group ID $groupId", "Updated current anonymity set for ${cryptoCurrency.identifier} with group ID $groupId",
level: LogLevel.Info, level: LogLevel.Info,
); );
} }
@ -99,8 +108,9 @@ class CachedElectrumXClient {
return set; return set;
} catch (e, s) { } catch (e, s) {
Logging.instance.log( Logging.instance.log(
"Failed to process CachedElectrumX.getAnonymitySet(): $e\n$s", "Failed to process CachedElectrumX.getAnonymitySet(): $e\n$s",
level: LogLevel.Error); level: LogLevel.Error,
);
rethrow; rethrow;
} }
} }
@ -108,11 +118,13 @@ class CachedElectrumXClient {
Future<Map<String, dynamic>> getSparkAnonymitySet({ Future<Map<String, dynamic>> getSparkAnonymitySet({
required String groupId, required String groupId,
String blockhash = "", String blockhash = "",
required Coin coin, required CryptoCurrency cryptoCurrency,
required bool useOnlyCacheIfNotEmpty, required bool useOnlyCacheIfNotEmpty,
}) async { }) async {
try { try {
final box = await DB.instance.getSparkAnonymitySetCacheBox(coin: coin); final box = await DB.instance.getSparkAnonymitySetCacheBox(
currency: cryptoCurrency,
);
final cachedSet = box.get(groupId) as Map?; final cachedSet = box.get(groupId) as Map?;
Map<String, dynamic> set; Map<String, dynamic> set;
@ -152,7 +164,7 @@ class CachedElectrumXClient {
// save set to db // save set to db
await box.put(groupId, set); await box.put(groupId, set);
Logging.instance.log( Logging.instance.log(
"Updated current anonymity set for ${coin.name} with group ID $groupId", "Updated current anonymity set for ${cryptoCurrency.identifier} with group ID $groupId",
level: LogLevel.Info, level: LogLevel.Info,
); );
} }
@ -160,8 +172,9 @@ class CachedElectrumXClient {
return set; return set;
} catch (e, s) { } catch (e, s) {
Logging.instance.log( Logging.instance.log(
"Failed to process CachedElectrumX.getSparkAnonymitySet(): $e\n$s", "Failed to process CachedElectrumX.getSparkAnonymitySet(): $e\n$s",
level: LogLevel.Error); level: LogLevel.Error,
);
rethrow; rethrow;
} }
} }
@ -182,11 +195,11 @@ class CachedElectrumXClient {
/// ElectrumX api only called if the tx does not exist in local db /// ElectrumX api only called if the tx does not exist in local db
Future<Map<String, dynamic>> getTransaction({ Future<Map<String, dynamic>> getTransaction({
required String txHash, required String txHash,
required Coin coin, required CryptoCurrency cryptoCurrency,
bool verbose = true, bool verbose = true,
}) async { }) async {
try { try {
final box = await DB.instance.getTxCacheBox(coin: coin); final box = await DB.instance.getTxCacheBox(currency: cryptoCurrency);
final cachedTx = box.get(txHash) as Map?; final cachedTx = box.get(txHash) as Map?;
if (cachedTx == null) { if (cachedTx == null) {
@ -213,22 +226,24 @@ class CachedElectrumXClient {
} }
} catch (e, s) { } catch (e, s) {
Logging.instance.log( Logging.instance.log(
"Failed to process CachedElectrumX.getTransaction(): $e\n$s", "Failed to process CachedElectrumX.getTransaction(): $e\n$s",
level: LogLevel.Error); level: LogLevel.Error,
);
rethrow; rethrow;
} }
} }
Future<List<String>> getUsedCoinSerials({ Future<List<String>> getUsedCoinSerials({
required Coin coin, required CryptoCurrency cryptoCurrency,
int startNumber = 0, int startNumber = 0,
}) async { }) async {
try { try {
final box = await DB.instance.getUsedSerialsCacheBox(coin: coin); final box =
await DB.instance.getUsedSerialsCacheBox(currency: cryptoCurrency);
final _list = box.get("serials") as List?; final _list = box.get("serials") as List?;
Set<String> cachedSerials = final Set<String> cachedSerials =
_list == null ? {} : List<String>.from(_list).toSet(); _list == null ? {} : List<String>.from(_list).toSet();
startNumber = max( startNumber = max(
@ -269,14 +284,16 @@ class CachedElectrumXClient {
} }
Future<Set<String>> getSparkUsedCoinsTags({ Future<Set<String>> getSparkUsedCoinsTags({
required Coin coin, required CryptoCurrency cryptoCurrency,
}) async { }) async {
try { try {
final box = await DB.instance.getSparkUsedCoinsTagsCacheBox(coin: coin); final box = await DB.instance.getSparkUsedCoinsTagsCacheBox(
currency: cryptoCurrency,
);
final _list = box.get("tags") as List?; final _list = box.get("tags") as List?;
Set<String> cachedTags = final Set<String> cachedTags =
_list == null ? {} : List<String>.from(_list).toSet(); _list == null ? {} : List<String>.from(_list).toSet();
final startNumber = max( final startNumber = max(
@ -314,8 +331,9 @@ class CachedElectrumXClient {
} }
/// Clear all cached transactions for the specified coin /// Clear all cached transactions for the specified coin
Future<void> clearSharedTransactionCache({required Coin coin}) async { Future<void> clearSharedTransactionCache(
await DB.instance.clearSharedTransactionCache(coin: coin); {required CryptoCurrency cryptoCurrency}) async {
await DB.instance.closeAnonymitySetCacheBox(coin: coin); await DB.instance.clearSharedTransactionCache(currency: cryptoCurrency);
await DB.instance.closeAnonymitySetCacheBox(currency: cryptoCurrency);
} }
} }

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:electrum_adapter/electrum_adapter.dart'; import 'package:electrum_adapter/electrum_adapter.dart';
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
class ClientManager { class ClientManager {
ClientManager._(); ClientManager._();

View file

@ -20,17 +20,17 @@ import 'package:event_bus/event_bus.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart'; import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart';
import 'package:mutex/mutex.dart'; import 'package:mutex/mutex.dart';
import 'package:stackwallet/electrumx_rpc/client_manager.dart'; import 'client_manager.dart';
import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import '../exceptions/electrumx/no_such_transaction.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import '../services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart'; import '../services/event_bus/events/global/tor_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import '../services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/tor_service.dart'; import '../services/tor_service.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart'; import '../utilities/prefs.dart';
import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart'; import '../wallets/crypto_currency/coins/dogecoin.dart';
import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart'; import '../wallets/crypto_currency/coins/firo.dart';
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
class WifiOnlyException implements Exception {} class WifiOnlyException implements Exception {}

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class AddressException extends SWException { class AddressException extends SWException {
AddressException(super.message); AddressException(super.message);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class NoSuchTransactionException extends SWException { class NoSuchTransactionException extends SWException {
final String txid; final String txid;

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
enum ExchangeExceptionType { generic, serializeResponseError, orderNotFound } enum ExchangeExceptionType { generic, serializeResponseError, orderNotFound }

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart'; import '../exchange_exception.dart';
class MBException extends ExchangeException { class MBException extends ExchangeException {
MBException(super.message, super.type); MBException(super.message, super.type);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart'; import 'exchange_exception.dart';
class PairUnavailableException extends ExchangeException { class PairUnavailableException extends ExchangeException {
PairUnavailableException(super.message, super.type); PairUnavailableException(super.message, super.type);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart'; import 'exchange_exception.dart';
class UnsupportedCurrencyException extends ExchangeException { class UnsupportedCurrencyException extends ExchangeException {
UnsupportedCurrencyException(super.message, super.type, this.currency); UnsupportedCurrencyException(super.message, super.type, this.currency);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class JsonRpcException implements SWException { class JsonRpcException implements SWException {
JsonRpcException(this.message); JsonRpcException(this.message);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class MainDBException extends SWException { class MainDBException extends SWException {
MainDBException(super.message, this.originalError); MainDBException(super.message, this.originalError);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class InsufficientBalanceException extends SWException { class InsufficientBalanceException extends SWException {
InsufficientBalanceException(super.message); InsufficientBalanceException(super.message);

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/exceptions/sw_exception.dart'; import '../sw_exception.dart';
class PaynymSendException extends SWException { class PaynymSendException extends SWException {
PaynymSendException(super.message); PaynymSendException(super.message);

View file

@ -1,28 +1,28 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_1a.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_1a.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_1b.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_1b.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_2.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_2.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_3.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_3.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_4.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_4.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart'; import 'pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1a.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1a.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1b.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1b.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_2abd.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_2abd.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_2c.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_2c.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_3abd.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_3abd.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_3c.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_3c.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_4.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_4.dart';
import 'package:stackwallet/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_5.dart'; import 'pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_5.dart';
import 'package:stackwallet/pages/send_view/frost_ms/send_steps/frost_send_step_1a.dart'; import 'pages/send_view/frost_ms/send_steps/frost_send_step_1a.dart';
import 'package:stackwallet/pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart'; import 'pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart';
import 'package:stackwallet/pages/send_view/frost_ms/send_steps/frost_send_step_2.dart'; import 'pages/send_view/frost_ms/send_steps/frost_send_step_2.dart';
import 'package:stackwallet/pages/send_view/frost_ms/send_steps/frost_send_step_3.dart'; import 'pages/send_view/frost_ms/send_steps/frost_send_step_3.dart';
import 'package:stackwallet/pages/send_view/frost_ms/send_steps/frost_send_step_4.dart'; import 'pages/send_view/frost_ms/send_steps/frost_send_step_4.dart';
import 'package:stackwallet/route_generator.dart'; import 'route_generator.dart';
import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart'; import 'wallets/crypto_currency/intermediate/frost_currency.dart';
typedef FrostStepRoute = ({String routeName, String title}); typedef FrostStepRoute = ({String routeName, String title});

View file

@ -14,6 +14,7 @@ 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:cw_core/node.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -28,54 +29,56 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart'; import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:stackwallet/db/db_version_migration.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/db/isar/main_db.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/notification_model.dart';
import 'package:stackwallet/models/trade_wallet_lookup.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages/intro_view.dart';
import 'package:stackwallet/pages/loading_view.dart';
import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
import 'package:stackwallet/pages_desktop_specific/password/desktop_login_view.dart';
import 'package:stackwallet/providers/db/main_db_provider.dart';
import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
import 'package:stackwallet/providers/global/base_currencies_provider.dart';
// import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
// import 'package:stackwallet/services/buy/buy_data_loading_service.dart';
import 'package:stackwallet/services/debug_service.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/services/locale_service.dart';
import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/services/notifications_api.dart';
import 'package:stackwallet/services/notifications_service.dart';
import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/services/trade_service.dart';
import 'package:stackwallet/themes/theme_providers.dart';
import 'package:stackwallet/themes/theme_service.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/utilities/stack_file_system.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/wallets/isar/providers/all_wallets_info_provider.dart';
import 'package:stackwallet/widgets/crypto_notifications.dart';
import 'package:window_size/window_size.dart'; import 'package:window_size/window_size.dart';
import 'app_config.dart';
import 'db/db_version_migration.dart';
import 'db/hive/db.dart';
import 'db/isar/main_db.dart';
import 'models/exchange/change_now/exchange_transaction.dart';
import 'models/exchange/change_now/exchange_transaction_status.dart';
import 'models/exchange/response_objects/trade.dart';
import 'models/isar/models/isar_models.dart';
import 'models/models.dart';
import 'models/node_model.dart';
import 'models/notification_model.dart';
import 'models/trade_wallet_lookup.dart';
import 'pages/home_view/home_view.dart';
import 'pages/intro_view.dart';
import 'pages/loading_view.dart';
import 'pages/pinpad_views/create_pin_view.dart';
import 'pages/pinpad_views/lock_screen_view.dart';
import 'pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
import 'pages_desktop_specific/password/desktop_login_view.dart';
import 'providers/db/main_db_provider.dart';
import 'providers/desktop/storage_crypto_handler_provider.dart';
import 'providers/global/auto_swb_service_provider.dart';
import 'providers/global/base_currencies_provider.dart';
// import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
import 'providers/global/trades_service_provider.dart';
import 'providers/providers.dart';
import 'route_generator.dart';
// import 'package:stackwallet/services/buy/buy_data_loading_service.dart';
import 'services/debug_service.dart';
import 'services/exchange/exchange_data_loading_service.dart';
import 'services/locale_service.dart';
import 'services/node_service.dart';
import 'services/notifications_api.dart';
import 'services/notifications_service.dart';
import 'services/tor_service.dart';
import 'services/trade_service.dart';
import 'themes/theme_providers.dart';
import 'themes/theme_service.dart';
import 'utilities/constants.dart';
import 'utilities/enums/backup_frequency_type.dart';
import 'utilities/flutter_secure_storage_interface.dart';
import 'utilities/logger.dart';
import 'utilities/prefs.dart';
import 'utilities/stack_file_system.dart';
import 'utilities/util.dart';
import 'wallets/isar/providers/all_wallets_info_provider.dart';
import 'widgets/crypto_notifications.dart';
final openedFromSWBFileStringStateProvider = final openedFromSWBFileStringStateProvider =
StateProvider<String?>((ref) => null); StateProvider<String?>((ref) => null);
@ -86,9 +89,15 @@ void main(List<String> args) async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
if (Util.isDesktop && args.length == 2 && args.first == "-d") { if (Util.isDesktop && args.length == 2 && args.first == "-d") {
StackFileSystem.overrideDir = args.last; StackFileSystem.setDesktopOverrideDir(args.last);
} }
// Tell flutter_libmonero how to get access to the application dir
FS.setApplicationRootDirectoryFunction(
StackFileSystem.applicationRootDirectory,
);
// TODO set any other external libs file paths (bad external lib design workaround)
final loadCoinlibFuture = loadCoinlib(); final loadCoinlibFuture = loadCoinlib();
GoogleFonts.config.allowRuntimeFetching = false; GoogleFonts.config.allowRuntimeFetching = false;
@ -102,7 +111,7 @@ void main(List<String> args) async {
} }
if (Util.isDesktop && !Platform.isIOS) { if (Util.isDesktop && !Platform.isIOS) {
setWindowTitle('Stack Wallet'); setWindowTitle(AppConfig.appName);
setWindowMinSize(const Size(1220, 100)); setWindowMinSize(const Size(1220, 100));
setWindowMaxSize(Size.infinite); setWindowMaxSize(Size.infinite);
@ -585,8 +594,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
routeOnSuccessArguments: encrypted, routeOnSuccessArguments: encrypted,
biometricsCancelButtonString: "CANCEL", biometricsCancelButtonString: "CANCEL",
biometricsLocalizedReason: biometricsLocalizedReason:
"Authenticate to restore Stack Wallet backup", "Authenticate to restore ${AppConfig.appName} backup",
biometricsAuthenticationTitle: "Restore Stack backup", biometricsAuthenticationTitle: "Restore ${AppConfig.prefix} backup",
), ),
settings: const RouteSettings(name: "/swbrestorelockscreen"), settings: const RouteSettings(name: "/swbrestorelockscreen"),
), ),
@ -617,7 +626,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
return MaterialApp( return MaterialApp(
key: GlobalKey(), key: GlobalKey(),
navigatorKey: navigatorKey, navigatorKey: navigatorKey,
title: 'Stack Wallet', title: AppConfig.appName,
onGenerateRoute: RouteGenerator.generateRoute, onGenerateRoute: RouteGenerator.generateRoute,
theme: ThemeData( theme: ThemeData(
extensions: [colorScheme], extensions: [colorScheme],
@ -761,9 +770,10 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
isInitialAppLogin: true, isInitialAppLogin: true,
routeOnSuccess: HomeView.routeName, routeOnSuccess: HomeView.routeName,
routeOnSuccessArguments: startupWalletId, routeOnSuccessArguments: startupWalletId,
biometricsAuthenticationTitle: "Unlock Stack", biometricsAuthenticationTitle:
"Unlock ${AppConfig.prefix}",
biometricsLocalizedReason: biometricsLocalizedReason:
"Unlock your stack wallet using biometrics", "Unlock your ${AppConfig.appName} using biometrics",
biometricsCancelButtonString: "Cancel", biometricsCancelButtonString: "Cancel",
); );
} else { } else {

View file

@ -9,10 +9,10 @@
*/ */
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../wallets/crypto_currency/crypto_currency.dart';
abstract class AddWalletListEntity extends Equatable { abstract class AddWalletListEntity extends Equatable {
Coin get coin; CryptoCurrency get cryptoCurrency;
String get name; String get name;
String get ticker; String get ticker;
} }

View file

@ -8,23 +8,23 @@
* *
*/ */
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart'; import '../add_wallet_list_entity.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../../wallets/crypto_currency/crypto_currency.dart';
class CoinEntity extends AddWalletListEntity { class CoinEntity extends AddWalletListEntity {
CoinEntity(this._coin); CoinEntity(this._coin);
final Coin _coin; final CryptoCurrency _coin;
@override @override
Coin get coin => _coin; CryptoCurrency get cryptoCurrency => _coin;
@override @override
String get name => coin.prettyName; String get name => cryptoCurrency.prettyName;
@override @override
String get ticker => coin.ticker; String get ticker => cryptoCurrency.ticker;
@override @override
List<Object?> get props => [coin, name, ticker]; List<Object?> get props => [cryptoCurrency.identifier, name, ticker];
} }

View file

@ -8,17 +8,19 @@
* *
*/ */
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart'; import '../add_wallet_list_entity.dart';
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart'; import '../../isar/models/ethereum/eth_contract.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../../../wallets/crypto_currency/coins/ethereum.dart';
import '../../../wallets/crypto_currency/crypto_currency.dart';
class EthTokenEntity extends AddWalletListEntity { class EthTokenEntity extends AddWalletListEntity {
EthTokenEntity(this.token); EthTokenEntity(this.token);
final EthContract token; final EthContract token;
// TODO: check other networks in future and handle differently?
@override @override
Coin get coin => Coin.ethereum; CryptoCurrency get cryptoCurrency => Ethereum(CryptoCurrencyNetwork.main);
@override @override
String get name => token.name; String get name => token.name;
@ -27,5 +29,6 @@ class EthTokenEntity extends AddWalletListEntity {
String get ticker => token.symbol; String get ticker => token.symbol;
@override @override
List<Object?> get props => [coin, name, ticker, token.address]; List<Object?> get props =>
[cryptoCurrency.identifier, name, ticker, token.address];
} }

View file

@ -9,46 +9,46 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
class AddressBookFilter extends ChangeNotifier { class AddressBookFilter extends ChangeNotifier {
AddressBookFilter(Set<Coin> coins) { AddressBookFilter(Set<CryptoCurrency> coins) {
_coins = coins; _coins = coins;
} }
Set<Coin> _coins = {}; Set<CryptoCurrency> _coins = {};
Set<Coin> get coins => _coins; Set<CryptoCurrency> get coins => _coins;
set coins(Set<Coin> coins) { set coins(Set<CryptoCurrency> coins) {
_coins = coins; _coins = coins;
notifyListeners(); notifyListeners();
} }
void add(Coin coin, bool shouldNotifyListeners) { void add(CryptoCurrency coin, bool shouldNotifyListeners) {
_coins.add(coin); _coins.add(coin);
if (shouldNotifyListeners) { if (shouldNotifyListeners) {
notifyListeners(); notifyListeners();
} }
} }
void addAll(Iterable<Coin> coins, bool shouldNotifyListeners) { void addAll(Iterable<CryptoCurrency> coins, bool shouldNotifyListeners) {
_coins.addAll(coins); _coins.addAll(coins);
if (shouldNotifyListeners) { if (shouldNotifyListeners) {
notifyListeners(); notifyListeners();
} }
} }
void remove(Coin coin, bool shouldNotifyListeners) { void remove(CryptoCurrency coin, bool shouldNotifyListeners) {
_coins.removeWhere((e) => e.name == coin.name); _coins.removeWhere((e) => e.identifier == coin.identifier);
if (shouldNotifyListeners) { if (shouldNotifyListeners) {
notifyListeners(); notifyListeners();
} }
} }
void removeMany(Set<Coin> coins, bool shouldNotifyListeners) { void removeMany(Set<CryptoCurrency> coins, bool shouldNotifyListeners) {
for (final coin in coins) { for (final coin in coins) {
_coins.removeWhere((e) => e.name == coin.name); _coins.removeWhere((e) => e.identifier == coin.identifier);
} }
if (shouldNotifyListeners) { if (shouldNotifyListeners) {
notifyListeners(); notifyListeners();

View file

@ -10,8 +10,8 @@
import 'dart:convert'; import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart'; import '../utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
class Balance { class Balance {
final Amount total; final Amount total;
@ -26,10 +26,10 @@ class Balance {
required this.pendingSpendable, required this.pendingSpendable,
}); });
factory Balance.zeroForCoin({required Coin coin}) { factory Balance.zeroFor({required CryptoCurrency currency}) {
final amount = Amount( final amount = Amount(
rawValue: BigInt.zero, rawValue: BigInt.zero,
fractionDigits: coin.decimals, fractionDigits: currency.fractionDigits,
); );
return Balance( return Balance(

View file

@ -10,7 +10,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stackwallet/services/buy/buy.dart'; import '../../services/buy/buy.dart';
class BuyFormState extends ChangeNotifier { class BuyFormState extends ChangeNotifier {
Buy? _buy; Buy? _buy;

View file

@ -8,7 +8,7 @@
* *
*/ */
import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'quote.dart';
class SimplexOrder { class SimplexOrder {
final SimplexQuote quote; final SimplexQuote quote;

View file

@ -9,8 +9,8 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/buy/response_objects/crypto.dart'; import 'crypto.dart';
import 'package:stackwallet/models/buy/response_objects/fiat.dart'; import 'fiat.dart';
class SimplexQuote { class SimplexQuote {
final Crypto crypto; final Crypto crypto;

View file

@ -9,10 +9,10 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/buy/response_objects/crypto.dart'; import '../response_objects/crypto.dart';
import 'package:stackwallet/models/buy/response_objects/fiat.dart'; import '../response_objects/fiat.dart';
import 'package:stackwallet/models/buy/response_objects/order.dart'; import '../response_objects/order.dart';
import 'package:stackwallet/models/buy/response_objects/quote.dart'; import '../response_objects/quote.dart';
class Simplex { class Simplex {
List<Crypto> supportedCryptos = []; List<Crypto> supportedCryptos = [];

View file

@ -10,7 +10,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:stackwallet/models/contact_address_entry.dart'; import 'contact_address_entry.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@Deprecated("Use lib/models/isar/models/contact_entry.dart instead") @Deprecated("Use lib/models/isar/models/contact_entry.dart instead")

View file

@ -10,11 +10,12 @@
import 'dart:convert'; import 'dart:convert';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import '../app_config.dart';
import '../wallets/crypto_currency/crypto_currency.dart';
@Deprecated("Use lib/models/isar/models/contact_entry.dart instead") @Deprecated("Use lib/models/isar/models/contact_entry.dart instead")
class ContactAddressEntry { class ContactAddressEntry {
final Coin coin; final CryptoCurrency coin;
final String address; final String address;
final String label; final String label;
final String? other; final String? other;
@ -27,7 +28,7 @@ class ContactAddressEntry {
}); });
ContactAddressEntry copyWith({ ContactAddressEntry copyWith({
Coin? coin, CryptoCurrency? coin,
String? address, String? address,
String? label, String? label,
String? other, String? other,
@ -42,7 +43,7 @@ class ContactAddressEntry {
factory ContactAddressEntry.fromJson(Map<String, dynamic> jsonObject) { factory ContactAddressEntry.fromJson(Map<String, dynamic> jsonObject) {
return ContactAddressEntry( return ContactAddressEntry(
coin: Coin.values.byName(jsonObject["coin"] as String), coin: AppConfig.getCryptoCurrencyFor(jsonObject["coin"] as String)!,
address: jsonObject["address"] as String, address: jsonObject["address"] as String,
label: jsonObject["label"] as String, label: jsonObject["label"] as String,
other: jsonObject["other"] as String?, other: jsonObject["other"] as String?,
@ -53,7 +54,7 @@ class ContactAddressEntry {
return { return {
"label": label, "label": label,
"address": address, "address": address,
"coin": coin.name, "coin": coin.identifier,
"other": other ?? "", "other": other ?? "",
}; };
} }

View file

@ -9,9 +9,8 @@
*/ */
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:stackwallet/models/isar/models/contact_entry.dart'; import 'isar/models/contact_entry.dart';
import 'package:stackwallet/utilities/address_utils.dart'; import '../wallets/crypto_currency/crypto_currency.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
class AddressEntryData extends ChangeNotifier { class AddressEntryData extends ChangeNotifier {
late int id; late int id;
@ -20,7 +19,7 @@ class AddressEntryData extends ChangeNotifier {
String? _addressLabel; String? _addressLabel;
String? _address; String? _address;
Coin? _coin; CryptoCurrency? _coin;
String? get addressLabel => _addressLabel; String? get addressLabel => _addressLabel;
@ -36,9 +35,9 @@ class AddressEntryData extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Coin? get coin => _coin; CryptoCurrency? get coin => _coin;
set coin(Coin? coin) { set coin(CryptoCurrency? coin) {
_coin = coin; _coin = coin;
notifyListeners(); notifyListeners();
} }
@ -73,12 +72,12 @@ class AddressEntryData extends ChangeNotifier {
if (_address == null) { if (_address == null) {
return false; return false;
} }
return AddressUtils.validateAddress(_address!, _coin!); return _coin!.validateAddress(_address!);
} }
ContactAddressEntry buildAddressEntry() { ContactAddressEntry buildAddressEntry() {
return ContactAddressEntry() return ContactAddressEntry()
..coinName = coin!.name ..coinName = coin!.identifier
..address = address! ..address = address!
..other = null ..other = null
..label = addressLabel!; ..label = addressLabel!;
@ -86,6 +85,6 @@ class AddressEntryData extends ChangeNotifier {
@override @override
String toString() { String toString() {
return "AddressEntryData: { addressLabel: $addressLabel, address: $address, coin: ${coin?.name} }"; return "AddressEntryData: { addressLabel: $addressLabel, address: $address, coin: ${coin?.identifier} }";
} }
} }

View file

@ -11,7 +11,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:stackwallet/models/epicbox_server_model.dart'; import 'epicbox_server_model.dart';
part 'type_adaptors/epicbox_config_model.g.dart'; part 'type_adaptors/epicbox_config_model.g.dart';

View file

@ -9,7 +9,7 @@
*/ */
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart'; import 'aggregate_currency.dart';
class ActivePair extends ChangeNotifier { class ActivePair extends ChangeNotifier {
AggregateCurrency? _send; AggregateCurrency? _send;

View file

@ -8,8 +8,8 @@
* *
*/ */
import 'package:stackwallet/models/isar/exchange_cache/currency.dart'; import '../isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart'; import '../isar/exchange_cache/pair.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class AggregateCurrency { class AggregateCurrency {

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../../utilities/logger.dart';
enum CNEstimateType { direct, reverse } enum CNEstimateType { direct, reverse }

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../../utilities/logger.dart';
class EstimatedExchangeAmount { class EstimatedExchangeAmount {
/// Estimated exchange amount /// Estimated exchange amount

View file

@ -10,7 +10,7 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'; import 'exchange_transaction_status.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
part '../../type_adaptors/exchange_transaction.g.dart'; part '../../type_adaptors/exchange_transaction.g.dart';

View file

@ -9,7 +9,7 @@
*/ */
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../../utilities/logger.dart';
part '../../type_adaptors/exchange_transaction_status.g.dart'; part '../../type_adaptors/exchange_transaction_status.g.dart';

View file

@ -10,9 +10,9 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/response_objects/estimate.dart'; import 'response_objects/estimate.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'response_objects/trade.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart'; import '../../utilities/enums/exchange_rate_type_enum.dart';
class IncompleteExchangeModel extends ChangeNotifier { class IncompleteExchangeModel extends ChangeNotifier {
final String sendTicker; final String sendTicker;

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart'; import 'mb_object.dart';
class MBLimit extends MBObject { class MBLimit extends MBObject {
MBLimit({ MBLimit({

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart'; import 'mb_object.dart';
enum MBOrderType { enum MBOrderType {
fixed, fixed,

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart'; import 'mb_object.dart';
class MBOrderCalculation extends MBObject { class MBOrderCalculation extends MBObject {
MBOrderCalculation({ MBOrderCalculation({

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart'; import 'mb_object.dart';
class MBOrderStatus extends MBObject { class MBOrderStatus extends MBObject {
MBOrderStatus({ MBOrderStatus({

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart'; import 'mb_object.dart';
class MBRate extends MBObject { class MBRate extends MBObject {
MBRate({required this.fromCurrency, required this.toCurrency, required this.rate,}); MBRate({required this.fromCurrency, required this.toCurrency, required this.rate,});

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../../utilities/logger.dart';
class Estimate { class Estimate {
final Decimal estimatedAmount; final Decimal estimatedAmount;

View file

@ -9,7 +9,7 @@
*/ */
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart'; import '../../../utilities/logger.dart';
class FixedRateMarket { class FixedRateMarket {
/// Currency ticker /// Currency ticker

Some files were not shown because too many files have changed in this diff Show more