diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index e9c53c00f..cca5bb4bf 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
- java-version: "11.x"
+ java-version: "17.x"
- name: Configure placeholder git details
run: |
git config --global user.email "CI@cakewallet.com"
diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build_android.yml
similarity index 88%
rename from .github/workflows/pr_test_build.yml
rename to .github/workflows/pr_test_build_android.yml
index a7c5fd66a..0b8309aad 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -56,7 +56,9 @@ jobs:
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
+ run: |
+ sudo apt update
+ 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: |
@@ -212,35 +214,3 @@ jobs:
title: "${{ env.BRANCH_NAME }}.apk"
filename: ${{ env.BRANCH_NAME }}.apk
initial_comment: ${{ github.event.head_commit.message }}
-
- - name: 🦾 Cache gradle
- uses: gradle/actions/setup-gradle@v3
-
- - name: 🦾 Cache AVD
- uses: actions/cache@v4
- id: avd-cache
- with:
- path: |
- ~/.android/avd/*
- ~/.android/adb*
- key: avd-${{ matrix.api-level }}
-
- - name: 🦾 Create AVD and generate snapshot for caching
- if: steps.avd-cache.outputs.cache-hit != 'true'
- uses: reactivecircus/android-emulator-runner@v2
- with:
- api-level: ${{ matrix.api-level }}
- force-avd-creation: false
- emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
- disable-animations: false
- script: echo "Generated AVD snapshot for caching."
-
- - name: 🚀 Integration tests on Android Emualator
- timeout-minutes: 30
- uses: reactivecircus/android-emulator-runner@v2
- with:
- api-level: ${{ matrix.api-level }}
- force-avd-creation: false
- emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
- disable-animations: true
- script: flutter test integration_test
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
new file mode 100644
index 000000000..12c930120
--- /dev/null
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -0,0 +1,186 @@
+name: PR Test Build linux
+
+on:
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+ inputs:
+ branch:
+ description: "Branch name to build"
+ required: true
+ default: "main"
+
+jobs:
+ PR_test_build:
+ runs-on: ubuntu-20.04
+ env:
+ STORE_PASS: test@cake_wallet
+ KEY_PASS: test@cake_wallet
+ PR_NUMBER: ${{ github.event.number }}
+
+ steps:
+ - name: is pr
+ if: github.event_name == 'pull_request'
+ run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
+
+ - name: is not pr
+ if: github.event_name != 'pull_request'
+ run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENVg
+
+ - uses: actions/checkout@v2
+ - uses: actions/setup-java@v1
+ with:
+ java-version: "17.x"
+ - name: Configure placeholder git details
+ run: |
+ git config --global user.email "CI@cakewallet.com"
+ git config --global user.name "Cake Github Actions"
+ - name: Flutter action
+ uses: subosito/flutter-action@v1
+ with:
+ flutter-version: "3.19.6"
+ channel: stable
+
+ - name: Install package dependencies
+ run: |
+ sudo apt update
+ sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
+
+ - name: Install desktop dependencies
+ run: |
+ sudo apt update
+ sudo apt install -y ninja-build libgtk-3-dev gperf
+ - name: Execute Build and Setup Commands
+ run: |
+ sudo mkdir -p /opt/android
+ sudo chown $USER /opt/android
+ cd /opt/android
+ -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+ cargo install cargo-ndk
+ git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
+ cd scripts && ./gen_android_manifest.sh && cd ..
+ cd cake_wallet/scripts/android/
+ source ./app_env.sh cakewallet
+ ./app_config.sh
+ cd ../../..
+ cd cake_wallet/scripts/linux/
+ source ./app_env.sh cakewallet
+ ./app_config.sh
+ cd ../../..
+
+ - name: Cache Externals
+ id: cache-externals
+ uses: actions/cache@v3
+ with:
+ path: |
+ /opt/android/cake_wallet/cw_haven/android/.cxx
+ /opt/android/cake_wallet/scripts/monero_c/release
+ key: linux-${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh') }}
+
+ - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
+ name: Generate Externals
+ run: |
+ cd /opt/android/cake_wallet/scripts/linux/
+ source ./app_env.sh cakewallet
+ ./build_monero_all.sh
+
+ - name: Install Flutter dependencies
+ run: |
+ cd /opt/android/cake_wallet
+ flutter pub get
+
+ - 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
+ ./model_generator.sh
+
+ - name: Add secrets
+ run: |
+ cd /opt/android/cake_wallet
+ touch lib/.secrets.g.dart
+ touch cw_evm/lib/.secrets.g.dart
+ touch cw_solana/lib/.secrets.g.dart
+ touch cw_core/lib/.secrets.g.dart
+ touch cw_nano/lib/.secrets.g.dart
+ touch cw_tron/lib/.secrets.g.dart
+ 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 changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> 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 simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> 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
+ echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+ echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
+ echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
+ echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
+ echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
+ echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
+ echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
+ echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+ echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+ echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+ echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+ echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+
+ - name: Rename app
+ run: |
+ echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+
+ - name: Build
+ run: |
+ cd /opt/android/cake_wallet
+ flutter build linux --release
+
+ - name: Prepare release zip file
+ run: |
+ cd /opt/android/cake_wallet/build/linux/x64/release
+ zip -r ${{env.BRANCH_NAME}}.zip bundle
+
+ - name: Upload Artifact
+ uses: kittaakos/upload-artifact-as-is@v0
+ with:
+ path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+
+ - name: Send Test APK
+ continue-on-error: true
+ uses: adrey/slack-file-upload-action@1.0.5
+ with:
+ token: ${{ secrets.SLACK_APP_TOKEN }}
+ path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+ channel: ${{ secrets.SLACK_APK_CHANNEL }}
+ title: "${{ env.BRANCH_NAME }}_linux.zip"
+ filename: ${{ env.BRANCH_NAME }}_linux.zip
+ initial_comment: ${{ github.event.head_commit.message }}
diff --git a/.gitignore b/.gitignore
index d8f5bb988..970241189 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,6 +160,8 @@ macos/Runner/Release.entitlements
macos/Runner/Runner.entitlements
lib/core/secure_storage.dart
+lib/core/secure_storage.dart
+
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
diff --git a/.metadata b/.metadata
index 7d00ca21a..c7b8dc9f8 100644
--- a/.metadata
+++ b/.metadata
@@ -18,6 +18,12 @@ migration:
- platform: windows
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ - platform: macos
+ create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ - platform: linux
+ create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
# User provided section
diff --git a/README.md b/README.md
index 7823734fb..6e507bfcd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+![logo](.github/assets/Logo_CakeWallet.png)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 60defb1fd..2f5427531 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -91,5 +91,4 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- implementation 'com.unstoppabledomains:resolution:5.0.0'
}
diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
index 29b37c46c..df3f6be01 100644
--- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
+++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
@@ -20,14 +20,10 @@ import android.net.Uri;
import android.os.PowerManager;
import android.provider.Settings;
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
- final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
boolean isAppSecure = false;
@Override
@@ -53,14 +49,6 @@ public class MainActivity extends FlutterFragmentActivity {
random.nextBytes(bytes);
handler.post(() -> result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
@@ -85,23 +73,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
index d0a465d22..83a790683 100644
--- a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
+++ b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
import android.os.PowerManager;
import android.provider.Settings;
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
- final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
@@ -51,14 +47,6 @@ public class MainActivity extends FlutterFragmentActivity {
random.nextBytes(bytes);
handler.post(() -> result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "disableBatteryOptimization":
disableBatteryOptimization();
handler.post(() -> result.success(null));
@@ -75,23 +63,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/monero/app/MainActivity.java b/android/app/src/main/java/com/monero/app/MainActivity.java
index 49c368ec7..e6306d27b 100644
--- a/android/app/src/main/java/com/monero/app/MainActivity.java
+++ b/android/app/src/main/java/com/monero/app/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
import android.os.PowerManager;
import android.provider.Settings;
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
- final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
boolean isAppSecure = false;
@Override
@@ -52,14 +48,6 @@ public class MainActivity extends FlutterFragmentActivity {
random.nextBytes(bytes);
handler.post(() -> result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
@@ -84,23 +72,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/build.gradle b/android/build.gradle
index aa9f5005d..7ddb75179 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -2,7 +2,7 @@ buildscript {
ext.kotlin_version = '1.8.21'
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
@@ -15,7 +15,7 @@ buildscript {
allprojects {
repositories {
google()
- jcenter()
+ mavenCentral()
}
}
diff --git a/assets/images/dfx_dark.png b/assets/images/dfx_dark.png
index cbba87372..6ac112eae 100644
Binary files a/assets/images/dfx_dark.png and b/assets/images/dfx_dark.png differ
diff --git a/assets/images/dfx_light.png b/assets/images/dfx_light.png
index e4836be3e..a045d3e68 100644
Binary files a/assets/images/dfx_light.png and b/assets/images/dfx_light.png differ
diff --git a/assets/images/moonpay.png b/assets/images/moonpay.png
index b02af6c00..088c93d59 100644
Binary files a/assets/images/moonpay.png and b/assets/images/moonpay.png differ
diff --git a/assets/images/moonpay_dark.png b/assets/images/moonpay_dark.png
index 872e322e2..21de98eb4 100644
Binary files a/assets/images/moonpay_dark.png and b/assets/images/moonpay_dark.png differ
diff --git a/assets/images/moonpay_light.png b/assets/images/moonpay_light.png
index c76ae6e74..3d3de2e4f 100644
Binary files a/assets/images/moonpay_light.png and b/assets/images/moonpay_light.png differ
diff --git a/assets/images/trocador.png b/assets/images/trocador.png
index 67c9f221c..37e643de4 100644
Binary files a/assets/images/trocador.png and b/assets/images/trocador.png differ
diff --git a/build-guide-linux.md b/build-guide-linux.md
new file mode 100644
index 000000000..e0158945b
--- /dev/null
+++ b/build-guide-linux.md
@@ -0,0 +1,176 @@
+# Building CakeWallet for Linux
+
+## Requirements and Setup
+
+The following are the system requirements to build CakeWallet for your Linux device.
+
+```
+Ubuntu >= 16.04
+Flutter 3.10.x
+```
+
+## Building CakeWallet on Linux
+
+These steps will help you configure and execute a build of CakeWallet from its source code.
+
+### 1. Installing Package Dependencies
+
+CakeWallet requires some packages to be install on your build system. You may easily install them on your build system with the following command:
+
+`$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool`
+
+> [!WARNING]
+>
+> ### Check gcc version
+>
+> It is needed to use gcc 10 or 9 to successfully link dependencies with flutter.\
+> To check what gcc version you are using:
+>
+> ```bash
+> $ gcc --version
+> $ g++ --version
+> ```
+>
+> If you are using gcc version newer than 10, then you need to downgrade to version 10.4.0:
+>
+> ```bash
+> $ sudo apt install gcc-10 g++-10
+> $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
+> $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
+> ```
+
+> [!NOTE]
+>
+> Alternatively, you can use the [nix-shell](https://nixos.org/) with the `gcc10.nix` file\
+> present on `scripts/linux` like so:
+> ```bash
+> $ nix-shell gcc10.nix
+> ```
+> This will get you in a nix environment with all the required dependencies that you can use to build the software from,\
+> and it works in any linux distro.
+
+### 2. Installing Flutter
+
+Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux).
+
+### 3. Verify Installations
+
+Verify that the Flutter 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, 3.10.x, on Linux, locale en_US.UTF-8)
+```
+
+### 4. Acquiring the CakeWallet Source Code
+
+Download CakeWallet source code
+
+`$ git clone https://github.com/cake-tech/cake_wallet.git --branch linux/password-direct-input`
+
+Proceed into the source code before proceeding with the next steps:
+
+`$ cd cake_wallet/scripts/linux/`
+
+To configure some project properties run:
+
+`$ ./cakewallet.sh`
+
+Build the Monero libraries and their dependencies:
+
+`$ ./build_all.sh`
+
+Now the dependencies need to be copied into the CakeWallet project with this command:
+
+`$ ./setup.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`
+
+> #### If you will get an error like:
+>
+> ```
+> The plugin `cw_shared_external` requires your app to be migrated to the Android embedding v2. Follow the steps on the migration doc above and re-run
+> this command.
+> ```
+>
+> Then need to config Android project settings. For this open `scripts/android` (`$ cd scripts/android`) directory and run followed commands:
+>
+> ```
+> $ source ./app_env.sh cakewallet
+> $ ./app_config.sh
+> $ cd ../..
+> ```
+>
+> Then re-configure Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run:
+> `$ ./cakewallet.sh`
+> and back to project root directory:
+> `$ cd ../..`
+> and fetch dependecies again
+> `$ flutter pub get`
+
+Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command:
+
+`$ flutter packages pub run tool/generate_new_secrets.dart`
+
+We will generate mobx models for the project.
+
+`$ ./model_generator.sh`
+
+Then we need to generate localization files.
+
+`$ flutter packages pub run tool/generate_localization.dart`
+
+### 5. Build!
+
+`$ flutter build linux --release`
+
+Path to executable file will be:
+
+`build/linux/x64/release/bundle/cake_wallet`
+
+> ### Troubleshooting
+>
+> If you got an error while building the application with `$ flutter build linux --release` command, add `-v` argument to the command (`$ flutter build linux -v --release`) to get details.\
+> If you got in flutter build logs: undefined reference to `hid_free_enumeration`, or another error with undefined reference to `hid_*`, then rebuild monero lib without hidapi lib. Check does exists `libhidapi-dev` in your scope and remove it from your scope for build without it.
+
+# Flatpak
+
+For package the built application into flatpak you need fistly to install `flatpak` and `flatpak-builder`:
+
+`$ sudo apt install flatpak flatpak-builder`
+
+Then need to [add flathub](https://flatpak.org/setup/Ubuntu) (or just `$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`). Then need to install freedesktop runtime and sdk:
+
+`$ flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08`
+
+To build with using of `flatpak-build` directory run next:
+
+`$ flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml`
+
+And then export bundle:
+
+`$ flatpak build-export export flatpak-build`
+
+`$ flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet`
+
+Result file: `cake_wallet.flatpak` should be generated in current directory.
+
+For install generated flatpak file use:
+
+`$ flatpak --user install cake_wallet.flatpak`
+
+For run the installed application run:
+
+`$ flatpak run com.cakewallet.CakeWallet`
+
+Copyright (c) 2023 Cake Technologies LLC.
diff --git a/com.cakewallet.CakeWallet.yml b/com.cakewallet.CakeWallet.yml
new file mode 100644
index 000000000..83efa1388
--- /dev/null
+++ b/com.cakewallet.CakeWallet.yml
@@ -0,0 +1,35 @@
+app-id: com.cakewallet.CakeWallet
+runtime: org.freedesktop.Platform
+runtime-version: '22.08'
+sdk: org.freedesktop.Sdk
+command: cake_wallet
+separate-locales: false
+finish-args:
+ - --share=ipc
+ - --socket=fallback-x11
+ - --socket=wayland
+ - --device=dri
+ - --socket=pulseaudio
+ - --share=network
+ - --filesystem=home
+modules:
+ - name: cake_wallet
+ buildsystem: simple
+ only-arches:
+ - x86_64
+ build-commands:
+ - "cp -R bundle /app/cake_wallet"
+ - "chmod +x /app/cake_wallet/cake_wallet"
+ - "mkdir -p /app/bin"
+ - "ln -s /app/cake_wallet/cake_wallet /app/bin/cake_wallet"
+ - "mkdir -p /app/share/icons/hicolor/scalable/apps"
+ - "cp cakewallet_icon_180.png /app/share/icons/hicolor/scalable/apps/com.cakewallet.CakeWallet.png"
+ - "mkdir -p /app/share/applications"
+ - "cp com.cakewallet.CakeWallet.desktop /app/share/applications"
+ sources:
+ - type: dir
+ path: build/linux/x64/release
+ - type: file
+ path: assets/images/cakewallet_icon_180.png
+ - type: file
+ path: linux/com.cakewallet.CakeWallet.desktop
diff --git a/configure_cake_wallet.sh b/configure_cake_wallet.sh
index 0539221a3..90ce1c446 100755
--- a/configure_cake_wallet.sh
+++ b/configure_cake_wallet.sh
@@ -3,12 +3,13 @@
IOS="ios"
ANDROID="android"
MACOS="macos"
+LINUX="linux"
-PLATFORMS=($IOS $ANDROID $MACOS)
+PLATFORMS=($IOS $ANDROID $MACOS $LINUX)
PLATFORM=$1
if ! [[ " ${PLATFORMS[*]} " =~ " ${PLATFORM} " ]]; then
- echo "specify platform: ./configure_cake_wallet.sh ios|android|macos"
+ echo "specify platform: ./configure_cake_wallet.sh ios|android|macos|linux"
exit 1
fi
@@ -27,9 +28,14 @@ if [ "$PLATFORM" == "$ANDROID" ]; then
cd scripts/android
fi
+if [ "$PLATFORM" == "$LINUX" ]; then
+ echo "Configuring for linux"
+ cd scripts/linux
+fi
+
source ./app_env.sh cakewallet
./app_config.sh
cd ../.. && flutter pub get
-#flutter packages pub run tool/generate_localization.dart
+flutter packages pub run tool/generate_localization.dart
./model_generator.sh
-#cd macos && pod install
\ No newline at end of file
+#cd macos && pod install
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index 7b8250541..e2e537ee8 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -5,9 +5,10 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
+import 'package:cw_core/encryption_file_utils.dart';
+import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
-import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
import 'package:cw_bitcoin/psbt_transaction_builder.dart';
@@ -30,6 +31,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
+ required EncryptionFileUtils encryptionFileUtils,
Uint8List? seedBytes,
String? mnemonic,
String? xpub,
@@ -58,6 +60,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
+ encryptionFileUtils: encryptionFileUtils,
currency:
networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
alwaysScan: alwaysScan,
@@ -90,6 +93,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
+ required EncryptionFileUtils encryptionFileUtils,
String? passphrase,
String? addressPageType,
BasedUtxoNetwork? network,
@@ -124,6 +128,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialSilentAddresses: initialSilentAddresses,
initialSilentAddressIndex: initialSilentAddressIndex,
initialBalance: initialBalance,
+ encryptionFileUtils: encryptionFileUtils,
seedBytes: seedBytes,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
@@ -137,6 +142,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
required String password,
+ required EncryptionFileUtils encryptionFileUtils,
required bool alwaysScan,
}) async {
final network = walletInfo.network != null
@@ -148,7 +154,13 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
ElectrumWalletSnapshot? snp = null;
try {
- snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password, network);
+ snp = await ElectrumWalletSnapshot.load(
+ encryptionFileUtils,
+ name,
+ walletInfo.type,
+ password,
+ network,
+ );
} catch (e) {
if (!hasKeysFile) rethrow;
}
@@ -156,10 +168,18 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
final WalletKeysData keysData;
// Migrate wallet from the old scheme to then new .keys file scheme
if (!hasKeysFile) {
- keysData =
- WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
+ keysData = WalletKeysData(
+ mnemonic: snp!.mnemonic,
+ xPub: snp.xpub,
+ passphrase: snp.passphrase,
+ );
} else {
- keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+ keysData = await WalletKeysFile.readKeysFile(
+ name,
+ walletInfo.type,
+ password,
+ encryptionFileUtils,
+ );
}
walletInfo.derivationInfo ??= DerivationInfo();
@@ -198,6 +218,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialSilentAddresses: snp?.silentAddresses,
initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
initialBalance: snp?.balance,
+ encryptionFileUtils: encryptionFileUtils,
seedBytes: seedBytes,
initialRegularAddressIndex: snp?.regularAddressIndex,
initialChangeAddressIndex: snp?.changeAddressIndex,
diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
index 915d7cc10..91b8e4ae2 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
@@ -6,11 +6,13 @@ class BitcoinNewWalletCredentials extends WalletCredentials {
BitcoinNewWalletCredentials(
{required String name,
WalletInfo? walletInfo,
+ String? password,
DerivationType? derivationType,
String? derivationPath})
: super(
name: name,
walletInfo: walletInfo,
+ password: password,
);
}
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index cf93aa29d..d6d97f3de 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -3,6 +3,7 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
+import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_service.dart';
@@ -19,11 +20,12 @@ class BitcoinWalletService extends WalletService<
BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials,
BitcoinRestoreWalletFromHardware> {
- BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan);
+ BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect);
final Box walletInfoSource;
final Box unspentCoinsInfoSource;
final bool alwaysScan;
+ final bool isDirect;
@override
WalletType getType() => WalletType.bitcoin;
@@ -40,6 +42,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
network: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.save();
@@ -63,6 +66,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
saveBackup(name);
@@ -75,6 +79,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
return wallet;
@@ -99,6 +104,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: currentWalletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await currentWallet.renameWalletFiles(newName);
@@ -125,6 +131,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
networkParam: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.save();
await wallet.init();
@@ -153,6 +160,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
network: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.save();
await wallet.init();
diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart
index a7de414e4..806f813dd 100644
--- a/cw_bitcoin/lib/electrum_transaction_history.dart
+++ b/cw_bitcoin/lib/electrum_transaction_history.dart
@@ -1,4 +1,5 @@
import 'dart:convert';
+import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_core/pathForWallet.dart';
@@ -6,6 +7,8 @@ import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:mobx/mobx.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
part 'electrum_transaction_history.g.dart';
@@ -15,13 +18,15 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase with _$Electru
abstract class ElectrumTransactionHistoryBase
extends TransactionHistoryBase with Store {
- ElectrumTransactionHistoryBase({required this.walletInfo, required String password})
+ ElectrumTransactionHistoryBase(
+ {required this.walletInfo, required String password, required this.encryptionFileUtils})
: _password = password,
_height = 0 {
transactions = ObservableMap();
}
final WalletInfo walletInfo;
+ final EncryptionFileUtils encryptionFileUtils;
String _password;
int _height;
@@ -44,7 +49,7 @@ abstract class ElectrumTransactionHistoryBase
txjson[tx.key] = tx.value.toJson();
}
final data = json.encode({'height': _height, 'transactions': txjson});
- await writeData(path: path, password: _password, data: data);
+ await encryptionFileUtils.write(path: path, password: _password, data: data);
} catch (e) {
print('Error while save bitcoin transaction history: ${e.toString()}');
}
@@ -58,7 +63,7 @@ abstract class ElectrumTransactionHistoryBase
Future