Merge remote-tracking branch 'origin/staging' into tor

This commit is contained in:
Josh Babb 2023-07-12 16:50:55 -05:00
commit a71815ede7
811 changed files with 34548 additions and 7699 deletions

View file

@ -8,12 +8,12 @@ jobs:
- name: Prepare repository
uses: actions/checkout@v3
with:
flutter-version: '3.7.10'
flutter-version: '3.10.3'
channel: 'stable'
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.7.10'
flutter-version: '3.10.3'
channel: 'stable'
- name: Setup | Rust
uses: ATiltedTree/setup-rust@v1

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"dart.lineLength": 80,
}

View file

@ -34,6 +34,8 @@ if (keystorePropertiesFile.exists()) {
android {
compileSdkVersion 33
ndkVersion = "21.1.6352462"
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
@ -47,6 +49,7 @@ android {
applicationId "com.cypherstack.stackwallet"
minSdkVersion 23
targetSdkVersion 33
ndkVersion = "21.1.6352462"
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View file

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.7.20'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@ -14,7 +14,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}
@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

View file

@ -1,15 +1,11 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

Binary file not shown.

Binary file not shown.

83
assets/svg/anonymize.svg Normal file
View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
version="1.1"
id="svg18"
sodipodi:docname="tx-icon-anonymize.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata22">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2262"
inkscape:window-height="1263"
id="namedview20"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="-15.813559"
inkscape:cy="12"
inkscape:window-x="1019"
inkscape:window-y="569"
inkscape:window-maximized="0"
inkscape:current-layer="g8" />
<g
clip-path="url(#clip0_5035_57299)"
id="g8">
<g
clip-path="url(#clip1_5035_57299)"
id="g6"
transform="matrix(1.6610229,0,0,1.7055051,-7.9831634,-8.2054918)">
<path
d="m 9.92728,11.6469 c 0.13122,0.5688 -0.49218,1.0145 -0.9871,0.7028 L 8.27572,11.934 6.88393,14.1606 c -0.3645,0.583 0.05479,1.3393 0.74238,1.3393 h 0.87554 c 0.48235,0 0.87446,0.3916 0.87446,0.8739 0,0.4824 -0.39211,0.8764 -0.87446,0.8764 H 7.62904 c -2.06062,0 -3.31679,-2.2651 -2.22769,-4.0141 L 6.79123,11.0098 6.12514,10.5915 C 5.62994,10.2797 5.75627,9.52505 6.32557,9.3938 L 8.8256,8.81548 C 9.06049,8.7649 9.29838,8.90709 9.35307,9.14498 Z M 12.741,7.15873 13.8689,8.96724 13.2058,9.37959 c -0.4966,0.30925 -0.3711,1.06481 0.199,1.19681 l 2.4992,0.5783 c 0.2358,0.0546 0.4712,-0.0926 0.5253,-0.3284 L 17.0046,8.32631 C 17.1356,7.75728 16.5138,7.31322 16.0183,7.62193 L 15.3522,8.03755 14.2257,6.23396 C 13.1981,4.58951 10.8023,4.58841 9.77416,6.23227 L 9.57182,6.55552 C 9.31752,6.96158 9.4433,7.50381 9.84799,7.75865 10.256,8.01456 10.7987,7.89225 11.0541,7.48412 L 11.2576,7.159 c 0.3486,-0.55754 1.1498,-0.53703 1.4834,-2.7e-4 z m 5.857,6.07957 -0.4646,-0.7454 c -0.2553,-0.4096 -0.7946,-0.5348 -1.2042,-0.2791 -0.4085,0.2548 -0.5338,0.797 -0.2784,1.2053 l 0.4646,0.7424 c 0.365,0.5829 -0.0542,1.3398 -0.7421,1.3398 h -2.6247 l 6e-4,-0.7859 c 0,-0.5846 -0.7068,-0.8774 -1.1203,-0.464 l -1.8159,1.8165 c -0.1701,0.1701 -0.1701,0.4487 2e-4,0.6188 l 1.8161,1.8139 c 0.4135,0.4129 1.1198,0.12 1.1198,-0.4643 l -7e-4,-0.7842 h 2.6212 c 2.0616,3e-4 3.3194,-2.2665 2.2284,-4.0138 z"
id="path4"
inkscape:connector-curvature="0"
style="fill:#494949" />
</g>
</g>
<defs
id="defs16">
<clipPath
id="clip0_5035_57299">
<rect
width="24"
height="24"
fill="white"
id="rect10" />
</clipPath>
<clipPath
id="clip1_5035_57299">
<rect
width="14"
height="14"
fill="white"
transform="translate(5 5)"
id="rect13" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -1 +1 @@
Subproject commit 594ab89bc665a15a810ba7476ed2ad255fa8b5ac
Subproject commit e1df088733695ad06d377087d069eae1746d55a7

@ -1 +1 @@
Subproject commit b3fac32f57d7ef97da8641463d1a852f41660f9b
Subproject commit ec3cf5e8e1b90e006188aa8c323d4cd52dbfa9b9

@ -1 +1 @@
Subproject commit 81659ce57952c5ab54ffe6bacfbf43da159fff3e
Subproject commit 26a152fea3ca4b8c3f1130392a02f579c2ff218c

View file

@ -4,43 +4,31 @@ Here you will find instructions on how to install the necessary tools for buildi
## Prerequisites
- The only OS supported for building is Ubuntu 20.04. Advanced users may also be able to build on other Debian-based distributions like Linux Mint.
- The only OS supported for building Android and Linux desktop is Ubuntu 20.04. Windows build are completed using Ubuntu 20.04 on WSL2. Advanced users may also be able to build on other Debian-based distributions like Linux Mint.
- Android setup ([Android Studio](https://developer.android.com/studio) and subsequent dependencies)
- 100 GB of storage
Install Android Studio following the instructions below before proceeding, then the following prerequisites can be installed with the setup script [`scripts/setup.sh`](./../scripts/setup.sh) or manually as described below:
- Flutter 3.7.12 [(install manually or with git, do not install with snap)](https://docs.flutter.dev/get-started/install)
- Dart SDK Requirement (>=2.19.0, up until <3.0.0) (normally included with a flutter install)
## Linux host
The following instructions are for building and running on a Linux host. Alternatively, see the [Windows](#Windows host) section.
### Android Studio
Android Studio is the recommended IDE for development, not just for launching on Android devices and emulators but also for Linux desktop development.
Follow instructions here [https://developer.android.com/studio/install#linux](https://developer.android.com/studio/install#linux) or install via snap:
Install Android Studio. Follow instructions here [https://developer.android.com/studio/install#linux](https://developer.android.com/studio/install#linux) or install via snap:
```
# setup android studio
sudo apt install -y openjdk-11-jdk
sudo snap install android-studio --classic
```
Use Tools > SDK Manager to install:
- SDK Tools > Android SDK (API 30)
- SDK Tools > NDK
- SDK Tools > Android SDK command line tools
- SDK Tools > CMake
Use `Tools > SDK Manager` to install:
- `SDK Tools > Android SDK (API 30)`
- `SDK Tools > NDK`
- `SDK Tools > Android SDK command line tools`
- `SDK Tools > CMake`
Then in File > Settings > Plugins, install the Flutter plugin and restart the IDE. In File > Settings > Languages & Frameworks > Flutter > Editor, enable auto format on save to match the project's code style. If you have problems with the Dart SDK, make sure to run `flutter` in a terminal to download it (use `source ~/.bashrc` to update your environment variables if you're still using the same terminal from which you ran `setup.sh`)
Then in `File > Settings > Plugins`, install the **Flutter** and **Dart** plugins and restart the IDE. In `File > Settings > Languages & Frameworks > Flutter > Editor`, enable auto format on save to match the project's code style. If you have problems with the Dart SDK, make sure to run `flutter` in a terminal to download it (use `source ~/.bashrc` to update your environment variables if you're still using the same terminal from which you ran `setup.sh`). Run `flutter doctor` to install any missing dependencies and review and agree to any license agreements.
Make a Pixel 4 (API 30) x86_64 emulator with 2GB of storage space for emulation
### Scripted setup
[`scripts/setup.sh`](./../scripts/setup.sh) is provided as a tool to set up installation for building: download the script and run it anywhere. This script should skip the entire [Manual setup](#manual-setup) section below and prepare you for [running](#running). It will set up the stack_wallet repository in `~/projects/stack_wallet` and build it there.
### Manual setup
> If you used the `setup.sh` script, skip to [running](#running)
Install basic dependencies
```
sudo apt-get install libssl-dev curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm python3-distutils
@ -82,15 +70,6 @@ git submodule update --init --recursive
```
Run prebuild script
```
cd scripts
./prebuild.sh
// when finished go back to the root directory
cd ..
```
Remove pre-installed system libraries for the following packages built by cryptography plugins in the crypto_plugins folder: `boost iconv libjson-dev libsecret openssl sodium unbound zmq`. You can use
```
sudo apt list --installed | grep boost
@ -101,26 +80,40 @@ sudo apt-get remove '^libboost.*-dev.*'
```
<!-- TODO: configure compiler to prefer built over system libraries. Should already use them? -->
Building plugins for Android
### Run prebuild script
Certain test wallet parameter and API key template files must be created in order to run Stack Wallet. These can be created by script as in
```
cd scripts
./prebuild.sh
// when finished go back to the root directory
cd ..
```
or manually by creating the files referenced in that script with the specified content.
### Build plugins
#### Building plugins for Android
> Warning: This will take a long time, please be patient
```
cd scripts/android/
cd scripts/android
./build_all.sh
// when finished go back to the root directory
cd ../..
```
Building plugins for Linux
#### Building plugins for Linux
```
cd scripts/linux/
cd scripts/linux
./build_all.sh
// when finished go back to the root directory
cd ../..
```
## Running
### Android
#### Building plugins for Windows
```
cd scripts/windows
./deps.sh
./build_all.sh
```
### Running
#### Android
Plug in your android device or use the emulator available via Android Studio and then run the following commands:
```
flutter pub get
@ -129,9 +122,58 @@ flutter run android
Note on Emulators: Only x86_64 emulators are supported, x86 emulators will not work
### Linux
#### Linux
Plug in your android device or use the emulator available via Android Studio and then run the following commands:
```
flutter pub get Linux
flutter pub get
flutter run linux
```
## Windows host
### Visual Studio
Visual Studio is required for Windows development with the Flutter SDK. Download it at https://visualstudio.microsoft.com/downloads/ and install the "Desktop development with C++" workload, including all of its default components.
### Building libraries in WSL2
Set up Ubuntu 20.04 in WSL2. Follow the entire Linux host section to get set up and build windows `dll` libraries. Copy the resulting `dll`s to their respective positions on the Windows host:
- `stack_wallet/crypto_plugins/flutter_libepiccash/scripts/windows/build/libepic_cash_wallet.dll`
- `stack_wallet/crypto_plugins/flutter_liblelantus/scripts/windows/build/libmobileliblelantus.dll`
<!-- TODO: script the copying or installation of libraries from WSL2 to the parent Windows host -->
### Install Flutter on Windows host
Install Flutter 3.10.3 on your Windows host (not in WSL2) by following these instructions: https://docs.flutter.dev/get-started/install/windows or by running `scripts/windows/deps.ps1`. You may still have to add `C:\development\flutter\bin` to PATH before proceeding, even if you ran `deps.ps1`. Run `flutter doctor` in PowerShell to confirm its installation.
### Dependencies
Install the Windows SDK: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ You may need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/), which can be installed [by Visual Studio](https://stackoverflow.com/a/73923899) (`Tools > Get Tools and Features... > Modify > Individual Components > Windows 10 SDK`).
Enable Developer Mode for symlink support,
```
start ms-settings:developers
```
You may need to install NuGet and CppWinRT / C++/WinRT SDKs version `2.0.210806.1`:
```
winget install 9WZDNCRDMDM3 # NuGet, can also use Microsoft.NuGet
winget install Microsoft.Windows.CppWinRT -Version 2.0.210806.1
```
or [download the package](https://www.nuget.org/packages/Microsoft.Windows.CppWinRT/2.0.210806.1) and [manually install it](https://github.com/Baseflow/flutter-permission-handler/issues/1025#issuecomment-1518576722) by placing it in `flutter/bin` with [nuget.exe](https://dist.nuget.org/win-x86-commandline/latest/nuget.exe) and installing by running `nuget install Microsoft.Windows.CppWinRT -Version 2.0.210806.1` in the root `stack_wallet` folder.
<!-- TODO: script this NuGet and WinCppRT installation -->
### Run prebuild script
Certain test wallet parameter and API key template files must be created in order to run Stack Wallet. These can be created by script as in
```
cd scripts
./prebuild.ps1
// when finished go back to the root directory
cd ..
```
or manually by creating the files referenced in that script with the specified content.
### Running
Run the following commands:
```
flutter pub get
flutter run -d windows
```

View file

@ -1,9 +1,18 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:isolate';
import 'package:cw_core/wallet_info.dart' as xmr;
import 'package:hive/hive.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/notification_model.dart';
@ -13,8 +22,13 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
class DB {
// legacy (required for migrations)
@Deprecated("Left over for migration from old versions of Stack Wallet")
static const String boxNameAddressBook = "addressBook";
static const String boxNameDebugInfo = "debugInfoBox";
static const String boxNameTrades = "exchangeTransactionsBox";
// in use
// TODO: migrate
static const String boxNameNodeModels = "nodeModels";
static const String boxNamePrimaryNodes = "primaryNodes";
static const String boxNameAllWalletsData = "wallets";
@ -22,33 +36,31 @@ class DB {
static const String boxNameWatchedTransactions =
"watchedTxNotificationModels";
static const String boxNameWatchedTrades = "watchedTradesNotificationModels";
static const String boxNameTrades = "exchangeTransactionsBox";
static const String boxNameTradesV2 = "exchangeTradesBox";
static const String boxNameTradeNotes = "tradeNotesBox";
static const String boxNameTradeLookup = "tradeToTxidLookUpBox";
static const String boxNameFavoriteWallets = "favoriteWallets";
static const String boxNamePrefs = "prefs";
static const String boxNameWalletsToDeleteOnStart = "walletsToDeleteOnStart";
static const String boxNamePriceCache = "priceAPIPrice24hCache";
static const String boxNameDBInfo = "dbInfo";
// static const String boxNameTheme = "theme";
static const String boxNameDesktopData = "desktopData";
static const String boxNameBuys = "buysBox";
String boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
String boxNameSetCache({required Coin coin}) =>
// in use (keep for now)
static const String boxNameDBInfo = "dbInfo";
static const String boxNamePrefs = "prefs";
String _boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
// firo only
String _boxNameSetCache({required Coin coin}) =>
"${coin.name}_anonymitySetCache";
String boxNameUsedSerialsCache({required Coin coin}) =>
String _boxNameUsedSerialsCache({required Coin coin}) =>
"${coin.name}_usedSerialsCache";
Box<String>? _boxDebugInfo;
Box<NodeModel>? _boxNodeModels;
Box<NodeModel>? _boxPrimaryNodes;
Box<dynamic>? _boxAllWalletsData;
Box<NotificationModel>? _boxNotifications;
Box<NotificationModel>? _boxWatchedTransactions;
Box<NotificationModel>? _boxWatchedTrades;
Box<ExchangeTransaction>? _boxTrades;
Box<Trade>? _boxTradesV2;
Box<String>? _boxTradeNotes;
Box<String>? _boxFavoriteWallets;
@ -56,7 +68,7 @@ class DB {
Box<dynamic>? _boxPrefs;
Box<TradeWalletLookup>? _boxTradeLookup;
Box<dynamic>? _boxDBInfo;
Box<String>? _boxDesktopData;
// Box<String>? _boxDesktopData;
final Map<String, Box<dynamic>> _walletBoxes = {};
@ -99,8 +111,6 @@ class DB {
_boxPrefs = await Hive.openBox<dynamic>(boxNamePrefs);
}
_boxDebugInfo = await Hive.openBox<String>(boxNameDebugInfo);
if (Hive.isBoxOpen(boxNameNodeModels)) {
_boxNodeModels = Hive.box<NodeModel>(boxNameNodeModels);
} else {
@ -119,19 +129,12 @@ class DB {
_boxAllWalletsData = await Hive.openBox<dynamic>(boxNameAllWalletsData);
}
if (Hive.isBoxOpen(boxNameDesktopData)) {
_boxDesktopData = Hive.box<String>(boxNameDesktopData);
} else {
_boxDesktopData = await Hive.openBox<String>(boxNameDesktopData);
}
_boxNotifications =
await Hive.openBox<NotificationModel>(boxNameNotifications);
_boxWatchedTransactions =
await Hive.openBox<NotificationModel>(boxNameWatchedTransactions);
_boxWatchedTrades =
await Hive.openBox<NotificationModel>(boxNameWatchedTrades);
_boxTrades = await Hive.openBox<ExchangeTransaction>(boxNameTrades);
_boxTradesV2 = await Hive.openBox<Trade>(boxNameTradesV2);
_boxTradeNotes = await Hive.openBox<String>(boxNameTradeNotes);
_boxTradeLookup = await Hive.openBox<TradeWalletLookup>(boxNameTradeLookup);
@ -142,7 +145,6 @@ class DB {
await Future.wait([
Hive.openBox<dynamic>(boxNamePriceCache),
_loadWalletBoxes(),
_loadSharedCoinCacheBoxes(),
]);
}
@ -174,14 +176,39 @@ class DB {
}
}
Future<void> _loadSharedCoinCacheBoxes() async {
for (final coin in Coin.values) {
_txCacheBoxes[coin] =
await Hive.openBox<dynamic>(boxNameTxCache(coin: coin));
_setCacheBoxes[coin] =
await Hive.openBox<dynamic>(boxNameSetCache(coin: coin));
_usedSerialsCacheBoxes[coin] =
await Hive.openBox<dynamic>(boxNameUsedSerialsCache(coin: coin));
Future<Box<dynamic>> getTxCacheBox({required Coin coin}) async {
return _txCacheBoxes[coin] ??=
await Hive.openBox<dynamic>(_boxNameTxCache(coin: coin));
}
Future<void> closeTxCacheBox({required Coin coin}) async {
await _txCacheBoxes[coin]?.close();
}
Future<Box<dynamic>> getAnonymitySetCacheBox({required Coin coin}) async {
return _setCacheBoxes[coin] ??=
await Hive.openBox<dynamic>(_boxNameSetCache(coin: coin));
}
Future<void> closeAnonymitySetCacheBox({required Coin coin}) async {
await _setCacheBoxes[coin]?.close();
}
Future<Box<dynamic>> getUsedSerialsCacheBox({required Coin coin}) async {
return _usedSerialsCacheBoxes[coin] ??=
await Hive.openBox<dynamic>(_boxNameUsedSerialsCache(coin: coin));
}
Future<void> closeUsedSerialsCacheBox({required Coin coin}) async {
await _usedSerialsCacheBoxes[coin]?.close();
}
/// Clear all cached transactions for the specified coin
Future<void> clearSharedTransactionCache({required Coin coin}) async {
await deleteAll<dynamic>(boxName: _boxNameTxCache(coin: coin));
if (coin == Coin.firo) {
await deleteAll<dynamic>(boxName: _boxNameSetCache(coin: coin));
await deleteAll<dynamic>(boxName: _boxNameUsedSerialsCache(coin: coin));
}
}
@ -243,6 +270,36 @@ class DB {
Future<void> deleteBoxFromDisk({required String boxName}) async =>
await mutex.protect(() async => await Hive.deleteBoxFromDisk(boxName));
///////////////////////////////////////////////////////////////////////////
Future<bool> deleteEverything() async {
try {
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameAddressBook);
await DB.instance.deleteBoxFromDisk(boxName: "debugInfoBox");
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameNodeModels);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNamePrimaryNodes);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameAllWalletsData);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameNotifications);
await DB.instance
.deleteBoxFromDisk(boxName: DB.boxNameWatchedTransactions);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameWatchedTrades);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameTrades);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameTradesV2);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameTradeNotes);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameTradeLookup);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameFavoriteWallets);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNamePrefs);
await DB.instance
.deleteBoxFromDisk(boxName: DB.boxNameWalletsToDeleteOnStart);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNamePriceCache);
await DB.instance.deleteBoxFromDisk(boxName: DB.boxNameDBInfo);
await DB.instance.deleteBoxFromDisk(boxName: "theme");
return true;
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
}
abstract class DBKeys {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:flutter_native_splash/cli_commands.dart';
import 'package:isar/isar.dart';
@ -13,6 +23,11 @@ import 'package:tuple/tuple.dart';
part '../queries/queries.dart';
/*
* This file includes the functions that are used to interact with the main database.
* To add a new function, add it in the class MainDB.
*/
class MainDB {
MainDB._();
static MainDB? _instance;
@ -50,8 +65,8 @@ class MainDB {
}
// contact entries
List<ContactEntry> getContactEntries(){
return isar.contactEntrys.where().findAllSync();
List<ContactEntry> getContactEntries() {
return isar.contactEntrys.where().sortByName().findAllSync();
}
Future<bool> deleteContactEntry({required String id}) {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
part of 'package:stackwallet/db/isar/main_db.dart';
enum CCFilter {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
/// address : "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"
/// blockNumber : 16484149
/// logIndex : 61

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart';
@ -106,13 +116,13 @@ class EthTokenTxExtraDTO {
map['timestamp'] = timestamp;
map['from'] = from;
map['to'] = to;
map['value'] = value;
map['gas'] = gas;
map['gasPrice'] = gasPrice;
map['value'] = value.toJsonString();
map['gas'] = gas.toJsonString();
map['gasPrice'] = gasPrice.toJsonString();
map['input'] = input;
map['nonce'] = nonce;
map['gasCost'] = gasCost;
map['gasUsed'] = gasUsed;
map['gasCost'] = gasCost.toJsonString();
map['gasUsed'] = gasUsed.toJsonString();
return map;
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
/// blockHash : null
/// blockNumber : null
/// from : "0x..."

View file

@ -1,46 +1,36 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:string_validator/string_validator.dart';
class CachedElectrumX {
final ElectrumX? electrumXClient;
final String server;
final int port;
final bool useSSL;
final Prefs prefs;
final List<ElectrumXNode> failovers;
final ElectrumX electrumXClient;
static const minCacheConfirms = 30;
const CachedElectrumX({
required this.server,
required this.port,
required this.useSSL,
required this.prefs,
required this.failovers,
this.electrumXClient,
required this.electrumXClient,
});
factory CachedElectrumX.from({
required ElectrumXNode node,
required Prefs prefs,
required List<ElectrumXNode> failovers,
ElectrumX? electrumXClient,
required ElectrumX electrumXClient,
}) =>
CachedElectrumX(
server: node.address,
port: node.port,
useSSL: node.useSSL,
prefs: prefs,
failovers: failovers,
electrumXClient: electrumXClient);
electrumXClient: electrumXClient,
);
Future<Map<String, dynamic>> getAnonymitySet({
required String groupId,
@ -48,9 +38,8 @@ class CachedElectrumX {
required Coin coin,
}) async {
try {
final cachedSet = DB.instance.get<dynamic>(
boxName: DB.instance.boxNameSetCache(coin: coin),
key: groupId) as Map?;
final box = await DB.instance.getAnonymitySetCacheBox(coin: coin);
final cachedSet = box.get(groupId) as Map?;
Map<String, dynamic> set;
@ -66,16 +55,7 @@ class CachedElectrumX {
set = Map<String, dynamic>.from(cachedSet);
}
final client = electrumXClient ??
ElectrumX(
host: server,
port: port,
useSSL: useSSL,
prefs: prefs,
failovers: failovers,
);
final newSet = await client.getAnonymitySet(
final newSet = await electrumXClient.getAnonymitySet(
groupId: groupId,
blockhash: set["blockHash"] as String,
);
@ -90,7 +70,7 @@ class CachedElectrumX {
: newSet["blockHash"];
for (int i = (newSet["coins"] as List).length - 1; i >= 0; i--) {
dynamic newCoin = newSet["coins"][i];
List translatedCoin = [];
List<dynamic> translatedCoin = [];
translatedCoin.add(!isHexadecimal(newCoin[0] as String)
? base64ToHex(newCoin[0] as String)
: newCoin[0]);
@ -110,13 +90,11 @@ class CachedElectrumX {
set["coins"].insert(0, translatedCoin);
}
// save set to db
await DB.instance.put<dynamic>(
boxName: DB.instance.boxNameSetCache(coin: coin),
key: groupId,
value: set);
await box.put(groupId, set);
Logging.instance.log(
"Updated currently anonymity set for ${coin.name} with group ID $groupId",
level: LogLevel.Info);
"Updated current anonymity set for ${coin.name} with group ID $groupId",
level: LogLevel.Info,
);
}
return set;
@ -148,29 +126,19 @@ class CachedElectrumX {
bool verbose = true,
}) async {
try {
final cachedTx = DB.instance.get<dynamic>(
boxName: DB.instance.boxNameTxCache(coin: coin), key: txHash) as Map?;
final box = await DB.instance.getTxCacheBox(coin: coin);
final cachedTx = box.get(txHash) as Map?;
if (cachedTx == null) {
final client = electrumXClient ??
ElectrumX(
host: server,
port: port,
useSSL: useSSL,
prefs: prefs,
failovers: failovers,
);
final Map<String, dynamic> result =
await client.getTransaction(txHash: txHash, verbose: verbose);
final Map<String, dynamic> result = await electrumXClient
.getTransaction(txHash: txHash, verbose: verbose);
result.remove("hex");
result.remove("lelantusData");
if (result["confirmations"] != null &&
result["confirmations"] as int > minCacheConfirms) {
await DB.instance.put<dynamic>(
boxName: DB.instance.boxNameTxCache(coin: coin),
key: txHash,
value: result);
await box.put(txHash, result);
}
Logging.instance.log("using fetched result", level: LogLevel.Info);
@ -187,31 +155,25 @@ class CachedElectrumX {
}
}
Future<List<dynamic>> getUsedCoinSerials({
Future<List<String>> getUsedCoinSerials({
required Coin coin,
int startNumber = 0,
}) async {
try {
List<dynamic>? cachedSerials = DB.instance.get<dynamic>(
boxName: DB.instance.boxNameUsedSerialsCache(coin: coin),
key: "serials") as List?;
final box = await DB.instance.getUsedSerialsCacheBox(coin: coin);
cachedSerials ??= [];
final _list = box.get("serials") as List?;
List<String> cachedSerials =
_list == null ? [] : List<String>.from(_list);
final startNumber = cachedSerials.length;
final client = electrumXClient ??
ElectrumX(
host: server,
port: port,
useSSL: useSSL,
prefs: prefs,
failovers: failovers,
);
final serials =
await electrumXClient.getUsedCoinSerials(startNumber: startNumber);
List<String> newSerials = [];
final serials = await client.getUsedCoinSerials(startNumber: startNumber);
List newSerials = [];
for (var element in (serials["serials"] as List)) {
for (final element in (serials["serials"] as List)) {
if (!isHexadecimal(element as String)) {
newSerials.add(base64ToHex(element));
} else {
@ -220,10 +182,10 @@ class CachedElectrumX {
}
cachedSerials.addAll(newSerials);
await DB.instance.put<dynamic>(
boxName: DB.instance.boxNameUsedSerialsCache(coin: coin),
key: "serials",
value: cachedSerials);
await box.put(
"serials",
cachedSerials,
);
return cachedSerials;
} catch (e, s) {
@ -236,11 +198,6 @@ class CachedElectrumX {
/// Clear all cached transactions for the specified coin
Future<void> clearSharedTransactionCache({required Coin coin}) async {
await DB.instance
.deleteAll<dynamic>(boxName: DB.instance.boxNameTxCache(coin: coin));
await DB.instance
.deleteAll<dynamic>(boxName: DB.instance.boxNameSetCache(coin: coin));
await DB.instance.deleteAll<dynamic>(
boxName: DB.instance.boxNameUsedSerialsCache(coin: coin));
await DB.instance.closeAnonymitySetCacheBox(coin: coin);
}
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'dart:io';
@ -132,8 +142,12 @@ class ElectrumX {
final response = await _rpcClient!.request(jsonRequestString);
if (response["error"] != null) {
if (response["error"]
if (response.exception != null) {
throw response.exception!;
}
if (response.data is Map && response.data["error"] != null) {
if (response.data["error"]
.toString()
.contains("No such mempool or blockchain transaction")) {
throw NoSuchTransactionException(
@ -143,11 +157,15 @@ class ElectrumX {
}
throw Exception(
"JSONRPC response \ncommand: $command \nargs: $args \nerror: $response");
"JSONRPC response\n"
" command: $command\n"
" args: $args\n"
" error: ${response.data}",
);
}
currentFailoverIndex = -1;
return response;
return response.data;
} on WifiOnlyException {
rethrow;
} on SocketException {
@ -228,7 +246,13 @@ class ElectrumX {
// Logging.instance.log("batch request: $request");
// send batch request
final response = (await _rpcClient!.request(request)) as List<dynamic>;
final jsonRpcResponse = (await _rpcClient!.request(request));
if (jsonRpcResponse.exception != null) {
throw jsonRpcResponse.exception!;
}
final response = jsonRpcResponse.data as List;
// check for errors, format and throw if there are any
final List<String> errors = [];
@ -310,6 +334,13 @@ class ElectrumX {
requestID: requestID,
command: 'blockchain.headers.subscribe',
);
if (response["result"] == null) {
Logging.instance.log(
"getBlockHeadTip returned null response",
level: LogLevel.Error,
);
throw 'getBlockHeadTip returned null response';
}
return Map<String, dynamic>.from(response["result"] as Map);
} catch (e) {
rethrow;
@ -546,8 +577,9 @@ class ElectrumX {
bool verbose = true,
String? requestID,
}) async {
dynamic response;
try {
final response = await request(
response = await request(
requestID: requestID,
command: 'blockchain.transaction.get',
args: [
@ -561,6 +593,10 @@ class ElectrumX {
return Map<String, dynamic>.from(response["result"] as Map);
} catch (e) {
Logging.instance.log(
"getTransaction($txHash) response: $response",
level: LogLevel.Error,
);
rethrow;
}
}

View file

@ -1,10 +1,22 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/utilities/logger.dart';
// hacky fix to receive large jsonrpc responses
// Json RPC class to handle connecting to electrumx servers
class JsonRPC {
JsonRPC({
required this.host,
@ -12,65 +24,267 @@ class JsonRPC {
this.useSSL = false,
this.connectionTimeout = const Duration(seconds: 60),
});
bool useSSL;
String host;
int port;
Duration connectionTimeout;
final bool useSSL;
final String host;
final int port;
final Duration connectionTimeout;
Future<dynamic> request(String jsonRpcRequest) async {
Socket? socket;
final completer = Completer<dynamic>();
final List<int> responseData = [];
final _requestMutex = Mutex();
final _JsonRPCRequestQueue _requestQueue = _JsonRPCRequestQueue();
Socket? _socket;
StreamSubscription<Uint8List>? _subscription;
void dataHandler(List<int> data) {
responseData.addAll(data);
void _dataHandler(List<int> data) {
_requestQueue.nextIncompleteReq.then((req) {
if (req != null) {
req.appendDataAndCheckIfComplete(data);
// 0x0A is newline
// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html
if (data.last == 0x0A) {
try {
final response = json.decode(String.fromCharCodes(responseData));
completer.complete(response);
} catch (e, s) {
Logging.instance
.log("JsonRPC json.decode: $e\n$s", level: LogLevel.Error);
completer.completeError(e, s);
} finally {
socket?.destroy();
if (req.isComplete) {
_onReqCompleted(req);
}
} else {
Logging.instance.log(
"_dataHandler found a null req!",
level: LogLevel.Warning,
);
}
}
});
}
void errorHandler(Object error, StackTrace trace) {
Logging.instance
.log("JsonRPC errorHandler: $error\n$trace", level: LogLevel.Error);
completer.completeError(error, trace);
socket?.destroy();
}
void _errorHandler(Object error, StackTrace trace) {
_requestQueue.nextIncompleteReq.then((req) {
if (req != null) {
req.completer.completeError(error, trace);
_onReqCompleted(req);
}
});
}
void doneHandler() {
socket?.destroy();
void _doneHandler() {
disconnect(reason: "JsonRPC _doneHandler() called");
}
void _onReqCompleted(_JsonRPCRequest req) {
_requestQueue.remove(req).then((_) {
// attempt to send next request
_sendNextAvailableRequest();
});
}
void _sendNextAvailableRequest() {
_requestQueue.nextIncompleteReq.then((req) {
if (req != null) {
// \r\n required by electrumx server
_socket!.write('${req.jsonRequest}\r\n');
// TODO different timeout length?
req.initiateTimeout(
const Duration(seconds: 10),
onTimedOut: () {
_requestQueue.remove(req);
},
);
}
});
}
Future<JsonRPCResponse> request(String jsonRpcRequest) async {
await _requestMutex.protect(() async {
if (_socket == null) {
Logging.instance.log(
"JsonRPC request: opening socket $host:$port",
level: LogLevel.Info,
);
await connect();
}
});
final req = _JsonRPCRequest(
jsonRequest: jsonRpcRequest,
completer: Completer<JsonRPCResponse>(),
);
final future = req.completer.future.onError(
(error, stackTrace) async {
await disconnect(
reason: "return req.completer.future.onError: $error\n$stackTrace",
);
return JsonRPCResponse(
exception: error is Exception
? error
: Exception(
"req.completer.future.onError: $error\n$stackTrace",
),
);
},
);
// if this is the only/first request then send it right away
await _requestQueue.add(
req,
onInitialRequestAdded: _sendNextAvailableRequest,
);
return future;
}
Future<void> disconnect({required String reason}) async {
await _requestMutex.protect(() async {
await _subscription?.cancel();
_subscription = null;
_socket?.destroy();
_socket = null;
// clean up remaining queue
await _requestQueue.completeRemainingWithError(
"JsonRPC disconnect() called with reason: \"$reason\"",
);
});
}
Future<void> connect() async {
if (_socket != null) {
throw Exception(
"JsonRPC attempted to connect to an already existing socket!",
);
}
if (useSSL) {
await SecureSocket.connect(host, port,
timeout: connectionTimeout,
onBadCertificate: (_) => true).then((Socket sock) {
socket = sock;
socket?.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: true);
});
_socket = await SecureSocket.connect(
host,
port,
timeout: connectionTimeout,
onBadCertificate: (_) => true,
); // TODO do not automatically trust bad certificates
} else {
await Socket.connect(host, port, timeout: connectionTimeout)
.then((Socket sock) {
socket = sock;
socket?.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: true);
});
_socket = await Socket.connect(
host,
port,
timeout: connectionTimeout,
);
}
socket?.write('$jsonRpcRequest\r\n');
return completer.future;
_subscription = _socket!.listen(
_dataHandler,
onError: _errorHandler,
onDone: _doneHandler,
cancelOnError: true,
);
}
}
class _JsonRPCRequestQueue {
final _lock = Mutex();
final List<_JsonRPCRequest> _rq = [];
Future<void> add(
_JsonRPCRequest req, {
VoidCallback? onInitialRequestAdded,
}) async {
return await _lock.protect(() async {
_rq.add(req);
if (_rq.length == 1) {
onInitialRequestAdded?.call();
}
});
}
Future<bool> remove(_JsonRPCRequest req) async {
return await _lock.protect(() async {
final result = _rq.remove(req);
return result;
});
}
Future<_JsonRPCRequest?> get nextIncompleteReq async {
return await _lock.protect(() async {
int removeCount = 0;
_JsonRPCRequest? returnValue;
for (final req in _rq) {
if (req.isComplete) {
removeCount++;
} else {
returnValue = req;
break;
}
}
_rq.removeRange(0, removeCount);
return returnValue;
});
}
Future<void> completeRemainingWithError(
String error, {
StackTrace? stackTrace,
}) async {
await _lock.protect(() async {
for (final req in _rq) {
if (!req.isComplete) {
req.completer.completeError(Exception(error), stackTrace);
}
}
_rq.clear();
});
}
Future<bool> get isEmpty async {
return await _lock.protect(() async {
return _rq.isEmpty;
});
}
}
class _JsonRPCRequest {
// 0x0A is newline
// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html
static const int separatorByte = 0x0A;
final String jsonRequest;
final Completer<JsonRPCResponse> completer;
final List<int> _responseData = [];
_JsonRPCRequest({required this.jsonRequest, required this.completer});
void appendDataAndCheckIfComplete(List<int> data) {
_responseData.addAll(data);
if (data.last == separatorByte) {
try {
final response = json.decode(String.fromCharCodes(_responseData));
completer.complete(JsonRPCResponse(data: response));
} catch (e, s) {
Logging.instance.log(
"JsonRPC json.decode: $e\n$s",
level: LogLevel.Error,
);
completer.completeError(e, s);
}
}
}
void initiateTimeout(
Duration timeout, {
VoidCallback? onTimedOut,
}) {
Future<void>.delayed(timeout).then((_) {
if (!isComplete) {
try {
throw Exception("_JsonRPCRequest timed out: $jsonRequest");
} catch (e, s) {
completer.completeError(e, s);
onTimedOut?.call();
}
}
});
}
bool get isComplete => completer.isCompleted;
}
class JsonRPCResponse {
final dynamic data;
final Exception? exception;
JsonRPCResponse({this.data, this.exception});
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:async';
import 'dart:convert';
import 'dart:io';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
class AddressException extends SWException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
class NoSuchTransactionException extends SWException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
enum ExchangeExceptionType { generic, serializeResponseError, orderNotFound }

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart';
class MBException extends ExchangeException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart';
class PairUnavailableException extends ExchangeException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/exchange/exchange_exception.dart';
class UnsupportedCurrencyException extends ExchangeException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
class MainDBException extends SWException {

View file

@ -1,7 +1,17 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
// generic stack wallet exception which all other custom exceptions should
// extend from
class SWException with Exception {
class SWException implements Exception {
SWException(this.message);
final String message;

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
class InsufficientBalanceException extends SWException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/exceptions/sw_exception.dart';
class PaynymSendException extends SWException {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:async';
import 'dart:io';
import 'dart:math';
@ -71,7 +81,7 @@ final openedFromSWBFileStringStateProvider =
// runs the MyApp widget and checks for new users, caching the value in the
// miscellaneous box for later use
void main() async {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
WidgetsFlutterBinding.ensureInitialized();
GoogleFonts.config.allowRuntimeFetching = false;
if (Platform.isIOS) {
Util.libraryPath = await getLibraryDirectory();
@ -158,6 +168,8 @@ void main() async {
await Hive.openBox<dynamic>(DB.boxNamePrefs);
await Prefs.instance.init();
await StackFileSystem.initThemesDir();
// Desktop migrate handled elsewhere (currently desktop_login_view.dart)
if (!Util.isDesktop) {
int dbVersion = DB.instance.get<dynamic>(
@ -179,8 +191,12 @@ void main() async {
}
}
monero.onStartup();
wownero.onStartup();
if (!Platform.isWindows) {
monero.onStartup();
}
if (!Platform.isLinux && !Platform.isWindows) {
wownero.onStartup();
}
dynamic tor = Tor();
tor.start();
@ -192,32 +208,28 @@ void main() async {
await MainDB.instance.initMainDB();
ThemeService.instance.init(MainDB.instance);
// install default themes
if (!(await ThemeService.instance.verifyInstalled(themeId: "light"))) {
Logging.instance.log(
"Installing default light theme...",
level: LogLevel.Info,
);
final lightZip = await rootBundle.load("assets/default_themes/light.zip");
await ThemeService.instance
.install(themeArchiveData: lightZip.buffer.asUint8List());
Logging.instance.log(
"Installing default light theme... finished",
level: LogLevel.Info,
);
// check and update or install default themes
await ThemeService.instance.checkDefaultThemesOnStartup();
// verify current user preference theme and revert to default
// if problems are found to prevent app being unusable
if (!(await ThemeService.instance
.verifyInstalled(themeId: Prefs.instance.themeId))) {
Prefs.instance.themeId = "light";
}
if (!(await ThemeService.instance.verifyInstalled(themeId: "dark"))) {
Logging.instance.log(
"Installing default dark theme... ",
level: LogLevel.Info,
);
final darkZip = await rootBundle.load("assets/default_themes/dark.zip");
await ThemeService.instance
.install(themeArchiveData: darkZip.buffer.asUint8List());
Logging.instance.log(
"Installing default dark theme... finished",
level: LogLevel.Info,
);
// verify current user preference light brightness theme and revert to default
// if problems are found to prevent app being unusable
if (!(await ThemeService.instance
.verifyInstalled(themeId: Prefs.instance.systemBrightnessLightThemeId))) {
Prefs.instance.systemBrightnessLightThemeId = "light";
}
// verify current user preference dark brightness theme and revert to default
// if problems are found to prevent app being unusable
if (!(await ThemeService.instance
.verifyInstalled(themeId: Prefs.instance.systemBrightnessDarkThemeId))) {
Prefs.instance.systemBrightnessDarkThemeId = "dark";
}
runApp(const ProviderScope(child: MyApp()));
@ -306,7 +318,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
}
ref.read(applicationThemesDirectoryPathProvider.notifier).state =
(await StackFileSystem.applicationThemesDirectory()).path;
StackFileSystem.themesDir!.path;
_notificationsService = ref.read(notificationsProvider);
_nodeService = ref.read(nodeServiceChangeNotifierProvider);
@ -401,7 +413,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
WidgetsBinding.instance.addPostFrameCallback((_) async {
//Add themes path to provider
ref.read(applicationThemesDirectoryPathProvider.notifier).state =
(await StackFileSystem.applicationThemesDirectory()).path;
StackFileSystem.themesDir!.path;
ref.read(themeProvider.state).state = ref.read(pThemeService).getTheme(
themeId: themeId,
@ -457,6 +469,12 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
super.dispose();
}
@override
void didChangeLocales(List<Locale>? locales) {
ref.read(localeServiceChangeNotifierProvider).loadLocale();
super.didChangeLocales(locales);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
debugPrint("didChangeAppLifecycleState: ${state.name}");

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:equatable/equatable.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/utilities/amount/amount.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:stackwallet/services/buy/buy.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
class Crypto {
/// Crypto ticker
final String ticker;

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
class Fiat {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/models/buy/response_objects/quote.dart';
class SimplexOrder {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/buy/response_objects/crypto.dart';
import 'package:stackwallet/models/buy/response_objects/fiat.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/buy/response_objects/crypto.dart';
import 'package:stackwallet/models/buy/response_objects/fiat.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/models/contact_address_entry.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:flutter/cupertino.dart';
import 'package:stackwallet/models/isar/models/contact_entry.dart';
import 'package:stackwallet/utilities/address_utils.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:hive/hive.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
part 'type_adaptors/epicbox_server_model.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:tuple/tuple.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:hive/hive.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
import 'package:stackwallet/utilities/logger.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart';

View file

@ -1 +1,11 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
abstract class MBObject {}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/majestic_bank/mb_object.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:decimal/decimal.dart';
class Range {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/utilities/logger.dart';
class SPCurrency {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
part 'pair.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
part 'address_label.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:isar/isar.dart';
@ -123,7 +133,9 @@ enum AddressType {
mimbleWimble,
unknown,
nonWallet,
ethereum;
ethereum,
nano,
banano;
String get readableName {
switch (this) {
@ -143,6 +155,10 @@ enum AddressType {
return "Non wallet/unknown";
case AddressType.ethereum:
return "Ethereum";
case AddressType.nano:
return "Nano";
case AddressType.banano:
return "Banano";
}
}
}

View file

@ -261,6 +261,8 @@ const _AddresstypeEnumValueMap = {
'unknown': 5,
'nonWallet': 6,
'ethereum': 7,
'nano': 8,
'banano': 9,
};
const _AddresstypeValueEnumMap = {
0: AddressType.p2pkh,
@ -271,6 +273,8 @@ const _AddresstypeValueEnumMap = {
5: AddressType.unknown,
6: AddressType.nonWallet,
7: AddressType.ethereum,
8: AddressType.nano,
9: AddressType.banano,
};
Id _addressGetId(Address object) {

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
abstract class CryptoCurrencyAddress {
// future use?
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:isar/isar.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'package:isar/isar.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:convert';
import 'dart:math';
@ -12,6 +22,7 @@ part 'transaction.g.dart';
@Collection()
class Transaction {
Transaction({
required this.walletId,
required this.txid,
@ -29,6 +40,7 @@ class Transaction {
required this.inputs,
required this.outputs,
required this.nonce,
required this.numberOfMessages,
});
Tuple2<Transaction, Address?> copyWith({
@ -50,6 +62,7 @@ class Transaction {
int? nonce,
Id? id,
Address? address,
int? numberOfMessages,
}) {
return Tuple2(
Transaction(
@ -68,7 +81,8 @@ class Transaction {
otherData: otherData ?? this.otherData,
nonce: nonce ?? this.nonce,
inputs: inputs ?? this.inputs,
outputs: outputs ?? this.outputs)
outputs: outputs ?? this.outputs,
numberOfMessages: numberOfMessages ?? this.numberOfMessages)
..id = id ?? this.id,
address ?? this.address.value,
);
@ -114,6 +128,8 @@ class Transaction {
late final List<Output> outputs;
late final int? numberOfMessages;
@Backlink(to: "transactions")
final address = IsarLink<Address>();
@ -154,6 +170,7 @@ class Transaction {
"address: ${address.value}, "
"inputsLength: ${inputs.length}, "
"outputsLength: ${outputs.length}, "
"numberOfMessages: $numberOfMessages, "
"}";
String toJsonString() {
@ -175,6 +192,7 @@ class Transaction {
"address": address.value?.toJsonString(),
"inputs": inputs.map((e) => e.toJsonString()).toList(),
"outputs": outputs.map((e) => e.toJsonString()).toList(),
"numberOfMessages": numberOfMessages,
};
return jsonEncode(result);
}
@ -205,6 +223,7 @@ class Transaction {
outputs: List<String>.from(json["outputs"] as List)
.map((e) => Output.fromJsonString(e))
.toList(),
numberOfMessages: json["numberOfMessages"] as int,
);
if (json["address"] == null) {
return Tuple2(transaction, null);

View file

@ -58,46 +58,51 @@ const TransactionSchema = CollectionSchema(
name: r'nonce',
type: IsarType.long,
),
r'otherData': PropertySchema(
r'numberOfMessages': PropertySchema(
id: 8,
name: r'numberOfMessages',
type: IsarType.long,
),
r'otherData': PropertySchema(
id: 9,
name: r'otherData',
type: IsarType.string,
),
r'outputs': PropertySchema(
id: 9,
id: 10,
name: r'outputs',
type: IsarType.objectList,
target: r'Output',
),
r'slateId': PropertySchema(
id: 10,
id: 11,
name: r'slateId',
type: IsarType.string,
),
r'subType': PropertySchema(
id: 11,
id: 12,
name: r'subType',
type: IsarType.byte,
enumMap: _TransactionsubTypeEnumValueMap,
),
r'timestamp': PropertySchema(
id: 12,
id: 13,
name: r'timestamp',
type: IsarType.long,
),
r'txid': PropertySchema(
id: 13,
id: 14,
name: r'txid',
type: IsarType.string,
),
r'type': PropertySchema(
id: 14,
id: 15,
name: r'type',
type: IsarType.byte,
enumMap: _TransactiontypeEnumValueMap,
),
r'walletId': PropertySchema(
id: 15,
id: 16,
name: r'walletId',
type: IsarType.string,
)
@ -233,19 +238,20 @@ void _transactionSerialize(
writer.writeBool(offsets[5], object.isCancelled);
writer.writeBool(offsets[6], object.isLelantus);
writer.writeLong(offsets[7], object.nonce);
writer.writeString(offsets[8], object.otherData);
writer.writeLong(offsets[8], object.numberOfMessages);
writer.writeString(offsets[9], object.otherData);
writer.writeObjectList<Output>(
offsets[9],
offsets[10],
allOffsets,
OutputSchema.serialize,
object.outputs,
);
writer.writeString(offsets[10], object.slateId);
writer.writeByte(offsets[11], object.subType.index);
writer.writeLong(offsets[12], object.timestamp);
writer.writeString(offsets[13], object.txid);
writer.writeByte(offsets[14], object.type.index);
writer.writeString(offsets[15], object.walletId);
writer.writeString(offsets[11], object.slateId);
writer.writeByte(offsets[12], object.subType.index);
writer.writeLong(offsets[13], object.timestamp);
writer.writeString(offsets[14], object.txid);
writer.writeByte(offsets[15], object.type.index);
writer.writeString(offsets[16], object.walletId);
}
Transaction _transactionDeserialize(
@ -269,23 +275,24 @@ Transaction _transactionDeserialize(
isCancelled: reader.readBool(offsets[5]),
isLelantus: reader.readBoolOrNull(offsets[6]),
nonce: reader.readLongOrNull(offsets[7]),
otherData: reader.readStringOrNull(offsets[8]),
numberOfMessages: reader.readLongOrNull(offsets[8]),
otherData: reader.readStringOrNull(offsets[9]),
outputs: reader.readObjectList<Output>(
offsets[9],
offsets[10],
OutputSchema.deserialize,
allOffsets,
Output(),
) ??
[],
slateId: reader.readStringOrNull(offsets[10]),
slateId: reader.readStringOrNull(offsets[11]),
subType:
_TransactionsubTypeValueEnumMap[reader.readByteOrNull(offsets[11])] ??
_TransactionsubTypeValueEnumMap[reader.readByteOrNull(offsets[12])] ??
TransactionSubType.none,
timestamp: reader.readLong(offsets[12]),
txid: reader.readString(offsets[13]),
type: _TransactiontypeValueEnumMap[reader.readByteOrNull(offsets[14])] ??
timestamp: reader.readLong(offsets[13]),
txid: reader.readString(offsets[14]),
type: _TransactiontypeValueEnumMap[reader.readByteOrNull(offsets[15])] ??
TransactionType.outgoing,
walletId: reader.readString(offsets[15]),
walletId: reader.readString(offsets[16]),
);
object.id = id;
return object;
@ -321,8 +328,10 @@ P _transactionDeserializeProp<P>(
case 7:
return (reader.readLongOrNull(offset)) as P;
case 8:
return (reader.readStringOrNull(offset)) as P;
return (reader.readLongOrNull(offset)) as P;
case 9:
return (reader.readStringOrNull(offset)) as P;
case 10:
return (reader.readObjectList<Output>(
offset,
OutputSchema.deserialize,
@ -330,19 +339,19 @@ P _transactionDeserializeProp<P>(
Output(),
) ??
[]) as P;
case 10:
return (reader.readStringOrNull(offset)) as P;
case 11:
return (reader.readStringOrNull(offset)) as P;
case 12:
return (_TransactionsubTypeValueEnumMap[reader.readByteOrNull(offset)] ??
TransactionSubType.none) as P;
case 12:
return (reader.readLong(offset)) as P;
case 13:
return (reader.readString(offset)) as P;
return (reader.readLong(offset)) as P;
case 14:
return (reader.readString(offset)) as P;
case 15:
return (_TransactiontypeValueEnumMap[reader.readByteOrNull(offset)] ??
TransactionType.outgoing) as P;
case 15:
case 16:
return (reader.readString(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
@ -1374,6 +1383,80 @@ extension TransactionQueryFilter
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'numberOfMessages',
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'numberOfMessages',
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesEqualTo(int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'numberOfMessages',
value: value,
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'numberOfMessages',
value: value,
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'numberOfMessages',
value: value,
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
numberOfMessagesBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'numberOfMessages',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<Transaction, Transaction, QAfterFilterCondition>
otherDataIsNull() {
return QueryBuilder.apply(this, (query) {
@ -2320,6 +2403,20 @@ extension TransactionQuerySortBy
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy>
sortByNumberOfMessages() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'numberOfMessages', Sort.asc);
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy>
sortByNumberOfMessagesDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'numberOfMessages', Sort.desc);
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy> sortByOtherData() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'otherData', Sort.asc);
@ -2504,6 +2601,20 @@ extension TransactionQuerySortThenBy
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy>
thenByNumberOfMessages() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'numberOfMessages', Sort.asc);
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy>
thenByNumberOfMessagesDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'numberOfMessages', Sort.desc);
});
}
QueryBuilder<Transaction, Transaction, QAfterSortBy> thenByOtherData() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'otherData', Sort.asc);
@ -2634,6 +2745,13 @@ extension TransactionQueryWhereDistinct
});
}
QueryBuilder<Transaction, Transaction, QDistinct>
distinctByNumberOfMessages() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'numberOfMessages');
});
}
QueryBuilder<Transaction, Transaction, QDistinct> distinctByOtherData(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
@ -2737,6 +2855,12 @@ extension TransactionQueryProperty
});
}
QueryBuilder<Transaction, int?, QQueryOperations> numberOfMessagesProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'numberOfMessages');
});
}
QueryBuilder<Transaction, String?, QQueryOperations> otherDataProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'otherData');

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:math';
import 'package:isar/isar.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -23,6 +33,22 @@ class ContactEntry {
@Index(unique: true, replace: true)
late final String customId;
@ignore
List<ContactAddressEntry> get addressesSorted {
final List<ContactAddressEntry> sorted = [];
for (final coin in Coin.values) {
final slice = addresses.where((e) => e.coin == coin).toList();
if (slice.isNotEmpty) {
slice.sort(
(a, b) => (a.other ?? a.label).compareTo(b.other ?? b.label),
);
sorted.addAll(slice);
}
}
return sorted;
}
ContactEntry copyWith({
bool shouldCopyEmojiWithNull = false,
String? emojiChar,

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
abstract class Contract {
// for possible future use
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
part 'encrypted_string_value.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/models/contract.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
export 'address_label.dart';
export 'blockchain_data/address.dart';
export 'blockchain_data/input.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
// import 'package:stackwallet/models/isar/type_converters/log_level_converter.dart';
import 'package:stackwallet/utilities/enums/log_level_enum.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:isar/isar.dart';
part 'transaction_note.g.dart';

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
part 'type_adaptors/lelantus_coin.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
class LelantusFeeData {
int changeToMint;
int fee;

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
export 'lelantus_coin.dart';
export 'lelantus_fee_data.dart';
export 'paymint/fee_object_model.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:hive/hive.dart';
part 'type_adaptors/notification_model.g.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
class FeeObject {
final int fast;
final int medium;

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:dart_numerics/dart_numerics.dart';
import 'package:decimal/decimal.dart';
import 'package:hive/hive.dart';
@ -155,6 +165,9 @@ class Transaction {
// @HiveField(18)
final String? otherData;
// @HiveField(16)
final int? numberOfMessages;
Transaction({
required this.txid,
required this.confirmedStatus,
@ -176,6 +189,7 @@ class Transaction {
this.isCancelled = false,
this.slateId,
this.otherData,
this.numberOfMessages,
});
factory Transaction.fromJson(Map<String, dynamic> json) {
@ -211,6 +225,7 @@ class Transaction {
isCancelled: json["isCancelled"] as bool? ?? false,
slateId: json["slateId"] as String?,
otherData: json["otherData"] as String?,
numberOfMessages: json["numberOfMessages"] as int?,
);
}
@ -223,7 +238,7 @@ class Transaction {
txType: json['txType'] as String,
amount: (Decimal.parse(json["amount"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt(),
aliens: [],
@ -231,7 +246,7 @@ class Transaction {
worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0",
fees: (Decimal.parse(json["fees"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt(),
inputSize: json['inputSize'] as int? ?? 0,
@ -269,6 +284,7 @@ class Transaction {
bool? isCancelled,
String? slateId,
String? otherData,
int? numberOfMessages,
}) {
return Transaction(
txid: txid ?? this.txid,
@ -292,13 +308,14 @@ class Transaction {
isCancelled: isCancelled ?? this.isCancelled,
slateId: slateId ?? this.slateId,
otherData: otherData ?? this.otherData,
numberOfMessages: numberOfMessages ?? this.numberOfMessages,
);
}
@override
String toString() {
String transaction =
"{txid: $txid, type: $txType, subType: $subType, value: $amount, fee: $fees, height: $height, confirm: $confirmedStatus, confirmations: $confirmations, address: $address, timestamp: $timestamp, worthNow: $worthNow, inputs: $inputs, slateid: $slateId }";
"{txid: $txid, type: $txType, subType: $subType, value: $amount, fee: $fees, height: $height, confirm: $confirmedStatus, confirmations: $confirmations, address: $address, timestamp: $timestamp, worthNow: $worthNow, inputs: $inputs, slateid: $slateId, numberOfMessages: $numberOfMessages }";
return transaction;
}
}
@ -397,7 +414,7 @@ class Output {
value: (Decimal.parse(
(json["value"] ?? 0).toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt(),
);
@ -410,7 +427,7 @@ class Output {
scriptpubkeyAddress: "",
value: (Decimal.parse(0.toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt());
}

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:dart_numerics/dart_numerics.dart';
import 'package:hive/hive.dart';

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
class CreatedPaynym {
final bool claimed;
final String? nymAvatar;

View file

@ -1,3 +1,13 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
import 'package:stackwallet/models/paynym/paynym_code.dart';

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