diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml new file mode 100644 index 00000000..ffbca15c --- /dev/null +++ b/.github/workflows/build-android.yml @@ -0,0 +1,228 @@ +name: Hash Wallet Android build + +# Triggers: +# - push to dev/main (validate every commit) +# - PRs targeting dev/main (gate merges) +# - manual via workflow_dispatch +on: + push: + branches: [dev, main] + pull_request: + branches: [dev, main] + workflow_dispatch: + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-latest + container: + # Same Cake-Labs prebuilt image used for Linux. Bundles Flutter 3.32.0, + # Android NDK r28, Go 1.24.1, Android SDK, JDK 17, gradle, and the + # native build deps (boost, openssl, libsodium, libzmq, unbound, icu). + image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly + env: + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + APP_ANDROID_TYPE: cakewallet + + steps: + - name: Fix Actions HOME (writeable for ~/.cache + gradle) + run: echo "HOME=/root" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Configure git inside the container + run: | + git config --global --add safe.directory '*' + git config --global user.email "ci@suchsoftware.com" + git config --global user.name "Hash Wallet CI" + + # ---- External prebuilt deps (same approach as Linux workflow) -------- + - name: Fetch prebuilt torch_dart + run: | + set -x -e + pushd scripts + rm -rf torch_dart torch_dart.tar.gz + wget -q https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz + mkdir torch_dart + tar -xzf torch_dart.tar.gz -C torch_dart + rm torch_dart.tar.gz + popd + + - name: Fetch prebuilt reown_flutter + run: | + set -x -e + pushd scripts + rm -rf reown_flutter reown_flutter.tar.gz + wget -q https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz + mkdir reown_flutter + tar -xzf reown_flutter.tar.gz -C reown_flutter + rm reown_flutter.tar.gz + popd + + - name: Clone BitBox Flutter + run: | + set -x -e + pushd scripts + ./build_bitbox_flutter.sh + popd + + # ---- Native crypto cores (monero_c prebuilt bundle) ------------------ + # Same release-bundle.zip as Linux. Contains pre-cross-compiled .so + # files for monero/wownero/zano across all 4 Android ABIs. We only ship + # monero + wownero — zano libs in the bundle are ignored. + - name: Fetch prebuilt monero_c .so bundle + run: | + set -x -e + ./scripts/prepare_moneroc.sh + MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags) + echo "monero_c TAG: $MONERO_C_TAG" + mkdir -p "scripts/monero_c/release/$MONERO_C_TAG" + pushd "scripts/monero_c/release/$MONERO_C_TAG" + wget -q https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.6-RC1/release-bundle.zip + unzip -q release-bundle.zip + rm release-bundle.zip + ls + popd + + # ---- Stage native libs into android/app/src/main/jniLibs// ----- + # Flutter Android packaging auto-includes everything under jniLibs. + - name: Place Android .so files into jniLibs + run: | + set -x -e + MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags) + BUNDLE_DIR="scripts/monero_c/release/$MONERO_C_TAG" + + # monero_c target dir → Android ABI dir + declare -A ABI_MAP=( + [aarch64-linux-android]=arm64-v8a + [armv7a-linux-androideabi]=armeabi-v7a + [i686-linux-android]=x86 + [x86_64-linux-android]=x86_64 + ) + + for target in "${!ABI_MAP[@]}"; do + abi="${ABI_MAP[$target]}" + mkdir -p "android/app/src/main/jniLibs/$abi" + for coin in monero wownero; do + src="$BUNDLE_DIR/$target/lib${coin}_wallet2_api_c.so" + if [[ -f "$src" ]]; then + cp -v "$src" "android/app/src/main/jniLibs/$abi/" + else + echo "MISSING: $src — fail loud, the bundle layout may have changed" + exit 1 + fi + done + done + + echo "=== jniLibs contents ===" + find android/app/src/main/jniLibs/ -type f -name '*.so' | sort + + # mwebd (Litecoin MWEB) is NOT built here. LTC works without MWEB — + # users just don't get the privacy MWEB feature. Add a build_mwebd + # step if/when we want MWEB on Android. + + # ---- Configure: pubspec.yaml, AndroidManifest.xml, app_properties ---- + - name: Run Android configure (cakewallet profile) + run: | + set -x -e + pushd scripts/android + source ./app_env.sh cakewallet + ./app_config.sh + popd + + # ---- Secrets --------------------------------------------------------- + - name: Generate per-module secrets.g.dart files (all empty defaults) + run: dart run tool/generate_new_secrets.dart + + - name: Inject Trocador affiliate secrets into lib/.secrets.g.dart + env: + TROCADOR_API_KEY: ${{ secrets.TROCADOR_API_KEY }} + TROCADOR_MONERO_API_KEY: ${{ secrets.TROCADOR_MONERO_API_KEY }} + TROCADOR_EXCHANGE_MARKUP: ${{ secrets.TROCADOR_EXCHANGE_MARKUP }} + run: | + sed -i \ + -e "s|const trocadorApiKey = '';|const trocadorApiKey = '${TROCADOR_API_KEY}';|" \ + -e "s|const trocadorMoneroApiKey = '';|const trocadorMoneroApiKey = '${TROCADOR_MONERO_API_KEY}';|" \ + -e "s|const trocadorExchangeMarkup = '';|const trocadorExchangeMarkup = '${TROCADOR_EXCHANGE_MARKUP:-1}';|" \ + lib/.secrets.g.dart + grep '^const trocador' lib/.secrets.g.dart + + # ---- Signing: decode upload keystore + write key.properties --------- + - name: Decode Android upload keystore + write key.properties + env: + ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} + ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} + run: | + set -e + if [[ -z "$ANDROID_KEYSTORE_BASE64" ]]; then + echo "FATAL: ANDROID_KEYSTORE_BASE64 not set — configure Gitea Actions secrets first" + exit 1 + fi + # Write decoded keystore next to build.gradle (storeFile path + # in key.properties is resolved relative to android/app/). + echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > android/app/upload-keystore.jks + ls -la android/app/upload-keystore.jks + # key.properties consumed by build.gradle's signingConfigs.release. + cat > android/key.properties </dev/null | sort -V | tail -1 || which apksigner) + if [[ -n "$APKSIGNER" ]]; then + "$APKSIGNER" verify --print-certs build/app/outputs/flutter-apk/app-release.apk || true + else + echo "apksigner not on PATH; skipping sig print" + fi + + # actions/upload-artifact@v4 doesn't work on Gitea; pin to v3. + - name: Upload APK artifact (sideload-able) + uses: actions/upload-artifact@v3 + with: + name: hash-wallet-android-apk-${{ github.sha }} + path: build/app/outputs/flutter-apk/app-release.apk + retention-days: 14 + + - name: Upload AAB artifact (for Play Console) + uses: actions/upload-artifact@v3 + with: + name: hash-wallet-android-aab-${{ github.sha }} + path: build/app/outputs/bundle/release/app-release.aab + retention-days: 30 diff --git a/.github/workflows/build-ios-sim.yml b/.github/workflows/build-ios-sim.yml new file mode 100644 index 00000000..31db21bb --- /dev/null +++ b/.github/workflows/build-ios-sim.yml @@ -0,0 +1,164 @@ +name: Hash Wallet iOS Simulator build + +# Phase 1 of iOS CI: validate the Mac runner end-to-end by producing an +# unsigned simulator .app. Drop the resulting Runner.app into the iOS +# Simulator on any Apple Silicon Mac to verify the app actually compiles +# and launches. +# +# Phase 2 (separate workflow): full TestFlight pipeline with signing. + +on: + push: + branches: [dev, main] + pull_request: + branches: [dev, main] + workflow_dispatch: + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: macos-latest + env: + APP_IOS_TYPE: cakewallet + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Show toolchain + run: | + set -x + flutter --version + xcodebuild -version + pod --version + which wget unzip + uname -m + + # ---- External prebuilt deps (same as android/linux) ------------------ + - name: Fetch prebuilt torch_dart + run: | + set -x -e + pushd scripts + rm -rf torch_dart torch_dart.tar.gz + wget -q https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz + mkdir torch_dart + tar -xzf torch_dart.tar.gz -C torch_dart + rm torch_dart.tar.gz + popd + + - name: Fetch prebuilt reown_flutter + run: | + set -x -e + pushd scripts + rm -rf reown_flutter reown_flutter.tar.gz + wget -q https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz + mkdir reown_flutter + tar -xzf reown_flutter.tar.gz -C reown_flutter + rm reown_flutter.tar.gz + popd + + - name: Clone BitBox Flutter + run: | + set -x -e + pushd scripts + ./build_bitbox_flutter.sh + popd + + # ---- Native crypto cores (monero_c prebuilt bundle) ------------------ + - name: Fetch prebuilt monero_c bundle + run: | + set -x -e + ./scripts/prepare_moneroc.sh + MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags) + mkdir -p "scripts/monero_c/release/$MONERO_C_TAG" + pushd "scripts/monero_c/release/$MONERO_C_TAG" + wget -q https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.6-RC1/release-bundle.zip + unzip -q release-bundle.zip + rm release-bundle.zip + echo "=== bundle contents (one level) ===" + ls + popd + + # iOS native lib staging: Cake's scripts/ios/setup.sh + gen_framework.sh + # expect pre-built .a archives in specific paths. The first run will + # likely surface what's missing; we iterate from there. + - name: Inspect iOS targets available in monero_c bundle + run: | + set -x + MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags) + BUNDLE_DIR="scripts/monero_c/release/$MONERO_C_TAG" + # List anything iOS-y + find "$BUNDLE_DIR" -maxdepth 1 -name '*ios*' -o -name '*apple*' 2>/dev/null || true + ls "$BUNDLE_DIR" || true + + # ---- Configure: pubspec.yaml, Info.plist, GeneratedPluginRegistrant --- + - name: Run iOS configure (cakewallet profile) + run: | + set -x -e + pushd scripts/ios + source ./app_env.sh cakewallet + ./app_config.sh + popd + + # ---- Secrets --------------------------------------------------------- + - name: Generate per-module secrets.g.dart files (all empty defaults) + run: dart run tool/generate_new_secrets.dart + + - name: Inject Trocador affiliate secrets + env: + TROCADOR_API_KEY: ${{ secrets.TROCADOR_API_KEY }} + TROCADOR_MONERO_API_KEY: ${{ secrets.TROCADOR_MONERO_API_KEY }} + TROCADOR_EXCHANGE_MARKUP: ${{ secrets.TROCADOR_EXCHANGE_MARKUP }} + run: | + # macOS sed needs '' after -i; Linux sed doesn't accept that. This + # workflow runs on macos only. + sed -i '' \ + -e "s|const trocadorApiKey = '';|const trocadorApiKey = '${TROCADOR_API_KEY}';|" \ + -e "s|const trocadorMoneroApiKey = '';|const trocadorMoneroApiKey = '${TROCADOR_MONERO_API_KEY}';|" \ + -e "s|const trocadorExchangeMarkup = '';|const trocadorExchangeMarkup = '${TROCADOR_EXCHANGE_MARKUP:-1}';|" \ + lib/.secrets.g.dart + grep '^const trocador' lib/.secrets.g.dart + + # ---- Flutter init + codegen ----------------------------------------- + - name: Initialize Flutter SDK (iOS precache) + run: | + flutter --version + flutter precache --ios --no-linux --no-android --no-macos --no-windows --no-fuchsia --no-web || true + + - name: Build generated code (mobx + hive adapters) + run: bash model_generator.sh + + - name: Generate localization + run: dart run tool/generate_localization.dart + + # CocoaPods: the iOS Podfile installs Flutter plugin pods. Required + # before flutter build can link them. + - name: pod install + run: | + cd ios + pod install --repo-update + + # ---- Build iOS Simulator app (no codesign) --------------------------- + - name: Build iOS Simulator app + run: | + set -x -e + flutter build ios --simulator --no-codesign \ + --dart-define-from-file=env.json + ls -la build/ios/iphonesimulator/ + + - name: Zip Runner.app + run: | + cd build/ios/iphonesimulator + zip -r hash_wallet_ios_sim_${{ github.sha }}.zip Runner.app + + - name: Upload .app artifact + uses: actions/upload-artifact@v3 + with: + name: hash-wallet-ios-sim-${{ github.sha }} + path: build/ios/iphonesimulator/hash_wallet_ios_sim_*.zip + retention-days: 14 diff --git a/.github/workflows/build-ios-testflight.yml b/.github/workflows/build-ios-testflight.yml new file mode 100644 index 00000000..40151b56 --- /dev/null +++ b/.github/workflows/build-ios-testflight.yml @@ -0,0 +1,266 @@ +name: Hash Wallet iOS TestFlight build + +# Phase 2 of iOS CI: full signed build that uploads to TestFlight. +# Phase 1 (build-ios-sim.yml) validates the Mac runner with no signing — +# run that first if TestFlight blows up unexpectedly. +# +# Required Gitea Actions secrets (all account/app credentials): +# APPLE_TEAM_ID — 10-char (D8PL9F7X33) +# APPLE_KEY_ID — 10-char (CHK6B69G58) +# APPLE_ISSUER_ID — UUID +# APPLE_API_KEY_P8_BASE64 — base64 of AuthKey_.p8 +# APPLE_DIST_CERT_P12_BASE64 — base64 of distribution.p12 +# APPLE_DIST_CERT_P12_PASSWORD — password set during openssl pkcs12 export +# APPLE_PROVISIONING_PROFILE_BASE64 — base64 of Hash_Wallet.mobileprovision +# APPLE_KEYCHAIN_PASSWORD — any string, used to create the temp keychain +# TROCADOR_* — reused from Linux/Android + +on: + # Don't auto-trigger on every push — TestFlight uploads are slow and use + # build numbers. Manual trigger only; later we can add a workflow_dispatch + # input for build number or auto-bump. + workflow_dispatch: + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: macos-latest + env: + APP_IOS_TYPE: cakewallet + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Show toolchain + run: | + set -x + flutter --version + xcodebuild -version + pod --version + uname -m + + # ---- External prebuilt deps ----------------------------------------- + - name: Fetch prebuilt torch_dart + run: | + set -x -e + pushd scripts + rm -rf torch_dart torch_dart.tar.gz + wget -q https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz + mkdir torch_dart + tar -xzf torch_dart.tar.gz -C torch_dart + rm torch_dart.tar.gz + popd + + - name: Fetch prebuilt reown_flutter + run: | + set -x -e + pushd scripts + rm -rf reown_flutter reown_flutter.tar.gz + wget -q https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz + mkdir reown_flutter + tar -xzf reown_flutter.tar.gz -C reown_flutter + rm reown_flutter.tar.gz + popd + + - name: Clone BitBox Flutter + run: | + set -x -e + pushd scripts + ./build_bitbox_flutter.sh + popd + + - name: Fetch prebuilt monero_c bundle + run: | + set -x -e + ./scripts/prepare_moneroc.sh + MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags) + mkdir -p "scripts/monero_c/release/$MONERO_C_TAG" + pushd "scripts/monero_c/release/$MONERO_C_TAG" + wget -q https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.6-RC1/release-bundle.zip + unzip -q release-bundle.zip + rm release-bundle.zip + popd + + # ---- Configure: pubspec.yaml, Info.plist, etc. ---------------------- + - name: Run iOS configure (cakewallet profile) + run: | + set -x -e + pushd scripts/ios + source ./app_env.sh cakewallet + ./app_config.sh + popd + + # ---- Secrets --------------------------------------------------------- + - name: Generate per-module secrets.g.dart files (empty defaults) + run: dart run tool/generate_new_secrets.dart + + - name: Inject Trocador affiliate secrets + env: + TROCADOR_API_KEY: ${{ secrets.TROCADOR_API_KEY }} + TROCADOR_MONERO_API_KEY: ${{ secrets.TROCADOR_MONERO_API_KEY }} + TROCADOR_EXCHANGE_MARKUP: ${{ secrets.TROCADOR_EXCHANGE_MARKUP }} + run: | + sed -i '' \ + -e "s|const trocadorApiKey = '';|const trocadorApiKey = '${TROCADOR_API_KEY}';|" \ + -e "s|const trocadorMoneroApiKey = '';|const trocadorMoneroApiKey = '${TROCADOR_MONERO_API_KEY}';|" \ + -e "s|const trocadorExchangeMarkup = '';|const trocadorExchangeMarkup = '${TROCADOR_EXCHANGE_MARKUP:-1}';|" \ + lib/.secrets.g.dart + + # ---- Apple signing setup -------------------------------------------- + - name: Create temp keychain + import distribution cert + env: + APPLE_DIST_CERT_P12_BASE64: ${{ secrets.APPLE_DIST_CERT_P12_BASE64 }} + APPLE_DIST_CERT_P12_PASSWORD: ${{ secrets.APPLE_DIST_CERT_P12_PASSWORD }} + APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} + run: | + set -e + KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db" + # Create + unlock dedicated keychain so we don't touch the user's login keychain + security create-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" # 6 hours + security unlock-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + # Add to user search list so codesign can find it + security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | sed 's/"//g') + # Import the .p12 + P12="$RUNNER_TEMP/dist.p12" + echo "$APPLE_DIST_CERT_P12_BASE64" | base64 -d > "$P12" + security import "$P12" -k "$KEYCHAIN_PATH" -P "$APPLE_DIST_CERT_P12_PASSWORD" \ + -T /usr/bin/codesign -T /usr/bin/security + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$APPLE_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + # Sanity-check: list identities the keychain offers + security find-identity -v -p codesigning "$KEYCHAIN_PATH" + rm -f "$P12" + + - name: Install provisioning profile + parse name/UUID for ExportOptions + env: + APPLE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }} + run: | + set -e + PROFILES_DIR="$HOME/Library/MobileDevice/Provisioning Profiles" + mkdir -p "$PROFILES_DIR" + PROFILE="$RUNNER_TEMP/Hash_Wallet.mobileprovision" + echo "$APPLE_PROVISIONING_PROFILE_BASE64" | base64 -d > "$PROFILE" + + # Parse the .mobileprovision to get its UUID + Name (CMS-decoded plist). + PROFILE_UUID=$(security cms -D -i "$PROFILE" | plutil -extract UUID raw -o - -) + PROFILE_NAME=$(security cms -D -i "$PROFILE" | plutil -extract Name raw -o - -) + echo "Profile UUID: $PROFILE_UUID" + echo "Profile name: $PROFILE_NAME" + echo "PROFILE_UUID=$PROFILE_UUID" >> "$GITHUB_ENV" + echo "PROFILE_NAME=$PROFILE_NAME" >> "$GITHUB_ENV" + + # Xcode looks profiles up by UUID filename. + cp "$PROFILE" "$PROFILES_DIR/$PROFILE_UUID.mobileprovision" + ls -la "$PROFILES_DIR" | head -10 + + - name: Install App Store Connect API key for altool + env: + APPLE_API_KEY_P8_BASE64: ${{ secrets.APPLE_API_KEY_P8_BASE64 }} + APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }} + run: | + set -e + mkdir -p "$HOME/.appstoreconnect/private_keys" + echo "$APPLE_API_KEY_P8_BASE64" | base64 -d > "$HOME/.appstoreconnect/private_keys/AuthKey_${APPLE_KEY_ID}.p8" + ls -la "$HOME/.appstoreconnect/private_keys/" + + # ---- Flutter init + codegen + pod install --------------------------- + - name: Initialize Flutter SDK (iOS precache) + run: | + flutter --version + flutter precache --ios --no-linux --no-android --no-macos --no-windows --no-fuchsia --no-web || true + + - name: Build generated code + run: bash model_generator.sh + + - name: Generate localization + run: dart run tool/generate_localization.dart + + - name: pod install + run: | + cd ios + pod install --repo-update + + # ---- Generate ExportOptions.plist + build IPA ----------------------- + - name: Write ExportOptions.plist + env: + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + cat > ios/ExportOptions.plist < + + + + method + app-store + teamID + ${APPLE_TEAM_ID} + signingStyle + manual + signingCertificate + Apple Distribution + provisioningProfiles + + com.suchsoftware.hashwallet + ${PROFILE_NAME} + + uploadBitcode + + uploadSymbols + + destination + export + stripSwiftSymbols + + + + EOF + cat ios/ExportOptions.plist + + - name: Build IPA + run: | + set -x -e + flutter build ipa --release \ + --dart-define-from-file=env.json \ + --export-options-plist=ios/ExportOptions.plist + ls -la build/ios/ipa/ + + - name: Upload IPA artifact + uses: actions/upload-artifact@v3 + with: + name: hash-wallet-ios-${{ github.sha }} + path: build/ios/ipa/*.ipa + retention-days: 30 + + # ---- Upload to TestFlight ------------------------------------------- + - name: Upload to TestFlight via altool + env: + APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }} + APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }} + run: | + set -e + IPA=$(ls build/ios/ipa/*.ipa | head -1) + echo "Uploading $IPA to TestFlight..." + xcrun altool --upload-app \ + --type ios \ + --file "$IPA" \ + --apiKey "$APPLE_KEY_ID" \ + --apiIssuer "$APPLE_ISSUER_ID" + + # ---- Cleanup keychain so we don't leak it across builds ------------- + - name: Cleanup + if: always() + env: + APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} + run: | + set +e + KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db" + security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null + rm -rf "$HOME/.appstoreconnect/private_keys" + rm -f "$HOME/Library/MobileDevice/Provisioning Profiles"/*.mobileprovision + true diff --git a/lib/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart b/lib/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart index e3e28871..78e7353d 100644 --- a/lib/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart +++ b/lib/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart @@ -45,7 +45,11 @@ class TopBar extends StatelessWidget { isSyncHeavy: dashboardViewModel.isSyncHeavy, ), ModernButton.svg( - iconColor: Theme.of(context).colorScheme.primary, + // Hash Wallet: was theme.colorScheme.primary (dark forest green) + // which rendered the gear icon nearly invisible on the dark + // dashboard backdrop. onSurfaceVariant is the de-emphasized- + // foreground Material token. + iconColor: Theme.of(context).colorScheme.onSurfaceVariant, size: 36, onPressed: () { HapticFeedback.mediumImpact(); diff --git a/lib/src/screens/dashboard/widgets/new_main_navbar_widget.dart b/lib/src/screens/dashboard/widgets/new_main_navbar_widget.dart index 23f155b6..378f679c 100644 --- a/lib/src/screens/dashboard/widgets/new_main_navbar_widget.dart +++ b/lib/src/screens/dashboard/widgets/new_main_navbar_widget.dart @@ -122,7 +122,11 @@ class _NEWNewMainNavBarState extends State { final backgroundColor = theme.colorScheme.surfaceContainer.withAlpha(127); final pillColor = theme.colorScheme.onSurface.withAlpha(25); final activeColor = theme.colorScheme.onSurface; - final inactiveColor = theme.colorScheme.primary; + // Hash Wallet: was theme.colorScheme.primary — that's our brand forest + // green (#1A5C38), which renders dark-on-dark against the navbar's + // semi-transparent surface backdrop. Material's onSurfaceVariant is the + // standard token for de-emphasized icons and is visible across themes. + final inactiveColor = theme.colorScheme.onSurfaceVariant; return Observer( builder: (_) { diff --git a/lib/src/screens/seed/seed_verification/seed_verification_success_view.dart b/lib/src/screens/seed/seed_verification/seed_verification_success_view.dart index b2409309..1e19e623 100644 --- a/lib/src/screens/seed/seed_verification/seed_verification_success_view.dart +++ b/lib/src/screens/seed/seed_verification/seed_verification_success_view.dart @@ -66,13 +66,15 @@ class SeedVerificationSuccessView extends StatelessWidget { PrimaryButton( key: ValueKey('wallet_seed_page_open_wallet_button_key'), onPressed: () { - if (walletType == WalletType.bitcoin) { - Navigator.of(context).pushNamed(Routes.lightningUsernamePage, arguments: true); - } else { - Navigator.of(context).popUntil((route) => route.isFirst); - } + // Hash Wallet: Lightning Username onboarding skipped. The original + // Cake flow pushed BTC wallets to the lightning_username_page, + // which suggests an @cake.cash address. We disabled Lightning + // entirely (no Greenlight infra) and the screen is meaningless + // without it. Re-enable here if we ever stand up our own LN + // backend + domain. + Navigator.of(context).popUntil((route) => route.isFirst); }, - text: (walletType == WalletType.bitcoin) ? S.current.continue_text : S.current.open_wallet, + text: S.current.open_wallet, color: Theme.of(context).colorScheme.primary, textColor: Theme.of(context).colorScheme.onPrimary, ),