diff --git a/.gitignore b/.gitignore index cf669e13b..0ba59c910 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ diff --git a/README.md b/README.md index 7d67e06d3..6ccd7a967 100644 --- a/README.md +++ b/README.md @@ -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` \ No newline at end of file diff --git a/cw_monero/android/CMakeLists.txt b/cw_monero/android/CMakeLists.txt index 0b812409b..fdfe20b83 100644 --- a/cw_monero/android/CMakeLists.txt +++ b/cw_monero/android/CMakeLists.txt @@ -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 diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp index d90b6fd7d..7a6de3b28 100644 --- a/cw_monero/ios/Classes/monero_api.cpp +++ b/cw_monero/ios/Classes/monero_api.cpp @@ -6,7 +6,7 @@ #include #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; diff --git a/howto-build-android.md b/howto-build-android.md new file mode 100644 index 000000000..9b8d6e44e --- /dev/null +++ b/howto-build-android.md @@ -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= keyPassword=` + +**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. \ No newline at end of file diff --git a/lib/di.dart b/lib/di.dart index f17dd736c..520556d83 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -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(), tradeFilterStore: getIt.get(), transactionFilterStore: getIt.get(), + settingsStore: settingsStore, ordersSource: _ordersSource, ordersStore: getIt.get(), wyreViewModel: getIt.get())); diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index 01b6f1b96..69674131d 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -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/'; diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 45e2aa520..6e16e2324 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -38,6 +38,7 @@ abstract class SettingsStoreBase with Store { @required Map 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 load( {@required Box 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, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 02ffe4b8f..66fc53269 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -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> filterItems; + bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled; + ReactionDisposer _reaction; ReactionDisposer _onMoneroAccountChangeReaction; diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart index c0dcf27bd..71088d339 100644 --- a/lib/view_model/settings/settings_view_model.dart +++ b/lib/view_model/settings/settings_view_model.dart @@ -188,6 +188,8 @@ abstract class SettingsViewModelBase with Store { @computed ThemeBase get theme => _settingsStore.currentTheme; + bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled; + final Map itemHeaders; List> sections; final SettingsStore _settingsStore; diff --git a/pubspec.yaml b/pubspec.yaml index 3efe5ad0a..931a8d8be 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 diff --git a/scripts/android/build_all.sh b/scripts/android/build_all.sh new file mode 100755 index 000000000..208a4f9ef --- /dev/null +++ b/scripts/android/build_all.sh @@ -0,0 +1,8 @@ +# /bin/bash + +./build_iconv.sh +./build_boost.sh +./build_openssl.sh +./build_sodium.sh +./build_zmq.sh +./build_monero.sh diff --git a/scripts/android/build_boost.sh b/scripts/android/build_boost.sh new file mode 100755 index 000000000..2da334703 --- /dev/null +++ b/scripts/android/build_boost.sh @@ -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 diff --git a/scripts/android/build_iconv.sh b/scripts/android/build_iconv.sh new file mode 100755 index 000000000..9c0350a01 --- /dev/null +++ b/scripts/android/build_iconv.sh @@ -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 diff --git a/scripts/android/build_monero.sh b/scripts/android/build_monero.sh new file mode 100755 index 000000000..c2db7c085 --- /dev/null +++ b/scripts/android/build_monero.sh @@ -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 diff --git a/scripts/android/build_openssl.sh b/scripts/android/build_openssl.sh new file mode 100755 index 000000000..3674612b0 --- /dev/null +++ b/scripts/android/build_openssl.sh @@ -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 + + diff --git a/scripts/android/build_sodium.sh b/scripts/android/build_sodium.sh new file mode 100755 index 000000000..e13541924 --- /dev/null +++ b/scripts/android/build_sodium.sh @@ -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 diff --git a/scripts/android/build_zmq.sh b/scripts/android/build_zmq.sh new file mode 100755 index 000000000..c161e6044 --- /dev/null +++ b/scripts/android/build_zmq.sh @@ -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 diff --git a/scripts/android/copy_monero_deps.sh b/scripts/android/copy_monero_deps.sh new file mode 100755 index 000000000..dc5e53fec --- /dev/null +++ b/scripts/android/copy_monero_deps.sh @@ -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 diff --git a/scripts/android/finish_boost.sh b/scripts/android/finish_boost.sh new file mode 100755 index 000000000..0016b3152 --- /dev/null +++ b/scripts/android/finish_boost.sh @@ -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 diff --git a/scripts/android/init_boost.sh b/scripts/android/init_boost.sh new file mode 100755 index 000000000..ac2527b17 --- /dev/null +++ b/scripts/android/init_boost.sh @@ -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} diff --git a/scripts/android/install_ndk.sh b/scripts/android/install_ndk.sh new file mode 100755 index 000000000..619bdc118 --- /dev/null +++ b/scripts/android/install_ndk.sh @@ -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++ diff --git a/tool/.secrets-test.json b/tool/.secrets-test.json deleted file mode 100644 index 678b918cd..000000000 --- a/tool/.secrets-test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "salt": "", - "keychainSalt": "", - "key": "", - "walletSalt": "", - "shortKey": "", - "change_now_api_key": "" -} \ No newline at end of file diff --git a/tool/generate_android_key_properties.dart b/tool/generate_android_key_properties.dart new file mode 100644 index 000000000..beab5d0a5 --- /dev/null +++ b/tool/generate_android_key_properties.dart @@ -0,0 +1,14 @@ +import 'dart:io'; + +const outputPath = 'android/key.properties'; + +Future main(List 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); +} diff --git a/tool/generate_new_secrets.dart b/tool/generate_new_secrets.dart new file mode 100644 index 000000000..e3695fff6 --- /dev/null +++ b/tool/generate_new_secrets.dart @@ -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 main(List args) async => generateSecrets(args); + +Future generateSecrets(List args) async { + await generateSecretsConfig(args); + await importSecretsConfig(); +} \ No newline at end of file diff --git a/tool/generate_secrets_config.dart b/tool/generate_secrets_config.dart new file mode 100644 index 000000000..a66905524 --- /dev/null +++ b/tool/generate_secrets_config.dart @@ -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 main(List args) async => generateSecretsConfig(args); + +Future generateSecretsConfig(List args) async { + final extraInfo = + args.fold({}, (Map 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 = {}; + + 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); +} diff --git a/tool/import_secrets_config.dart b/tool/import_secrets_config.dart new file mode 100644 index 000000000..8fc62f9f0 --- /dev/null +++ b/tool/import_secrets_config.dart @@ -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 main(List args) async => importSecretsConfig(); + +Future importSecretsConfig() async { + final outputFile = File(outputPath); + final input = json.decode(File(configPath).readAsStringSync()) + as Map ?? + {}; + final output = input.keys + .fold('', (String acc, String val) => acc + generateConst(val, input)); + + if (outputFile.existsSync()) { + await outputFile.delete(); + } + + await outputFile.writeAsString(output); +} diff --git a/tool/secrets.dart b/tool/secrets.dart deleted file mode 100644 index ab8765770..000000000 --- a/tool/secrets.dart +++ /dev/null @@ -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 main() async { - final inputPath = FileSystemEntity.typeSync(secretsProdPath) != - FileSystemEntityType.notFound - ? secretsProdPath - : secretsTestPath; - - final inoutContent = File(inputPath).readAsStringSync(); - final config = json.decode(inoutContent) as Map; - 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); -} diff --git a/tool/update_secrets.dart b/tool/update_secrets.dart new file mode 100644 index 000000000..69e3f8447 --- /dev/null +++ b/tool/update_secrets.dart @@ -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 main(List args) async { + await updateSecretsConfig(args); + await importSecretsConfig(); +} + +Future updateSecretsConfig(List args) async { + final extraInfo = + args.fold({}, (Map 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 = {}; + + secrets.addAll(extraInfo); + secrets.removeWhere((key, dynamic value) { + if (key.contains('--')) { + return true; + } + + return false; + }); + + final fileConfig = + json.decode(configFile.readAsStringSync()) as Map ?? + {}; + 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); +} diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart new file mode 100644 index 000000000..9bf2d2722 --- /dev/null +++ b/tool/utils/secret_key.dart @@ -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; +} diff --git a/tool/utils/utils.dart b/tool/utils/utils.dart new file mode 100644 index 000000000..8fccb6883 --- /dev/null +++ b/tool/utils/utils.dart @@ -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 config) => + 'const $name = \'${config["$name"]}\';\n'; \ No newline at end of file