diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..83a48756 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,17 @@ +{ + "name": "flutter_docker", + "context": "..", + "dockerFile": "../.docker/android-dev.dockerfile", + "remoteUser": "komodo", + "postAttachCommand": "sh .docker/dev-setup.sh", + "runArgs": [ + "--privileged" + ], + "workspaceMount": "source=${localWorkspaceFolder},target=/home/komodo/workspace,type=bind,consistency=delegated", + "workspaceFolder": "/home/komodo/workspace", + "hostRequirements": { + "cpus": 4, + "memory": "16gb", + "storage": "32gb" + } +} \ No newline at end of file diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile new file mode 100644 index 00000000..1856ba57 --- /dev/null +++ b/.docker/android-apk-build.dockerfile @@ -0,0 +1,43 @@ +FROM komodo/kdf-android:latest as build + +RUN cd /app && \ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + export PATH=$PATH:/android-ndk/bin && \ + CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ + mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a + +FROM komodo/android-sdk:34 as final + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" +ENV USER="komodo" +ENV PATH $PATH:$FLUTTER_HOME/bin +ENV ANDROID_AARCH64_LIB=android/app/src/main/cpp/libs/arm64-v8a +ENV ANDROID_AARCH64_LIB_SRC=/app/target/aarch64-linux-android/release/libmm2.a +ENV ANDROID_ARMV7_LIB=android/app/src/main/cpp/libs/armeabi-v7a +ENV ANDROID_ARMV7_LIB_SRC=/app/target/armv7-linux-androideabi/release/libmm2.a + +WORKDIR /app +COPY . . + +RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ + curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ + mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ + mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ + git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} && \ + cd ${FLUTTER_HOME} && \ + git fetch && \ + git checkout tags/2.8.1 + +COPY --from=build --chown=$USER:$USER ${ANDROID_AARCH64_LIB_SRC} ${ANDROID_AARCH64_LIB} +COPY --from=build --chown=$USER:$USER ${ANDROID_ARMV7_LIB_SRC} ${ANDROID_ARMV7_LIB} + +RUN flutter config --no-analytics \ + && flutter precache \ + && yes "y" | flutter doctor --android-licenses \ + && flutter doctor \ + && flutter update-packages diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile new file mode 100644 index 00000000..375b59e7 --- /dev/null +++ b/.docker/android-dev.dockerfile @@ -0,0 +1,170 @@ +FROM docker.io/ubuntu:22.04 + +ARG KDF_BRANCH=main +ENV KDF_DIR=/kdf + +# Libz is distributed in the android ndk, but for some unknown reason it is not +# found in the build process of some crates, so we explicit set the DEP_Z_ROOT +ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ + CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ + CC_x86_64_linux_android=x86_64-linux-android-clang \ + CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + CC_aarch64_linux_android=aarch64-linux-android21-clang \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ + OPENSSL_STATIC=1 \ + OPENSSL_DIR=/openssl \ + OPENSSL_INCLUDE_DIR=/openssl/include \ + OPENSSL_LIB_DIR=/openssl/lib \ + RUST_TEST_THREADS=1 \ + HOME=/home/komodo/ \ + TMPDIR=/tmp/ \ + ANDROID_DATA=/ \ + ANDROID_DNS_MODE=local \ + ANDROID_ROOT=/system + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" +ENV USER="komodo" +ENV USER_ID=1000 +ENV PATH $PATH:$FLUTTER_HOME/bin +ENV AR=/usr/bin/llvm-ar-16 +ENV CC=/usr/bin/clang-16 +ENV PATH="$HOME/.cargo/bin:$PATH" +ENV PATH=$PATH:/android-ndk/bin +ENV ANDROID_HOME=/opt/android-sdk-linux \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + LANGUAGE=en_US:en + +ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ + PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator + +# comes from https://developer.android.com/studio/#command-tools +ENV ANDROID_SDK_TOOLS_VERSION 11076708 + +# https://developer.android.com/studio/releases/build-tools +ENV ANDROID_PLATFORM_VERSION 34 +ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 + +# https://developer.android.com/ndk/downloads +ENV ANDROID_NDK_VERSION 26.3.11579264 + +RUN apt update && apt install -y sudo && \ + useradd -u $USER_ID -m $USER && \ + usermod -aG sudo $USER && \ + echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +USER $USER + +RUN sudo apt-get update -y && \ + sudo apt-get install -y --no-install-recommends \ + ca-certificates \ + build-essential \ + libssl-dev \ + cmake \ + llvm-dev \ + libclang-dev \ + lld \ + gcc \ + libc6-dev \ + jq \ + make \ + pkg-config \ + git \ + automake \ + libtool \ + m4 \ + autoconf \ + make \ + file \ + curl \ + wget \ + gnupg \ + software-properties-common \ + lsb-release \ + libudev-dev \ + zip unzip \ + binutils && \ + sudo apt-get clean + +RUN sudo ln -s /usr/bin/python3 /bin/python &&\ + sudo curl --output llvm.sh https://apt.llvm.org/llvm.sh && \ + sudo chmod +x llvm.sh && \ + sudo ./llvm.sh 16 && \ + sudo rm ./llvm.sh && \ + sudo ln -s /usr/bin/clang-16 /usr/bin/clang && \ + PROTOC_ZIP=protoc-25.3-linux-x86_64.zip && \ + sudo curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.3/$PROTOC_ZIP && \ + sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \ + sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*' && \ + sudo rm -f $PROTOC_ZIP && \ + sudo mkdir $KDF_DIR && \ + sudo chown -R $USER:$USER $KDF_DIR + +RUN PATH="$HOME/.cargo/bin:$PATH" && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ + export PATH="$HOME/.cargo/bin:$PATH" && \ + sudo chown -R $USER:$USER $HOME/.cargo && \ + rustup toolchain install nightly-2022-10-29 --no-self-update --profile=minimal &&\ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + sudo apt install -y python3 python3-pip git curl nodejs python3-venv sudo && \ + git clone https://github.com/KomodoPlatform/komodo-defi-framework.git $KDF_DIR && \ + cd $KDF_DIR && \ + git fetch --all && \ + git checkout origin/$KDF_BRANCH && \ + if [ "$(uname -m)" = "x86_64" ]; then \ + bash ./scripts/ci/android-ndk.sh x86 23; \ + elif [ "$(uname -m)" = "aarch64" ]; then \ + bash ./scripts/ci/android-ndk.sh arm64 23; \ + else \ + echo "Unsupported architecture"; \ + exit 1; \ + fi + +RUN set -e -o xtrace \ + && cd /opt \ + && sudo chown -R $USER:$USER /opt \ + && sudo apt-get update \ + && sudo apt-get install -y jq \ + openjdk-17-jdk \ + wget zip unzip git openssh-client curl bc software-properties-common build-essential \ + ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov \ + libsqlite3-dev --no-install-recommends \ + # for x86 emulators + libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ + && sudo rm -rf /var/lib/apt/lists/* \ + && sudo sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ + && sudo locale-gen \ + && sudo update-locale LANG=en_US.UTF-8 \ + && wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ + && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \ + && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \ + && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ + && sudo chown -R $USER:$USER $ANDROID_HOME \ + && rm android-sdk-tools.zip \ + && yes | sdkmanager --licenses \ + && sdkmanager platform-tools \ + && git config --global user.email "hello@komodoplatform.com" \ + && git config --global user.name "Komodo Platform" \ + && yes | sdkmanager \ + "platforms;android-$ANDROID_PLATFORM_VERSION" \ + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" + +RUN git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ + && cd ${FLUTTER_HOME} \ + && git fetch \ + && git checkout tags/2.8.1 \ + && flutter config --no-analytics \ + && flutter precache \ + && yes "y" | flutter doctor --android-licenses \ + && flutter doctor \ + && flutter update-packages diff --git a/.docker/android-sdk.dockerfile b/.docker/android-sdk.dockerfile new file mode 100644 index 00000000..7f176434 --- /dev/null +++ b/.docker/android-sdk.dockerfile @@ -0,0 +1,56 @@ +FROM docker.io/ubuntu:22.04 + +# Credit to Cirrus Labs for the original Dockerfile +# LABEL org.opencontainers.image.source=https://github.com/cirruslabs/docker-images-android + +USER root + +ENV ANDROID_HOME=/opt/android-sdk-linux \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + LANGUAGE=en_US:en + +ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ + PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator + +# comes from https://developer.android.com/studio/#command-tools +ENV ANDROID_SDK_TOOLS_VERSION 11076708 + +# https://developer.android.com/studio/releases/build-tools +ENV ANDROID_PLATFORM_VERSION 34 +ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 + +# https://developer.android.com/ndk/downloads +ENV ANDROID_NDK_VERSION 26.3.11579264 + +RUN set -o xtrace \ + && cd /opt \ + && apt-get update \ + && apt-get install -y jq \ + openjdk-17-jdk \ + sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ + # for x86 emulators + libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ + && rm -rf /var/lib/apt/lists/* \ + && sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ + && locale-gen \ + && update-locale LANG=en_US.UTF-8 \ + && wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ + && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \ + && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \ + && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ + && chown -R root:root $ANDROID_HOME \ + && rm android-sdk-tools.zip \ + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ + && yes | sdkmanager --licenses \ + && wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \ + && chmod +x /usr/bin/android-wait-for-emulator \ + && sdkmanager platform-tools \ + && mkdir -p /root/.android \ + && touch /root/.android/repositories.cfg \ + && git config --global user.email "hello@komodoplatform.com" \ + && git config --global user.name "Komodo Platform" \ + && yes | sdkmanager \ + "platforms;android-$ANDROID_PLATFORM_VERSION" \ + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \ + && yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \ No newline at end of file diff --git a/.docker/build_apk_release.sh b/.docker/build_apk_release.sh new file mode 100644 index 00000000..0936bd73 --- /dev/null +++ b/.docker/build_apk_release.sh @@ -0,0 +1,6 @@ +set -e + +docker build -f .docker/kdf-android-build.dockerfile . -t komodo/kdf-android --build-arg KDF_BRANCH=main +docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 +docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile +docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest flutter build apk --release \ No newline at end of file diff --git a/.docker/build_config.json b/.docker/build_config.json new file mode 100644 index 00000000..cf879573 --- /dev/null +++ b/.docker/build_config.json @@ -0,0 +1,28 @@ +{ + "api": { + "release_tag": "v2.0.0-beta", + "use_latest_release": false, + "github_repository": "https://github.com/KomodoPlatform/komodo-defi-framework", + "platforms": { + "ios": { + "keywords": [ + "ios", + "aarch64" + ], + "path": "ios" + }, + "android-armv7": { + "keywords": [ + "android-armv7" + ], + "path": "android/app/src/main/cpp/libs/armeabi-v7a" + }, + "android-aarch64": { + "keywords": [ + "android-aarch64" + ], + "path": "android/app/src/main/cpp/libs/arm64-v8a" + } + } + } +} \ No newline at end of file diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh new file mode 100644 index 00000000..0b0f225c --- /dev/null +++ b/.docker/dev-setup.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +sudo git config core.fileMode false +sudo chmod -R u+rwx /home/komodo/workspace +sudo chown -R komodo:komodo /home/komodo/workspace +flutter pub get + +curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins +curl -o assets/coins_config_tcp.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config_tcp.json +mkdir -p android/app/src/main/cpp/libs/armeabi-v7a +mkdir -p android/app/src/main/cpp/libs/arm64-v8a + +cd /kdf +export PATH="$HOME/.cargo/bin:$PATH" +export PATH=$PATH:/android-ndk/bin +CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib +CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib +mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a +mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a + +mv /kdf/target/aarch64-linux-android/release/libmm2.a /home/komodo/workspace/android/app/src/main/cpp/libs/arm64-v8a/libmm2.a +mv /kdf/target/armv7-linux-androideabi/release/libmm2.a /home/komodo/workspace/android/app/src/main/cpp/libs/armeabi-v7a/libmm2.a \ No newline at end of file diff --git a/.docker/kdf-android-build.dockerfile b/.docker/kdf-android-build.dockerfile new file mode 100644 index 00000000..dc687b0f --- /dev/null +++ b/.docker/kdf-android-build.dockerfile @@ -0,0 +1,102 @@ +FROM docker.io/ubuntu:22.04 + +LABEL Author "Onur Özkan " +ARG KDF_BRANCH=main + +RUN apt-get update -y && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + build-essential \ + libssl-dev \ + cmake \ + llvm-dev \ + libclang-dev \ + lld \ + gcc \ + libc6-dev \ + jq \ + make \ + pkg-config \ + git \ + automake \ + libtool \ + m4 \ + autoconf \ + make \ + file \ + curl \ + wget \ + gnupg \ + software-properties-common \ + lsb-release \ + libudev-dev \ + zip unzip \ + binutils && \ + apt-get clean + +RUN ln -s /usr/bin/python3 /bin/python &&\ + curl --output llvm.sh https://apt.llvm.org/llvm.sh && \ + chmod +x llvm.sh && \ + ./llvm.sh 16 && \ + rm ./llvm.sh && \ + ln -s /usr/bin/clang-16 /usr/bin/clang && \ + PROTOC_ZIP=protoc-25.3-linux-x86_64.zip && \ + curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.3/$PROTOC_ZIP && \ + unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \ + unzip -o $PROTOC_ZIP -d /usr/local 'include/*' && \ + rm -f $PROTOC_ZIP + +ENV AR=/usr/bin/llvm-ar-16 +ENV CC=/usr/bin/clang-16 + +RUN mkdir -m 0755 -p /etc/apt/keyrings + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ + export PATH="/root/.cargo/bin:$PATH" && \ + rustup toolchain install nightly-2022-10-29 --no-self-update --profile=minimal &&\ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + apt install -y python3 python3-pip git curl nodejs python3-venv sudo && \ + git clone https://github.com/KomodoPlatform/komodo-defi-framework.git /app && \ + cd /app && \ + git fetch --all && \ + git checkout origin/$KDF_BRANCH && \ + if [ "$(uname -m)" = "x86_64" ]; then \ + bash ./scripts/ci/android-ndk.sh x86 23; \ + elif [ "$(uname -m)" = "aarch64" ]; then \ + bash ./scripts/ci/android-ndk.sh arm64 23; \ + else \ + echo "Unsupported architecture"; \ + exit 1; \ + fi + +ENV PATH="/root/.cargo/bin:$PATH" + +ENV PATH=$PATH:/android-ndk/bin + +# Libz is distributed in the android ndk, but for some unknown reason it is not +# found in the build process of some crates, so we explicit set the DEP_Z_ROOT +ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ + CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ + CC_x86_64_linux_android=x86_64-linux-android-clang \ + CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + CC_aarch64_linux_android=aarch64-linux-android21-clang \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ + OPENSSL_STATIC=1 \ + OPENSSL_DIR=/openssl \ + OPENSSL_INCLUDE_DIR=/openssl/include \ + OPENSSL_LIB_DIR=/openssl/lib \ + RUST_TEST_THREADS=1 \ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_DATA=/ \ + ANDROID_DNS_MODE=local \ + ANDROID_ROOT=/system diff --git a/.docker/requirements.txt b/.docker/requirements.txt new file mode 100644 index 00000000..6a46b2c2 --- /dev/null +++ b/.docker/requirements.txt @@ -0,0 +1,3 @@ +requests==2.31.0 +beautifulsoup4==4.12.2 + diff --git a/.docker/update_api.py b/.docker/update_api.py new file mode 100644 index 00000000..e27d6069 --- /dev/null +++ b/.docker/update_api.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +import os +import sys +import json +import shutil +import zipfile +import requests +import argparse +from pathlib import Path +from datetime import datetime + +class UpdateAPI: + '''Updates the API module version for all or a specified platform.''' + def __init__(self, tag=None, platform=None, force=False): + self.tag = tag + self.platform = platform + self.force = force + + # Get the absolute path of the project root directory + self.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.config_file = os.path.join(self.project_root, ".docker/build_config.json") + + # Load the build_config.json + with open(self.config_file, "r") as f: + self.config = json.load(f) + + # Use tag from build_config.json if tag is not specified + if not self.tag: + self.tag = self.config["api"]["release_tag"] + + # Get the platforms config + self.platforms_config = self.config["api"]["platforms"] + + # Get the GitHub repository URL + self.github_repo = self.config["api"]["github_repository"].replace("https://github.com/", "https://api.github.com/repos/") + + # Check if should use the latest release + self.use_latest_release = self.config["api"].get("use_latest_release", False) + + def get_platform_destination_folder(self, platform): + '''Returns the destination folder for the specified platform.''' + if platform in self.platforms_config: + return os.path.join(self.project_root, self.platforms_config[platform]["path"]) + else: + raise ValueError(f"Invalid platform: {platform}. Please select a valid platform from the following list: {', '.join(self.platforms_config.keys())}") + + def get_release_assets(self): + '''Fetches the assets of the specified or latest release from the GitHub repository.''' + if self.use_latest_release: + api_url = f"{self.github_repo}/releases/latest" + else: + api_url = f"{self.github_repo}/releases/tags/{self.tag}" + + response = requests.get(api_url) + response.raise_for_status() + release = response.json() + + return release["assets"] + + def get_zip_file_url(self, platform): + '''Returns the URL of the zip file for the requested version / platform.''' + assets = self.get_release_assets() + search_parameters = self.platforms_config[platform] + keywords = search_parameters["keywords"] + for asset in assets: + file_name = asset["name"] + if all(keyword in file_name for keyword in keywords): + return asset["browser_download_url"] + raise ValueError(f"Could not find release zip file for tag '{self.tag}' on '{platform}' platform!") + + def download_api_file(self, platform): + '''Downloads the API version zip file for a specific platform.''' + # Get the URL of the zip file + zip_file_url = self.get_zip_file_url(platform) + + # Download the zip file + print(f"Downloading '{self.tag}' API module for [{platform}]...") + response = requests.get(zip_file_url, stream=True) + response.raise_for_status() + + destination_folder = self.get_platform_destination_folder(platform) + zip_file_name = os.path.basename(zip_file_url) + destination_path = os.path.join(destination_folder, zip_file_name) + + # Ensure the destination directory exists + os.makedirs(destination_folder, exist_ok=True) + + # Save the zip file to the specified folder + with open(destination_path, "wb") as file: + response.raw.decode_content = True + shutil.copyfileobj(response.raw, file) + + print(f"Saved to '{destination_path}'") + return destination_path + + def update_api(self): + '''Updates the API module.''' + tag = self.config["api"]["release_tag"] + platforms = self.config["api"]["platforms"] + + # If a platform is specified, only update that platform + if self.platform: + platforms = {self.platform: platforms[self.platform]} + + for platform in platforms: + # Set the api module destination folder + destination_folder = self.get_platform_destination_folder(platform) + + # Check if .api_last_updated file exists + last_api_update_file = os.path.join(destination_folder, ".api_last_updated") + + is_outdated = True + + if not self.force and os.path.exists(last_api_update_file): + with open(last_api_update_file, "r") as f: + last_api_update = json.load(f) + if last_api_update.get("tag") == tag: + print(f"{platform} API module is up to date ({tag}).") + is_outdated = False + + if is_outdated: + # Download the API file for the platform + zip_file_path = self.download_api_file(platform) + + # Unzip the downloaded file + print(f"Extracting...") + with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: + zip_ref.extractall(destination_folder) + + # Make mm2 file executable for Linux + if platform == 'linux': + print("Make mm2 file executable for Linux") + os.chmod(os.path.join(destination_folder, "mm2"), 0o755) + + # Delete the zip file after extraction + os.remove(zip_file_path) + + # Update .api_last_updated file + with open(last_api_update_file, "w") as f: + current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + json.dump({"tag": tag, "timestamp": current_timestamp}, f) + + def update_build_config_tag(self): + '''Updates the API tag in build_config.json.''' + self.config["api"]["release_tag"] = self.tag + + with open(self.config_file, "w") as f: + json.dump(self.config, f, indent=4) + + print(f"Tag in build_config.json updated to {self.tag}.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Download API module file for specified tag and platform.") + # Optional arguments + parser.add_argument("-a", "--api", help="tag of the API module to download.", default=None) + parser.add_argument("-p", "--platform", help="platform for which the API module should be downloaded.", default=None) + parser.add_argument("--force", action="store_true", help="force update, ignoring .api_last_updated.", default=False) + args = parser.parse_args() + + try: + updateAPI = UpdateAPI(args.api, args.platform, args.force) + # Update the API tag in build_config.json if the API tag is specified + if args.api: + updateAPI.update_build_config_tag() + updateAPI.update_api() + + except Exception as e: + print(f"Error: {e}") diff --git a/.gitignore b/.gitignore index 6739ab05..d8e0ec18 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ .buildlog/ .history .svn/ +**/.api_last_updated # coins file extras # /assets/coins.json diff --git a/README.md b/README.md index 3a394f0c..96dc35c7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Komodo Wallet - Open Source GitHub Repository 🚀 +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/KomodoPlatform/komodo-wallet-mobile?quickstart=1) + ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/komodoplatform/atomicdex-mobile/build.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/komodoplatform/atomicdex-mobile) ![GitHub contributors](https://img.shields.io/github/contributors-anon/komodoplatform/atomicdex-mobile) @@ -68,6 +70,27 @@ Windows: `choco install jq`, [Choco software](https://chocolatey.org/) https://github.com/KomodoPlatform/AtomicDEX-mobile/wiki/Project-Setup#build-and-run +### Build with docker + +To build from a container without installing Flutter on an x86_64 machine (Linux or Windows) with Docker or Podman installed, you can use the provided Dockerfile. + +```bash +sh .docker/build_apk_release.sh +``` + +You can also manually build using docker with the following commands: + +```bash +docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 +docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile +docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest +``` + +The build output should be in the following directory: `build/app/outputs/flutter-apk/app-release.apk` + +NOTE: There are known issues with building this repository using docker on ARM-based systems (e.g. M-series Macs, Raspberry Pi): + - linux/amd64: [Dart VM emulation on M1 Mac fails](https://github.com/dart-lang/sdk/issues/48420) + - linux/arm64: fails due to dependencies limiting the versions of the dart sdk, android gradle plugin, and gradle build tools. See the [Gradle Compatibility Matrix](https://docs.gradle.org/current/userguide/compatibility.html) ## Run/Build with screenshot and video recording ON @@ -96,6 +119,17 @@ Ensure you run the most recent Komodo DeFi Framework [stable release](https://gi See [our wiki](https://github.com/KomodoPlatform/atomicdex-mobile/wiki/Project-Setup#android-builds-from-scratch) here for more thorough project setup steps. Besides installing the API binary, Komodo Wallet is set up similarly to any other cloned Flutter project. +### Setup with Python script + +You can use the provided Python script to download and extract the API binary for you. This script will download the latest release of the API binary from GitHub and extract it to the correct location. + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip install -r .docker/requirements.txt +python .docker/update_api.py --force +``` + ## Accessing the database adb exec-out run-as com.komodoplatform.atomicdex cat /data/data/com.komodoplatform.atomicdex/app_flutter/AtomicDEX.db > AtomicDEX.db diff --git a/fetch_coins.ps1 b/fetch_coins.ps1 index aa30463b..b90fbad8 100644 --- a/fetch_coins.ps1 +++ b/fetch_coins.ps1 @@ -1,4 +1,5 @@ $config_init_mm2 = "assets\coins.json" +$config_mm2 = "assets\coins_config_tcp.json" # back compatibility if ( ( Test-Path -Path $config_init_mm2 -PathType Leaf ) -and -not ( Test-Path -Path "coins_ci.json" -PathType Leaf ) ) { @@ -8,13 +9,14 @@ if ( ( Test-Path -Path $config_init_mm2 -PathType Leaf ) -and -not ( Test-Path - # get coins file $coins_repo_commit = $( jq.exe -r '.coins_repo_commit' .\coins_ci.json) curl.exe -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/coins" --output $config_init_mm2 +curl.exe -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/utils/coins_config_tcp.json" --output $config_mm2 # clean checks from previous run rm .\app_assets rm .\coins_assets # get assets lists -jq.exe -r 'keys | .[]' "assets/coins_config.json" > app_assets +jq.exe -r 'keys | .[]' $config_mm2 > app_assets jq.exe -r '.[].coin' $config_init_mm2 > coins_assets # check if all assets from coins_config are present in coins.json diff --git a/fetch_coins.sh b/fetch_coins.sh index 0061015f..b250268c 100755 --- a/fetch_coins.sh +++ b/fetch_coins.sh @@ -10,9 +10,10 @@ fi # get coins file coins_repo_commit="$( jq -r '.coins_repo_commit' coins_ci.json )" curl -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/coins" --output "assets/coins.json" +curl -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/utils/coins_config_tcp.json" --output "assets/coins_config_tcp.json" # get assets lists -jq -r 'keys | .[]' assets/coins_config.json > app_assets +jq -r 'keys | .[]' assets/coins_config_tcp.json > app_assets jq -r '.[].coin' assets/coins.json > coins_assets # check if all assets from 0.5.6-coins are present in coins.json diff --git a/lib/app_config/app_config.dart b/lib/app_config/app_config.dart index 9155d59c..dda39429 100644 --- a/lib/app_config/app_config.dart +++ b/lib/app_config/app_config.dart @@ -177,7 +177,7 @@ class AppConfig { // endpoint source code: // https://github.com/KomodoPlatform/mobile_endpoints_proxy/blob/main/main.py#L113 String get fiatPricesEndpoint => - 'https://rates.komodo.earth/api/v1/usd_rates'; + 'https://defi-stats.komodo.earth/api/v3/rates/fixer_io'; // endpoint source code: // https://github.com/KomodoPlatform/mobile_endpoints_proxy/blob/main/main.py#L95