diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml new file mode 100644 index 000000000..dd2f1edeb --- /dev/null +++ b/.github/workflows/pr_test_build.yml @@ -0,0 +1,116 @@ +name: PR Test Build + +on: + pull_request: + branches: [ main ] + +jobs: + test: + + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: '8.x' + + - name: Flutter action + uses: subosito/flutter-action@v1 + with: + flutter-version: '3.3.x' + channel: stable + + - name: Install package dependencies + run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang + + - name: Execute Build and Setup Commands + run: | + sudo mkdir -p /opt/android + sudo chown $USER /opt/android + cd /opt/android + git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF + cd cake_wallet/scripts/android/ + ./install_ndk.sh + source ./app_env.sh cakewallet + ./app_config.sh + ./build_all.sh + ./copy_monero_deps.sh + + - name: Install Flutter dependencies + run: | + cd /opt/android/cake_wallet + flutter pub get + + - name: Generate KeyStore + run: | + cd /opt/android/cake_wallet/android/app + keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }} + + - name: Generate key properties + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }} + + - name: Generate localization + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_localization.dart + + - name: Build generated code + run: | + cd /opt/android/cake_wallet + cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + flutter packages pub run build_runner build --delete-conflicting-outputs + + - name: Add secrets + run: | + cd /opt/android/cake_wallet + touch lib/.secrets.g.dart + echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart + echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart + echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart + echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart + echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart + echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart + echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart + echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart + echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart + echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart + echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart + echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart + echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart + echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart + echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart + + - name: Build + run: | + cd /opt/android/cake_wallet + flutter build apk --release + +# - name: Push to App Center +# run: | +# echo 'Installing App Center CLI tools' +# npm install -g appcenter-cli +# echo "Publishing test to App Center" +# appcenter distribute release \ +# --group "Testers" \ +# --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \ +# --release-notes ${GITHUB_HEAD_REF} \ +# --app Cake-Labs/Cake-Wallet \ +# --token ${{ secrets.APP_CENTER_TOKEN }} \ +# --quiet + + - name: Send Test APK + run: | + cd /opt/android/cake_wallet + var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk) + curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}' + diff --git a/android/app/build.gradle b/android/app/build.gradle index 74cd0f8f7..00cef6393 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -46,7 +46,7 @@ android { defaultConfig { applicationId appProperties['id'] minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index f43b0369b..22278d5f1 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -21,7 +21,8 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" - android:screenOrientation="portrait"> + android:screenOrientation="portrait" + android:exported="true"> ` and checkout version 2.0.4 by `git checkout 2.0.4`. +Need to install flutter with version `3.x.x`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). ### 4. Verify Installations @@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct 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, 2.0.4, on Linux, locale en_US.UTF-8) +[✓] Flutter (Channel stable, 3.x.x, on Linux, locale en_US.UTF-8) [✓] Android toolchain - develop for Android devices (Android SDK version 28) [✓] Android Studio (version 4.0) ``` @@ -156,6 +156,10 @@ Generate mobx models for `cw_bitcoin`: `cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..` +Generate mobx models for `cw_haven`: + +`cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..` + Finally build mobx models for the app: `$ flutter packages pub run build_runner build --delete-conflicting-outputs` diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 36394d936..8c0758d86 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -11,6 +11,7 @@ class PreferencesKey { static const shouldSaveRecipientAddressKey = 'save_recipient_address'; static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication'; + static const disableExchangeKey = 'disable_exchange'; static const currentTheme = 'current_theme'; static const isDarkThemeLegacy = 'dark_theme'; static const displayActionListModeKey = 'display_list_mode'; diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index cb90bb8e0..c21365aa4 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -315,6 +315,8 @@ class DashboardPage extends BasePage { } Future _onClickExchangeButton(BuildContext context) async { - await Navigator.of(context).pushNamed(Routes.exchange); + if (walletViewModel.isEnabledExchangeAction) { + await Navigator.of(context).pushNamed(Routes.exchange); + } } } diff --git a/lib/src/screens/receive/widgets/qr_painter.dart b/lib/src/screens/receive/widgets/qr_painter.dart index 90dba73ac..e4af59f1a 100644 --- a/lib/src/screens/receive/widgets/qr_painter.dart +++ b/lib/src/screens/receive/widgets/qr_painter.dart @@ -9,7 +9,6 @@ class QrPainter extends CustomPainter { this.errorCorrectionLevel, ) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) { _p.color = this.color; - _qr.addData(data); _qrImage = QrImage(_qr); } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index c6534bcea..15fb2cf77 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -29,6 +29,7 @@ abstract class SettingsStoreBase with Store { required BalanceDisplayMode initialBalanceDisplayMode, required bool initialSaveRecipientAddress, required bool initialAllowBiometricalAuthentication, + required bool initialExchangeEnabled, required ThemeBase initialTheme, required int initialPinLength, required String initialLanguageCode, @@ -47,6 +48,7 @@ abstract class SettingsStoreBase with Store { balanceDisplayMode = initialBalanceDisplayMode, shouldSaveRecipientAddress = initialSaveRecipientAddress, allowBiometricalAuthentication = initialAllowBiometricalAuthentication, + disableExchange = initialExchangeEnabled, currentTheme = initialTheme, pinCodeLength = initialPinLength, languageCode = initialLanguageCode, @@ -149,6 +151,9 @@ abstract class SettingsStoreBase with Store { @observable bool allowBiometricalAuthentication; + @observable + bool disableExchange; + @observable ThemeBase currentTheme; @@ -230,6 +235,8 @@ abstract class SettingsStoreBase with Store { final allowBiometricalAuthentication = sharedPreferences .getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false; + final disableExchange = sharedPreferences + .getBool(PreferencesKey.disableExchangeKey) ?? false; final legacyTheme = (sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy) ?? false) ? ThemeType.dark.index @@ -295,6 +302,7 @@ abstract class SettingsStoreBase with Store { initialBalanceDisplayMode: currentBalanceDisplayMode, initialSaveRecipientAddress: shouldSaveRecipientAddress, initialAllowBiometricalAuthentication: allowBiometricalAuthentication, + initialExchangeEnabled: disableExchange, initialTheme: savedTheme, actionlistDisplayMode: actionListDisplayMode, initialPinLength: pinLength, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 49dd2437a..7f11b0c2f 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -53,7 +53,6 @@ abstract class DashboardViewModelBase with Store { hasBuyAction = false, isEnabledBuyAction = false, hasExchangeAction = false, - isEnabledExchangeAction = false, isShowFirstYatIntroduction = false, isShowSecondYatIntroduction = false, isShowThirdYatIntroduction = false, @@ -249,8 +248,8 @@ abstract class DashboardViewModelBase with Store { void furtherShowYatPopup(bool shouldShow) => settingsStore.shouldShowYatPopup = shouldShow; - @observable - bool isEnabledExchangeAction; + @computed + bool get isEnabledExchangeAction => !settingsStore.disableExchange; @observable bool hasExchangeAction; @@ -365,7 +364,6 @@ abstract class DashboardViewModelBase with Store { } void updateActions() { - isEnabledExchangeAction = true; hasExchangeAction = !isHaven; isEnabledBuyAction = wallet.type != WalletType.haven && wallet.type != WalletType.monero; diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index e7e73855b..725208324 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -7,7 +7,6 @@ import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart' import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart'; import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; -import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/crypto_currency.dart'; @@ -375,96 +374,105 @@ abstract class ExchangeViewModelBase with Store { TradeRequest? request; String amount = ''; - for (var provider in _sortedAvailableProviders.values) { - if (!(await provider.checkIsAvailable())) { - continue; - } + try { + for (var provider in _sortedAvailableProviders.values) { + if (!(await provider.checkIsAvailable())) { + continue; + } - if (provider is SideShiftExchangeProvider) { - request = SideShiftRequest( - depositMethod: depositCurrency, - settleMethod: receiveCurrency, - depositAmount: depositAmount.replaceAll(',', '.'), - settleAddress: receiveAddress, - refundAddress: depositAddress, - ); - amount = depositAmount; - } + if (provider is SideShiftExchangeProvider) { + request = SideShiftRequest( + depositMethod: depositCurrency, + settleMethod: receiveCurrency, + depositAmount: depositAmount.replaceAll(',', '.'), + settleAddress: receiveAddress, + refundAddress: depositAddress, + ); + amount = depositAmount; + } - if (provider is SimpleSwapExchangeProvider) { - request = SimpleSwapRequest( - from: depositCurrency, - to: receiveCurrency, - amount: depositAmount.replaceAll(',', '.'), - address: receiveAddress, - refundAddress: depositAddress, - ); - amount = depositAmount; - } - - if (provider is XMRTOExchangeProvider) { - request = XMRTOTradeRequest( + if (provider is SimpleSwapExchangeProvider) { + request = SimpleSwapRequest( from: depositCurrency, to: receiveCurrency, amount: depositAmount.replaceAll(',', '.'), - receiveAmount: receiveAmount.replaceAll(',', '.'), address: receiveAddress, refundAddress: depositAddress, - isBTCRequest: isReceiveAmountEntered); - amount = depositAmount; - } + ); + amount = depositAmount; + } - if (provider is ChangeNowExchangeProvider) { - request = ChangeNowRequest( - from: depositCurrency, - to: receiveCurrency, - fromAmount: depositAmount.replaceAll(',', '.'), - toAmount: receiveAmount.replaceAll(',', '.'), - refundAddress: depositAddress, - address: receiveAddress, - isReverse: isReverse); - amount = isReverse ? receiveAmount : depositAmount; - } + if (provider is XMRTOExchangeProvider) { + request = XMRTOTradeRequest( + from: depositCurrency, + to: receiveCurrency, + amount: depositAmount.replaceAll(',', '.'), + receiveAmount: receiveAmount.replaceAll(',', '.'), + address: receiveAddress, + refundAddress: depositAddress, + isBTCRequest: isReceiveAmountEntered); + amount = depositAmount; + } - if (provider is MorphTokenExchangeProvider) { - request = MorphTokenRequest( - from: depositCurrency, - to: receiveCurrency, - amount: depositAmount.replaceAll(',', '.'), - refundAddress: depositAddress, - address: receiveAddress); - amount = depositAmount; - } + if (provider is ChangeNowExchangeProvider) { + request = ChangeNowRequest( + from: depositCurrency, + to: receiveCurrency, + fromAmount: depositAmount.replaceAll(',', '.'), + toAmount: receiveAmount.replaceAll(',', '.'), + refundAddress: depositAddress, + address: receiveAddress, + isReverse: isReverse); + amount = isReverse ? receiveAmount : depositAmount; + } - amount = amount.replaceAll(',', '.'); + if (provider is MorphTokenExchangeProvider) { + request = MorphTokenRequest( + from: depositCurrency, + to: receiveCurrency, + amount: depositAmount.replaceAll(',', '.'), + refundAddress: depositAddress, + address: receiveAddress); + amount = depositAmount; + } - if (limitsState is LimitsLoadedSuccessfully) { - if (double.parse(amount) < limits.min!) { - continue; - } else if (limits.max != null && double.parse(amount) > limits.max!) { - continue; - } else { - try { - tradeState = TradeIsCreating(); - final trade = await provider.createTrade( - request: request!, isFixedRateMode: isFixedRateMode); - trade.walletId = wallet.id; - tradesStore.setTrade(trade); - await trades.add(trade); - tradeState = TradeIsCreatedSuccessfully(trade: trade); - /// return after the first successful trade - return; - } catch (e) { + amount = amount.replaceAll(',', '.'); + + if (limitsState is LimitsLoadedSuccessfully) { + if (double.parse(amount) < limits.min!) { continue; + } else if (limits.max != null && double.parse(amount) > limits.max!) { + continue; + } else { + try { + tradeState = TradeIsCreating(); + final trade = await provider.createTrade( + request: request!, isFixedRateMode: isFixedRateMode); + trade.walletId = wallet.id; + tradesStore.setTrade(trade); + await trades.add(trade); + tradeState = TradeIsCreatedSuccessfully(trade: trade); + /// return after the first successful trade + return; + } catch (e) { + continue; + } } } } - } - /// if the code reached here then none of the providers succeeded - tradeState = TradeIsCreatedFailure( - title: S.current.trade_not_created, - error: S.current.none_of_selected_providers_can_exchange); + /// if the code reached here then none of the providers succeeded + tradeState = TradeIsCreatedFailure( + title: S.current.trade_not_created, + error: S.current.none_of_selected_providers_can_exchange); + } on ConcurrentModificationError { + /// if create trade happened at the exact same time of the scheduled rate update + /// then delay the create trade a bit and try again + /// + /// this is because the limitation of the SplayTreeMap that + /// you can't modify it while iterating through it + Future.delayed(Duration(milliseconds: 500), createTrade); + } } @action diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 248a06de0..00e1a39b1 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -34,7 +34,7 @@ dependencies: local_auth: ^2.1.0 package_info: ^2.0.0 #package_info_plus: ^1.4.2 - devicelocale: ^0.5.4 + devicelocale: ^0.4.3 auto_size_text: ^3.0.0 dotted_border: ^2.0.0+2 smooth_page_indicator: ^1.0.0+2 diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index eacc8e618..8f211b102 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -658,5 +658,6 @@ "other_settings": "Andere Einstellungen", "require_pin_after": "PIN anfordern nach", "always": "immer", - "minutes_to_pin_code": "${minute} Minuten" + "minutes_to_pin_code": "${minute} Minuten", + "disable_exchange": "Exchange deaktivieren" } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 65b72f5c6..b170316df 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -661,5 +661,6 @@ "other_settings": "Other settings", "require_pin_after": "Require PIN after", "always": "Always", - "minutes_to_pin_code": "${minute} minutes" + "minutes_to_pin_code": "${minute} minutes", + "disable_exchange": "Disable exchange" } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 903e6c380..0d764e170 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -658,5 +658,6 @@ "other_settings": "Otras configuraciones", "require_pin_after": "Requerir PIN después de", "always": "siempre", - "minutes_to_pin_code": "${minute} minutos" + "minutes_to_pin_code": "${minute} minutos", + "disable_exchange": "Deshabilitar intercambio" } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index d82f1d2de..576ea91f8 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -656,5 +656,6 @@ "other_settings": "Autres paramètres", "require_pin_after": "NIP requis après", "always": "toujours", - "minutes_to_pin_code": "${minute} minutes" + "minutes_to_pin_code": "${minute} minutes", + "disable_exchange": "Désactiver l'échange" } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 9175cb17c..af5ce56dc 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -658,5 +658,6 @@ "other_settings": "अन्य सेटिंग्स", "require_pin_after": "इसके बाद पिन आवश्यक है", "always": "हमेशा", - "minutes_to_pin_code": "${minute} मिनट" + "minutes_to_pin_code": "${minute} मिनट", + "disable_exchange": "एक्सचेंज अक्षम करें" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index e60bedd74..7b160bf8d 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -658,5 +658,6 @@ "other_settings": "Ostale postavke", "require_pin_after": "Zahtijevaj PIN nakon", "always": "Uvijek", - "minutes_to_pin_code": "${minute} minuta" + "minutes_to_pin_code": "${minute} minuta", + "disable_exchange": "Onemogući exchange" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 548c51b22..229a69f75 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -658,5 +658,6 @@ "other_settings": "Altre impostazioni", "require_pin_after": "Richiedi PIN dopo", "always": "sempre", - "minutes_to_pin_code": "${minute} minuti" + "minutes_to_pin_code": "${minute} minuti", + "disable_exchange": "Disabilita scambio" } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 7fc1f5105..da1dfb708 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -658,5 +658,6 @@ "other_settings": "その他の設定", "require_pin_after": "後に PIN が必要", "always": "いつも", - "minutes_to_pin_code": "${minute} 分" + "minutes_to_pin_code": "${minute} 分", + "disable_exchange": "交換を無効にする" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 471d9ed11..5e835a29b 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -658,5 +658,6 @@ "other_settings": "기타 설정", "require_pin_after": "다음 이후에 PIN 필요", "always": "언제나", - "minutes_to_pin_code": "${minute}분" + "minutes_to_pin_code": "${minute}분", + "disable_exchange": "교환 비활성화" } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 1eb16e051..059bb27dc 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -658,5 +658,6 @@ "other_settings": "Andere instellingen", "require_pin_after": "Pincode vereist na", "always": "altijd", - "minutes_to_pin_code": "${minute} minuten" + "minutes_to_pin_code": "${minute} minuten", + "disable_exchange": "Uitwisseling uitschakelen" } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 78793c074..68d8595b0 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -658,5 +658,6 @@ "other_settings": "Inne ustawienia", "require_pin_after": "Wymagaj kodu PIN po", "always": "zawsze", - "minutes_to_pin_code": "${minute} minut" + "minutes_to_pin_code": "${minute} minut", + "disable_exchange": "Wyłącz wymianę" } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index e7fc9aa92..6f8eb5f64 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -658,5 +658,6 @@ "other_settings": "Outras configurações", "require_pin_after": "Exigir PIN após", "always": "sempre", - "minutes_to_pin_code": "${minute} minutos" + "minutes_to_pin_code": "${minute} minutos", + "disable_exchange": "Desativar troca" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 34fe7a145..9b2691ad7 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -658,5 +658,6 @@ "other_settings": "Другие настройки", "require_pin_after": "Требовать ПИН после", "always": "всегда", - "minutes_to_pin_code": "${minute} минут" + "minutes_to_pin_code": "${minute} минут", + "disable_exchange": "Отключить обмен" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index fab6ed71e..97e7362d1 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -657,6 +657,6 @@ "other_settings": "Інші налаштування", "require_pin_after": "Вимагати PIN після", "always": "Завжди", - "minutes_to_pin_code": "${minute} хвилин" - + "minutes_to_pin_code": "${minute} хвилин", + "disable_exchange": "Вимкнути exchange" } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 8f89f7b63..2e07983f4 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -656,5 +656,6 @@ "other_settings": "其他设置", "require_pin_after": "之后需要 PIN", "always": "总是", - "minutes_to_pin_code": "${minute} 分钟" + "minutes_to_pin_code": "${minute} 分钟", + "disable_exchange": "禁用交换" } diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 54ad0b4d4..d361c8dfa 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=28 +MONERO_COM_VERSION="1.2.1" +MONERO_COM_BUILD_NUMBER=32 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=132 +CAKEWALLET_VERSION="4.5.1" +CAKEWALLET_BUILD_NUMBER=136 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index c7ecaa60b..8bb945680 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=28 +MONERO_COM_VERSION="1.2.1" +MONERO_COM_BUILD_NUMBER=29 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=132 +CAKEWALLET_VERSION="4.5.1" +CAKEWALLET_BUILD_NUMBER=133 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index 64c7beefd..e5202a829 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -28,6 +28,7 @@ class SecretKey { SecretKey('simpleSwapApiKey', () => ''), SecretKey('anypayToken', () => ''), SecretKey('onramperApiKey', () => ''), + SecretKey('ioniaClientId', () => ''), ]; final String name;