mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Merge branch 'main' into CAKE-272-implement-localization-generation-script
This commit is contained in:
commit
8603e3f2bf
52 changed files with 1506 additions and 94 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -87,6 +87,8 @@ cw_monero/cw_monero/android/.cxx/
|
||||||
android/key.properties
|
android/key.properties
|
||||||
|
|
||||||
**/tool/.secrets-prod.json
|
**/tool/.secrets-prod.json
|
||||||
|
**/tool/.secrets-test.json
|
||||||
|
**/tool/.secrets-config.json
|
||||||
**/lib/.secrets.g.dart
|
**/lib/.secrets.g.dart
|
||||||
|
|
||||||
vendor/
|
vendor/
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
# Cake Wallet
|
# CakeWallet for Android and iOS
|
||||||
|
|
||||||
The project description, motivation, build scripts, instructions, tests will be added soon (February 2021);
|
## Open Source Monero and Bitcoin Wallet
|
||||||
|
|
||||||
Copyright (c) 2021 Cake Technologies LLC.
|
|
||||||
|
More instructions to follow
|
||||||
|
|
||||||
|
For instructions on how to build for Android: please view file `howto-build-android.md`
|
BIN
assets/images/wyre-icon.png
Normal file
BIN
assets/images/wyre-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -17,7 +17,7 @@ set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../ios/External/android)
|
||||||
|
|
||||||
add_library(sodium STATIC IMPORTED)
|
add_library(sodium STATIC IMPORTED)
|
||||||
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libsodium.a)
|
||||||
|
|
||||||
############
|
############
|
||||||
# OpenSSL
|
# OpenSSL
|
||||||
|
@ -25,11 +25,11 @@ set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||||
|
|
||||||
add_library(crypto STATIC IMPORTED)
|
add_library(crypto STATIC IMPORTED)
|
||||||
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libcrypto.a)
|
||||||
|
|
||||||
add_library(ssl STATIC IMPORTED)
|
add_library(ssl STATIC IMPORTED)
|
||||||
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libssl.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libssl.a)
|
||||||
|
|
||||||
############
|
############
|
||||||
# Boost
|
# Boost
|
||||||
|
@ -37,39 +37,39 @@ set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||||
|
|
||||||
add_library(boost_chrono STATIC IMPORTED)
|
add_library(boost_chrono STATIC IMPORTED)
|
||||||
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_chrono.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_chrono.a)
|
||||||
|
|
||||||
add_library(boost_date_time STATIC IMPORTED)
|
add_library(boost_date_time STATIC IMPORTED)
|
||||||
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_date_time.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_date_time.a)
|
||||||
|
|
||||||
add_library(boost_filesystem STATIC IMPORTED)
|
add_library(boost_filesystem STATIC IMPORTED)
|
||||||
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_filesystem.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_filesystem.a)
|
||||||
|
|
||||||
add_library(boost_program_options STATIC IMPORTED)
|
add_library(boost_program_options STATIC IMPORTED)
|
||||||
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_program_options.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_program_options.a)
|
||||||
|
|
||||||
add_library(boost_regex STATIC IMPORTED)
|
add_library(boost_regex STATIC IMPORTED)
|
||||||
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_regex.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_regex.a)
|
||||||
|
|
||||||
add_library(boost_serialization STATIC IMPORTED)
|
add_library(boost_serialization STATIC IMPORTED)
|
||||||
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_serialization.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_serialization.a)
|
||||||
|
|
||||||
add_library(boost_system STATIC IMPORTED)
|
add_library(boost_system STATIC IMPORTED)
|
||||||
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_system.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_system.a)
|
||||||
|
|
||||||
add_library(boost_thread STATIC IMPORTED)
|
add_library(boost_thread STATIC IMPORTED)
|
||||||
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_thread.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_thread.a)
|
||||||
|
|
||||||
add_library(boost_wserialization STATIC IMPORTED)
|
add_library(boost_wserialization STATIC IMPORTED)
|
||||||
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/libboost_wserialization.a)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# Monero
|
# Monero
|
||||||
|
@ -77,101 +77,111 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||||
|
|
||||||
add_library(wallet_api STATIC IMPORTED)
|
add_library(wallet_api STATIC IMPORTED)
|
||||||
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libwallet_api.a)
|
||||||
|
|
||||||
add_library(wallet STATIC IMPORTED)
|
add_library(wallet STATIC IMPORTED)
|
||||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libwallet.a)
|
||||||
|
|
||||||
add_library(cryptonote_core STATIC IMPORTED)
|
add_library(cryptonote_core STATIC IMPORTED)
|
||||||
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_core.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcryptonote_core.a)
|
||||||
|
|
||||||
add_library(cryptonote_basic STATIC IMPORTED)
|
add_library(cryptonote_basic STATIC IMPORTED)
|
||||||
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
|
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_basic.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcryptonote_basic.a)
|
||||||
|
|
||||||
add_library(mnemonics STATIC IMPORTED)
|
add_library(mnemonics STATIC IMPORTED)
|
||||||
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
|
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmnemonics.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libmnemonics.a)
|
||||||
|
|
||||||
add_library(common STATIC IMPORTED)
|
add_library(common STATIC IMPORTED)
|
||||||
set_target_properties(common PROPERTIES IMPORTED_LOCATION
|
set_target_properties(common PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcommon.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcommon.a)
|
||||||
|
|
||||||
add_library(cncrypto STATIC IMPORTED)
|
add_library(cncrypto STATIC IMPORTED)
|
||||||
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
|
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcncrypto.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcncrypto.a)
|
||||||
|
|
||||||
add_library(ringct STATIC IMPORTED)
|
add_library(ringct STATIC IMPORTED)
|
||||||
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libringct.a)
|
||||||
|
|
||||||
add_library(ringct_basic STATIC IMPORTED)
|
add_library(ringct_basic STATIC IMPORTED)
|
||||||
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libringct_basic.a)
|
||||||
|
|
||||||
add_library(blockchain_db STATIC IMPORTED)
|
add_library(blockchain_db STATIC IMPORTED)
|
||||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblockchain_db.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libblockchain_db.a)
|
||||||
|
|
||||||
add_library(lmdb STATIC IMPORTED)
|
add_library(lmdb STATIC IMPORTED)
|
||||||
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
|
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/liblmdb.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/liblmdb.a)
|
||||||
|
|
||||||
add_library(easylogging STATIC IMPORTED)
|
add_library(easylogging STATIC IMPORTED)
|
||||||
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libeasylogging.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libeasylogging.a)
|
||||||
|
|
||||||
add_library(unbound STATIC IMPORTED)
|
add_library(unbound STATIC IMPORTED)
|
||||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libunbound.a)
|
||||||
|
|
||||||
add_library(epee STATIC IMPORTED)
|
add_library(epee STATIC IMPORTED)
|
||||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libepee.a)
|
||||||
|
|
||||||
add_library(blocks STATIC IMPORTED)
|
add_library(blocks STATIC IMPORTED)
|
||||||
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libblocks.a)
|
||||||
|
|
||||||
add_library(checkpoints STATIC IMPORTED)
|
add_library(checkpoints STATIC IMPORTED)
|
||||||
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libcheckpoints.a)
|
||||||
|
|
||||||
add_library(device STATIC IMPORTED)
|
add_library(device STATIC IMPORTED)
|
||||||
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libdevice.a)
|
||||||
|
|
||||||
add_library(device_trezor STATIC IMPORTED)
|
add_library(device_trezor STATIC IMPORTED)
|
||||||
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice_trezor.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libdevice_trezor.a)
|
||||||
|
|
||||||
add_library(multisig STATIC IMPORTED)
|
add_library(multisig STATIC IMPORTED)
|
||||||
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libmultisig.a)
|
||||||
|
|
||||||
add_library(version STATIC IMPORTED)
|
add_library(version STATIC IMPORTED)
|
||||||
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libversion.a)
|
||||||
|
|
||||||
add_library(net STATIC IMPORTED)
|
add_library(net STATIC IMPORTED)
|
||||||
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libnet.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libnet.a)
|
||||||
|
|
||||||
add_library(hardforks STATIC IMPORTED)
|
add_library(hardforks STATIC IMPORTED)
|
||||||
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libhardforks.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/libhardforks.a)
|
||||||
|
|
||||||
add_library(randomx STATIC IMPORTED)
|
add_library(randomx STATIC IMPORTED)
|
||||||
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librandomx.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/librandomx.a)
|
||||||
|
|
||||||
add_library(rpc_base STATIC IMPORTED)
|
add_library(rpc_base STATIC IMPORTED)
|
||||||
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librpc_base.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/lib/monero/librpc_base.a)
|
||||||
|
|
||||||
include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
|
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
|
target_link_libraries( cw_monero
|
||||||
|
|
||||||
|
@ -199,6 +209,7 @@ target_link_libraries( cw_monero
|
||||||
randomx
|
randomx
|
||||||
hardforks
|
hardforks
|
||||||
rpc_base
|
rpc_base
|
||||||
|
${WALLET_CRYPTO}
|
||||||
|
|
||||||
boost_chrono
|
boost_chrono
|
||||||
boost_date_time
|
boost_date_time
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "thread"
|
#include "thread"
|
||||||
#include "CwWalletListener.h"
|
#include "CwWalletListener.h"
|
||||||
#include "../External/android/monero/include/wallet2_api.h"
|
#include "../External/android/x86/include/wallet2_api.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
|
136
howto-build-android.md
Normal file
136
howto-build-android.md
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
# Building CakeWallet for Android
|
||||||
|
|
||||||
|
## Requirements and Setup
|
||||||
|
|
||||||
|
The following are the system requirements to build CakeWallet for your Android device.
|
||||||
|
|
||||||
|
```
|
||||||
|
Ubuntu >= 16.04
|
||||||
|
Android SDK 28
|
||||||
|
Android NDK 17c
|
||||||
|
Flutter 1.22.6
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building CakeWallet on Android
|
||||||
|
|
||||||
|
These steps will help you configure and execute a build of CakeWallet from its source code.
|
||||||
|
|
||||||
|
### 1. Installing Package Dependencies
|
||||||
|
|
||||||
|
CakeWallet cannot be built without the following packages installed on your build system.
|
||||||
|
|
||||||
|
- unzip
|
||||||
|
|
||||||
|
- automake
|
||||||
|
|
||||||
|
- build-essential
|
||||||
|
|
||||||
|
- file
|
||||||
|
|
||||||
|
- pkg-config
|
||||||
|
|
||||||
|
- git
|
||||||
|
|
||||||
|
- python
|
||||||
|
|
||||||
|
- libtool
|
||||||
|
|
||||||
|
- libtinfo5
|
||||||
|
|
||||||
|
- cmake
|
||||||
|
|
||||||
|
- openjdk-8-jre-headless
|
||||||
|
|
||||||
|
You may easily install them on your build sytem with the following command:
|
||||||
|
|
||||||
|
`$ sudo apt-get install -y unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake openjdk-8-jre-headless`
|
||||||
|
|
||||||
|
### 2. Installing Android Studio and Android toolchain
|
||||||
|
|
||||||
|
You may download and install the latest version of Android Studio [here](https://developer.android.com/studio#downloads). After installing, start Android Studio, and go through the "Setup Wizard." This installs the latest Android SDK, Android SDK Command-line Tools, and Android SDK Build-Tools, which are required by CakeWallet. **Be sure you are installing SDK version 28 or later when stepping through the wizard**
|
||||||
|
|
||||||
|
### 3. Installing Flutter
|
||||||
|
|
||||||
|
CakeWallet requires **EXACTLY** Flutter version `1.22.6` to build properly.
|
||||||
|
|
||||||
|
To install this version of Flutter on your Ubuntu system, please use [these instructions](https://flutter.dev/docs/get-started/install/linux#install-flutter-manually).
|
||||||
|
|
||||||
|
### 4. Verify Installations
|
||||||
|
|
||||||
|
Verify that the Android toolchain, Flutter, and Android Studio have been correctly installed on your system with the following command:
|
||||||
|
|
||||||
|
`$ flutter doctor`
|
||||||
|
|
||||||
|
The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
|
||||||
|
```
|
||||||
|
Doctor summary (to see all details, run flutter doctor -v):
|
||||||
|
[✓] Flutter (Channel stable, 1.22.6, on Linux, locale en_US.UTF-8)
|
||||||
|
[✓] Android toolchain - develop for Android devices (Android SDK version 28)
|
||||||
|
[✓] Android Studio (version 4.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Generate a secure keystore for Android
|
||||||
|
|
||||||
|
`$ keytool -genkey -v -keystore $HOME/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key`
|
||||||
|
|
||||||
|
You will be prompted to create two passwords. First you will be prompted for the "store password", followed by a "key password" towards the end of the creation process. **TAKE NOTE OF THESE PASSWORDS!** You will need them in later steps.
|
||||||
|
|
||||||
|
### 6. Acquiring the CakeWallet Source Code
|
||||||
|
|
||||||
|
Create the directory that will be use to store the CakeWallet source...
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo mkdir -p /opt/android
|
||||||
|
$ sudo chown $USER /opt/android
|
||||||
|
$ cd /opt/android
|
||||||
|
```
|
||||||
|
|
||||||
|
..and download the source code into that directory.
|
||||||
|
|
||||||
|
`$ git clone https://github.com/cake-tech/cake_wallet.git --branch deploy`
|
||||||
|
|
||||||
|
Proceed into the source code before proceeding with the next steps:
|
||||||
|
|
||||||
|
`$ cd cake_wallet/scripts/android/`
|
||||||
|
|
||||||
|
### 7. Installing Android NDK
|
||||||
|
|
||||||
|
`$ ./install_ndk.sh`
|
||||||
|
|
||||||
|
### 8. Execute Build & Setup Commands for CakeWallet
|
||||||
|
|
||||||
|
Build the Monero libraries and their dependencies:
|
||||||
|
|
||||||
|
`$ ./build_all.sh`
|
||||||
|
|
||||||
|
Now the dependencies need to be copied into the CakeWallet project with this command:
|
||||||
|
|
||||||
|
`$ ./copy_monero_deps.sh`
|
||||||
|
|
||||||
|
It is now time to change back to the base directory of the CakeWallet source code:
|
||||||
|
|
||||||
|
`$ cd ../../`
|
||||||
|
|
||||||
|
Install Flutter package dependencies with this command:
|
||||||
|
|
||||||
|
`$ flutter pub get`
|
||||||
|
|
||||||
|
Your CakeWallet binary will be built with cryptographic salts, which are used for secure encryption of your data. You may generate these secret salts with the following command:
|
||||||
|
|
||||||
|
`$ flutter packages pub run tool/generate_new_secrets.dart`
|
||||||
|
|
||||||
|
Next, we must generate key properties based on the secure keystore you generated for Android (in step 5). **MODIFY THE FOLLOWING COMMAND** with the "store password" and "key password" you assigned when creating your keystore (in step 5).
|
||||||
|
|
||||||
|
`$ flutter packages pub run tool/generate_android_key_properties.dart keyAlias=key storeFile=$HOME/key.jks storePassword=<store password> keyPassword=<key password>`
|
||||||
|
|
||||||
|
**REMINDER:** The *above* command will **not** succeed unless you replaced the `storePassword` and `keyPassword` variables with the correct passwords for your keystore.
|
||||||
|
|
||||||
|
Lastly, we will generate mobx models for the project.
|
||||||
|
|
||||||
|
`$ flutter packages pub run build_runner build --delete-conflicting-outputs`
|
||||||
|
|
||||||
|
### 9. Build!
|
||||||
|
|
||||||
|
`$ flutter build apk —release`
|
||||||
|
|
||||||
|
Copyright (c) 2021 Cake Technologies LLC.
|
|
@ -86,6 +86,8 @@ PODS:
|
||||||
- SwiftyGif (5.3.0)
|
- SwiftyGif (5.3.0)
|
||||||
- url_launcher (0.0.1):
|
- url_launcher (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- webview_flutter (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
|
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
|
||||||
|
@ -104,6 +106,7 @@ DEPENDENCIES:
|
||||||
- share (from `.symlinks/plugins/share/ios`)
|
- share (from `.symlinks/plugins/share/ios`)
|
||||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||||
|
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://github.com/CocoaPods/Specs.git:
|
https://github.com/CocoaPods/Specs.git:
|
||||||
|
@ -147,6 +150,8 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
:path: ".symlinks/plugins/url_launcher/ios"
|
:path: ".symlinks/plugins/url_launcher/ios"
|
||||||
|
webview_flutter:
|
||||||
|
:path: ".symlinks/plugins/webview_flutter/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
|
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
|
||||||
|
@ -172,6 +177,7 @@ SPEC CHECKSUMS:
|
||||||
SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699
|
SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699
|
||||||
SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40
|
SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40
|
||||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||||
|
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
|
||||||
|
|
||||||
PODFILE CHECKSUM: 5b5f101b119a1b6eb857c967d462832a9062dec4
|
PODFILE CHECKSUM: 5b5f101b119a1b6eb857c967d462832a9062dec4
|
||||||
|
|
||||||
|
|
|
@ -357,7 +357,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 30;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
@ -374,7 +374,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 4.1.2;
|
MARKETING_VERSION = 4.1.3;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
@ -498,7 +498,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 30;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
@ -515,7 +515,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 4.1.2;
|
MARKETING_VERSION = 4.1.3;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
@ -533,7 +533,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 30;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
@ -550,7 +550,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 4.1.2;
|
MARKETING_VERSION = 4.1.3;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
|
51
lib/di.dart
51
lib/di.dart
|
@ -4,8 +4,10 @@ import 'package:cake_wallet/core/wallet_service.dart';
|
||||||
import 'package:cake_wallet/entities/biometric_auth.dart';
|
import 'package:cake_wallet/entities/biometric_auth.dart';
|
||||||
import 'package:cake_wallet/entities/contact_record.dart';
|
import 'package:cake_wallet/entities/contact_record.dart';
|
||||||
import 'package:cake_wallet/entities/load_current_wallet.dart';
|
import 'package:cake_wallet/entities/load_current_wallet.dart';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_info.dart';
|
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
|
import 'package:cake_wallet/entities/wyre_service.dart';
|
||||||
import 'package:cake_wallet/monero/monero_wallet_service.dart';
|
import 'package:cake_wallet/monero/monero_wallet_service.dart';
|
||||||
import 'package:cake_wallet/entities/contact.dart';
|
import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
|
@ -22,6 +24,7 @@ import 'package:cake_wallet/src/screens/faq/faq_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
|
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
|
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
|
import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||||
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
|
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
|
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
|
||||||
|
@ -39,6 +42,8 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
|
||||||
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
import 'package:cake_wallet/store/node_list_store.dart';
|
import 'package:cake_wallet/store/node_list_store.dart';
|
||||||
import 'package:cake_wallet/store/secret_store.dart';
|
import 'package:cake_wallet/store/secret_store.dart';
|
||||||
import 'package:cake_wallet/store/settings_store.dart';
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
@ -63,6 +68,7 @@ import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/order_details_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/rescan_view_model.dart';
|
import 'package:cake_wallet/view_model/rescan_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
|
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
|
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
|
||||||
|
@ -83,6 +89,7 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wyre_view_model.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -104,6 +111,7 @@ import 'package:cake_wallet/store/templates/send_template_store.dart';
|
||||||
import 'package:cake_wallet/store/templates/exchange_template_store.dart';
|
import 'package:cake_wallet/store/templates/exchange_template_store.dart';
|
||||||
import 'package:cake_wallet/entities/template.dart';
|
import 'package:cake_wallet/entities/template.dart';
|
||||||
import 'package:cake_wallet/exchange/exchange_template.dart';
|
import 'package:cake_wallet/exchange/exchange_template.dart';
|
||||||
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
|
|
||||||
|
@ -115,6 +123,7 @@ Box<Trade> _tradesSource;
|
||||||
Box<Template> _templates;
|
Box<Template> _templates;
|
||||||
Box<ExchangeTemplate> _exchangeTemplates;
|
Box<ExchangeTemplate> _exchangeTemplates;
|
||||||
Box<TransactionDescription> _transactionDescriptionBox;
|
Box<TransactionDescription> _transactionDescriptionBox;
|
||||||
|
Box<Order> _ordersSource;
|
||||||
|
|
||||||
Future setup(
|
Future setup(
|
||||||
{Box<WalletInfo> walletInfoSource,
|
{Box<WalletInfo> walletInfoSource,
|
||||||
|
@ -123,7 +132,8 @@ Future setup(
|
||||||
Box<Trade> tradesSource,
|
Box<Trade> tradesSource,
|
||||||
Box<Template> templates,
|
Box<Template> templates,
|
||||||
Box<ExchangeTemplate> exchangeTemplates,
|
Box<ExchangeTemplate> exchangeTemplates,
|
||||||
Box<TransactionDescription> transactionDescriptionBox}) async {
|
Box<TransactionDescription> transactionDescriptionBox,
|
||||||
|
Box<Order> ordersSource}) async {
|
||||||
_walletInfoSource = walletInfoSource;
|
_walletInfoSource = walletInfoSource;
|
||||||
_nodeSource = nodeSource;
|
_nodeSource = nodeSource;
|
||||||
_contactSource = contactSource;
|
_contactSource = contactSource;
|
||||||
|
@ -131,13 +141,18 @@ Future setup(
|
||||||
_templates = templates;
|
_templates = templates;
|
||||||
_exchangeTemplates = exchangeTemplates;
|
_exchangeTemplates = exchangeTemplates;
|
||||||
_transactionDescriptionBox = transactionDescriptionBox;
|
_transactionDescriptionBox = transactionDescriptionBox;
|
||||||
|
_ordersSource = ordersSource;
|
||||||
|
|
||||||
if (!_isSetupFinished) {
|
if (!_isSetupFinished) {
|
||||||
getIt.registerSingletonAsync<SharedPreferences>(
|
getIt.registerSingletonAsync<SharedPreferences>(
|
||||||
() => SharedPreferences.getInstance());
|
() => SharedPreferences.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
final settingsStore = await SettingsStoreBase.load(nodeSource: _nodeSource);
|
final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) &&
|
||||||
|
(secrets.wyreApiKey?.isNotEmpty ?? false) &&
|
||||||
|
(secrets.wyreAccountId?.isNotEmpty ?? false);
|
||||||
|
final settingsStore = await SettingsStoreBase.load(
|
||||||
|
nodeSource: _nodeSource, isBitcoinBuyEnabled: isBitcoinBuyEnabled);
|
||||||
|
|
||||||
if (_isSetupFinished) {
|
if (_isSetupFinished) {
|
||||||
return;
|
return;
|
||||||
|
@ -157,6 +172,8 @@ Future setup(
|
||||||
nodeListStore: getIt.get<NodeListStore>()));
|
nodeListStore: getIt.get<NodeListStore>()));
|
||||||
getIt.registerSingleton<TradesStore>(TradesStore(
|
getIt.registerSingleton<TradesStore>(TradesStore(
|
||||||
tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
|
tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
|
||||||
|
getIt.registerSingleton<OrdersStore>(OrdersStore(
|
||||||
|
ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
|
||||||
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
|
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
|
||||||
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore());
|
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore());
|
||||||
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
|
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
|
||||||
|
@ -219,7 +236,11 @@ Future setup(
|
||||||
appStore: getIt.get<AppStore>(),
|
appStore: getIt.get<AppStore>(),
|
||||||
tradesStore: getIt.get<TradesStore>(),
|
tradesStore: getIt.get<TradesStore>(),
|
||||||
tradeFilterStore: getIt.get<TradeFilterStore>(),
|
tradeFilterStore: getIt.get<TradeFilterStore>(),
|
||||||
transactionFilterStore: getIt.get<TransactionFilterStore>()));
|
transactionFilterStore: getIt.get<TransactionFilterStore>(),
|
||||||
|
settingsStore: settingsStore,
|
||||||
|
ordersSource: _ordersSource,
|
||||||
|
ordersStore: getIt.get<OrdersStore>(),
|
||||||
|
wyreViewModel: getIt.get<WyreViewModel>()));
|
||||||
|
|
||||||
getIt.registerFactory<AuthService>(() => AuthService(
|
getIt.registerFactory<AuthService>(() => AuthService(
|
||||||
secureStorage: getIt.get<FlutterSecureStorage>(),
|
secureStorage: getIt.get<FlutterSecureStorage>(),
|
||||||
|
@ -511,6 +532,30 @@ Future setup(
|
||||||
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
|
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
|
||||||
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
|
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
|
||||||
|
|
||||||
|
getIt.registerFactory(() {
|
||||||
|
final wallet = getIt.get<AppStore>().wallet;
|
||||||
|
return WyreService(walletType: wallet.type, walletAddress: wallet.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
getIt.registerFactory(() {
|
||||||
|
final wallet = getIt.get<AppStore>().wallet;
|
||||||
|
return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
|
||||||
|
walletId: wallet.id, address: wallet.address, type: wallet.type,
|
||||||
|
wyreService: getIt.get<WyreService>());
|
||||||
|
});
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<WyrePage, String, void>((String url, _) =>
|
||||||
|
WyrePage(getIt.get<WyreViewModel>(),
|
||||||
|
ordersStore: getIt.get<OrdersStore>(), url: url));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
|
||||||
|
(order, _) => OrderDetailsViewModel(
|
||||||
|
wyreViewModel: getIt.get<WyreViewModel>(),
|
||||||
|
orderForDetails: order));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
|
||||||
|
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportViewModel());
|
getIt.registerFactory(() => SupportViewModel());
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
||||||
|
|
55
lib/entities/order.dart
Normal file
55
lib/entities/order.dart
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||||
|
import 'package:cake_wallet/entities/format_amount.dart';
|
||||||
|
|
||||||
|
part 'order.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: Order.typeId)
|
||||||
|
class Order extends HiveObject {
|
||||||
|
Order(
|
||||||
|
{this.id,
|
||||||
|
this.transferId,
|
||||||
|
this.from,
|
||||||
|
this.to,
|
||||||
|
TradeState state,
|
||||||
|
this.createdAt,
|
||||||
|
this.amount,
|
||||||
|
this.receiveAddress,
|
||||||
|
this.walletId})
|
||||||
|
: stateRaw = state?.raw;
|
||||||
|
|
||||||
|
static const typeId = 8;
|
||||||
|
static const boxName = 'Orders';
|
||||||
|
static const boxKey = 'ordersBoxKey';
|
||||||
|
|
||||||
|
@HiveField(0)
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@HiveField(1)
|
||||||
|
String transferId;
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
String from;
|
||||||
|
|
||||||
|
@HiveField(3)
|
||||||
|
String to;
|
||||||
|
|
||||||
|
@HiveField(4)
|
||||||
|
String stateRaw;
|
||||||
|
|
||||||
|
TradeState get state => TradeState.deserialize(raw: stateRaw);
|
||||||
|
|
||||||
|
@HiveField(5)
|
||||||
|
DateTime createdAt;
|
||||||
|
|
||||||
|
@HiveField(6)
|
||||||
|
String amount;
|
||||||
|
|
||||||
|
@HiveField(7)
|
||||||
|
String receiveAddress;
|
||||||
|
|
||||||
|
@HiveField(8)
|
||||||
|
String walletId;
|
||||||
|
|
||||||
|
String amountFormatted() => formatAmount(amount);
|
||||||
|
}
|
8
lib/entities/wyre_exception.dart
Normal file
8
lib/entities/wyre_exception.dart
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class WyreException implements Exception {
|
||||||
|
WyreException(this.description);
|
||||||
|
|
||||||
|
String description;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => description;
|
||||||
|
}
|
111
lib/entities/wyre_service.dart
Normal file
111
lib/entities/wyre_service.dart
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:cake_wallet/entities/wyre_exception.dart';
|
||||||
|
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
|
||||||
|
class WyreService {
|
||||||
|
WyreService({
|
||||||
|
@required this.walletType,
|
||||||
|
@required this.walletAddress,
|
||||||
|
this.isTestEnvironment = false}) {
|
||||||
|
baseApiUrl = isTestEnvironment
|
||||||
|
? _baseTestApiUrl
|
||||||
|
: _baseProductApiUrl;
|
||||||
|
trackUrl = isTestEnvironment
|
||||||
|
? _trackTestUrl
|
||||||
|
: _trackProductUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _baseTestApiUrl = 'https://api.testwyre.com';
|
||||||
|
static const _baseProductApiUrl = 'https://api.sendwyre.com';
|
||||||
|
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
|
||||||
|
static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
|
||||||
|
static const _ordersSuffix = '/v3/orders';
|
||||||
|
static const _reserveSuffix = '/reserve';
|
||||||
|
static const _timeStampSuffix = '?timestamp=';
|
||||||
|
static const _transferSuffix = '/v2/transfer/';
|
||||||
|
static const _trackSuffix = '/track';
|
||||||
|
|
||||||
|
final bool isTestEnvironment;
|
||||||
|
final WalletType walletType;
|
||||||
|
final String walletAddress;
|
||||||
|
|
||||||
|
String baseApiUrl;
|
||||||
|
String trackUrl;
|
||||||
|
|
||||||
|
Future<String> getWyreUrl() async {
|
||||||
|
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
||||||
|
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
|
||||||
|
_timeStampSuffix + timestamp;
|
||||||
|
final secretKey = secrets.wyreSecretKey;
|
||||||
|
final accountId = secrets.wyreAccountId;
|
||||||
|
final body = {
|
||||||
|
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
|
||||||
|
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
|
||||||
|
'referrerAccountId': accountId,
|
||||||
|
'lockFields': ['destCurrency', 'dest']
|
||||||
|
};
|
||||||
|
|
||||||
|
final response = await post(url,
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer $secretKey',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'cache-control': 'no-cache'
|
||||||
|
},
|
||||||
|
body: json.encode(body));
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw WyreException('Url $url is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||||
|
final urlFromResponse = responseJSON['url'] as String;
|
||||||
|
return urlFromResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Order> findOrderById(String id) async {
|
||||||
|
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
|
||||||
|
final orderResponse = await get(orderUrl);
|
||||||
|
|
||||||
|
if (orderResponse.statusCode != 200) {
|
||||||
|
throw WyreException('Order $id is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final orderResponseJSON =
|
||||||
|
json.decode(orderResponse.body) as Map<String, dynamic>;
|
||||||
|
final transferId = orderResponseJSON['transferId'] as String;
|
||||||
|
final from = orderResponseJSON['sourceCurrency'] as String;
|
||||||
|
final to = orderResponseJSON['destCurrency'] as String;
|
||||||
|
final status = orderResponseJSON['status'] as String;
|
||||||
|
final state = TradeState.deserialize(raw: status.toLowerCase());
|
||||||
|
final createdAtRaw = orderResponseJSON['createdAt'] as int;
|
||||||
|
final createdAt =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
|
||||||
|
|
||||||
|
final transferUrl =
|
||||||
|
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
|
||||||
|
final transferResponse = await get(transferUrl);
|
||||||
|
|
||||||
|
if (transferResponse.statusCode != 200) {
|
||||||
|
throw WyreException('Transfer $transferId is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final transferResponseJSON =
|
||||||
|
json.decode(transferResponse.body) as Map<String, dynamic>;
|
||||||
|
final amount = transferResponseJSON['destAmount'] as double;
|
||||||
|
|
||||||
|
return Order(
|
||||||
|
id: id,
|
||||||
|
transferId: transferId,
|
||||||
|
from: from,
|
||||||
|
to: to,
|
||||||
|
state: state,
|
||||||
|
createdAt: createdAt,
|
||||||
|
amount: amount.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
static const apiUri = 'https://changenow.io/api/v1';
|
static const apiUri = 'https://changenow.io/api/v1';
|
||||||
static const apiKey = secrets.change_now_api_key;
|
static const apiKey = secrets.changeNowApiKey;
|
||||||
static const _exchangeAmountUriSufix = '/exchange-amount/';
|
static const _exchangeAmountUriSufix = '/exchange-amount/';
|
||||||
static const _transactionsUriSufix = '/transactions/';
|
static const _transactionsUriSufix = '/transactions/';
|
||||||
static const _minAmountUriSufix = '/min-amount/';
|
static const _minAmountUriSufix = '/min-amount/';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -69,11 +70,17 @@ Future<void> main() async {
|
||||||
Hive.registerAdapter(ExchangeTemplateAdapter());
|
Hive.registerAdapter(ExchangeTemplateAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Hive.isAdapterRegistered(Order.typeId)) {
|
||||||
|
Hive.registerAdapter(OrderAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
final secureStorage = FlutterSecureStorage();
|
final secureStorage = FlutterSecureStorage();
|
||||||
final transactionDescriptionsBoxKey = await getEncryptionKey(
|
final transactionDescriptionsBoxKey = await getEncryptionKey(
|
||||||
secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
||||||
final tradesBoxKey = await getEncryptionKey(
|
final tradesBoxKey = await getEncryptionKey(
|
||||||
secureStorage: secureStorage, forKey: Trade.boxKey);
|
secureStorage: secureStorage, forKey: Trade.boxKey);
|
||||||
|
final ordersBoxKey = await getEncryptionKey(
|
||||||
|
secureStorage: secureStorage, forKey: Order.boxKey);
|
||||||
final contacts = await Hive.openBox<Contact>(Contact.boxName);
|
final contacts = await Hive.openBox<Contact>(Contact.boxName);
|
||||||
final nodes = await Hive.openBox<Node>(Node.boxName);
|
final nodes = await Hive.openBox<Node>(Node.boxName);
|
||||||
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
|
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
|
||||||
|
@ -81,6 +88,8 @@ Future<void> main() async {
|
||||||
encryptionKey: transactionDescriptionsBoxKey);
|
encryptionKey: transactionDescriptionsBoxKey);
|
||||||
final trades =
|
final trades =
|
||||||
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
||||||
|
final orders =
|
||||||
|
await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
|
||||||
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
|
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||||
final templates = await Hive.openBox<Template>(Template.boxName);
|
final templates = await Hive.openBox<Template>(Template.boxName);
|
||||||
final exchangeTemplates =
|
final exchangeTemplates =
|
||||||
|
@ -91,6 +100,7 @@ Future<void> main() async {
|
||||||
walletInfoSource: walletInfoSource,
|
walletInfoSource: walletInfoSource,
|
||||||
contactSource: contacts,
|
contactSource: contacts,
|
||||||
tradesSource: trades,
|
tradesSource: trades,
|
||||||
|
ordersSource: orders,
|
||||||
// fiatConvertationService: fiatConvertationService,
|
// fiatConvertationService: fiatConvertationService,
|
||||||
templates: templates,
|
templates: templates,
|
||||||
exchangeTemplates: exchangeTemplates,
|
exchangeTemplates: exchangeTemplates,
|
||||||
|
@ -118,6 +128,7 @@ Future<void> initialSetup(
|
||||||
@required Box<WalletInfo> walletInfoSource,
|
@required Box<WalletInfo> walletInfoSource,
|
||||||
@required Box<Contact> contactSource,
|
@required Box<Contact> contactSource,
|
||||||
@required Box<Trade> tradesSource,
|
@required Box<Trade> tradesSource,
|
||||||
|
@required Box<Order> ordersSource,
|
||||||
// @required FiatConvertationService fiatConvertationService,
|
// @required FiatConvertationService fiatConvertationService,
|
||||||
@required Box<Template> templates,
|
@required Box<Template> templates,
|
||||||
@required Box<ExchangeTemplate> exchangeTemplates,
|
@required Box<ExchangeTemplate> exchangeTemplates,
|
||||||
|
@ -139,7 +150,8 @@ Future<void> initialSetup(
|
||||||
tradesSource: tradesSource,
|
tradesSource: tradesSource,
|
||||||
templates: templates,
|
templates: templates,
|
||||||
exchangeTemplates: exchangeTemplates,
|
exchangeTemplates: exchangeTemplates,
|
||||||
transactionDescriptionBox: transactionDescriptions);
|
transactionDescriptionBox: transactionDescriptions,
|
||||||
|
ordersSource: ordersSource);
|
||||||
await bootstrap(navigatorKey);
|
await bootstrap(navigatorKey);
|
||||||
monero_wallet.onStartup();
|
monero_wallet.onStartup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import 'package:cake_wallet/entities/contact_record.dart';
|
import 'package:cake_wallet/entities/contact_record.dart';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||||
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
|
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
|
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
|
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
|
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/support/support_page.dart';
|
import 'package:cake_wallet/src/screens/support/support_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
|
||||||
import 'package:cake_wallet/store/settings_store.dart';
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
@ -285,6 +288,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
builder: (_) =>
|
builder: (_) =>
|
||||||
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
|
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
|
||||||
|
|
||||||
|
case Routes.orderDetails:
|
||||||
|
return MaterialPageRoute<void>(
|
||||||
|
builder: (_) =>
|
||||||
|
getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
|
||||||
|
|
||||||
|
case Routes.wyre:
|
||||||
|
return MaterialPageRoute<void>(
|
||||||
|
builder: (_) =>
|
||||||
|
getIt.get<WyrePage>(param1: settings.arguments as String));
|
||||||
|
|
||||||
case Routes.restoreWalletFromSeedDetails:
|
case Routes.restoreWalletFromSeedDetails:
|
||||||
final args = settings.arguments as List;
|
final args = settings.arguments as List;
|
||||||
final walletRestorationFromSeedVM =
|
final walletRestorationFromSeedVM =
|
||||||
|
|
|
@ -52,4 +52,6 @@ class Routes {
|
||||||
static const editBackupPassword = '/edit_backup_passowrd';
|
static const editBackupPassword = '/edit_backup_passowrd';
|
||||||
static const restoreFromBackup = '/restore_from_backup';
|
static const restoreFromBackup = '/restore_from_backup';
|
||||||
static const support = '/support';
|
static const support = '/support';
|
||||||
|
static const orderDetails = '/order_details';
|
||||||
|
static const wyre = '/wyre';
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
|
@ -12,7 +13,9 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
||||||
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
|
||||||
class DashboardPage extends BasePage {
|
class DashboardPage extends BasePage {
|
||||||
DashboardPage({
|
DashboardPage({
|
||||||
|
@ -81,7 +84,7 @@ class DashboardPage extends BasePage {
|
||||||
final exchangeImage = Image.asset('assets/images/transfer.png',
|
final exchangeImage = Image.asset('assets/images/transfer.png',
|
||||||
height: 24.27, width: 22.25,
|
height: 24.27, width: 22.25,
|
||||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||||
final receiveImage = Image.asset('assets/images/download.png',
|
final buyImage = Image.asset('assets/images/coins.png',
|
||||||
height: 22.24, width: 24,
|
height: 22.24, width: 24,
|
||||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||||
_setEffects();
|
_setEffects();
|
||||||
|
@ -111,7 +114,7 @@ class DashboardPage extends BasePage {
|
||||||
)),
|
)),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(left: 45, right: 45, bottom: 24),
|
padding: EdgeInsets.only(left: 45, right: 45, bottom: 24),
|
||||||
child: Row(
|
child: Observer(builder: (_) => Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ActionButton(
|
ActionButton(
|
||||||
|
@ -122,8 +125,41 @@ class DashboardPage extends BasePage {
|
||||||
image: exchangeImage,
|
image: exchangeImage,
|
||||||
title: S.of(context).exchange,
|
title: S.of(context).exchange,
|
||||||
route: Routes.exchange),
|
route: Routes.exchange),
|
||||||
],
|
if (walletViewModel.type == WalletType.bitcoin) Observer(
|
||||||
|
builder: (_) => Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
children: [
|
||||||
|
if (walletViewModel.isRunningWebView) Positioned(
|
||||||
|
top: -5,
|
||||||
|
child: SpinKitRing(
|
||||||
|
color: Theme.of(context).buttonColor,
|
||||||
|
lineWidth: 3,
|
||||||
|
size: 70.0,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
ActionButton(
|
||||||
|
image: buyImage,
|
||||||
|
title: S.of(context).buy,
|
||||||
|
onClick: walletViewModel.isRunningWebView
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
try {
|
||||||
|
walletViewModel.isRunningWebView = true;
|
||||||
|
final url =
|
||||||
|
await walletViewModel.wyreViewModel.wyreUrl;
|
||||||
|
await Navigator.of(context)
|
||||||
|
.pushNamed(Routes.wyre, arguments: url);
|
||||||
|
walletViewModel.isRunningWebView = false;
|
||||||
|
} catch(e) {
|
||||||
|
print(e.toString());
|
||||||
|
walletViewModel.isRunningWebView = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
|
@ -4,13 +4,15 @@ class ActionButton extends StatelessWidget {
|
||||||
ActionButton(
|
ActionButton(
|
||||||
{@required this.image,
|
{@required this.image,
|
||||||
@required this.title,
|
@required this.title,
|
||||||
@required this.route,
|
this.route,
|
||||||
|
this.onClick,
|
||||||
this.alignment = Alignment.center});
|
this.alignment = Alignment.center});
|
||||||
|
|
||||||
final Image image;
|
final Image image;
|
||||||
final String title;
|
final String title;
|
||||||
final String route;
|
final String route;
|
||||||
final Alignment alignment;
|
final Alignment alignment;
|
||||||
|
final void Function() onClick;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -23,8 +25,10 @@ class ActionButton extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (route.isNotEmpty) {
|
if (route?.isNotEmpty ?? false) {
|
||||||
Navigator.of(context, rootNavigator: true).pushNamed(route);
|
Navigator.of(context, rootNavigator: true).pushNamed(route);
|
||||||
|
} else {
|
||||||
|
onClick?.call();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
72
lib/src/screens/dashboard/widgets/order_row.dart
Normal file
72
lib/src/screens/dashboard/widgets/order_row.dart
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class OrderRow extends StatelessWidget {
|
||||||
|
OrderRow({
|
||||||
|
@required this.onTap,
|
||||||
|
this.from,
|
||||||
|
this.to,
|
||||||
|
this.createdAtFormattedDate,
|
||||||
|
this.formattedAmount});
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final String from;
|
||||||
|
final String to;
|
||||||
|
final String createdAtFormattedDate;
|
||||||
|
final String formattedAmount;
|
||||||
|
final wyreImage =
|
||||||
|
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
wyreImage,
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Text('$from → $to',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).accentTextTheme.
|
||||||
|
display3.backgroundColor
|
||||||
|
)),
|
||||||
|
formattedAmount != null
|
||||||
|
? Text(formattedAmount + ' ' + to,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).accentTextTheme.
|
||||||
|
display3.backgroundColor
|
||||||
|
))
|
||||||
|
: Container()
|
||||||
|
]),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(createdAtFormattedDate,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Theme.of(context).textTheme
|
||||||
|
.overline.backgroundColor))
|
||||||
|
])
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
|
||||||
|
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
|
@ -75,6 +77,21 @@ class TransactionsPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item is OrderListItem) {
|
||||||
|
final order = item.order;
|
||||||
|
|
||||||
|
return OrderRow(
|
||||||
|
onTap: () => Navigator.of(context).pushNamed(
|
||||||
|
Routes.orderDetails,
|
||||||
|
arguments: order),
|
||||||
|
from: order.from,
|
||||||
|
to: order.to,
|
||||||
|
createdAtFormattedDate:
|
||||||
|
DateFormat('HH:mm').format(order.createdAt),
|
||||||
|
formattedAmount: item.orderFormattedAmount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
height: 1);
|
height: 1);
|
||||||
|
|
47
lib/src/screens/order_details/order_details_page.dart
Normal file
47
lib/src/screens/order_details/order_details_page.dart
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
|
import 'package:cake_wallet/view_model/order_details_view_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
|
||||||
|
|
||||||
|
class OrderDetailsPage extends BasePage {
|
||||||
|
OrderDetailsPage(this.orderDetailsViewModel);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get title => 'Order Details';
|
||||||
|
|
||||||
|
final OrderDetailsViewModel orderDetailsViewModel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget body(BuildContext context) {
|
||||||
|
return Observer(builder: (_) {
|
||||||
|
return SectionStandardList(
|
||||||
|
sectionCount: 1,
|
||||||
|
itemCounter: (int _) => orderDetailsViewModel.items.length,
|
||||||
|
itemBuilder: (_, __, index) {
|
||||||
|
final item = orderDetailsViewModel.items[index];
|
||||||
|
|
||||||
|
if (item is TrackTradeListItem) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: item.onTap,
|
||||||
|
child: StandartListRow(
|
||||||
|
title: '${item.title}', value: '${item.value}'));
|
||||||
|
} else {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Clipboard.setData(ClipboardData(text: '${item.value}'));
|
||||||
|
showBar<void>(context, S.of(context).copied_to_clipboard);
|
||||||
|
},
|
||||||
|
child: StandartListRow(
|
||||||
|
title: '${item.title}', value: '${item.value}'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
97
lib/src/screens/wyre/wyre_page.dart
Normal file
97
lib/src/screens/wyre/wyre_page.dart
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wyre_view_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
|
class WyrePage extends BasePage {
|
||||||
|
WyrePage(this.wyreViewModel,
|
||||||
|
{@required this.ordersStore, @required this.url});
|
||||||
|
|
||||||
|
final OrdersStore ordersStore;
|
||||||
|
final String url;
|
||||||
|
final WyreViewModel wyreViewModel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get title => S.current.buy;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get backgroundDarkColor => Colors.white;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get titleColor => Palette.darkBlueCraiola;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget body(BuildContext context) =>
|
||||||
|
WyrePageBody(wyreViewModel, ordersStore: ordersStore, url: url);
|
||||||
|
}
|
||||||
|
|
||||||
|
class WyrePageBody extends StatefulWidget {
|
||||||
|
WyrePageBody(this.wyreViewModel, {this.ordersStore, this.url});
|
||||||
|
|
||||||
|
final OrdersStore ordersStore;
|
||||||
|
final String url;
|
||||||
|
final WyreViewModel wyreViewModel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
WyrePageBodyState createState() => WyrePageBodyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class WyrePageBodyState extends State<WyrePageBody> {
|
||||||
|
String orderId;
|
||||||
|
WebViewController _webViewController;
|
||||||
|
GlobalKey _webViewkey;
|
||||||
|
Timer _timer;
|
||||||
|
bool _isSaving;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_webViewkey = GlobalKey();
|
||||||
|
_isSaving = false;
|
||||||
|
widget.ordersStore.orderId = '';
|
||||||
|
|
||||||
|
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
||||||
|
|
||||||
|
_timer?.cancel();
|
||||||
|
_timer = Timer.periodic(Duration(seconds: 1), (timer) async {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (_webViewController == null || _isSaving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final url = await _webViewController.currentUrl();
|
||||||
|
|
||||||
|
if (url.contains('completed')) {
|
||||||
|
final urlParts = url.split('/');
|
||||||
|
orderId = urlParts.last;
|
||||||
|
widget.ordersStore.orderId = orderId;
|
||||||
|
|
||||||
|
if (orderId.isNotEmpty) {
|
||||||
|
_isSaving = true;
|
||||||
|
await widget.wyreViewModel.saveOrder(orderId);
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_isSaving = false;
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WebView(
|
||||||
|
key: _webViewkey,
|
||||||
|
initialUrl: widget.url,
|
||||||
|
javascriptMode: JavascriptMode.unrestricted,
|
||||||
|
onWebViewCreated: (WebViewController controller) =>
|
||||||
|
setState(() => _webViewController = controller));
|
||||||
|
}
|
||||||
|
}
|
45
lib/store/dashboard/orders_store.dart
Normal file
45
lib/store/dashboard/orders_store.dart
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
|
||||||
|
part 'orders_store.g.dart';
|
||||||
|
|
||||||
|
class OrdersStore = OrdersStoreBase with _$OrdersStore;
|
||||||
|
|
||||||
|
abstract class OrdersStoreBase with Store {
|
||||||
|
OrdersStoreBase({this.ordersSource, this.settingsStore}) {
|
||||||
|
orders = <OrderListItem>[];
|
||||||
|
|
||||||
|
orderId = '';
|
||||||
|
|
||||||
|
_onOrdersChanged =
|
||||||
|
ordersSource.watch().listen((_) async => await updateOrderList());
|
||||||
|
|
||||||
|
updateOrderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Box<Order> ordersSource;
|
||||||
|
StreamSubscription<BoxEvent> _onOrdersChanged;
|
||||||
|
SettingsStore settingsStore;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
List<OrderListItem> orders;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
Order order;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String orderId;
|
||||||
|
|
||||||
|
@action
|
||||||
|
void setOrder(Order order) => this.order = order;
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future updateOrderList() async => orders =
|
||||||
|
ordersSource.values.map((order) => OrderListItem(
|
||||||
|
order: order,
|
||||||
|
displayMode: settingsStore.balanceDisplayMode)).toList();
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ abstract class SettingsStoreBase with Store {
|
||||||
@required Map<WalletType, Node> nodes,
|
@required Map<WalletType, Node> nodes,
|
||||||
@required TransactionPriority initialBitcoinTransactionPriority,
|
@required TransactionPriority initialBitcoinTransactionPriority,
|
||||||
@required TransactionPriority initialMoneroTransactionPriority,
|
@required TransactionPriority initialMoneroTransactionPriority,
|
||||||
|
@required this.isBitcoinBuyEnabled,
|
||||||
this.actionlistDisplayMode}) {
|
this.actionlistDisplayMode}) {
|
||||||
fiatCurrency = initialFiatCurrency;
|
fiatCurrency = initialFiatCurrency;
|
||||||
balanceDisplayMode = initialBalanceDisplayMode;
|
balanceDisplayMode = initialBalanceDisplayMode;
|
||||||
|
@ -144,8 +145,11 @@ abstract class SettingsStoreBase with Store {
|
||||||
|
|
||||||
Node getCurrentNode(WalletType walletType) => nodes[walletType];
|
Node getCurrentNode(WalletType walletType) => nodes[walletType];
|
||||||
|
|
||||||
|
bool isBitcoinBuyEnabled;
|
||||||
|
|
||||||
static Future<SettingsStore> load(
|
static Future<SettingsStore> load(
|
||||||
{@required Box<Node> nodeSource,
|
{@required Box<Node> nodeSource,
|
||||||
|
@required bool isBitcoinBuyEnabled,
|
||||||
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
||||||
MoneroTransactionPriority initialMoneroTransactionPriority =
|
MoneroTransactionPriority initialMoneroTransactionPriority =
|
||||||
MoneroTransactionPriority.slow,
|
MoneroTransactionPriority.slow,
|
||||||
|
@ -212,6 +216,7 @@ abstract class SettingsStoreBase with Store {
|
||||||
WalletType.bitcoin: bitcoinElectrumServer
|
WalletType.bitcoin: bitcoinElectrumServer
|
||||||
},
|
},
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
|
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
|
||||||
initialFiatCurrency: currentFiatCurrency,
|
initialFiatCurrency: currentFiatCurrency,
|
||||||
initialBalanceDisplayMode: currentBalanceDisplayMode,
|
initialBalanceDisplayMode: currentBalanceDisplayMode,
|
||||||
initialSaveRecipientAddress: shouldSaveRecipientAddress,
|
initialSaveRecipientAddress: shouldSaveRecipientAddress,
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
||||||
import 'package:cake_wallet/entities/balance.dart';
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_history.dart';
|
import 'package:cake_wallet/entities/transaction_history.dart';
|
||||||
|
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||||
import 'package:cake_wallet/monero/account.dart';
|
import 'package:cake_wallet/monero/account.dart';
|
||||||
import 'package:cake_wallet/monero/monero_balance.dart';
|
import 'package:cake_wallet/monero/monero_balance.dart';
|
||||||
import 'package:cake_wallet/monero/monero_transaction_history.dart';
|
import 'package:cake_wallet/monero/monero_transaction_history.dart';
|
||||||
|
@ -13,13 +18,21 @@ import 'package:cake_wallet/entities/transaction_direction.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_info.dart';
|
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||||
import 'package:cake_wallet/exchange/trade.dart';
|
import 'package:cake_wallet/exchange/trade.dart';
|
||||||
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
import 'package:cake_wallet/utils/mobx.dart';
|
import 'package:cake_wallet/utils/mobx.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
|
||||||
|
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/action_list_display_mode.dart';
|
import 'package:cake_wallet/view_model/dashboard/action_list_display_mode.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wyre_view_model.dart';
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/core/wallet_base.dart';
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
|
@ -30,6 +43,8 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
|
||||||
import 'package:cake_wallet/store/dashboard/trade_filter_store.dart';
|
import 'package:cake_wallet/store/dashboard/trade_filter_store.dart';
|
||||||
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
|
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/formatted_item_list.dart';
|
import 'package:cake_wallet/view_model/dashboard/formatted_item_list.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:convert/convert.dart';
|
||||||
|
|
||||||
part 'dashboard_view_model.g.dart';
|
part 'dashboard_view_model.g.dart';
|
||||||
|
|
||||||
|
@ -41,7 +56,11 @@ abstract class DashboardViewModelBase with Store {
|
||||||
this.appStore,
|
this.appStore,
|
||||||
this.tradesStore,
|
this.tradesStore,
|
||||||
this.tradeFilterStore,
|
this.tradeFilterStore,
|
||||||
this.transactionFilterStore}) {
|
this.transactionFilterStore,
|
||||||
|
this.settingsStore,
|
||||||
|
this.ordersSource,
|
||||||
|
this.ordersStore,
|
||||||
|
this.wyreViewModel}) {
|
||||||
filterItems = {
|
filterItems = {
|
||||||
S.current.transactions: [
|
S.current.transactions: [
|
||||||
FilterItem(
|
FilterItem(
|
||||||
|
@ -76,6 +95,8 @@ abstract class DashboardViewModelBase with Store {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
isRunningWebView = false;
|
||||||
|
|
||||||
name = appStore.wallet?.name;
|
name = appStore.wallet?.name;
|
||||||
wallet ??= appStore.wallet;
|
wallet ??= appStore.wallet;
|
||||||
type = wallet.type;
|
type = wallet.type;
|
||||||
|
@ -141,6 +162,9 @@ abstract class DashboardViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
String subname;
|
String subname;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isRunningWebView;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
String get address => wallet.address;
|
String get address => wallet.address;
|
||||||
|
|
||||||
|
@ -171,6 +195,11 @@ abstract class DashboardViewModelBase with Store {
|
||||||
.where((trade) => trade.trade.walletId == wallet.id)
|
.where((trade) => trade.trade.walletId == wallet.id)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
@computed
|
||||||
|
List<OrderListItem> get orders => ordersStore.orders
|
||||||
|
.where((item) => item.order.walletId == wallet.id)
|
||||||
|
.toList();
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
double get price => balanceViewModel.price;
|
double get price => balanceViewModel.price;
|
||||||
|
|
||||||
|
@ -180,6 +209,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
_items.addAll(transactionFilterStore.filtered(transactions: transactions));
|
_items.addAll(transactionFilterStore.filtered(transactions: transactions));
|
||||||
_items.addAll(tradeFilterStore.filtered(trades: trades, wallet: wallet));
|
_items.addAll(tradeFilterStore.filtered(trades: trades, wallet: wallet));
|
||||||
|
_items.addAll(orders);
|
||||||
|
|
||||||
return formattedItemsList(_items);
|
return formattedItemsList(_items);
|
||||||
}
|
}
|
||||||
|
@ -189,18 +219,28 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
bool get hasRescan => wallet.type == WalletType.monero;
|
bool get hasRescan => wallet.type == WalletType.monero;
|
||||||
|
|
||||||
|
Box<Order> ordersSource;
|
||||||
|
|
||||||
BalanceViewModel balanceViewModel;
|
BalanceViewModel balanceViewModel;
|
||||||
|
|
||||||
AppStore appStore;
|
AppStore appStore;
|
||||||
|
|
||||||
|
SettingsStore settingsStore;
|
||||||
|
|
||||||
TradesStore tradesStore;
|
TradesStore tradesStore;
|
||||||
|
|
||||||
|
OrdersStore ordersStore;
|
||||||
|
|
||||||
TradeFilterStore tradeFilterStore;
|
TradeFilterStore tradeFilterStore;
|
||||||
|
|
||||||
TransactionFilterStore transactionFilterStore;
|
TransactionFilterStore transactionFilterStore;
|
||||||
|
|
||||||
|
WyreViewModel wyreViewModel;
|
||||||
|
|
||||||
Map<String, List<FilterItem>> filterItems;
|
Map<String, List<FilterItem>> filterItems;
|
||||||
|
|
||||||
|
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
|
||||||
|
|
||||||
ReactionDisposer _reaction;
|
ReactionDisposer _reaction;
|
||||||
|
|
||||||
ReactionDisposer _onMoneroAccountChangeReaction;
|
ReactionDisposer _onMoneroAccountChangeReaction;
|
||||||
|
@ -279,4 +319,6 @@ abstract class DashboardViewModelBase with Store {
|
||||||
balanceViewModel: balanceViewModel,
|
balanceViewModel: balanceViewModel,
|
||||||
settingsStore: appStore.settingsStore)));
|
settingsStore: appStore.settingsStore)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
21
lib/view_model/dashboard/order_list_item.dart
Normal file
21
lib/view_model/dashboard/order_list_item.dart
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
||||||
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
|
|
||||||
|
class OrderListItem extends ActionListItem {
|
||||||
|
OrderListItem({this.order, this.displayMode});
|
||||||
|
|
||||||
|
final Order order;
|
||||||
|
final BalanceDisplayMode displayMode;
|
||||||
|
|
||||||
|
String get orderFormattedAmount {
|
||||||
|
return order.amount != null
|
||||||
|
? displayMode == BalanceDisplayMode.hiddenBalance
|
||||||
|
? '---'
|
||||||
|
: order.amountFormatted()
|
||||||
|
: order.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime get date => order.createdAt;
|
||||||
|
}
|
85
lib/view_model/order_details_view_model.dart
Normal file
85
lib/view_model/order_details_view_model.dart
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wyre_view_model.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
part 'order_details_view_model.g.dart';
|
||||||
|
|
||||||
|
class OrderDetailsViewModel = OrderDetailsViewModelBase
|
||||||
|
with _$OrderDetailsViewModel;
|
||||||
|
|
||||||
|
abstract class OrderDetailsViewModelBase with Store {
|
||||||
|
OrderDetailsViewModelBase({this.wyreViewModel, Order orderForDetails}) {
|
||||||
|
order = orderForDetails;
|
||||||
|
|
||||||
|
items = ObservableList<StandartListItem>();
|
||||||
|
|
||||||
|
_updateItems();
|
||||||
|
|
||||||
|
_updateOrder();
|
||||||
|
|
||||||
|
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@observable
|
||||||
|
Order order;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
ObservableList<StandartListItem> items;
|
||||||
|
|
||||||
|
WyreViewModel wyreViewModel;
|
||||||
|
|
||||||
|
Timer _timer;
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> _updateOrder() async {
|
||||||
|
try {
|
||||||
|
final updatedOrder =
|
||||||
|
await wyreViewModel.wyreService.findOrderById(order.id);
|
||||||
|
|
||||||
|
updatedOrder.receiveAddress = order.receiveAddress;
|
||||||
|
updatedOrder.walletId = order.walletId;
|
||||||
|
order = updatedOrder;
|
||||||
|
|
||||||
|
_updateItems();
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateItems() {
|
||||||
|
final dateFormat = DateFormatter.withCurrentLocal();
|
||||||
|
final buildURL =
|
||||||
|
wyreViewModel.trackUrl + '${order.transferId}';
|
||||||
|
|
||||||
|
items?.clear();
|
||||||
|
|
||||||
|
items.addAll([
|
||||||
|
StandartListItem(
|
||||||
|
title: 'Transfer ID',
|
||||||
|
value: order.transferId),
|
||||||
|
StandartListItem(
|
||||||
|
title: S.current.trade_details_state,
|
||||||
|
value: order.state != null
|
||||||
|
? order.state.toString()
|
||||||
|
: S.current.trade_details_fetching),
|
||||||
|
TrackTradeListItem(
|
||||||
|
title: 'Track',
|
||||||
|
value: buildURL,
|
||||||
|
onTap: () {
|
||||||
|
launch(buildURL);
|
||||||
|
}),
|
||||||
|
StandartListItem(
|
||||||
|
title: S.current.trade_details_created_at,
|
||||||
|
value: dateFormat.format(order.createdAt).toString()),
|
||||||
|
StandartListItem(
|
||||||
|
title: S.current.trade_details_pair,
|
||||||
|
value: '${order.from} → ${order.to}')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -188,6 +188,8 @@ abstract class SettingsViewModelBase with Store {
|
||||||
@computed
|
@computed
|
||||||
ThemeBase get theme => _settingsStore.currentTheme;
|
ThemeBase get theme => _settingsStore.currentTheme;
|
||||||
|
|
||||||
|
bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled;
|
||||||
|
|
||||||
final Map<String, String> itemHeaders;
|
final Map<String, String> itemHeaders;
|
||||||
List<List<SettingsListItem>> sections;
|
List<List<SettingsListItem>> sections;
|
||||||
final SettingsStore _settingsStore;
|
final SettingsStore _settingsStore;
|
||||||
|
|
42
lib/view_model/wyre_view_model.dart
Normal file
42
lib/view_model/wyre_view_model.dart
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import 'package:cake_wallet/entities/wyre_service.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
part 'wyre_view_model.g.dart';
|
||||||
|
|
||||||
|
class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
|
||||||
|
|
||||||
|
abstract class WyreViewModelBase with Store {
|
||||||
|
WyreViewModelBase(this.ordersSource, this.ordersStore,
|
||||||
|
{@required this.walletId, @required this.address, @required this.type,
|
||||||
|
@required this.wyreService});
|
||||||
|
|
||||||
|
Future<String> get wyreUrl => wyreService.getWyreUrl();
|
||||||
|
|
||||||
|
String get trackUrl => wyreService.trackUrl;
|
||||||
|
|
||||||
|
final Box<Order> ordersSource;
|
||||||
|
final OrdersStore ordersStore;
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
final WalletType type;
|
||||||
|
final String address;
|
||||||
|
|
||||||
|
final WyreService wyreService;
|
||||||
|
|
||||||
|
Future<void> saveOrder(String orderId) async {
|
||||||
|
try {
|
||||||
|
final order = await wyreService.findOrderById(orderId);
|
||||||
|
order.receiveAddress = address;
|
||||||
|
order.walletId = walletId;
|
||||||
|
await ordersSource.add(order);
|
||||||
|
ordersStore.setOrder(order);
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
pubspec.lock
14
pubspec.lock
|
@ -426,6 +426,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.7"
|
version: "0.5.7"
|
||||||
|
flutter_spinkit:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_spinkit
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2+1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -1029,6 +1036,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
webview_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: webview_flutter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.7"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: Cake Wallet.
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 4.1.2+41
|
version: 4.1.3+42
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
|
@ -55,6 +55,8 @@ dependencies:
|
||||||
auto_size_text: ^2.1.0
|
auto_size_text: ^2.1.0
|
||||||
dotted_border: ^1.0.5
|
dotted_border: ^1.0.5
|
||||||
smooth_page_indicator: ^0.2.0
|
smooth_page_indicator: ^0.2.0
|
||||||
|
webview_flutter: ^1.0.7
|
||||||
|
flutter_spinkit: ^4.1.2
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
@ -112,7 +114,7 @@ flutter:
|
||||||
fonts:
|
fonts:
|
||||||
- asset: assets/fonts/Lato-Regular.ttf
|
- asset: assets/fonts/Lato-Regular.ttf
|
||||||
- asset: assets/fonts/Lato-Medium.ttf
|
- asset: assets/fonts/Lato-Medium.ttf
|
||||||
- asset: assets/fonts/Lato-SemiBold.ttf
|
- asset: assets/fonts/Lato-Semibold.ttf
|
||||||
- asset: assets/fonts/Lato-Bold.ttf
|
- asset: assets/fonts/Lato-Bold.ttf
|
||||||
|
|
||||||
|
|
||||||
|
|
8
scripts/android/build_all.sh
Executable file
8
scripts/android/build_all.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
./build_iconv.sh
|
||||||
|
./build_boost.sh
|
||||||
|
./build_openssl.sh
|
||||||
|
./build_sodium.sh
|
||||||
|
./build_zmq.sh
|
||||||
|
./build_monero.sh
|
16
scripts/android/build_boost.sh
Executable file
16
scripts/android/build_boost.sh
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=$WORKDIR/prefix_${arch}
|
||||||
|
PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
|
||||||
|
|
||||||
|
./init_boost.sh $arch
|
||||||
|
./finish_boost.sh $arch
|
||||||
|
|
||||||
|
done
|
38
scripts/android/build_iconv.sh
Executable file
38
scripts/android/build_iconv.sh
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
export WORKDIR=/opt/android
|
||||||
|
export ICONV_FILENAME=libiconv-1.15.tar.gz
|
||||||
|
export ICONV_FILE_PATH=$WORKDIR/$ICONV_FILENAME
|
||||||
|
export ICONV_SRC_DIR=$WORKDIR/libiconv-1.15
|
||||||
|
|
||||||
|
wget http://ftp.gnu.org/pub/gnu/libiconv/$ICONV_FILENAME -O $ICONV_FILE_PATH
|
||||||
|
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
|
||||||
|
for arch in aarch aarch64 i686 x86_64
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=${WORKDIR}/prefix_${arch}
|
||||||
|
PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" )
|
||||||
|
CLANG=arm-linux-androideabi-clang
|
||||||
|
CXXLANG=arm-linux-androideabi-clang++
|
||||||
|
HOST="arm-linux-android";;
|
||||||
|
* )
|
||||||
|
CLANG=${arch}-linux-android-clang
|
||||||
|
CXXLANG=${arch}-linux-android-clang++
|
||||||
|
HOST="${arch}-linux-android";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cd $WORKDIR
|
||||||
|
rm -rf $ICONV_SRC_DIR
|
||||||
|
tar -xzf $ICONV_FILE_PATH -C $WORKDIR
|
||||||
|
cd $ICONV_SRC_DIR
|
||||||
|
CC=${CLANG} CXX=${CXXLANG} ./configure --build=x86_64-linux-gnu --host=${HOST} --prefix=${PREFIX} --disable-rpath
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
done
|
70
scripts/android/build_monero.sh
Executable file
70
scripts/android/build_monero.sh
Executable file
|
@ -0,0 +1,70 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
MONERO_BRANCH=v0.17.1.9-android
|
||||||
|
MONERO_SRC_DIR=${WORKDIR}/monero
|
||||||
|
|
||||||
|
git clone https://github.com/cake-tech/monero.git ${MONERO_SRC_DIR} --branch ${MONERO_BRANCH}
|
||||||
|
cd $MONERO_SRC_DIR
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
FLAGS=""
|
||||||
|
PREFIX=${WORKDIR}/prefix_${arch}
|
||||||
|
ANDROID_STANDALONE_TOOLCHAIN_PATH="${TOOLCHAIN_BASE_DIR}_${arch}"
|
||||||
|
PATH="${ANDROID_STANDALONE_TOOLCHAIN_PATH}/bin:${ORIGINAL_PATH}"
|
||||||
|
DEST_LIB_DIR=${PREFIX}/lib/monero
|
||||||
|
DEST_INCLUDE_DIR=${PREFIX}/include
|
||||||
|
export CMAKE_INCLUDE_PATH="${PREFIX}/include"
|
||||||
|
export CMAKE_LIBRARY_PATH="${PREFIX}/lib"
|
||||||
|
|
||||||
|
mkdir -p $DEST_LIB_DIR
|
||||||
|
mkdir -p $DEST_INCLUDE_DIR
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" )
|
||||||
|
CLANG=arm-linux-androideabi-clang
|
||||||
|
CXXLANG=arm-linux-androideabi-clang++
|
||||||
|
BUILD_64=OFF
|
||||||
|
TAG="android-armv7"
|
||||||
|
ARCH="armv7-a"
|
||||||
|
ARCH_ABI="armeabi-v7a"
|
||||||
|
FLAGS="-D CMAKE_ANDROID_ARM_MODE=ON -D NO_AES=true";;
|
||||||
|
"aarch64" )
|
||||||
|
CLANG=aarch64-linux-androideabi-clang
|
||||||
|
CXXLANG=aarch64-linux-androideabi-clang++
|
||||||
|
BUILD_64=ON
|
||||||
|
TAG="android-armv8"
|
||||||
|
ARCH="armv8-a"
|
||||||
|
ARCH_ABI="arm64-v8a";;
|
||||||
|
"i686" )
|
||||||
|
CLANG=i686-linux-androideabi-clang
|
||||||
|
CXXLANG=i686-linux-androideabi-clang++
|
||||||
|
BUILD_64=OFF
|
||||||
|
TAG="android-x86"
|
||||||
|
ARCH="i686"
|
||||||
|
ARCH_ABI="x86";;
|
||||||
|
"x86_64" )
|
||||||
|
CLANG=x86_64-linux-androideabi-clang
|
||||||
|
CXXLANG=x86_64-linux-androideabi-clang++
|
||||||
|
BUILD_64=ON
|
||||||
|
TAG="android-x86_64"
|
||||||
|
ARCH="x86-64"
|
||||||
|
ARCH_ABI="x86_64";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cd $MONERO_SRC_DIR
|
||||||
|
rm -rf ./build/release
|
||||||
|
mkdir -p ./build/release
|
||||||
|
cd ./build/release
|
||||||
|
CC=${CLANG} CXX=${CXXLANG} cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH=${ARCH} -D STATIC=ON -D BUILD_64=${BUILD_64} -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG=${TAG} -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI=${ARCH_ABI} $FLAGS ../..
|
||||||
|
make wallet_api -j4
|
||||||
|
find . -path ./lib -prune -o -name '*.a' -exec cp '{}' lib \;
|
||||||
|
|
||||||
|
cp -r ./lib/* $DEST_LIB_DIR
|
||||||
|
cp ../../src/wallet/api/wallet2_api.h $DEST_INCLUDE_DIR
|
||||||
|
done
|
44
scripts/android/build_openssl.sh
Executable file
44
scripts/android/build_openssl.sh
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
OPENSSL_FILENAME=openssl-1.0.2p.tar.gz
|
||||||
|
OPENSSL_FILE_PATH=$WORKDIR/$OPENSSL_FILENAME
|
||||||
|
OPENSSL_SRC_DIR=$WORKDIR/openssl-1.0.2p
|
||||||
|
ZLIB_FILENAME=zlib-1.2.11.tar.gz
|
||||||
|
ZLIB_FILE_PATH=$WORKDIR/$ZLIB_FILENAME
|
||||||
|
ZLIB_SRC_DIR=$WORKDIR/zlib-1.2.11
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
|
||||||
|
wget https://zlib.net/$ZLIB_FILENAME -O $ZLIB_FILE_PATH
|
||||||
|
tar -xzf $ZLIB_FILE_PATH -C $WORKDIR
|
||||||
|
cd $ZLIB_SRC_DIR
|
||||||
|
CC=clang CXX=clang++ ./configure --static
|
||||||
|
make
|
||||||
|
|
||||||
|
wget https://www.openssl.org/source/$OPENSSL_FILENAME -O $OPENSSL_FILE_PATH
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=$WORKDIR/prefix_${arch}
|
||||||
|
PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" ) TARGET="armv7";;
|
||||||
|
* ) TARGET="${arch}";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cd $WORKDIR
|
||||||
|
rm -rf $OPENSSL_SRC_DIR
|
||||||
|
tar -xzf $OPENSSL_FILE_PATH -C $WORKDIR
|
||||||
|
cd $OPENSSL_SRC_DIR
|
||||||
|
sed -i -e "s/mandroid/target\ ${TARGET}\-linux\-android/" Configure
|
||||||
|
CC=clang CXX=clang++ ./Configure android no-asm no-shared --static --with-zlib-include=${WORKDIR}/zlib --with-zlib-lib=${ZLIB_SRC_DIR} --prefix=${PREFIX} --openssldir=${PREFIX}
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
31
scripts/android/build_sodium.sh
Executable file
31
scripts/android/build_sodium.sh
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
SODIUM_SRC_DIR=${WORKDIR}/libsodium
|
||||||
|
SODIUM_BRANCH=1.0.16
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=$WORKDIR/prefix_${arch}
|
||||||
|
PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" ) TARGET="arm";;
|
||||||
|
"i686" ) TARGET="x86";;
|
||||||
|
* ) TARGET="${arch}";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
HOST="${TARGET}-linux-android"
|
||||||
|
cd $WORKDIR
|
||||||
|
rm -rf $SODIUM_SRC_DIR
|
||||||
|
git clone https://github.com/jedisct1/libsodium.git $SODIUM_SRC_DIR -b $SODIUM_BRANCH
|
||||||
|
cd $SODIUM_SRC_DIR
|
||||||
|
./autogen.sh
|
||||||
|
CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=${HOST} --enable-static --disable-shared
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
done
|
34
scripts/android/build_zmq.sh
Executable file
34
scripts/android/build_zmq.sh
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
TOOLCHAIN_BASE_DIR=${WORKDIR}/toolchain
|
||||||
|
ZMQ_SRC_DIR=$WORKDIR/libzmq
|
||||||
|
ZMQ_BRANCH=master
|
||||||
|
ZMQ_COMMIT_HASH=501d0815bf2b0abb93be8214fc66519918ef6c40
|
||||||
|
ORIGINAL_PATH=$PATH
|
||||||
|
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=$WORKDIR/prefix_${arch}
|
||||||
|
PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" ) TARGET="arm";;
|
||||||
|
"i686" ) TARGET="x86";;
|
||||||
|
* ) TARGET="${arch}";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
HOST="${TARGET}-linux-android"
|
||||||
|
cd $WORKDIR
|
||||||
|
rm -rf $ZMQ_SRC_DIR
|
||||||
|
git clone https://github.com/zeromq/libzmq.git ${ZMQ_SRC_DIR} -b ${ZMQ_BRANCH}
|
||||||
|
cd $ZMQ_SRC_DIR
|
||||||
|
git checkout ${ZMQ_COMMIT_HASH}
|
||||||
|
./autogen.sh
|
||||||
|
CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=${HOST} --enable-static --disable-shared
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
done
|
34
scripts/android/copy_monero_deps.sh
Executable file
34
scripts/android/copy_monero_deps.sh
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
CW_DIR=${WORKDIR}/cake_wallet
|
||||||
|
CW_EXRTERNAL_DIR=${CW_DIR}/cw_monero/ios/External/android
|
||||||
|
|
||||||
|
for arch in "aarch" "aarch64" "i686" "x86_64"
|
||||||
|
do
|
||||||
|
|
||||||
|
PREFIX=${WORKDIR}/prefix_${arch}
|
||||||
|
ABI=""
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
"aarch" )
|
||||||
|
ABI="armeabi-v7a";;
|
||||||
|
"aarch64" )
|
||||||
|
ABI="arm64-v8a";;
|
||||||
|
"i686" )
|
||||||
|
ABI="x86";;
|
||||||
|
"x86_64" )
|
||||||
|
ABI="x86_64";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
LIB_DIR=${CW_EXRTERNAL_DIR}/${ABI}/lib
|
||||||
|
INCLUDE_DIR=${CW_EXRTERNAL_DIR}/${ABI}/include
|
||||||
|
|
||||||
|
mkdir -p $LIB_DIR
|
||||||
|
mkdir -p $INCLUDE_DIR
|
||||||
|
|
||||||
|
cp -r ${PREFIX}/lib/* $LIB_DIR
|
||||||
|
cp -r ${PREFIX}/include/* $INCLUDE_DIR
|
||||||
|
|
||||||
|
|
||||||
|
done
|
9
scripts/android/finish_boost.sh
Executable file
9
scripts/android/finish_boost.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
ARCH=$1
|
||||||
|
PREFIX="${WORKDIR}/prefix_${ARCH}"
|
||||||
|
BOOST_SRC_DIR=$WORKDIR/boost_1_68_0
|
||||||
|
|
||||||
|
cd $BOOST_SRC_DIR
|
||||||
|
./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} install
|
18
scripts/android/init_boost.sh
Executable file
18
scripts/android/init_boost.sh
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
ARCH=$1
|
||||||
|
PREFIX="${WORKDIR}/prefix_${ARCH}"
|
||||||
|
BOOST_FILENAME=boost_1_68_0.tar.bz2
|
||||||
|
BOOST_FILE_PATH=$WORKDIR/$BOOST_FILENAME
|
||||||
|
BOOST_SRC_DIR=$WORKDIR/boost_1_68_0
|
||||||
|
|
||||||
|
if [ ! -e "$BOOST_FILE_PATH" ]; then
|
||||||
|
wget https://dl.bintray.com/boostorg/release/1.68.0/source/$BOOST_FILENAME -O $BOOST_FILE_PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $WORKDIR
|
||||||
|
rm -rf $BOOST_SRC_DIR
|
||||||
|
tar -xvf $BOOST_FILE_PATH -C $WORKDIR
|
||||||
|
cd $BOOST_SRC_DIR
|
||||||
|
./bootstrap.sh --prefix=${PREFIX}
|
17
scripts/android/install_ndk.sh
Executable file
17
scripts/android/install_ndk.sh
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
# /bin/bash
|
||||||
|
|
||||||
|
WORKDIR=/opt/android
|
||||||
|
ANDROID_NDK_ZIP=${WORKDIR}/android-ndk-r17c.zip
|
||||||
|
ANDROID_NDK_ROOT=${WORKDIR}/android-ndk-r17c
|
||||||
|
TOOLCHAIN_DIR=${WORKDIR}/toolchain
|
||||||
|
TOOLCHAIN_A32_DIR=${TOOLCHAIN_DIR}_aarch
|
||||||
|
TOOLCHAIN_A64_DIR=${TOOLCHAIN_DIR}_aarch64
|
||||||
|
TOOLCHAIN_x86_DIR=${TOOLCHAIN_DIR}_i686
|
||||||
|
TOOLCHAIN_x86_64_DIR=${TOOLCHAIN_DIR}_x86_64
|
||||||
|
|
||||||
|
wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip -O /opt/android/android-ndk-r17c.zip
|
||||||
|
unzip /opt/android/android-ndk-r17c.zip -d $WORKDIR
|
||||||
|
${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 --install-dir ${TOOLCHAIN_A64_DIR} --stl=libc++
|
||||||
|
${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch arm --api 21 --install-dir ${TOOLCHAIN_A32_DIR} --stl=libc++
|
||||||
|
${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch x86 --api 21 --install-dir ${TOOLCHAIN_x86_DIR} --stl=libc++
|
||||||
|
${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 --install-dir ${TOOLCHAIN_x86_64_DIR} --stl=libc++
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"salt": "",
|
|
||||||
"keychainSalt": "",
|
|
||||||
"key": "",
|
|
||||||
"walletSalt": "",
|
|
||||||
"shortKey": "",
|
|
||||||
"change_now_api_key": ""
|
|
||||||
}
|
|
14
tool/generate_android_key_properties.dart
Normal file
14
tool/generate_android_key_properties.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
const outputPath = 'android/key.properties';
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async {
|
||||||
|
final output = args.fold('', (String acc, String arg) => acc + arg + '\n');
|
||||||
|
final outputFile = File(outputPath);
|
||||||
|
|
||||||
|
if (outputFile.existsSync()) {
|
||||||
|
await outputFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
await outputFile.writeAsString(output);
|
||||||
|
}
|
12
tool/generate_new_secrets.dart
Normal file
12
tool/generate_new_secrets.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import 'generate_secrets_config.dart';
|
||||||
|
import 'import_secrets_config.dart';
|
||||||
|
|
||||||
|
const configPath = 'tool/.secrets-config.json';
|
||||||
|
const outputPath = 'lib/.secrets.g.dart';
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async => generateSecrets(args);
|
||||||
|
|
||||||
|
Future<void> generateSecrets(List<String> args) async {
|
||||||
|
await generateSecretsConfig(args);
|
||||||
|
await importSecretsConfig();
|
||||||
|
}
|
49
tool/generate_secrets_config.dart
Normal file
49
tool/generate_secrets_config.dart
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'utils/secret_key.dart';
|
||||||
|
import 'utils/utils.dart';
|
||||||
|
|
||||||
|
const configPath = 'tool/.secrets-config.json';
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async => generateSecretsConfig(args);
|
||||||
|
|
||||||
|
Future<void> generateSecretsConfig(List<String> args) async {
|
||||||
|
final extraInfo =
|
||||||
|
args.fold(<String, dynamic>{}, (Map<String, dynamic> acc, String arg) {
|
||||||
|
final parts = arg.split('=');
|
||||||
|
final key = normalizeKeyName(parts[0]);
|
||||||
|
acc[key] = acc[key] = parts.length > 1 ? parts[1] : 1;
|
||||||
|
return acc;
|
||||||
|
});
|
||||||
|
|
||||||
|
final configFile = File(configPath);
|
||||||
|
final secrets = <String, dynamic>{};
|
||||||
|
|
||||||
|
secrets.addAll(extraInfo);
|
||||||
|
secrets.removeWhere((key, dynamic value) {
|
||||||
|
if (key.contains('--')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (configFile.existsSync()) {
|
||||||
|
if (extraInfo['--force'] == 1) {
|
||||||
|
await configFile.delete();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SecretKey.base.forEach((sec) {
|
||||||
|
if (secrets[sec.name] != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
secrets[sec.name] = sec.generate();
|
||||||
|
});
|
||||||
|
|
||||||
|
final secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
await configFile.writeAsString(secretsJson);
|
||||||
|
}
|
23
tool/import_secrets_config.dart
Normal file
23
tool/import_secrets_config.dart
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'utils/utils.dart';
|
||||||
|
|
||||||
|
const configPath = 'tool/.secrets-config.json';
|
||||||
|
const outputPath = 'lib/.secrets.g.dart';
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async => importSecretsConfig();
|
||||||
|
|
||||||
|
Future<void> importSecretsConfig() async {
|
||||||
|
final outputFile = File(outputPath);
|
||||||
|
final input = json.decode(File(configPath).readAsStringSync())
|
||||||
|
as Map<String, dynamic> ??
|
||||||
|
<String, dynamic>{};
|
||||||
|
final output = input.keys
|
||||||
|
.fold('', (String acc, String val) => acc + generateConst(val, input));
|
||||||
|
|
||||||
|
if (outputFile.existsSync()) {
|
||||||
|
await outputFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
await outputFile.writeAsString(output);
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
const secretsProdPath = 'tool/.secrets-prod.json';
|
|
||||||
const secretsTestPath = 'tool/.secrets-test.json';
|
|
||||||
const outputPath = 'lib/.secrets.g.dart';
|
|
||||||
|
|
||||||
Future<void> main() async {
|
|
||||||
final inputPath = FileSystemEntity.typeSync(secretsProdPath) !=
|
|
||||||
FileSystemEntityType.notFound
|
|
||||||
? secretsProdPath
|
|
||||||
: secretsTestPath;
|
|
||||||
|
|
||||||
final inoutContent = File(inputPath).readAsStringSync();
|
|
||||||
final config = json.decode(inoutContent) as Map<String, dynamic>;
|
|
||||||
final output =
|
|
||||||
'const salt = \'${config["salt"]}\';const keychainSalt = \'${config["keychainSalt"]}\';\nconst key = \'${config["key"]}\';\nconst walletSalt = \'${config["walletSalt"]}\';\nconst shortKey = \'${config["shortKey"]}\';\nconst change_now_api_key = \'${config["change_now_api_key"]}\';';
|
|
||||||
|
|
||||||
await File(outputPath).writeAsString(output);
|
|
||||||
}
|
|
47
tool/update_secrets.dart
Normal file
47
tool/update_secrets.dart
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'generate_new_secrets.dart';
|
||||||
|
import 'import_secrets_config.dart';
|
||||||
|
import 'utils/utils.dart';
|
||||||
|
|
||||||
|
const configPath = 'tool/.secrets-config.json';
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async {
|
||||||
|
await updateSecretsConfig(args);
|
||||||
|
await importSecretsConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateSecretsConfig(List<String> args) async {
|
||||||
|
final extraInfo =
|
||||||
|
args.fold(<String, dynamic>{}, (Map<String, dynamic> acc, String arg) {
|
||||||
|
final parts = arg.split('=');
|
||||||
|
final key = normalizeKeyName(parts[0]);
|
||||||
|
acc[key] = parts.length > 1 ? parts[1] : 1;
|
||||||
|
return acc;
|
||||||
|
});
|
||||||
|
|
||||||
|
final configFile = File(configPath);
|
||||||
|
final secrets = <String, dynamic>{};
|
||||||
|
|
||||||
|
secrets.addAll(extraInfo);
|
||||||
|
secrets.removeWhere((key, dynamic value) {
|
||||||
|
if (key.contains('--')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
final fileConfig =
|
||||||
|
json.decode(configFile.readAsStringSync()) as Map<String, dynamic> ??
|
||||||
|
<String, dynamic>{};
|
||||||
|
fileConfig.forEach((key, dynamic value) {
|
||||||
|
if (secrets[key] == null) {
|
||||||
|
secrets[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
await configFile.writeAsString(secretsJson);
|
||||||
|
await generateSecrets(args);
|
||||||
|
}
|
28
tool/utils/secret_key.dart
Normal file
28
tool/utils/secret_key.dart
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||||
|
import 'package:convert/convert.dart';
|
||||||
|
|
||||||
|
class SecretKey {
|
||||||
|
const SecretKey(this.name, this.generate);
|
||||||
|
|
||||||
|
static final base = [
|
||||||
|
SecretKey('salt', () => hex.encode(encrypt.Key.fromSecureRandom(16).bytes)),
|
||||||
|
SecretKey('keychainSalt',
|
||||||
|
() => hex.encode(encrypt.Key.fromSecureRandom(12).bytes)),
|
||||||
|
SecretKey('key', () => hex.encode(encrypt.Key.fromSecureRandom(16).bytes)),
|
||||||
|
SecretKey(
|
||||||
|
'walletSalt', () => hex.encode(encrypt.Key.fromSecureRandom(4).bytes)),
|
||||||
|
SecretKey(
|
||||||
|
'shortKey', () => hex.encode(encrypt.Key.fromSecureRandom(12).bytes)),
|
||||||
|
SecretKey(
|
||||||
|
'backupSalt', () => hex.encode(encrypt.Key.fromSecureRandom(8).bytes)),
|
||||||
|
SecretKey('backupKeychainSalt',
|
||||||
|
() => hex.encode(encrypt.Key.fromSecureRandom(12).bytes)),
|
||||||
|
SecretKey('changeNowApiKey', () => ''),
|
||||||
|
SecretKey('wyreSecretKey', () => ''),
|
||||||
|
SecretKey('wyreApiKey', () => ''),
|
||||||
|
SecretKey('wyreAccountId', () => ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final String Function() generate;
|
||||||
|
}
|
13
tool/utils/utils.dart
Normal file
13
tool/utils/utils.dart
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
String normalizeKeyName(String key) {
|
||||||
|
final parts = key.split('_');
|
||||||
|
final firstWord = parts.removeAt(0);
|
||||||
|
final capitalized = parts
|
||||||
|
.map((e) => toBeginningOfSentenceCase(e))
|
||||||
|
.fold('', (String acc, String word) => acc + word);
|
||||||
|
return firstWord + capitalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
String generateConst(String name, Map<String, dynamic> config) =>
|
||||||
|
'const $name = \'${config["$name"]}\';\n';
|
Loading…
Reference in a new issue