Merge pull request #97 from cake-tech/deploy

Deploy
This commit is contained in:
M 2021-03-24 12:22:52 +02:00
commit 12d5fec5b1
31 changed files with 720 additions and 72 deletions

2
.gitignore vendored
View file

@ -87,6 +87,8 @@ cw_monero/cw_monero/android/.cxx/
android/key.properties
**/tool/.secrets-prod.json
**/tool/.secrets-test.json
**/tool/.secrets-config.json
**/lib/.secrets.g.dart
vendor/

View file

@ -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`

View file

@ -17,7 +17,7 @@ set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../ios/External/android)
add_library(sodium STATIC IMPORTED)
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
@ -25,11 +25,11 @@ set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
add_library(crypto STATIC IMPORTED)
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)
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
@ -37,39 +37,39 @@ set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
add_library(boost_chrono STATIC IMPORTED)
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)
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)
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)
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)
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)
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)
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)
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)
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
@ -77,101 +77,111 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
add_library(wallet_api STATIC IMPORTED)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
@ -199,6 +209,7 @@ target_link_libraries( cw_monero
randomx
hardforks
rpc_base
${WALLET_CRYPTO}
boost_chrono
boost_date_time

View file

@ -6,7 +6,7 @@
#include <unistd.h>
#include "thread"
#include "CwWalletListener.h"
#include "../External/android/monero/include/wallet2_api.h"
#include "../External/android/x86/include/wallet2_api.h"
using namespace std::chrono_literals;

136
howto-build-android.md Normal file
View 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.

View file

@ -111,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/entities/template.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
final getIt = GetIt.instance;
@ -147,7 +148,11 @@ Future setup(
() => 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) {
return;
@ -232,6 +237,7 @@ Future setup(
tradesStore: getIt.get<TradesStore>(),
tradeFilterStore: getIt.get<TradeFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore,
ordersSource: _ordersSource,
ordersStore: getIt.get<OrdersStore>(),
wyreViewModel: getIt.get<WyreViewModel>()));

View file

@ -25,7 +25,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
.toList());
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 _transactionsUriSufix = '/transactions/';
static const _minAmountUriSufix = '/min-amount/';

View file

@ -38,6 +38,7 @@ abstract class SettingsStoreBase with Store {
@required Map<WalletType, Node> nodes,
@required TransactionPriority initialBitcoinTransactionPriority,
@required TransactionPriority initialMoneroTransactionPriority,
@required this.isBitcoinBuyEnabled,
this.actionlistDisplayMode}) {
fiatCurrency = initialFiatCurrency;
balanceDisplayMode = initialBalanceDisplayMode;
@ -144,8 +145,11 @@ abstract class SettingsStoreBase with Store {
Node getCurrentNode(WalletType walletType) => nodes[walletType];
bool isBitcoinBuyEnabled;
static Future<SettingsStore> load(
{@required Box<Node> nodeSource,
@required bool isBitcoinBuyEnabled,
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
MoneroTransactionPriority initialMoneroTransactionPriority =
MoneroTransactionPriority.slow,
@ -212,6 +216,7 @@ abstract class SettingsStoreBase with Store {
WalletType.bitcoin: bitcoinElectrumServer
},
appVersion: packageInfo.version,
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
initialFiatCurrency: currentFiatCurrency,
initialBalanceDisplayMode: currentBalanceDisplayMode,
initialSaveRecipientAddress: shouldSaveRecipientAddress,

View file

@ -18,6 +18,7 @@ import 'package:cake_wallet/entities/transaction_direction.dart';
import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.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/view_model/dashboard/balance_view_model.dart';
@ -56,6 +57,7 @@ abstract class DashboardViewModelBase with Store {
this.tradesStore,
this.tradeFilterStore,
this.transactionFilterStore,
this.settingsStore,
this.ordersSource,
this.ordersStore,
this.wyreViewModel}) {
@ -223,6 +225,8 @@ abstract class DashboardViewModelBase with Store {
AppStore appStore;
SettingsStore settingsStore;
TradesStore tradesStore;
OrdersStore ordersStore;
@ -235,6 +239,8 @@ abstract class DashboardViewModelBase with Store {
Map<String, List<FilterItem>> filterItems;
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
ReactionDisposer _reaction;
ReactionDisposer _onMoneroAccountChangeReaction;

View file

@ -188,6 +188,8 @@ abstract class SettingsViewModelBase with Store {
@computed
ThemeBase get theme => _settingsStore.currentTheme;
bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled;
final Map<String, String> itemHeaders;
List<List<SettingsListItem>> sections;
final SettingsStore _settingsStore;

View file

@ -114,7 +114,7 @@ flutter:
fonts:
- asset: assets/fonts/Lato-Regular.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

8
scripts/android/build_all.sh Executable file
View 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
View 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
View 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
View 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

View 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
View 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
View 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

View 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

View 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
View 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
View 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++

View file

@ -1,8 +0,0 @@
{
"salt": "",
"keychainSalt": "",
"key": "",
"walletSalt": "",
"shortKey": "",
"change_now_api_key": ""
}

View 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);
}

View 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();
}

View 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);
}

View 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);
}

View file

@ -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
View 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);
}

View 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
View 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';