Merge branch 'main' into CW-621-Open-external-sites-in-default-browser

This commit is contained in:
Serhii 2024-07-05 12:23:56 +03:00
commit 87d266a7b2
466 changed files with 30584 additions and 11999 deletions

View file

@ -46,6 +46,7 @@ jobs:
/opt/android/cake_wallet/cw_monero/android/.cxx /opt/android/cake_wallet/cw_monero/android/.cxx
/opt/android/cake_wallet/cw_monero/ios/External /opt/android/cake_wallet/cw_monero/ios/External
/opt/android/cake_wallet/cw_shared_external/ios/External /opt/android/cake_wallet/cw_shared_external/ios/External
/opt/android/cake_wallet/scripts/monero_c/release
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }} key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }} - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}

View file

@ -27,18 +27,25 @@ jobs:
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
- name: Free Up GitHub Actions Ubuntu Runner Disk Space - name: Free Disk Space (Ubuntu)
run: | uses: insightsengineering/disk-space-reclaimer@v1
sudo rm -rf /usr/share/dotnet with:
sudo rm -rf /opt/ghc tools-cache: true
sudo rm -rf "/usr/local/share/boost" android: false
sudo rm -rf "$AGENT_TOOLSDIRECTORY" dotnet: true
haskell: true
large-packages: true
swap-storage: true
docker-images: true
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: "11.x" java-version: "11.x"
- name: Configure placeholder git details
run: |
git config --global user.email "CI@cakewallet.com"
git config --global user.name "Cake Github Actions"
- name: Flutter action - name: Flutter action
uses: subosito/flutter-action@v1 uses: subosito/flutter-action@v1
with: with:
@ -72,7 +79,8 @@ jobs:
/opt/android/cake_wallet/cw_monero/android/.cxx /opt/android/cake_wallet/cw_monero/android/.cxx
/opt/android/cake_wallet/cw_monero/ios/External /opt/android/cake_wallet/cw_monero/ios/External
/opt/android/cake_wallet/cw_shared_external/ios/External /opt/android/cake_wallet/cw_shared_external/ios/External
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }} /opt/android/cake_wallet/scripts/monero_c/release
key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }} - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
name: Generate Externals name: Generate Externals
@ -113,6 +121,8 @@ jobs:
touch lib/.secrets.g.dart touch lib/.secrets.g.dart
touch cw_evm/lib/.secrets.g.dart touch cw_evm/lib/.secrets.g.dart
touch cw_solana/lib/.secrets.g.dart touch cw_solana/lib/.secrets.g.dart
touch cw_core/lib/.secrets.g.dart
touch cw_nano/lib/.secrets.g.dart
touch cw_tron/lib/.secrets.g.dart touch cw_tron/lib/.secrets.g.dart
echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
@ -151,9 +161,15 @@ jobs:
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
- name: Rename app - name: Rename app
run: | run: |

8
.gitignore vendored
View file

@ -136,6 +136,7 @@ lib/nano/nano.dart
lib/polygon/polygon.dart lib/polygon/polygon.dart
lib/solana/solana.dart lib/solana/solana.dart
lib/tron/tron.dart lib/tron/tron.dart
lib/wownero/wownero.dart
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png
@ -156,6 +157,7 @@ assets/images/app_logo.png
macos/Runner/Info.plist macos/Runner/Info.plist
macos/Runner/DebugProfile.entitlements macos/Runner/DebugProfile.entitlements
macos/Runner/Release.entitlements macos/Runner/Release.entitlements
macos/Runner/Runner.entitlements
lib/core/secure_storage.dart lib/core/secure_storage.dart
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
@ -166,3 +168,9 @@ macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
macos/Runner/Configs/AppInfo.xcconfig macos/Runner/Configs/AppInfo.xcconfig
# Monero.dart (Monero_C)
scripts/monero_c
# iOS generated framework bin
ios/MoneroWallet.framework/MoneroWallet
ios/WowneroWallet.framework/WowneroWallet

View file

@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project. # This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc. # Used by Flutter tool to assess capabilities and perform upgrades etc.
# #
# This file should be version controlled. # This file should be version controlled and should not be manually edited.
version: version:
revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 revision: "367f9ea16bfae1ca451b9cc27c1366870b187ae2"
channel: stable channel: "stable"
project_type: app project_type: app
@ -13,11 +13,11 @@ project_type: app
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
- platform: macos - platform: windows
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
# User provided section # User provided section

View file

@ -38,7 +38,8 @@
android:fullBackupContent="false" android:fullBackupContent="false"
android:versionCode="__versionCode__" android:versionCode="__versionCode__"
android:versionName="__versionName__" android:versionName="__versionName__"
android:requestLegacyExternalStorage="true"> android:requestLegacyExternalStorage="true"
android:extractNativeLibs="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleInstance" android:launchMode="singleInstance"
@ -90,6 +91,9 @@
<data android:scheme="tron" /> <data android:scheme="tron" />
<data android:scheme="tron-wallet" /> <data android:scheme="tron-wallet" />
<data android:scheme="tron_wallet" /> <data android:scheme="tron_wallet" />
<data android:scheme="wownero" />
<data android:scheme="wownero-wallet" />
<data android:scheme="wownero_wallet" />
</intent-filter> </intent-filter>
<!-- nano-gpt link scheme --> <!-- nano-gpt link scheme -->
<intent-filter android:autoVerify="true"> <intent-filter android:autoVerify="true">

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/monero/aarch64-linux-android_libwallet2_api_c.so

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/wownero/aarch64-linux-android_libwallet2_api_c.so

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/monero/armv7a-linux-androideabi_libwallet2_api_c.so

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/wownero/armv7a-linux-androideabi_libwallet2_api_c.so

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/monero/x86_64-linux-android_libwallet2_api_c.so

View file

@ -0,0 +1 @@
../../../../../../scripts/monero_c/release/wownero/x86_64-linux-android_libwallet2_api_c.so

View file

@ -1,2 +1,8 @@
- -
uri: electrum.cakewallet.com:50002 uri: electrum.cakewallet.com:50002
useSSL: true
-
uri: btc-electrum.cakewallet.com:50002
isDefault: true
-
uri: electrs.cakewallet.com:50001

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View file

@ -1,7 +1,10 @@
-
uri: nano.nownodes.io
useSSL: true
is_default: true
- -
uri: rpc.nano.to uri: rpc.nano.to
useSSL: true useSSL: true
is_default: true
- -
uri: node.nautilus.io uri: node.nautilus.io
path: /api path: /api

View file

@ -1 +1,2 @@
Bug fixes and generic enhancements Monero enhancements
Bug fixes

View file

@ -1,2 +1,2 @@
Bitcoin Silent Payments Monero enhancements
Bug fixes and generic enhancements Bug fixes

View file

@ -1,8 +1,12 @@
- -
uri: tron-rpc.publicnode.com:443 uri: tron-rpc.publicnode.com:443
is_default: true is_default: false
useSSL: true useSSL: true
- -
uri: api.trongrid.io uri: api.trongrid.io
is_default: false is_default: false
useSSL: true useSSL: true
-
uri: trx.nownodes.io
is_default: true
useSSL: true

View file

@ -0,0 +1,12 @@
-
uri: node3.monerodevs.org:34568
is_default: true
useSSL: false
-
uri: node2.monerodevs.org:34568
is_default: false
useSSL: false
-
uri: node.monerodevs.org:34568
is_default: false
useSSL: false

38
build-guide-win.md Normal file
View file

@ -0,0 +1,38 @@
# Building CakeWallet for Windows
## Requirements and Setup
The following are the system requirements to build CakeWallet for your Windows PC.
```
Windows 10 or later (64-bit), x86-64 based
Flutter 3 or above
```
## Building CakeWallet on Windows
These steps will help you configure and execute a build of CakeWallet from its source code.
### 1. Installing Package Dependencies
For build CakeWallet windows application from sources you will be needed to have:
> [Install Flutter]Follow installation guide (https://docs.flutter.dev/get-started/install/windows) and install do not miss to dev tools (install https://docs.flutter.dev/get-started/install/windows/desktop#development-tools) which are required for windows desktop development (need to install Git for Windows and Visual Studio 2022). Then install `Desktop development with C++` packages via GUI Visual Studio 2022, or Visual Studio Build Tools 2022 including: `C++ Build Tools core features`, `C++ 2022 Redistributable Update`, `C++ core desktop features`, `MVC v143 - VS 2022 C++ x64/x86 build tools`, `C++ CMake tools for Windwos`, `Testing tools core features - Build Tools`, `C++ AddressSanitizer`.
> [Install WSL] for building monero dependencies need to install Windows WSL (https://learn.microsoft.com/en-us/windows/wsl/install) and required packages for WSL (Ubuntu):
`$ sudo apt update `
`$ sudo apt build-essential cmake gcc-mingw-w64 g++-mingw-w64 autoconf libtool pkg-config`
### 2. Pull CakeWallet source code
You can downlaod CakeWallet source code from our [GitHub repository](github.com/cake-tech/cake_wallet) via git by following next command:
`$ git clone https://github.com/cake-tech/cake_wallet.git --branch MrCyjaneK-cyjan-monerodart`
OR you can download it as [Zip archive](https://github.com/cake-tech/cake_wallet/archive/refs/heads/MrCyjaneK-cyjan-monerodart.zip)
### 3. Build Monero, Monero_c and their dependencies
For use monero in the application need to build Monero wrapper - Monero_C which will be used by monero.dart package. For that need to run shell (bash - typically same named utility should be available after WSL is enabled in your system) with previously installed WSL, then change current directory to the application project directory with your used shell and then change current directory to `scripts/windows`: `$ cd scripts/windows`. Run build script: `$ ./build_all.sh`.
### 4. Configure and build CakeWallet application
To configure the application open directory where you have downloaded or unarchived CakeWallet sources and run `cakewallet.bat`.
Or if you used WSL and have active shell session you can run `$ ./cakewallet.sh` script in `scripts/windows` which will run `cakewallet.bat` in WSL.
After execution of `cakewallet.bat` you should to get `Cake Wallet.zip` in project root directory which will contains `CakeWallet.exe` file and another needed files for run the application. Now you can extract files from `Cake Wallet.zip` archive and run the application.

51
cakewallet.bat Normal file
View file

@ -0,0 +1,51 @@
@echo off
set cw_win_app_config=--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron
set cw_root=%cd%
set cw_archive_name=Cake Wallet.zip
set cw_archive_path=%cw_root%\%cw_archive_name%
set secrets_file_path=lib\.secrets.g.dart
set release_dir=build\windows\x64\runner\Release
@REM Path could be different
if [%~1]==[] (set tools_root=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.38.33135\x64\Microsoft.VC143.CRT) else (set tools_root=%1)
@REM Generate android manifest file
cd scripts
bash.exe gen_android_manifest.sh
cd /d %cw_root%
echo === Generating pubspec.yaml ===
copy /Y pubspec_description.yaml pubspec.yaml > nul
call flutter pub get > nul
call dart run tool\generate_pubspec.dart
call flutter pub get > nul
call dart run tool\configure.dart %cw_win_app_config%
IF NOT EXIST "%secrets_file_path%" (
echo === Generating new secrets file ===
call dart run tool\generate_new_secrets.dart
) ELSE (echo === Using previously/already generated secrets file: %secrets_file_path% ===)
echo === Generating mobx models ===
for /d %%i in (cw_core cw_monero cw_bitcoin cw_ethereum cw_evm cw_polygon cw_nano cw_bitcoin_cash cw_solana cw_tron .) do (
cd %%i
call flutter pub get > nul
call dart run build_runner build --delete-conflicting-outputs > nul
cd /d %cw_root%
)
echo === Generating localization files ===
call dart run tool\generate_localization.dart
echo === Building the application executable file ===
call flutter build windows --dart-define-from-file=env.json --release
echo === Prepare distribution actions. Copy needed files to the application bundle ===
copy /Y "%tools_root%\msvcp140.dll" "%release_dir%\" > nul
copy /Y "%tools_root%\vcruntime140.dll" "%release_dir%\" > nul
copy /Y "%tools_root%\vcruntime140_1.dll" "%release_dir%\" > nul
echo === Generate the application archive ===
xcopy /s /e /v /Y "%release_dir%\*.*" "build\Cake Wallet\" > nul
tar acf "%cw_archive_name%" -C build\ "Cake Wallet"
echo === Open Explorer with the application archive ===
echo Cake Wallet created archive at: %cw_archive_path%
%SystemRoot%\explorer.exe /select, %cw_archive_path%

View file

@ -1,11 +1,14 @@
#!/bin/bash
IOS="ios" IOS="ios"
ANDROID="android" ANDROID="android"
MACOS="macos"
PLATFORMS=($IOS $ANDROID) PLATFORMS=($IOS $ANDROID $MACOS)
PLATFORM=$1 PLATFORM=$1
if ! [[ " ${PLATFORMS[*]} " =~ " ${PLATFORM} " ]]; then if ! [[ " ${PLATFORMS[*]} " =~ " ${PLATFORM} " ]]; then
echo "specify platform: ./configure_cake_wallet.sh ios|android" echo "specify platform: ./configure_cake_wallet.sh ios|android|macos"
exit 1 exit 1
fi fi
@ -14,6 +17,11 @@ if [ "$PLATFORM" == "$IOS" ]; then
cd scripts/ios cd scripts/ios
fi fi
if [ "$PLATFORM" == "$MACOS" ]; then
echo "Configuring for macOS"
cd scripts/macos
fi
if [ "$PLATFORM" == "$ANDROID" ]; then if [ "$PLATFORM" == "$ANDROID" ]; then
echo "Configuring for Android" echo "Configuring for Android"
cd scripts/android cd scripts/android
@ -22,5 +30,6 @@ fi
source ./app_env.sh cakewallet source ./app_env.sh cakewallet
./app_config.sh ./app_config.sh
cd ../.. && flutter pub get cd ../.. && flutter pub get
flutter packages pub run tool/generate_localization.dart #flutter packages pub run tool/generate_localization.dart
./model_generator.sh ./model_generator.sh
#cd macos && pod install

View file

@ -2,9 +2,9 @@ import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:unorm_dart/unorm_dart.dart' as unorm;
import 'package:cryptography/cryptography.dart' as cryptography; import 'package:cryptography/cryptography.dart' as cryptography;
import 'package:cw_core/sec_random_native.dart'; import 'package:cw_core/sec_random_native.dart';
import 'package:cw_core/utils/text_normalizer.dart';
const segwit = '100'; const segwit = '100';
final wordlist = englishWordlist; final wordlist = englishWordlist;
@ -137,121 +137,6 @@ bool validateMnemonic(String mnemonic, {String prefix = segwit}) {
} }
} }
final COMBININGCODEPOINTS = combiningcodepoints();
List<int> combiningcodepoints() {
final source = '300:34e|350:36f|483:487|591:5bd|5bf|5c1|5c2|5c4|5c5|5c7|610:61a|64b:65f|670|' +
'6d6:6dc|6df:6e4|6e7|6e8|6ea:6ed|711|730:74a|7eb:7f3|816:819|81b:823|825:827|' +
'829:82d|859:85b|8d4:8e1|8e3:8ff|93c|94d|951:954|9bc|9cd|a3c|a4d|abc|acd|b3c|' +
'b4d|bcd|c4d|c55|c56|cbc|ccd|d4d|dca|e38:e3a|e48:e4b|eb8|eb9|ec8:ecb|f18|f19|' +
'f35|f37|f39|f71|f72|f74|f7a:f7d|f80|f82:f84|f86|f87|fc6|1037|1039|103a|108d|' +
'135d:135f|1714|1734|17d2|17dd|18a9|1939:193b|1a17|1a18|1a60|1a75:1a7c|1a7f|' +
'1ab0:1abd|1b34|1b44|1b6b:1b73|1baa|1bab|1be6|1bf2|1bf3|1c37|1cd0:1cd2|' +
'1cd4:1ce0|1ce2:1ce8|1ced|1cf4|1cf8|1cf9|1dc0:1df5|1dfb:1dff|20d0:20dc|20e1|' +
'20e5:20f0|2cef:2cf1|2d7f|2de0:2dff|302a:302f|3099|309a|a66f|a674:a67d|a69e|' +
'a69f|a6f0|a6f1|a806|a8c4|a8e0:a8f1|a92b:a92d|a953|a9b3|a9c0|aab0|aab2:aab4|' +
'aab7|aab8|aabe|aabf|aac1|aaf6|abed|fb1e|fe20:fe2f|101fd|102e0|10376:1037a|' +
'10a0d|10a0f|10a38:10a3a|10a3f|10ae5|10ae6|11046|1107f|110b9|110ba|11100:11102|' +
'11133|11134|11173|111c0|111ca|11235|11236|112e9|112ea|1133c|1134d|11366:1136c|' +
'11370:11374|11442|11446|114c2|114c3|115bf|115c0|1163f|116b6|116b7|1172b|11c3f|' +
'16af0:16af4|16b30:16b36|1bc9e|1d165:1d169|1d16d:1d172|1d17b:1d182|1d185:1d18b|' +
'1d1aa:1d1ad|1d242:1d244|1e000:1e006|1e008:1e018|1e01b:1e021|1e023|1e024|' +
'1e026:1e02a|1e8d0:1e8d6|1e944:1e94a';
return source.split('|').map((e) {
if (e.contains(':')) {
return e.split(':').map((hex) => int.parse(hex, radix: 16));
}
return int.parse(e, radix: 16);
}).fold(<int>[], (List<int> acc, element) {
if (element is List) {
for (var i = element[0] as int; i <= (element[1] as int); i++) {}
} else if (element is int) {
acc.add(element);
}
return acc;
}).toList();
}
String removeCombiningCharacters(String source) {
return source
.split('')
.where((char) => !COMBININGCODEPOINTS.contains(char.codeUnits.first))
.join('');
}
bool isCJK(String char) {
final n = char.codeUnitAt(0);
for (var x in CJKINTERVALS) {
final imin = x[0] as num;
final imax = x[1] as num;
if (n >= imin && n <= imax) return true;
}
return false;
}
String removeCJKSpaces(String source) {
final splitted = source.split('');
final filtered = <String>[];
for (var i = 0; i < splitted.length; i++) {
final char = splitted[i];
final isSpace = char.trim() == '';
final prevIsCJK = i != 0 && isCJK(splitted[i - 1]);
final nextIsCJK = i != splitted.length - 1 && isCJK(splitted[i + 1]);
if (!(isSpace && prevIsCJK && nextIsCJK)) {
filtered.add(char);
}
}
return filtered.join('');
}
String normalizeText(String source) {
final res =
removeCombiningCharacters(unorm.nfkd(source).toLowerCase()).trim().split('/\s+/').join(' ');
return removeCJKSpaces(res);
}
const CJKINTERVALS = [
[0x4e00, 0x9fff, 'CJK Unified Ideographs'],
[0x3400, 0x4dbf, 'CJK Unified Ideographs Extension A'],
[0x20000, 0x2a6df, 'CJK Unified Ideographs Extension B'],
[0x2a700, 0x2b73f, 'CJK Unified Ideographs Extension C'],
[0x2b740, 0x2b81f, 'CJK Unified Ideographs Extension D'],
[0xf900, 0xfaff, 'CJK Compatibility Ideographs'],
[0x2f800, 0x2fa1d, 'CJK Compatibility Ideographs Supplement'],
[0x3190, 0x319f, 'Kanbun'],
[0x2e80, 0x2eff, 'CJK Radicals Supplement'],
[0x2f00, 0x2fdf, 'CJK Radicals'],
[0x31c0, 0x31ef, 'CJK Strokes'],
[0x2ff0, 0x2fff, 'Ideographic Description Characters'],
[0xe0100, 0xe01ef, 'Variation Selectors Supplement'],
[0x3100, 0x312f, 'Bopomofo'],
[0x31a0, 0x31bf, 'Bopomofo Extended'],
[0xff00, 0xffef, 'Halfwidth and Fullwidth Forms'],
[0x3040, 0x309f, 'Hiragana'],
[0x30a0, 0x30ff, 'Katakana'],
[0x31f0, 0x31ff, 'Katakana Phonetic Extensions'],
[0x1b000, 0x1b0ff, 'Kana Supplement'],
[0xac00, 0xd7af, 'Hangul Syllables'],
[0x1100, 0x11ff, 'Hangul Jamo'],
[0xa960, 0xa97f, 'Hangul Jamo Extended A'],
[0xd7b0, 0xd7ff, 'Hangul Jamo Extended B'],
[0x3130, 0x318f, 'Hangul Compatibility Jamo'],
[0xa4d0, 0xa4ff, 'Lisu'],
[0x16f00, 0x16f9f, 'Miao'],
[0xa000, 0xa48f, 'Yi Syllables'],
[0xa490, 0xa4cf, 'Yi Radicals'],
];
final englishWordlist = <String>[ final englishWordlist = <String>[
'abandon', 'abandon',
'ability', 'ability',

View file

@ -6,6 +6,7 @@ import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:convert/convert.dart'; import 'package:convert/convert.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/electrum_wallet.dart';
@ -150,7 +151,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
); );
// set the default if not present: // set the default if not present:
walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? "m/0'/0"; walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? electrum_path;
walletInfo.derivationInfo!.derivationType = snp.derivationType ?? DerivationType.electrum; walletInfo.derivationInfo!.derivationType = snp.derivationType ?? DerivationType.electrum;
Uint8List? seedBytes = null; Uint8List? seedBytes = null;

View file

@ -64,7 +64,7 @@ class ElectrumClient {
await socket?.close(); await socket?.close();
} catch (_) {} } catch (_) {}
if (useSSL == false) { if (useSSL == false || (useSSL == null && uri.toString().contains("btc-electrum"))) {
socket = await Socket.connect(host, port, timeout: connectionTimeout); socket = await Socket.connect(host, port, timeout: connectionTimeout);
} else { } else {
socket = await SecureSocket.connect(host, port, socket = await SecureSocket.connect(host, port,

View file

@ -108,3 +108,6 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
), ),
], ],
}; };
String electrum_path = electrum_derivations[DerivationType.electrum]!.first.derivationPath!;

View file

@ -17,6 +17,7 @@ import 'package:cw_bitcoin/bitcoin_unspent.dart';
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart'; import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
import 'package:cw_bitcoin/electrum.dart'; import 'package:cw_bitcoin/electrum.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/electrum_transaction_history.dart'; import 'package:cw_bitcoin/electrum_transaction_history.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart'; import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart'; import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
@ -96,13 +97,17 @@ abstract class ElectrumWalletBase
this.walletInfo = walletInfo; this.walletInfo = walletInfo;
transactionHistory = ElectrumTransactionHistory(walletInfo: walletInfo, password: password); transactionHistory = ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
reaction((_) => syncStatus, (SyncStatus syncStatus) { reaction((_) => syncStatus, (SyncStatus syncStatus) async {
if (syncStatus is! AttemptingSyncStatus && syncStatus is! SyncedTipSyncStatus) if (syncStatus is! AttemptingSyncStatus && syncStatus is! SyncedTipSyncStatus) {
silentPaymentsScanningActive = syncStatus is SyncingSyncStatus; silentPaymentsScanningActive = syncStatus is SyncingSyncStatus;
}
if (syncStatus is NotConnectedSyncStatus) { if (syncStatus is NotConnectedSyncStatus) {
// Needs to re-subscribe to all scripthashes when reconnected // Needs to re-subscribe to all scripthashes when reconnected
_scripthashesUpdateSubject = {}; _scripthashesUpdateSubject = {};
// TODO: double check this and make sure it doesn't cause any un-necessary calls
// await this.electrumClient.connectToUri(node!.uri, useSSL: node!.useSSL);
} }
// Message is shown on the UI for 3 seconds, revert to synced // Message is shown on the UI for 3 seconds, revert to synced
@ -129,7 +134,7 @@ abstract class ElectrumWalletBase
return currency == CryptoCurrency.bch return currency == CryptoCurrency.bch
? bitcoinCashHDWallet(seedBytes) ? bitcoinCashHDWallet(seedBytes)
: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) : bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
.derivePath(_hardenedDerivationPath(derivationInfo?.derivationPath ?? "m/0'")); .derivePath(_hardenedDerivationPath(derivationInfo?.derivationPath ?? electrum_path));
} }
return bitcoin.HDWallet.fromBase58(xpub!); return bitcoin.HDWallet.fromBase58(xpub!);
@ -197,7 +202,7 @@ abstract class ElectrumWalletBase
bool silentPaymentsScanningActive = false; bool silentPaymentsScanningActive = false;
@action @action
Future<void> setSilentPaymentsScanning(bool active) async { Future<void> setSilentPaymentsScanning(bool active, bool usingElectrs) async {
silentPaymentsScanningActive = active; silentPaymentsScanningActive = active;
if (active) { if (active) {
@ -210,18 +215,22 @@ abstract class ElectrumWalletBase
} }
if (tip > walletInfo.restoreHeight) { if (tip > walletInfo.restoreHeight) {
_setListeners(walletInfo.restoreHeight, chainTipParam: _currentChainTip); _setListeners(
walletInfo.restoreHeight,
chainTipParam: _currentChainTip,
usingElectrs: usingElectrs,
);
} }
} else { } else {
alwaysScan = false; alwaysScan = false;
(await _isolate)?.kill(priority: Isolate.immediate); _isolate?.then((value) => value.kill(priority: Isolate.immediate));
if (electrumClient.isConnected) { if (electrumClient.isConnected) {
syncStatus = SyncedSyncStatus(); syncStatus = SyncedSyncStatus();
} else { } else {
if (electrumClient.uri != null) { if (electrumClient.uri != null) {
await electrumClient.connectToUri(electrumClient.uri!); await electrumClient.connectToUri(electrumClient.uri!, useSSL: electrumClient.useSSL);
startSync(); startSync();
} }
} }
@ -277,7 +286,12 @@ abstract class ElectrumWalletBase
} }
@action @action
Future<void> _setListeners(int height, {int? chainTipParam, bool? doSingleScan}) async { Future<void> _setListeners(
int height, {
int? chainTipParam,
bool? doSingleScan,
bool? usingElectrs,
}) async {
final chainTip = chainTipParam ?? await getUpdatedChainTip(); final chainTip = chainTipParam ?? await getUpdatedChainTip();
if (chainTip == height) { if (chainTip == height) {
@ -303,7 +317,7 @@ abstract class ElectrumWalletBase
chainTip: chainTip, chainTip: chainTip,
electrumClient: ElectrumClient(), electrumClient: ElectrumClient(),
transactionHistoryIds: transactionHistory.transactions.keys.toList(), transactionHistoryIds: transactionHistory.transactions.keys.toList(),
node: ScanNode(node!.uri, node!.useSSL), node: usingElectrs == true ? ScanNode(node!.uri, node!.useSSL) : null,
labels: walletAddresses.labels, labels: walletAddresses.labels,
labelIndexes: walletAddresses.silentAddresses labelIndexes: walletAddresses.silentAddresses
.where((addr) => addr.type == SilentPaymentsAddresType.p2sp && addr.index >= 1) .where((addr) => addr.type == SilentPaymentsAddresType.p2sp && addr.index >= 1)
@ -454,17 +468,7 @@ abstract class ElectrumWalletBase
await electrumClient.close(); await electrumClient.close();
electrumClient.onConnectionStatusChange = (bool? isConnected) async { electrumClient.onConnectionStatusChange = _onConnectionStatusChange;
if (syncStatus is SyncingSyncStatus) return;
if (isConnected == true && syncStatus is! SyncedSyncStatus) {
syncStatus = ConnectedSyncStatus();
} else if (isConnected == false) {
syncStatus = LostConnectionSyncStatus();
} else if (!(isConnected ?? false) && syncStatus is! ConnectingSyncStatus) {
syncStatus = NotConnectedSyncStatus();
}
};
await electrumClient.connectToUri(node.uri, useSSL: node.useSSL); await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
} catch (e) { } catch (e) {
@ -1122,10 +1126,15 @@ abstract class ElectrumWalletBase
@action @action
@override @override
Future<void> rescan( Future<void> rescan({
{required int height, int? chainTip, ScanData? scanData, bool? doSingleScan}) async { required int height,
int? chainTip,
ScanData? scanData,
bool? doSingleScan,
bool? usingElectrs,
}) async {
silentPaymentsScanningActive = true; silentPaymentsScanningActive = true;
_setListeners(height, doSingleScan: doSingleScan); _setListeners(height, doSingleScan: doSingleScan, usingElectrs: usingElectrs);
} }
@override @override
@ -1465,7 +1474,7 @@ abstract class ElectrumWalletBase
time = status["block_time"] as int?; time = status["block_time"] as int?;
final height = status["block_height"] as int? ?? 0; final height = status["block_height"] as int? ?? 0;
final tip = await getCurrentChainTip(); final tip = await getUpdatedChainTip();
if (tip > 0) confirmations = height > 0 ? tip - height + 1 : 0; if (tip > 0) confirmations = height > 0 ? tip - height + 1 : 0;
} else { } else {
final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash); final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
@ -1519,6 +1528,23 @@ abstract class ElectrumWalletBase
await fetchTransactionsForAddressType(historiesWithDetails, SegwitAddresType.p2wpkh); await fetchTransactionsForAddressType(historiesWithDetails, SegwitAddresType.p2wpkh);
} }
transactionHistory.transactions.values.forEach((tx) async {
final isPendingSilentPaymentUtxo =
(tx.isPending || tx.confirmations == 0) && historiesWithDetails[tx.id] == null;
if (isPendingSilentPaymentUtxo) {
final info =
await fetchTransactionInfo(hash: tx.id, height: tx.height, retryOnFailure: true);
if (info != null) {
tx.confirmations = info.confirmations;
tx.isPending = tx.confirmations == 0;
transactionHistory.addOne(tx);
await transactionHistory.save();
}
}
});
return historiesWithDetails; return historiesWithDetails;
} catch (e) { } catch (e) {
print(e.toString()); print(e.toString());
@ -1626,6 +1652,7 @@ abstract class ElectrumWalletBase
if (_isTransactionUpdating) { if (_isTransactionUpdating) {
return; return;
} }
await getCurrentChainTip();
transactionHistory.transactions.values.forEach((tx) async { transactionHistory.transactions.values.forEach((tx) async {
if (tx.unspents != null && tx.unspents!.isNotEmpty && tx.height > 0) { if (tx.unspents != null && tx.unspents!.isNotEmpty && tx.height > 0) {
@ -1790,6 +1817,19 @@ abstract class ElectrumWalletBase
static String _hardenedDerivationPath(String derivationPath) => static String _hardenedDerivationPath(String derivationPath) =>
derivationPath.substring(0, derivationPath.lastIndexOf("'") + 1); derivationPath.substring(0, derivationPath.lastIndexOf("'") + 1);
@action
void _onConnectionStatusChange(bool? isConnected) {
if (syncStatus is SyncingSyncStatus) return;
if (isConnected == true && syncStatus is! SyncedSyncStatus) {
syncStatus = ConnectedSyncStatus();
} else if (isConnected == false) {
syncStatus = LostConnectionSyncStatus();
} else if (isConnected != true && syncStatus is! ConnectingSyncStatus) {
syncStatus = NotConnectedSyncStatus();
}
}
} }
class ScanNode { class ScanNode {
@ -1803,7 +1843,7 @@ class ScanData {
final SendPort sendPort; final SendPort sendPort;
final SilentPaymentOwner silentAddress; final SilentPaymentOwner silentAddress;
final int height; final int height;
final ScanNode node; final ScanNode? node;
final BasedUtxoNetwork network; final BasedUtxoNetwork network;
final int chainTip; final int chainTip;
final ElectrumClient electrumClient; final ElectrumClient electrumClient;
@ -1864,7 +1904,10 @@ Future<void> startRefresh(ScanData scanData) async {
scanData.sendPort.send(SyncResponse(syncHeight, syncingStatus)); scanData.sendPort.send(SyncResponse(syncHeight, syncingStatus));
final electrumClient = scanData.electrumClient; final electrumClient = scanData.electrumClient;
await electrumClient.connectToUri(scanData.node.uri, useSSL: scanData.node.useSSL); await electrumClient.connectToUri(
scanData.node?.uri ?? Uri.parse("tcp://electrs.cakewallet.com:50001"),
useSSL: scanData.node?.useSSL ?? false,
);
if (tweaksSubscription == null) { if (tweaksSubscription == null) {
final count = scanData.isSingleScan ? 1 : TWEAKS_COUNT; final count = scanData.isSingleScan ? 1 : TWEAKS_COUNT;

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/utils/file.dart'; import 'package:cw_core/utils/file.dart';
@ -71,7 +72,7 @@ class ElectrumWalletSnapshot {
final derivationType = DerivationType final derivationType = DerivationType
.values[(data['derivationTypeIndex'] as int?) ?? DerivationType.electrum.index]; .values[(data['derivationTypeIndex'] as int?) ?? DerivationType.electrum.index];
final derivationPath = data['derivationPath'] as String? ?? "m/0'/0"; final derivationPath = data['derivationPath'] as String? ?? electrum_path;
try { try {
regularAddressIndexByType = { regularAddressIndexByType = {

View file

@ -5,58 +5,64 @@ import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData; import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
import 'package:hex/hex.dart'; import 'package:hex/hex.dart';
bitcoin.PaymentData generatePaymentData({required bitcoin.HDWallet hd, int? index}) { bitcoin.PaymentData generatePaymentData({
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; required bitcoin.HDWallet hd,
required int index,
}) {
final pubKey = hd.derive(index).pubKey!;
return PaymentData(pubkey: Uint8List.fromList(HEX.decode(pubKey))); return PaymentData(pubkey: Uint8List.fromList(HEX.decode(pubKey)));
} }
ECPrivate generateECPrivate( ECPrivate generateECPrivate({
{required bitcoin.HDWallet hd, required BasedUtxoNetwork network, int? index}) { required bitcoin.HDWallet hd,
final wif = index != null ? hd.derive(index).wif! : hd.wif!; required BasedUtxoNetwork network,
required int index,
}) {
final wif = hd.derive(index).wif!;
return ECPrivate.fromWif(wif, netVersion: network.wifNetVer); return ECPrivate.fromWif(wif, netVersion: network.wifNetVer);
} }
String generateP2WPKHAddress({ String generateP2WPKHAddress({
required bitcoin.HDWallet hd, required bitcoin.HDWallet hd,
required BasedUtxoNetwork network, required BasedUtxoNetwork network,
int? index, required int index,
}) { }) {
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; final pubKey = hd.derive(index).pubKey!;
return ECPublic.fromHex(pubKey).toP2wpkhAddress().toAddress(network); return ECPublic.fromHex(pubKey).toP2wpkhAddress().toAddress(network);
} }
String generateP2SHAddress({ String generateP2SHAddress({
required bitcoin.HDWallet hd, required bitcoin.HDWallet hd,
required BasedUtxoNetwork network, required BasedUtxoNetwork network,
int? index, required int index,
}) { }) {
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; final pubKey = hd.derive(index).pubKey!;
return ECPublic.fromHex(pubKey).toP2wpkhInP2sh().toAddress(network); return ECPublic.fromHex(pubKey).toP2wpkhInP2sh().toAddress(network);
} }
String generateP2WSHAddress({ String generateP2WSHAddress({
required bitcoin.HDWallet hd, required bitcoin.HDWallet hd,
required BasedUtxoNetwork network, required BasedUtxoNetwork network,
int? index, required int index,
}) { }) {
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; final pubKey = hd.derive(index).pubKey!;
return ECPublic.fromHex(pubKey).toP2wshAddress().toAddress(network); return ECPublic.fromHex(pubKey).toP2wshAddress().toAddress(network);
} }
String generateP2PKHAddress({ String generateP2PKHAddress({
required bitcoin.HDWallet hd, required bitcoin.HDWallet hd,
required BasedUtxoNetwork network, required BasedUtxoNetwork network,
int? index, required int index,
}) { }) {
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; final pubKey = hd.derive(index).pubKey!;
return ECPublic.fromHex(pubKey).toP2pkhAddress().toAddress(network); return ECPublic.fromHex(pubKey).toP2pkhAddress().toAddress(network);
} }
String generateP2TRAddress({ String generateP2TRAddress({
required bitcoin.HDWallet hd, required bitcoin.HDWallet hd,
required BasedUtxoNetwork network, required BasedUtxoNetwork network,
int? index, required int index,
}) { }) {
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!; final pubKey = hd.derive(index).pubKey!;
return ECPublic.fromHex(pubKey).toTaprootAddress().toAddress(network); return ECPublic.fromHex(pubKey).toTaprootAddress().toAddress(network);
} }

View file

@ -793,8 +793,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "sp_v1.0.0" ref: "sp_v2.0.0"
resolved-ref: a9a4c6d051f37a15a3a52cc2a0094f24c68b62c5 resolved-ref: "62c152b9086cd968019128845371072f7e1168de"
url: "https://github.com/cake-tech/sp_scanner" url: "https://github.com/cake-tech/sp_scanner"
source: git source: git
version: "0.0.1" version: "0.0.1"
@ -863,7 +863,7 @@ packages:
source: hosted source: hosted
version: "1.3.2" version: "1.3.2"
unorm_dart: unorm_dart:
dependency: "direct main" dependency: transitive
description: description:
name: unorm_dart name: unorm_dart
sha256: "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b" sha256: "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b"

View file

@ -28,7 +28,6 @@ dependencies:
url: https://github.com/cake-tech/bitbox-flutter.git url: https://github.com/cake-tech/bitbox-flutter.git
ref: Add-Support-For-OP-Return-data ref: Add-Support-For-OP-Return-data
rxdart: ^0.27.5 rxdart: ^0.27.5
unorm_dart: ^0.2.0
cryptography: ^2.0.5 cryptography: ^2.0.5
bitcoin_base: bitcoin_base:
git: git:

View file

@ -4,10 +4,8 @@ import 'package:cw_core/crypto_currency.dart';
class AmountConverter { class AmountConverter {
static const _moneroAmountLength = 12; static const _moneroAmountLength = 12;
static const _moneroAmountDivider = 1000000000000; static const _moneroAmountDivider = 1000000000000;
static const _litecoinAmountDivider = 100000000; static const _wowneroAmountLength = 11;
static const _ethereumAmountDivider = 1000000000000000000; static const _wowneroAmountDivider = 100000000000;
static const _dashAmountDivider = 100000000;
static const _bitcoinCashAmountDivider = 100000000;
static const _bitcoinAmountDivider = 100000000; static const _bitcoinAmountDivider = 100000000;
static const _bitcoinAmountLength = 8; static const _bitcoinAmountLength = 8;
static final _bitcoinAmountFormat = NumberFormat() static final _bitcoinAmountFormat = NumberFormat()
@ -16,69 +14,16 @@ class AmountConverter {
static final _moneroAmountFormat = NumberFormat() static final _moneroAmountFormat = NumberFormat()
..maximumFractionDigits = _moneroAmountLength ..maximumFractionDigits = _moneroAmountLength
..minimumFractionDigits = 1; ..minimumFractionDigits = 1;
static final _wowneroAmountFormat = NumberFormat()
static double amountIntToDouble(CryptoCurrency cryptoCurrency, int amount) { ..maximumFractionDigits = _wowneroAmountLength
switch (cryptoCurrency) { ..minimumFractionDigits = 1;
case CryptoCurrency.xmr:
return _moneroAmountToDouble(amount);
case CryptoCurrency.btc:
return _bitcoinAmountToDouble(amount);
case CryptoCurrency.bch:
return _bitcoinCashAmountToDouble(amount);
case CryptoCurrency.dash:
return _dashAmountToDouble(amount);
case CryptoCurrency.eth:
return _ethereumAmountToDouble(amount);
case CryptoCurrency.ltc:
return _litecoinAmountToDouble(amount);
case CryptoCurrency.xhv:
case CryptoCurrency.xag:
case CryptoCurrency.xau:
case CryptoCurrency.xaud:
case CryptoCurrency.xbtc:
case CryptoCurrency.xcad:
case CryptoCurrency.xchf:
case CryptoCurrency.xcny:
case CryptoCurrency.xeur:
case CryptoCurrency.xgbp:
case CryptoCurrency.xjpy:
case CryptoCurrency.xnok:
case CryptoCurrency.xnzd:
case CryptoCurrency.xusd:
return _moneroAmountToDouble(amount);
default:
return 0.0;
}
}
static int amountStringToInt(CryptoCurrency cryptoCurrency, String amount) {
switch (cryptoCurrency) {
case CryptoCurrency.xmr:
return _moneroParseAmount(amount);
case CryptoCurrency.xhv:
case CryptoCurrency.xag:
case CryptoCurrency.xau:
case CryptoCurrency.xaud:
case CryptoCurrency.xbtc:
case CryptoCurrency.xcad:
case CryptoCurrency.xchf:
case CryptoCurrency.xcny:
case CryptoCurrency.xeur:
case CryptoCurrency.xgbp:
case CryptoCurrency.xjpy:
case CryptoCurrency.xnok:
case CryptoCurrency.xnzd:
case CryptoCurrency.xusd:
return _moneroParseAmount(amount);
default:
return 0;
}
}
static String amountIntToString(CryptoCurrency cryptoCurrency, int amount) { static String amountIntToString(CryptoCurrency cryptoCurrency, int amount) {
switch (cryptoCurrency) { switch (cryptoCurrency) {
case CryptoCurrency.xmr: case CryptoCurrency.xmr:
return _moneroAmountToString(amount); return _moneroAmountToString(amount);
case CryptoCurrency.wow:
return _wowneroAmountToString(amount);
case CryptoCurrency.btc: case CryptoCurrency.btc:
case CryptoCurrency.bch: case CryptoCurrency.bch:
case CryptoCurrency.ltc: case CryptoCurrency.ltc:
@ -106,34 +51,12 @@ class AmountConverter {
static double cryptoAmountToDouble({required num amount, required num divider}) => static double cryptoAmountToDouble({required num amount, required num divider}) =>
amount / divider; amount / divider;
static String _moneroAmountToString(int amount) => _moneroAmountFormat.format( static String _moneroAmountToString(int amount) => _moneroAmountFormat
cryptoAmountToDouble(amount: amount, divider: _moneroAmountDivider)); .format(cryptoAmountToDouble(amount: amount, divider: _moneroAmountDivider));
static double _moneroAmountToDouble(int amount) => static String _bitcoinAmountToString(int amount) => _bitcoinAmountFormat
cryptoAmountToDouble(amount: amount, divider: _moneroAmountDivider); .format(cryptoAmountToDouble(amount: amount, divider: _bitcoinAmountDivider));
static int _moneroParseAmount(String amount) => static String _wowneroAmountToString(int amount) => _wowneroAmountFormat
_moneroAmountFormat.parse(amount).toInt(); .format(cryptoAmountToDouble(amount: amount, divider: _wowneroAmountDivider));
static String _bitcoinAmountToString(int amount) =>
_bitcoinAmountFormat.format(
cryptoAmountToDouble(amount: amount, divider: _bitcoinAmountDivider));
static double _bitcoinAmountToDouble(int amount) =>
cryptoAmountToDouble(amount: amount, divider: _bitcoinAmountDivider);
static int _doubleToBitcoinAmount(double amount) =>
(amount * _bitcoinAmountDivider).toInt();
static double _bitcoinCashAmountToDouble(int amount) =>
cryptoAmountToDouble(amount: amount, divider: _bitcoinCashAmountDivider);
static double _dashAmountToDouble(int amount) =>
cryptoAmountToDouble(amount: amount, divider: _dashAmountDivider);
static double _ethereumAmountToDouble(num amount) =>
cryptoAmountToDouble(amount: amount, divider: _ethereumAmountDivider);
static double _litecoinAmountToDouble(int amount) =>
cryptoAmountToDouble(amount: amount, divider: _litecoinAmountDivider);
} }

View file

@ -105,6 +105,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.usdtSol, CryptoCurrency.usdtSol,
CryptoCurrency.usdcTrc20, CryptoCurrency.usdcTrc20,
CryptoCurrency.tbtc, CryptoCurrency.tbtc,
CryptoCurrency.wow,
]; ];
static const havenCurrencies = [ static const havenCurrencies = [
@ -221,6 +222,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'USDT Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/usdt_icon.png', decimals: 6); static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'USDT Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/usdt_icon.png', decimals: 6);
static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6); static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6);
static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8); static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8);
static const wow = CryptoCurrency(title: 'WOW', fullName: 'Wownero', raw: 94, name: 'wow', iconPath: 'assets/images/wownero_icon.png', decimals: 11);
static final Map<int, CryptoCurrency> _rawCurrencyMap = static final Map<int, CryptoCurrency> _rawCurrencyMap =

View file

@ -28,7 +28,9 @@ CryptoCurrency currencyForWalletType(WalletType type, {bool? isTestnet}) {
return CryptoCurrency.sol; return CryptoCurrency.sol;
case WalletType.tron: case WalletType.tron:
return CryptoCurrency.trx; return CryptoCurrency.trx;
default: case WalletType.wownero:
return CryptoCurrency.wow;
case WalletType.none:
throw Exception( throw Exception(
'Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType'); 'Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
} }

View file

@ -245,6 +245,7 @@ Future<int> getHavenCurrentHeight() async {
// Data taken from https://timechaincalendar.com/ // Data taken from https://timechaincalendar.com/
const bitcoinDates = { const bitcoinDates = {
"2024-06": 846005,
"2024-05": 841590, "2024-05": 841590,
"2024-04": 837182, "2024-04": 837182,
"2024-03": 832623, "2024-03": 832623,
@ -296,3 +297,81 @@ DateTime getDateByBitcoinHeight(int height) {
return estimatedDate; return estimatedDate;
} }
// TODO: enhance all of this global const lists
const wowDates = {
"2023-12": 583048,
"2023-11": 575048,
"2023-10": 566048,
"2023-09": 558048,
"2023-08": 549048,
"2023-07": 540048,
"2023-06": 532048,
"2023-05": 523048,
"2023-04": 514048,
"2023-03": 505048,
"2023-02": 497048,
"2023-01": 488048,
"2022-12": 479048,
"2022-11": 471048,
"2022-10": 462048,
"2022-09": 453048,
"2022-08": 444048,
"2022-07": 435048,
"2022-06": 427048,
"2022-05": 418048,
"2022-04": 410048,
"2022-03": 401048,
"2022-02": 393048,
"2022-01": 384048,
"2021-12": 375048,
"2021-11": 367048,
"2021-10": 358048,
"2021-09": 349048,
"2021-08": 340048,
"2021-07": 331048,
"2021-06": 322048,
"2021-05": 313048,
"2021-04": 305048,
"2021-03": 295048,
"2021-02": 287048,
"2021-01": 279148,
"2020-10": 252000,
"2020-09": 243000,
"2020-08": 234000,
"2020-07": 225000,
"2020-06": 217500,
"2020-05": 208500,
"2020-04": 199500,
"2020-03": 190500,
"2020-02": 183000,
"2020-01": 174000,
"2019-12": 165000,
"2019-11": 156000,
"2019-10": 147000,
"2019-09": 138000,
"2019-08": 129000,
"2019-07": 120000,
"2019-06": 112500,
"2019-05": 103500,
"2019-04": 94500,
"2019-03": 85500,
"2019-02": 79500,
"2019-01": 73500,
"2018-12": 67500,
"2018-11": 61500,
"2018-10": 52500,
"2018-09": 45000,
"2018-08": 36000,
"2018-07": 27000,
"2018-06": 18000,
"2018-05": 9000,
"2018-04": 1
};
int getWowneroHeightByDate({required DateTime date}) {
String closestKey =
wowDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
return wowDates[closestKey] ?? 0;
}

View file

@ -6,6 +6,7 @@ import 'package:hive/hive.dart';
import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:http/io_client.dart' as ioc; import 'package:http/io_client.dart' as ioc;
// import 'package:tor/tor.dart'; // import 'package:tor/tor.dart';
part 'node.g.dart'; part 'node.g.dart';
@ -79,6 +80,7 @@ class Node extends HiveObject with Keyable {
switch (type) { switch (type) {
case WalletType.monero: case WalletType.monero:
case WalletType.haven: case WalletType.haven:
case WalletType.wownero:
return Uri.http(uriRaw, ''); return Uri.http(uriRaw, '');
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
@ -96,7 +98,7 @@ class Node extends HiveObject with Keyable {
case WalletType.solana: case WalletType.solana:
case WalletType.tron: case WalletType.tron:
return Uri.https(uriRaw, path ?? ''); return Uri.https(uriRaw, path ?? '');
default: case WalletType.none:
throw Exception('Unexpected type ${type.toString()} for Node uri'); throw Exception('Unexpected type ${type.toString()} for Node uri');
} }
} }
@ -143,10 +145,10 @@ class Node extends HiveObject with Keyable {
switch (type) { switch (type) {
case WalletType.monero: case WalletType.monero:
case WalletType.haven: case WalletType.haven:
case WalletType.wownero:
return requestMoneroNode(); return requestMoneroNode();
case WalletType.nano: case WalletType.nano:
case WalletType.banano: case WalletType.banano:
return requestNanoNode();
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
@ -155,7 +157,7 @@ class Node extends HiveObject with Keyable {
case WalletType.solana: case WalletType.solana:
case WalletType.tron: case WalletType.tron:
return requestElectrumServer(); return requestElectrumServer();
default: case WalletType.none:
return false; return false;
} }
} catch (_) { } catch (_) {
@ -201,23 +203,6 @@ class Node extends HiveObject with Keyable {
} }
} }
Future<bool> requestNanoNode() async {
http.Response response = await http.post(
uri,
headers: {'Content-type': 'application/json'},
body: json.encode(
{
"action": "block_count",
},
),
);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
Future<bool> requestNodeWithProxy() async { Future<bool> requestNodeWithProxy() async {
if (!isValidProxyAddress /* && !Tor.instance.enabled*/) { if (!isValidProxyAddress /* && !Tor.instance.enabled*/) {
return false; return false;

View file

@ -1,9 +1,10 @@
import 'dart:io'; import 'dart:io';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
Future<String> pathForWalletDir({required String name, required WalletType type}) async { Future<String> pathForWalletDir({required String name, required WalletType type}) async {
final root = await getApplicationDocumentsDirectory(); final root = await getAppDir();
final prefix = walletTypeToString(type).toLowerCase(); final prefix = walletTypeToString(type).toLowerCase();
final walletsDir = Directory('${root.path}/wallets'); final walletsDir = Directory('${root.path}/wallets');
final walletDire = Directory('${walletsDir.path}/$prefix/$name'); final walletDire = Directory('${walletsDir.path}/$prefix/$name');
@ -20,7 +21,7 @@ Future<String> pathForWallet({required String name, required WalletType type}) a
.then((path) => path + '/$name'); .then((path) => path + '/$name');
Future<String> outdatedAndroidPathForWalletDir({required String name}) async { Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
final directory = await getApplicationDocumentsDirectory(); final directory = await getAppDir();
final pathDir = directory.path + '/$name'; final pathDir = directory.path + '/$name';
return pathDir; return pathDir;

35
cw_core/lib/root_dir.dart Normal file
View file

@ -0,0 +1,35 @@
import 'dart:io';
import 'package:path_provider/path_provider.dart';
String? _rootDirPath;
void setRootDirFromEnv() => _rootDirPath = Platform.environment['CAKE_WALLET_DIR'];
Future<Directory> getAppDir({String appName = 'cake_wallet'}) async {
Directory dir;
if (_rootDirPath != null && _rootDirPath!.isNotEmpty) {
dir = Directory.fromUri(Uri.file(_rootDirPath!));
dir.create(recursive: true);
} else {
if (Platform.isWindows) {
dir = await getApplicationSupportDirectory();
} else if (Platform.isLinux) {
String appDirPath;
try {
dir = await getApplicationDocumentsDirectory();
appDirPath = '${dir.path}/$appName';
} catch (e) {
appDirPath = '/home/${Platform.environment['USER']}/.$appName';
}
dir = Directory.fromUri(Uri.file(appDirPath));
await dir.create(recursive: true);
} else {
dir = await getApplicationDocumentsDirectory();
}
}
return dir;
}

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -6,6 +8,12 @@ const utils = const MethodChannel('com.cake_wallet/native_utils');
Future<Uint8List> secRandom(int count) async { Future<Uint8List> secRandom(int count) async {
try { try {
if (Platform.isWindows || Platform.isLinux) {
// Used method to get securely generated random bytes from cake backups
const byteSize = 256;
final rng = Random.secure();
return Uint8List.fromList(List<int>.generate(count, (_) => rng.nextInt(byteSize)));
}
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]); return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
} on PlatformException catch (_) { } on PlatformException catch (_) {
return Uint8List.fromList([]); return Uint8List.fromList([]);

View file

@ -16,6 +16,7 @@ abstract class TransactionInfo extends Object with Keyable {
void changeFiatAmount(String amount); void changeFiatAmount(String amount);
String? to; String? to;
String? from; String? from;
String? evmSignatureName;
List<String>? inputAddresses; List<String>? inputAddresses;
List<String>? outputAddresses; List<String>? outputAddresses;

View file

@ -0,0 +1,117 @@
import 'package:unorm_dart/unorm_dart.dart' as unorm;
const CJKINTERVALS = [
[0x4e00, 0x9fff, 'CJK Unified Ideographs'],
[0x3400, 0x4dbf, 'CJK Unified Ideographs Extension A'],
[0x20000, 0x2a6df, 'CJK Unified Ideographs Extension B'],
[0x2a700, 0x2b73f, 'CJK Unified Ideographs Extension C'],
[0x2b740, 0x2b81f, 'CJK Unified Ideographs Extension D'],
[0xf900, 0xfaff, 'CJK Compatibility Ideographs'],
[0x2f800, 0x2fa1d, 'CJK Compatibility Ideographs Supplement'],
[0x3190, 0x319f, 'Kanbun'],
[0x2e80, 0x2eff, 'CJK Radicals Supplement'],
[0x2f00, 0x2fdf, 'CJK Radicals'],
[0x31c0, 0x31ef, 'CJK Strokes'],
[0x2ff0, 0x2fff, 'Ideographic Description Characters'],
[0xe0100, 0xe01ef, 'Variation Selectors Supplement'],
[0x3100, 0x312f, 'Bopomofo'],
[0x31a0, 0x31bf, 'Bopomofo Extended'],
[0xff00, 0xffef, 'Halfwidth and Fullwidth Forms'],
[0x3040, 0x309f, 'Hiragana'],
[0x30a0, 0x30ff, 'Katakana'],
[0x31f0, 0x31ff, 'Katakana Phonetic Extensions'],
[0x1b000, 0x1b0ff, 'Kana Supplement'],
[0xac00, 0xd7af, 'Hangul Syllables'],
[0x1100, 0x11ff, 'Hangul Jamo'],
[0xa960, 0xa97f, 'Hangul Jamo Extended A'],
[0xd7b0, 0xd7ff, 'Hangul Jamo Extended B'],
[0x3130, 0x318f, 'Hangul Compatibility Jamo'],
[0xa4d0, 0xa4ff, 'Lisu'],
[0x16f00, 0x16f9f, 'Miao'],
[0xa000, 0xa48f, 'Yi Syllables'],
[0xa490, 0xa4cf, 'Yi Radicals'],
];
final COMBININGCODEPOINTS = combiningcodepoints();
List<int> combiningcodepoints() {
final source = '300:34e|350:36f|483:487|591:5bd|5bf|5c1|5c2|5c4|5c5|5c7|610:61a|64b:65f|670|' +
'6d6:6dc|6df:6e4|6e7|6e8|6ea:6ed|711|730:74a|7eb:7f3|816:819|81b:823|825:827|' +
'829:82d|859:85b|8d4:8e1|8e3:8ff|93c|94d|951:954|9bc|9cd|a3c|a4d|abc|acd|b3c|' +
'b4d|bcd|c4d|c55|c56|cbc|ccd|d4d|dca|e38:e3a|e48:e4b|eb8|eb9|ec8:ecb|f18|f19|' +
'f35|f37|f39|f71|f72|f74|f7a:f7d|f80|f82:f84|f86|f87|fc6|1037|1039|103a|108d|' +
'135d:135f|1714|1734|17d2|17dd|18a9|1939:193b|1a17|1a18|1a60|1a75:1a7c|1a7f|' +
'1ab0:1abd|1b34|1b44|1b6b:1b73|1baa|1bab|1be6|1bf2|1bf3|1c37|1cd0:1cd2|' +
'1cd4:1ce0|1ce2:1ce8|1ced|1cf4|1cf8|1cf9|1dc0:1df5|1dfb:1dff|20d0:20dc|20e1|' +
'20e5:20f0|2cef:2cf1|2d7f|2de0:2dff|302a:302f|3099|309a|a66f|a674:a67d|a69e|' +
'a69f|a6f0|a6f1|a806|a8c4|a8e0:a8f1|a92b:a92d|a953|a9b3|a9c0|aab0|aab2:aab4|' +
'aab7|aab8|aabe|aabf|aac1|aaf6|abed|fb1e|fe20:fe2f|101fd|102e0|10376:1037a|' +
'10a0d|10a0f|10a38:10a3a|10a3f|10ae5|10ae6|11046|1107f|110b9|110ba|11100:11102|' +
'11133|11134|11173|111c0|111ca|11235|11236|112e9|112ea|1133c|1134d|11366:1136c|' +
'11370:11374|11442|11446|114c2|114c3|115bf|115c0|1163f|116b6|116b7|1172b|11c3f|' +
'16af0:16af4|16b30:16b36|1bc9e|1d165:1d169|1d16d:1d172|1d17b:1d182|1d185:1d18b|' +
'1d1aa:1d1ad|1d242:1d244|1e000:1e006|1e008:1e018|1e01b:1e021|1e023|1e024|' +
'1e026:1e02a|1e8d0:1e8d6|1e944:1e94a';
return source.split('|').map((e) {
if (e.contains(':')) {
return e.split(':').map((hex) => int.parse(hex, radix: 16));
}
return int.parse(e, radix: 16);
}).fold(<int>[], (List<int> acc, element) {
if (element is List) {
for (var i = element[0] as int; i <= (element[1] as int); i++) {}
} else if (element is int) {
acc.add(element);
}
return acc;
}).toList();
}
String _removeCombiningCharacters(String source) {
return source
.split('')
.where((char) => !COMBININGCODEPOINTS.contains(char.codeUnits.first))
.join('');
}
String _removeCJKSpaces(String source) {
final splitted = source.split('');
final filtered = <String>[];
for (var i = 0; i < splitted.length; i++) {
final char = splitted[i];
final isSpace = char.trim() == '';
final prevIsCJK = i != 0 && _isCJK(splitted[i - 1]);
final nextIsCJK = i != splitted.length - 1 && _isCJK(splitted[i + 1]);
if (!(isSpace && prevIsCJK && nextIsCJK)) {
filtered.add(char);
}
}
return filtered.join('');
}
bool _isCJK(String char) {
final n = char.codeUnitAt(0);
for (var x in CJKINTERVALS) {
final imin = x[0] as num;
final imax = x[1] as num;
if (n >= imin && n <= imax) return true;
}
return false;
}
/// This method normalize text which transforms Unicode text into an equivalent decomposed form, allowing for easier sorting and searching of text.
String normalizeText(String source) {
final res =
_removeCombiningCharacters(unorm.nfkd(source).toLowerCase()).trim().split('/\s+/').join(' ');
return _removeCJKSpaces(res);
}

View file

@ -54,7 +54,10 @@ enum WalletType {
solana, solana,
@HiveField(11) @HiveField(11)
tron tron,
@HiveField(12)
wownero,
} }
int serializeToInt(WalletType type) { int serializeToInt(WalletType type) {
@ -81,7 +84,9 @@ int serializeToInt(WalletType type) {
return 9; return 9;
case WalletType.tron: case WalletType.tron:
return 10; return 10;
default: case WalletType.wownero:
return 11;
case WalletType.none:
return -1; return -1;
} }
} }
@ -110,6 +115,8 @@ WalletType deserializeFromInt(int raw) {
return WalletType.solana; return WalletType.solana;
case 10: case 10:
return WalletType.tron; return WalletType.tron;
case 11:
return WalletType.wownero;
default: default:
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt'); throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
} }
@ -139,7 +146,9 @@ String walletTypeToString(WalletType type) {
return 'Solana'; return 'Solana';
case WalletType.tron: case WalletType.tron:
return 'Tron'; return 'Tron';
default: case WalletType.wownero:
return 'Wownero';
case WalletType.none:
return ''; return '';
} }
} }
@ -168,7 +177,9 @@ String walletTypeToDisplayName(WalletType type) {
return 'Solana (SOL)'; return 'Solana (SOL)';
case WalletType.tron: case WalletType.tron:
return 'Tron (TRX)'; return 'Tron (TRX)';
default: case WalletType.wownero:
return 'Wownero (WOW)';
case WalletType.none:
return ''; return '';
} }
} }
@ -200,7 +211,9 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
return CryptoCurrency.sol; return CryptoCurrency.sol;
case WalletType.tron: case WalletType.tron:
return CryptoCurrency.trx; return CryptoCurrency.trx;
default: case WalletType.wownero:
return CryptoCurrency.wow;
case WalletType.none:
throw Exception( throw Exception(
'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency'); 'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
} }

View file

@ -0,0 +1,18 @@
import 'package:intl/intl.dart';
import 'package:cw_core/crypto_amount_format.dart';
const wowneroAmountLength = 11;
const wowneroAmountDivider = 100000000000;
final wowneroAmountFormat = NumberFormat()
..maximumFractionDigits = wowneroAmountLength
..minimumFractionDigits = 1;
String wowneroAmountToString({required int amount}) => wowneroAmountFormat
.format(cryptoAmountToDouble(amount: amount, divider: wowneroAmountDivider))
.replaceAll(',', '');
double wowneroAmountToDouble({required int amount}) =>
cryptoAmountToDouble(amount: amount, divider: wowneroAmountDivider);
int wowneroParseAmount({required String amount}) =>
(double.parse(amount) * wowneroAmountDivider).round();

View file

@ -0,0 +1,38 @@
import 'package:cw_core/balance.dart';
import 'package:cw_core/wownero_amount_format.dart';
class WowneroBalance extends Balance {
WowneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
: formattedFullBalance = wowneroAmountToString(amount: fullBalance),
formattedUnlockedBalance = wowneroAmountToString(amount: unlockedBalance - frozenBalance),
formattedLockedBalance =
wowneroAmountToString(amount: frozenBalance + fullBalance - unlockedBalance),
super(unlockedBalance, fullBalance);
WowneroBalance.fromString(
{required this.formattedFullBalance,
required this.formattedUnlockedBalance,
this.formattedLockedBalance = '0.0'})
: fullBalance = wowneroParseAmount(amount: formattedFullBalance),
unlockedBalance = wowneroParseAmount(amount: formattedUnlockedBalance),
frozenBalance = wowneroParseAmount(amount: formattedLockedBalance),
super(wowneroParseAmount(amount: formattedUnlockedBalance),
wowneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
final int frozenBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
final String formattedLockedBalance;
@override
String get formattedUnAvailableBalance =>
formattedLockedBalance == '0.0' ? '' : formattedLockedBalance;
@override
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
}

View file

@ -656,6 +656,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.3.2"
unorm_dart:
dependency: "direct main"
description:
name: unorm_dart
sha256: "23d8bf65605401a6a32cff99435fed66ef3dab3ddcad3454059165df46496a3b"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:

View file

@ -20,6 +20,7 @@ dependencies:
intl: ^0.18.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
socks5_proxy: ^1.0.4 socks5_proxy: ^1.0.4
unorm_dart: ^0.3.0
# tor: # tor:
# git: # git:
# url: https://github.com/cake-tech/tor.git # url: https://github.com/cake-tech/tor.git

View file

@ -29,6 +29,11 @@ class EthereumClient extends EVMChainClient {
final jsonResponse = json.decode(response.body) as Map<String, dynamic>; final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
if (jsonResponse['result'] is String) {
log(jsonResponse['result']);
return [];
}
if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) { if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
return (jsonResponse['result'] as List) return (jsonResponse['result'] as List)
.map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH')) .map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH'))

View file

@ -14,6 +14,7 @@ class EthereumTransactionInfo extends EVMChainTransactionInfo {
required super.confirmations, required super.confirmations,
required super.to, required super.to,
required super.from, required super.from,
super.evmSignatureName,
super.exponent, super.exponent,
}); });
@ -31,6 +32,7 @@ class EthereumTransactionInfo extends EVMChainTransactionInfo {
tokenSymbol: data['tokenSymbol'] as String, tokenSymbol: data['tokenSymbol'] as String,
to: data['to'], to: data['to'],
from: data['from'], from: data['from'],
evmSignatureName: data['evmSignatureName'],
); );
} }

View file

@ -94,6 +94,7 @@ class EthereumWallet extends EVMChainWallet {
tokenSymbol: transactionModel.tokenSymbol ?? "ETH", tokenSymbol: transactionModel.tokenSymbol ?? "ETH",
to: transactionModel.to, to: transactionModel.to,
from: transactionModel.from, from: transactionModel.from,
evmSignatureName: transactionModel.evmSignatureName,
); );
return model; return model;
} }

View file

@ -1,15 +1,13 @@
import 'package:intl/intl.dart'; import 'dart:math';
const evmChainAmountLength = 12;
const evmChainAmountDivider = 1000000000000;
final evmChainAmountFormat = NumberFormat()
..maximumFractionDigits = evmChainAmountLength
..minimumFractionDigits = 1;
class EVMChainFormatter { class EVMChainFormatter {
static int _divider = 0;
static int parseEVMChainAmount(String amount) { static int parseEVMChainAmount(String amount) {
try { try {
return (double.parse(amount) * evmChainAmountDivider).round(); final decimalLength = _getDividerForInput(amount);
_divider = decimalLength;
return (double.parse(amount) * pow(10, decimalLength)).round();
} catch (_) { } catch (_) {
return 0; return 0;
} }
@ -17,9 +15,19 @@ class EVMChainFormatter {
static double parseEVMChainAmountToDouble(int amount) { static double parseEVMChainAmountToDouble(int amount) {
try { try {
return amount / evmChainAmountDivider; return amount / pow(10, _divider);
} catch (_) { } catch (_) {
return 0; return 0;
} }
} }
static int _getDividerForInput(String amount) {
final result = amount.split('.');
if (result.length > 1) {
final decimalLength = result[1].length;
return decimalLength;
} else {
return 0;
}
}
} }

View file

@ -20,6 +20,7 @@ abstract class EVMChainTransactionInfo extends TransactionInfo {
required this.confirmations, required this.confirmations,
required this.to, required this.to,
required this.from, required this.from,
this.evmSignatureName,
}) : amount = ethAmount.toInt(), }) : amount = ethAmount.toInt(),
fee = ethFee.toInt(); fee = ethFee.toInt();
@ -38,6 +39,7 @@ abstract class EVMChainTransactionInfo extends TransactionInfo {
String? _fiatAmount; String? _fiatAmount;
final String? to; final String? to;
final String? from; final String? from;
final String? evmSignatureName;
//! Getter to be overridden in child classes //! Getter to be overridden in child classes
String get feeCurrency; String get feeCurrency;
@ -73,5 +75,6 @@ abstract class EVMChainTransactionInfo extends TransactionInfo {
'tokenSymbol': tokenSymbol, 'tokenSymbol': tokenSymbol,
'to': to, 'to': to,
'from': from, 'from': from,
'evmSignatureName': evmSignatureName,
}; };
} }

View file

@ -12,6 +12,8 @@ class EVMChainTransactionModel {
final String? tokenSymbol; final String? tokenSymbol;
final int? tokenDecimal; final int? tokenDecimal;
final bool isError; final bool isError;
final String input;
String? evmSignatureName;
EVMChainTransactionModel({ EVMChainTransactionModel({
required this.date, required this.date,
@ -27,6 +29,8 @@ class EVMChainTransactionModel {
required this.tokenSymbol, required this.tokenSymbol,
required this.tokenDecimal, required this.tokenDecimal,
required this.isError, required this.isError,
required this.input,
this.evmSignatureName,
}); });
factory EVMChainTransactionModel.fromJson(Map<String, dynamic> json, String defaultSymbol) => factory EVMChainTransactionModel.fromJson(Map<String, dynamic> json, String defaultSymbol) =>
@ -44,5 +48,7 @@ class EVMChainTransactionModel {
tokenSymbol: json["tokenSymbol"] ?? defaultSymbol, tokenSymbol: json["tokenSymbol"] ?? defaultSymbol,
tokenDecimal: int.tryParse(json["tokenDecimal"] ?? ""), tokenDecimal: int.tryParse(json["tokenDecimal"] ?? ""),
isError: json["isError"] == "1", isError: json["isError"] == "1",
input: json["input"] ?? "",
evmSignatureName: json["evmSignatureName"],
); );
} }

View file

@ -39,6 +39,20 @@ import 'evm_erc20_balance.dart';
part 'evm_chain_wallet.g.dart'; part 'evm_chain_wallet.g.dart';
const Map<String, String> methodSignatureToType = {
'0x095ea7b3': 'approval',
'0xa9059cbb': 'transfer',
'0x23b872dd': 'transferFrom',
'0x574da717': 'transferOut',
'0x2e1a7d4d': 'withdraw',
'0x7ff36ab5': 'swapExactETHForTokens',
'0x40c10f19': 'mint',
'0x44bc937b': 'depositWithExpiry',
'0xd0e30db0': 'deposit',
'0xe8e33700': 'addLiquidity',
'0xd505accf': 'permit',
};
abstract class EVMChainWallet = EVMChainWalletBase with _$EVMChainWallet; abstract class EVMChainWallet = EVMChainWalletBase with _$EVMChainWallet;
abstract class EVMChainWalletBase abstract class EVMChainWalletBase
@ -235,7 +249,8 @@ abstract class EVMChainWalletBase
String? hexOpReturnMemo; String? hexOpReturnMemo;
if (opReturnMemo != null) { if (opReturnMemo != null) {
hexOpReturnMemo = '0x${opReturnMemo.codeUnits.map((char) => char.toRadixString(16).padLeft(2, '0')).join()}'; hexOpReturnMemo =
'0x${opReturnMemo.codeUnits.map((char) => char.toRadixString(16).padLeft(2, '0')).join()}';
} }
final CryptoCurrency transactionCurrency = final CryptoCurrency transactionCurrency =
@ -337,11 +352,21 @@ abstract class EVMChainWalletBase
@override @override
Future<Map<String, EVMChainTransactionInfo>> fetchTransactions() async { Future<Map<String, EVMChainTransactionInfo>> fetchTransactions() async {
final List<EVMChainTransactionModel> transactions = [];
final List<Future<List<EVMChainTransactionModel>>> erc20TokensTransactions = [];
final address = _evmChainPrivateKey.address.hex; final address = _evmChainPrivateKey.address.hex;
final transactions = await _client.fetchTransactions(address); final externalTransactions = await _client.fetchTransactions(address);
final internalTransactions = await _client.fetchInternalTransactions(address); final internalTransactions = await _client.fetchInternalTransactions(address);
final List<Future<List<EVMChainTransactionModel>>> erc20TokensTransactions = []; for (var transaction in externalTransactions) {
final evmSignatureName = analyzeTransaction(transaction.input);
if (evmSignatureName != 'depositWithExpiry' && evmSignatureName != 'transfer') {
transaction.evmSignatureName = evmSignatureName;
transactions.add(transaction);
}
}
for (var token in balance.keys) { for (var token in balance.keys) {
if (token is Erc20Token) { if (token is Erc20Token) {
@ -369,6 +394,17 @@ abstract class EVMChainWalletBase
return result; return result;
} }
String? analyzeTransaction(String? transactionInput) {
if (transactionInput == '0x' || transactionInput == null || transactionInput.isEmpty) {
return 'simpleTransfer';
}
final methodSignature =
transactionInput.length >= 10 ? transactionInput.substring(0, 10) : null;
return methodSignatureToType[methodSignature];
}
@override @override
Object get keys => throw UnimplementedError("keys"); Object get keys => throw UnimplementedError("keys");
@ -482,11 +518,11 @@ abstract class EVMChainWalletBase
await token.delete(); await token.delete();
balance.remove(token); balance.remove(token);
await _removeTokenTransactionsInHistory(token); await removeTokenTransactionsInHistory(token);
_updateBalance(); _updateBalance();
} }
Future<void> _removeTokenTransactionsInHistory(Erc20Token token) async { Future<void> removeTokenTransactionsInHistory(Erc20Token token) async {
transactionHistory.transactions.removeWhere((key, value) => value.tokenSymbol == token.title); transactionHistory.transactions.removeWhere((key, value) => value.tokenSymbol == token.title);
await transactionHistory.save(); await transactionHistory.save();
} }

View file

@ -4,7 +4,6 @@ import 'package:cw_haven/api/signatures.dart';
import 'package:cw_haven/api/types.dart'; import 'package:cw_haven/api/types.dart';
import 'package:cw_haven/api/haven_api.dart'; import 'package:cw_haven/api/haven_api.dart';
import 'package:cw_haven/api/structs/account_row.dart'; import 'package:cw_haven/api/structs/account_row.dart';
import 'package:flutter/foundation.dart';
import 'package:cw_haven/api/wallet.dart'; import 'package:cw_haven/api/wallet.dart';
final accountSizeNative = havenApi final accountSizeNative = havenApi
@ -72,12 +71,11 @@ void _setLabelForAccount(Map<String, dynamic> args) {
} }
Future<void> addAccount({required String label}) async { Future<void> addAccount({required String label}) async {
await compute(_addAccount, label); _addAccount(label);
await store(); await store();
} }
Future<void> setLabelForAccount({required int accountIndex, required String label}) async { Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
await compute( _setLabelForAccount({'accountIndex': accountIndex, 'label': label});
_setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
await store(); await store();
} }

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View file

@ -1,8 +0,0 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>cw_monero</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View file

@ -1,13 +0,0 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0-20191016123526+0000))
connection.project.dir=../../android
eclipse.preferences.version=1
gradle.user.home=
java.home=
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View file

@ -1,232 +0,0 @@
cmake_minimum_required(VERSION 3.4.1)
add_library( cw_monero
SHARED
./jni/monero_jni.cpp
../ios/Classes/monero_api.cpp)
find_library( log-lib log )
set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../../cw_shared_external/ios/External/android)
############
# libsodium
############
add_library(sodium STATIC IMPORTED)
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libsodium.a)
############
# OpenSSL
############
add_library(crypto STATIC IMPORTED)
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libcrypto.a)
add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libssl.a)
############
# Boost
############
add_library(boost_chrono STATIC IMPORTED)
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_chrono.a)
add_library(boost_date_time STATIC IMPORTED)
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_date_time.a)
add_library(boost_filesystem STATIC IMPORTED)
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_filesystem.a)
add_library(boost_program_options STATIC IMPORTED)
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_program_options.a)
add_library(boost_regex STATIC IMPORTED)
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_regex.a)
add_library(boost_serialization STATIC IMPORTED)
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_serialization.a)
add_library(boost_system STATIC IMPORTED)
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_system.a)
add_library(boost_thread STATIC IMPORTED)
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_thread.a)
add_library(boost_wserialization STATIC IMPORTED)
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_wserialization.a)
#############
# Monero
#############
add_library(wallet_api STATIC IMPORTED)
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libwallet_api.a)
add_library(wallet STATIC IMPORTED)
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libwallet.a)
add_library(cryptonote_core STATIC IMPORTED)
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcryptonote_core.a)
add_library(cryptonote_basic STATIC IMPORTED)
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcryptonote_basic.a)
add_library(cryptonote_format_utils_basic STATIC IMPORTED)
set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcryptonote_format_utils_basic.a)
add_library(mnemonics STATIC IMPORTED)
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libmnemonics.a)
add_library(common STATIC IMPORTED)
set_target_properties(common PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcommon.a)
add_library(cncrypto STATIC IMPORTED)
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcncrypto.a)
add_library(ringct STATIC IMPORTED)
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libringct.a)
add_library(ringct_basic STATIC IMPORTED)
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libringct_basic.a)
add_library(blockchain_db STATIC IMPORTED)
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libblockchain_db.a)
add_library(lmdb STATIC IMPORTED)
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/liblmdb.a)
add_library(easylogging STATIC IMPORTED)
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libeasylogging.a)
add_library(unbound STATIC IMPORTED)
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libunbound.a)
add_library(epee STATIC IMPORTED)
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libepee.a)
add_library(blocks STATIC IMPORTED)
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libblocks.a)
add_library(checkpoints STATIC IMPORTED)
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcheckpoints.a)
add_library(device STATIC IMPORTED)
set_target_properties(device PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libdevice.a)
add_library(device_trezor STATIC IMPORTED)
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libdevice_trezor.a)
add_library(multisig STATIC IMPORTED)
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libmultisig.a)
add_library(version STATIC IMPORTED)
set_target_properties(version PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libversion.a)
add_library(net STATIC IMPORTED)
set_target_properties(net PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libnet.a)
add_library(hardforks STATIC IMPORTED)
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libhardforks.a)
add_library(randomx STATIC IMPORTED)
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/librandomx.a)
add_library(rpc_base STATIC IMPORTED)
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/librpc_base.a)
add_library(wallet-crypto STATIC IMPORTED)
set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libwallet-crypto.a)
set(WALLET_CRYPTO "")
if(${ANDROID_ABI} STREQUAL "x86_64")
set(WALLET_CRYPTO "wallet-crypto")
endif()
include_directories( ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/include )
target_link_libraries( cw_monero
wallet_api
wallet
cryptonote_core
cryptonote_basic
cryptonote_format_utils_basic
mnemonics
ringct
ringct_basic
net
common
cncrypto
blockchain_db
lmdb
easylogging
unbound
epee
blocks
checkpoints
device
device_trezor
multisig
version
randomx
hardforks
rpc_base
${WALLET_CRYPTO}
boost_chrono
boost_date_time
boost_filesystem
boost_program_options
boost_regex
boost_serialization
boost_system
boost_thread
boost_wserialization
ssl
crypto
sodium
${log-lib} )

View file

@ -1,49 +0,0 @@
group 'com.cakewallet.monero'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
disable 'InvalidPackage'
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View file

@ -1,4 +0,0 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View file

@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View file

@ -1,74 +0,0 @@
#include <string.h>
#include <jni.h>
#include "../../ios/Classes/monero_api.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL
Java_com_cakewallet_monero_MoneroApi_setNodeAddressJNI(
JNIEnv *env,
jobject inst,
jstring uri,
jstring login,
jstring password,
jboolean use_ssl,
jboolean is_light_wallet) {
const char *_uri = env->GetStringUTFChars(uri, 0);
const char *_login = "";
const char *_password = "";
char *error;
if (login != NULL) {
_login = env->GetStringUTFChars(login, 0);
}
if (password != NULL) {
_password = env->GetStringUTFChars(password, 0);
}
char *__uri = (char*) _uri;
char *__login = (char*) _login;
char *__password = (char*) _password;
bool inited = setup_node(__uri, __login, __password, false, false, error);
if (!inited) {
env->ThrowNew(env->FindClass("java/lang/Exception"), error);
}
}
JNIEXPORT void JNICALL
Java_com_cakewallet_monero_MoneroApi_connectToNodeJNI(
JNIEnv *env,
jobject inst) {
char *error;
bool is_connected = connect_to_node(error);
if (!is_connected) {
env->ThrowNew(env->FindClass("java/lang/Exception"), error);
}
}
JNIEXPORT void JNICALL
Java_com_cakewallet_monero_MoneroApi_startSyncJNI(
JNIEnv *env,
jobject inst) {
start_refresh();
}
JNIEXPORT void JNICALL
Java_com_cakewallet_monero_MoneroApi_loadWalletJNI(
JNIEnv *env,
jobject inst,
jstring path,
jstring password) {
char *_path = (char *) env->GetStringUTFChars(path, 0);
char *_password = (char *) env->GetStringUTFChars(password, 0);
load_wallet(_path, _password, 0);
}
#ifdef __cplusplus
}
#endif

View file

@ -1 +0,0 @@
rootProject.name = 'cw_monero'

View file

@ -1,4 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cakewallet.monero">
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View file

@ -1,74 +0,0 @@
package com.cakewallet.monero
import android.app.Activity
import android.os.AsyncTask
import android.os.Looper
import android.os.Handler
import android.os.Process
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void?): Void? {
Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
handler()
return null
}
}
class CwMoneroPlugin: MethodCallHandler {
companion object {
// val moneroApi = MoneroApi()
val main = Handler(Looper.getMainLooper());
init {
System.loadLibrary("cw_monero")
}
@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "cw_monero")
channel.setMethodCallHandler(CwMoneroPlugin())
}
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "setupNode") {
val uri = call.argument("address") ?: ""
val login = call.argument("login") ?: ""
val password = call.argument("password") ?: ""
val useSSL = false
val isLightWallet = false
// doAsync {
// try {
// moneroApi.setNodeAddressJNI(uri, login, password, useSSL, isLightWallet)
// main.post({
// result.success(true)
// });
// } catch(e: Throwable) {
// main.post({
// result.error("CONNECTION_ERROR", e.message, null)
// });
// }
// }.execute()
}
if (call.method == "startSync") {
// doAsync {
// moneroApi.startSyncJNI()
// main.post({
// result.success(true)
// });
// }.execute()
}
if (call.method == "loadWallet") {
val path = call.argument("path") ?: ""
val password = call.argument("password") ?: ""
// moneroApi.loadWalletJNI(path, password)
result.success(true)
}
}
}

View file

@ -1,44 +0,0 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

View file

@ -1,16 +0,0 @@
# cw_monero_example
Demonstrates how to use the cw_monero plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View file

@ -1,29 +0,0 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View file

@ -1,63 +0,0 @@
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:cw_monero/cw_monero.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final _cwMoneroPlugin = CwMonero();
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion =
await _cwMoneroPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
}

View file

@ -1,7 +0,0 @@
# Flutter-related
**/Flutter/ephemeral/
**/Pods/
# Xcode-related
**/dgph
**/xcuserdata/

View file

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"

View file

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"

View file

@ -1,14 +0,0 @@
//
// Generated file. Do not edit.
//
import FlutterMacOS
import Foundation
import cw_monero
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
CwMoneroPlugin.register(with: registry.registrar(forPlugin: "CwMoneroPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
}

View file

@ -1,40 +0,0 @@
platform :osx, '10.11'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_macos_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
end

View file

@ -1,22 +0,0 @@
PODS:
- FlutterMacOS (1.0.0)
- path_provider_macos (0.0.1):
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
path_provider_macos:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
SPEC CHECKSUMS:
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
COCOAPODS: 1.11.2

View file

@ -1,632 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXAggregateTarget section */
33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
buildPhases = (
33CC111E2044C6BF0003C045 /* ShellScript */,
);
dependencies = (
);
name = "Flutter Assemble";
productName = FLX;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
428E7496E2068D0AB138F295 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C29B2253BA962B7A415DBA77 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 33CC111A2044C6BA0003C045;
remoteInfo = FLX;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
33CC110E2044A8840003C045 /* Bundle Framework */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* cw_monero_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = cw_monero_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
A9CDA1605413332AB9056C23 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
C29B2253BA962B7A415DBA77 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E434913D71DC2682EF8E9059 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
EEF09839C86335F78056F812 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
33CC10EA2044A3C60003C045 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
428E7496E2068D0AB138F295 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
33BA886A226E78AF003329D5 /* Configs */ = {
isa = PBXGroup;
children = (
33E5194F232828860026EE4D /* AppInfo.xcconfig */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
);
path = Configs;
sourceTree = "<group>";
};
33CC10E42044A3C60003C045 = {
isa = PBXGroup;
children = (
33FAB671232836740065AC1E /* Runner */,
33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
77870A4C94A9AB6EEC2EE261 /* Pods */,
);
sourceTree = "<group>";
};
33CC10EE2044A3C60003C045 /* Products */ = {
isa = PBXGroup;
children = (
33CC10ED2044A3C60003C045 /* cw_monero_example.app */,
);
name = Products;
sourceTree = "<group>";
};
33CC11242044D66E0003C045 /* Resources */ = {
isa = PBXGroup;
children = (
33CC10F22044A3C60003C045 /* Assets.xcassets */,
33CC10F42044A3C60003C045 /* MainMenu.xib */,
33CC10F72044A3C60003C045 /* Info.plist */,
);
name = Resources;
path = ..;
sourceTree = "<group>";
};
33CEB47122A05771004F2AC0 /* Flutter */ = {
isa = PBXGroup;
children = (
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
);
path = Flutter;
sourceTree = "<group>";
};
33FAB671232836740065AC1E /* Runner */ = {
isa = PBXGroup;
children = (
33CC10F02044A3C60003C045 /* AppDelegate.swift */,
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
33E51913231747F40026EE4D /* DebugProfile.entitlements */,
33E51914231749380026EE4D /* Release.entitlements */,
33CC11242044D66E0003C045 /* Resources */,
33BA886A226E78AF003329D5 /* Configs */,
);
path = Runner;
sourceTree = "<group>";
};
77870A4C94A9AB6EEC2EE261 /* Pods */ = {
isa = PBXGroup;
children = (
EEF09839C86335F78056F812 /* Pods-Runner.debug.xcconfig */,
A9CDA1605413332AB9056C23 /* Pods-Runner.release.xcconfig */,
E434913D71DC2682EF8E9059 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
C29B2253BA962B7A415DBA77 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
33CC10EC2044A3C60003C045 /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
0A239C1738C005E3F6E4DFC6 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
0CEAA82AE8A029C31B39F234 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
33CC11202044C79F0003C045 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
productReference = 33CC10ED2044A3C60003C045 /* cw_monero_example.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
33CC10E52044A3C60003C045 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
33CC111A2044C6BA0003C045 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 33CC10E42044A3C60003C045;
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
33CC10EC2044A3C60003C045 /* Runner */,
33CC111A2044C6BA0003C045 /* Flutter Assemble */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
33CC10EB2044A3C60003C045 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0A239C1738C005E3F6E4DFC6 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
0CEAA82AE8A029C31B39F234 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
};
33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
Flutter/ephemeral/FlutterInputs.xcfilelist,
);
inputPaths = (
Flutter/ephemeral/tripwire,
);
outputFileListPaths = (
Flutter/ephemeral/FlutterOutputs.xcfilelist,
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
33CC10E92044A3C60003C045 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
33CC10F52044A3C60003C045 /* Base */,
);
name = MainMenu.xib;
path = Runner;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
338D0CE9231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Profile;
};
338D0CEA231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Profile;
};
338D0CEB231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Profile;
};
33CC10F92044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
33CC10FA2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
33CC10FC2044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
33CC10FD2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Release;
};
33CC111C2044C6BA0003C045 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
33CC111D2044C6BA0003C045 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10F92044A3C60003C045 /* Debug */,
33CC10FA2044A3C60003C045 /* Release */,
338D0CE9231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10FC2044A3C60003C045 /* Debug */,
33CC10FD2044A3C60003C045 /* Release */,
338D0CEA231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC111C2044C6BA0003C045 /* Debug */,
33CC111D2044C6BA0003C045 /* Release */,
338D0CEB231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 33CC10E52044A3C60003C045 /* Project object */;
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "cw_monero_example.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "cw_monero_example.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "cw_monero_example.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "cw_monero_example.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,9 +0,0 @@
import Cocoa
import FlutterMacOS
@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}

View file

@ -1,68 +0,0 @@
{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_16.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_64.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_1024.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,343 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
<connections>
<outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
<outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="APP_NAME" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About APP_NAME" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="EPT-qC-fAb">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="rJ0-wn-3NY"/>
</menuItem>
</items>
<point key="canvasLocation" x="142" y="-258"/>
</menu>
<window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="335" y="390" width="800" height="600"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</window>
</objects>
</document>

View file

@ -1,14 +0,0 @@
// Application-level settings for the Runner target.
//
// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
// future. If not, the values below would default to using the project name when this becomes a
// 'flutter create' template.
// The application's name. By default this is also the title of the Flutter window.
PRODUCT_NAME = cw_monero_example
// The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.cakewallet.cwMoneroExample
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2022 com.cakewallet. All rights reserved.

View file

@ -1,2 +0,0 @@
#include "../../Flutter/Flutter-Debug.xcconfig"
#include "Warnings.xcconfig"

View file

@ -1,2 +0,0 @@
#include "../../Flutter/Flutter-Release.xcconfig"
#include "Warnings.xcconfig"

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