diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2501f075..11e50cf2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,6 +52,7 @@ jobs: env: GRPC_BUILD_ENABLE_CCACHE: "ON" GH_TOKEN: ${{ secrets.GNUS_TOKEN_1 }} + RELEASE_TAG_INPUT: ${{ github.event.inputs.tag }} runs-on: ${{matrix.host}} container: image: ${{matrix.container}} @@ -66,10 +67,11 @@ jobs: abi: [""] include: - target: Linux - host: ubuntu-22.04 + host: sg-ubuntu-linux flutter-platform: linux abi: x86_64 build-type: Release + container: ghcr.io/geniusventures/debian-bullseye:latest - target: Linux host: ubuntu-24.04-arm flutter-platform: linux @@ -77,13 +79,13 @@ jobs: build-type: Release container: ghcr.io/geniusventures/debian-bullseye:latest - target: Windows - host: windows-latest + host: SG-WIN11 flutter-platform: windows - target: OSX host: macos-latest flutter-platform: macos - target: Android - host: ubuntu-latest + host: sg-ubuntu-linux flutter-platform: apk - target: iOS host: macos-latest @@ -92,6 +94,52 @@ jobs: - target: Linux abi: "" steps: + - name: Clean workspace (self-hosted runners) + if: ${{ runner.environment == 'self-hosted' }} + working-directory: ${{runner.workspace}} + run: | + echo "=== PRE-CLEANUP DEBUG ===" + echo "Current working directory: $(pwd)" + echo "Runner workspace: ${{runner.workspace}}" + echo "GitHub workspace: ${{github.workspace}}" + + echo "=== CLEANUP ARTIFACTS ===" + # Clean up artifacts from previous runs (self-hosted runners only) + + # Clean contents of GeniusWallet directory but keep the directory itself + if [ -d "GeniusWallet" ]; then + echo "Cleaning GeniusWallet directory contents..." + rm -rf GeniusWallet/* GeniusWallet/.* 2>/dev/null || true + echo "GeniusWallet directory cleaned (kept the directory)" + fi + + # Delete sibling dependency directories completely + if [ -d "thirdparty" ]; then + echo "Removing thirdparty directory..." + rm -rf thirdparty + fi + if [ -d "zkLLVM" ]; then + echo "Removing zkLLVM directory..." + rm -rf zkLLVM + fi + if [ -d "SuperGenius" ]; then + echo "Removing SuperGenius directory..." + rm -rf SuperGenius + fi + if [ -d "GeniusSDK" ]; then + echo "Removing GeniusSDK directory..." + rm -rf GeniusSDK + fi + + echo "=== POST-CLEANUP DEBUG ===" + echo "Runner workspace contents:" + ls -la + if [ -d "GeniusWallet" ]; then + echo "GeniusWallet directory exists and contains:" + ls -la GeniusWallet/ 2>/dev/null || echo " (empty)" + fi + shell: bash + - name: Configure Linux host if: ${{ runner.os == 'Linux'}} run: | @@ -118,9 +166,20 @@ jobs: - name: Configure macOS host if: ${{ runner.os == 'macOS' }} run: | - brew install ccache ninja bash gnu-tar - PATH="$HOMEBREW_PREFIX/opt/gnu-tar/libexec/gnubin:$PATH" - echo "PATH=$PATH" >> $GITHUB_ENV + brew install ninja bash gnu-tar + + # Ensure GNU tar is first in PATH - check both possible Homebrew locations + if [ -d "/opt/homebrew/opt/gnu-tar/libexec/gnubin" ]; then + echo "PATH=/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH" >> $GITHUB_ENV + echo "Using GNU tar from /opt/homebrew" + elif [ -d "/usr/local/opt/gnu-tar/libexec/gnubin" ]; then + echo "PATH=/usr/local/opt/gnu-tar/libexec/gnubin:$PATH" >> $GITHUB_ENV + echo "Using GNU tar from /usr/local" + else + echo "WARNING: GNU tar installation not found in expected locations" + echo "Available tar: $(which tar)" + fi + echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV - name: Setup Flutter @@ -197,6 +256,13 @@ jobs: echo -n "$DEVELOPER_ID_INSTALLER_CERT_BASE64" | base64 --decode -o $DEVELOPER_ID_INSTALLER_CERT_PATH echo -n "$DEVELOPER_ID_PROVISION_BASE64" | base64 --decode -o $DEVELOPER_ID_PP_PATH + # Clean up old keychain from previous run (self-hosted runners reuse $RUNNER_TEMP) + if [ -f "$KEYCHAIN_PATH" ]; then + echo "Cleaning up existing keychain: $KEYCHAIN_PATH" + security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true + rm -f "$KEYCHAIN_PATH" 2>/dev/null || true + fi + # create temporary keychain security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH @@ -219,6 +285,9 @@ jobs: security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security list-keychains -d user -s $KEYCHAIN_PATH + + echo "=== Keychain search list after configuration ===" + security list-keychains -d user echo "=== Available identities in keychain ===" security find-identity -v @@ -292,6 +361,60 @@ jobs: run: | flutter pub get + - name: Setup Android SDK and NDK + if: ${{ matrix.target == 'Android' }} + run: | + # Setup Android SDK + ANDROID_SDK_ROOT="$HOME/android-sdk" + + # Download command-line tools if not present + if [ ! -d "$ANDROID_SDK_ROOT/cmdline-tools/latest" ]; then + echo "Downloading Android command-line tools..." + mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" + wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O cmdline-tools.zip + unzip -q cmdline-tools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools" + mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" + rm cmdline-tools.zip + else + echo "Android command-line tools already exist" + fi + + # Always accept licenses and install/update required SDK components + echo "Installing/updating Android SDK components..." + yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses || true + "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" "platform-tools" "platforms;android-34" "build-tools;34.0.0" + + # Set environment variables + echo "ANDROID_HOME=$ANDROID_SDK_ROOT" >> $GITHUB_ENV + echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" >> $GITHUB_ENV + echo "$ANDROID_SDK_ROOT/platform-tools" >> $GITHUB_PATH + echo "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin" >> $GITHUB_PATH + + # Verify SDK installation + echo "=== Android SDK Setup ===" + echo "ANDROID_HOME: $ANDROID_SDK_ROOT" + echo "SDK contents:" + ls -la "$ANDROID_SDK_ROOT" + + # Download and setup Android NDK + NDK_VERSION="r27b" + NDK_DIR="$HOME/android-ndk-$NDK_VERSION" + if [ ! -d "$NDK_DIR" ]; then + echo "Downloading Android NDK $NDK_VERSION..." + wget https://dl.google.com/android/repository/android-ndk-$NDK_VERSION-linux.zip -O ndk.zip + unzip -q ndk.zip -d $HOME + rm ndk.zip + else + echo "Android NDK already exists at $NDK_DIR" + fi + echo "ANDROID_NDK_HOME=$NDK_DIR" >> $GITHUB_ENV + + echo "=== Environment Summary ===" + echo "ANDROID_HOME=$ANDROID_SDK_ROOT" + echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" + echo "ANDROID_NDK_HOME=$NDK_DIR" + shell: bash + - name: Setup CMake Arguments run: | CMAKE_ARGS="-DCMAKE_BUILD_TYPE=${{matrix.build-type}}" @@ -317,6 +440,11 @@ jobs: # Add verbose output for debugging CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_VERBOSE_MAKEFILE=ON" + # macOS universal binary: disable precompiled headers (incompatible with multi-arch) + if [ "${{ matrix.target }}" = "OSX" ]; then + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON" + fi + # Windows-specific: ensure message output if [ "${{ matrix.target }}" = "Windows" ]; then CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_MESSAGE_LOG_LEVEL=STATUS" @@ -357,13 +485,20 @@ jobs: fi - name: Sign and package macOS app - if: ${{ matrix.target == 'OSX' && (github.ref_name == 'main' || github.ref_name == 'develop') }} + if: ${{ matrix.target == 'OSX' && (github.ref_name == 'main' || github.ref_name == 'develop' || env.IS_TAG == 'true') }} env: APPLE_ID: ${{ secrets.WALLET_NOTARIZE_APPLE_ID }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} NOTARIZATION_PASSWORD: ${{ secrets.WALLET_NOTARIZATION_PASSWORD }} run: | cd build/macos/Build/Products/${{matrix.build-type}} + + # Re-ensure temp keychain is the only one in search list + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + security list-keychains -d user -s $KEYCHAIN_PATH + + echo "=== Keychain search list at signing step ===" + security list-keychains -d user # First, let's see what certificates are available echo "=== Available signing identities ===" @@ -581,7 +716,11 @@ jobs: cd build/macos/Build/Products/${{matrix.build-type}} # Copy the signed packages - cp -r *.pkg ../../../../../artifacts/ || true + if ls *.pkg >/dev/null 2>&1; then + cp -r *.pkg ../../../../../artifacts/ + else + echo "No macOS .pkg files found to upload" + fi # Create a README explaining the different packages cat > ../../../../../artifacts/README.txt << EOF @@ -672,101 +811,71 @@ jobs: fi shell: bash - - name: Wait for primary release creation - if: (github.ref_name == 'main' || github.ref_name == 'develop') && (matrix.target == 'Linux' && matrix.abi == 'aarch64') && env.IS_TAG != 'true' - working-directory: ${{github.workspace}} - run: | - RELEASE_TAG='${{matrix.target}}-${{github.ref_name}}-${{matrix.build-type}}' - - echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV - echo "Waiting for primary job to create/update release: $RELEASE_TAG" - - # Wait up to 120 minutes for the release to be created/updated - ATTEMPT=1 - MAX_ATTEMPTS=720 - while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do - if gh release view $RELEASE_TAG >/dev/null 2>&1; then - echo "Release found!" - # Check if it's at the correct commit - if gh release view $RELEASE_TAG | grep -q "${{ github.sha }}"; then - echo "Release is at correct commit" - break - fi - fi - echo "Waiting for release... (attempt $ATTEMPT/$MAX_ATTEMPTS)" - sleep 10 - ATTEMPT=$((ATTEMPT + 1)) - done - shell: bash - - name: Create release of GeniusWallet working-directory: ${{github.workspace}} - if: (github.ref_name == 'main' || github.ref_name == 'develop' || env.IS_TAG == 'true') && (env.IS_TAG == 'true' || !(matrix.target == 'Linux' && matrix.abi == 'aarch64')) + if: github.ref_name == 'main' || github.ref_name == 'develop' || env.IS_TAG == 'true' shell: bash run: | - if ${{github.event_name == 'workflow_dispatch'}} && [ '${{ github.event.inputs.tag }}' ]; then - RELEASE_TAG="${{ github.event.inputs.tag }}" + if [ -n "${RELEASE_TAG_INPUT}" ]; then + RELEASE_TAG="${RELEASE_TAG_INPUT}" IS_TAG_RELEASE="true" else - RELEASE_TAG='${{matrix.target}}-${{github.ref_name}}-${{matrix.build-type}}' + # Include ABI in release tag if defined + if [ '${{matrix.abi}}' ]; then + RELEASE_TAG='${{matrix.target}}-${{matrix.abi}}-${{github.ref_name}}-${{matrix.build-type}}' + else + RELEASE_TAG='${{matrix.target}}-${{github.ref_name}}-${{matrix.build-type}}' + fi IS_TAG_RELEASE="false" fi echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV - - echo "Checking if release $RELEASE_TAG exists..." - set +e - gh release view "$RELEASE_TAG" - releaseFound=$? - set -e - - if [[ $releaseFound -eq 0 ]]; then - if [[ "$IS_TAG_RELEASE" == "false" ]]; then - echo "Deleting existing branch-based release + tag..." - gh release delete "$RELEASE_TAG" --yes - git push origin ":refs/tags/$RELEASE_TAG" || true + echo "IS_TAG_RELEASE=${IS_TAG_RELEASE}" >> $GITHUB_ENV + + echo "Checking if release $RELEASE_TAG exists..." + if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then + if [ "$IS_TAG_RELEASE" == "false" ]; then + echo "Deleting existing release/tag $RELEASE_TAG..." + gh release delete "$RELEASE_TAG" --yes || true + git push origin ":refs/tags/$RELEASE_TAG" || true + git tag -d "$RELEASE_TAG" || true else - echo "Tag release $RELEASE_TAG already exists, skipping creation" - exit 0 + echo "Release $RELEASE_TAG already exists. Skipping create." + exit 0 fi - fi + fi - RELEASE_TYPE="--draft" - - if [[ "$IS_TAG_RELEASE" == "true" ]]; then - # For tag releases, just create the release (tag already exists) - RELEASE_TITLE="${{ github.event.inputs.tag }} build artifacts" - RELEASE_NOTES="Build artifacts for tag ${{ github.event.inputs.tag }}" - echo "Creating release for existing tag: $RELEASE_TAG" - gh release create "$RELEASE_TAG" \ - --draft \ - -t "$RELEASE_TITLE" \ - -n "$RELEASE_NOTES" - else - # For branch releases, create and push tag first - echo "Tagging commit ${{ github.sha }} as $RELEASE_TAG" - git tag -f "$RELEASE_TAG" "${{ github.sha }}" - git push --force origin "$RELEASE_TAG" - - RELEASE_TITLE="${{ matrix.target }} ${{ github.ref_name }} ${{ matrix.build-type }} build" - RELEASE_NOTES="Branch: ${{ github.ref_name }} | SHA: ${{ github.sha }}" - echo "Creating release for branch build" - gh release create "$RELEASE_TAG" \ - --target "${{ github.sha }}" \ - -t "$RELEASE_TITLE" \ - -n "$RELEASE_NOTES" \ - ${RELEASE_TYPE} - fi + echo "Creating new tag $RELEASE_TAG..." + git tag -f "$RELEASE_TAG" "${{ github.sha }}" + git push origin "$RELEASE_TAG" --force + + if [ "$IS_TAG_RELEASE" = "true" ]; then + RELEASE_TITLE="$RELEASE_TAG" + else + RELEASE_TITLE="${{ matrix.target }} ${{ github.ref_name }} ${{ matrix.build-type }} build" + fi + + echo "Creating GitHub release $RELEASE_TAG..." + gh release create "$RELEASE_TAG" \ + --target "${{ github.sha }}" \ + -t "$RELEASE_TITLE" \ + -n "Branch: ${{ github.ref_name }} | SHA: ${{ github.sha }}" \ + $( [ "$IS_TAG_RELEASE" = "true" ] && echo "--draft" || echo "--prerelease" ) - name: Upload file if: github.ref_name == 'main' || github.ref_name == 'develop' || env.IS_TAG == 'true' working-directory: ${{github.workspace}} run: | # Ensure RELEASE_TAG is set for upload step - if ${{github.event_name == 'workflow_dispatch'}} && [ '${{ github.event.inputs.tag }}' ]; then - RELEASE_TAG="${{ github.event.inputs.tag }}" + if [ -n "${RELEASE_TAG_INPUT}" ]; then + RELEASE_TAG="${RELEASE_TAG_INPUT}" else - RELEASE_TAG='${{matrix.target}}-${{github.ref_name}}-${{matrix.build-type}}' + # Include ABI in release tag if defined + if [ '${{matrix.abi}}' ]; then + RELEASE_TAG='${{matrix.target}}-${{matrix.abi}}-${{github.ref_name}}-${{matrix.build-type}}' + else + RELEASE_TAG='${{matrix.target}}-${{github.ref_name}}-${{matrix.build-type}}' + fi fi echo "Upload step using RELEASE_TAG: $RELEASE_TAG" diff --git a/cmake/CommonBuildParameters.cmake b/cmake/CommonBuildParameters.cmake index 8908b5b3..aab8373e 100755 --- a/cmake/CommonBuildParameters.cmake +++ b/cmake/CommonBuildParameters.cmake @@ -342,6 +342,11 @@ if(NOT CMAKE_SKIP_THIRD_PARTY) set(nlohmann_json_DIR "${THIRDPARTY_BUILD_DIR}/json/share/cmake/nlohmann_json") find_package(nlohmann_json CONFIG REQUIRED) + if(LINUX) + find_package(PkgConfig) + pkg_check_modules(LIBSECRET REQUIRED IMPORTED_TARGET libsecret-1>=0.18.4) + endif() + # -------------------------------------------------------- # Set config of crypto3 add_library(crypto3::algebra INTERFACE IMPORTED) @@ -403,6 +408,7 @@ if(NOT CMAKE_SKIP_THIRD_PARTY) ) # zkLLVM set(zkLLVM_INCLUDE_DIR "${ZKLLVM_BUILD_DIR}/zkLLVM/include") + include_directories(${zkLLVM_INCLUDE_DIR}) # Set config of llvm set(LLVM_DIR "${ZKLLVM_BUILD_DIR}/zkLLVM/lib/cmake/llvm") diff --git a/cmake/DownloadDependencies.cmake b/cmake/DownloadDependencies.cmake index 71da7063..72fe95a7 100644 --- a/cmake/DownloadDependencies.cmake +++ b/cmake/DownloadDependencies.cmake @@ -154,16 +154,6 @@ function(download_dependency DEP_NAME) # Get platform name get_platform_dir_name(PLATFORM_NAME) - - # Determine the release tag format - if(DEFINED BRANCH_IS_TAG AND BRANCH_IS_TAG) - # For tags, use the tag name directly - set(RELEASE_TAG "${ARG_BRANCH}") - message(STATUS "Using Git tag format: ${ARG_BRANCH}") - else() - # For branches, use the platform-branch-buildtype format - set(RELEASE_TAG "${PLATFORM_NAME}-${ARG_BRANCH}-${ARG_BUILD_TYPE}") - endif() # GitHub repository information set(GITHUB_REPO "GeniusVentures/${DEP_NAME}") @@ -194,6 +184,15 @@ function(download_dependency DEP_NAME) continue() endif() + # Determine the release tag format for this ABI + if(DEFINED BRANCH_IS_TAG AND BRANCH_IS_TAG) + # For tags, use the tag name directly + set(RELEASE_TAG "${ARG_BRANCH}") + else() + # For branches, use the platform-ABI-branch-buildtype format + set(RELEASE_TAG "${PLATFORM_NAME}-${ABI}-${ARG_BRANCH}-${ARG_BUILD_TYPE}") + endif() + set(ARCHIVE_NAME "${PLATFORM_NAME}-${ABI}-${ARG_BUILD_TYPE}.tar.gz") set(RELEASE_URL "https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/${ARCHIVE_NAME}") set(ARCHIVE_PATH "${CMAKE_BINARY_DIR}/${DEP_NAME}-${ARCHIVE_NAME}") @@ -241,6 +240,19 @@ function(download_dependency DEP_NAME) endforeach() else() # Non-Android download logic + + # Determine the release tag format + if(DEFINED BRANCH_IS_TAG AND BRANCH_IS_TAG) + # For tags, use the tag name directly + set(RELEASE_TAG "${ARG_BRANCH}") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND ARCH) + # For Linux with ARCH, include ARCH in the release tag + set(RELEASE_TAG "${PLATFORM_NAME}-${ARCH}-${ARG_BRANCH}-${ARG_BUILD_TYPE}") + else() + # For other platforms, use the platform-branch-buildtype format + set(RELEASE_TAG "${PLATFORM_NAME}-${ARG_BRANCH}-${ARG_BUILD_TYPE}") + endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND ARCH) set(ARCHIVE_NAME "${PLATFORM_NAME}-${ARCH}-${ARG_BUILD_TYPE}.tar.gz") else() diff --git a/lib/banxa/banaxa_api_services.dart b/lib/banxa/banaxa_api_services.dart index 77fde214..2ac0c2c3 100644 --- a/lib/banxa/banaxa_api_services.dart +++ b/lib/banxa/banaxa_api_services.dart @@ -13,7 +13,7 @@ class BanxaApiService { static const String _partnerCode = 'gnus'; static const String _apiKey = 'b8282030faffa2dc15fbf428142be5bdb1d4e346'; static const String _baseUrl = - 'https://api.banxa.com/$_partnerCode/v2'; // Sandbox URL + 'https://api.banxa.com/$_partnerCode/v2'; static const redirectUrl = 'geniuswallet://banxa/callback'; static const String banxaKycUrl = 'https://$_partnerCode.banxa-sandbox.com'; @@ -134,7 +134,6 @@ class BanxaApiService { required String cryptoAmount, String? fiatAmount, String? externalCustomerId, - String? email, String? metadata, String? subPartnerId, }) async { @@ -158,7 +157,6 @@ class BanxaApiService { 'redirectUrl': redirectUrl, 'cryptoAmount': cryptoAmount, if (fiatAmount != null) 'fiatAmount': fiatAmount, - if (email != null) 'email': email, if (externalCustomerId != null) 'externalCustomerId': externalCustomerId, 'externalOrderId': extOrderId, if (metadata != null) 'metadata': metadata, diff --git a/lib/banxa/banxa_order/create_order_cubit.dart b/lib/banxa/banxa_order/create_order_cubit.dart index 7612e220..6ad82133 100644 --- a/lib/banxa/banxa_order/create_order_cubit.dart +++ b/lib/banxa/banxa_order/create_order_cubit.dart @@ -201,7 +201,6 @@ class MakeOrderCubit extends Cubit { cryptoAmount: state.quote!.cryptoAmount, fiatAmount: state.quote!.fiatAmount, externalCustomerId: 'my_id_${DateTime.now().millisecondsSinceEpoch}', - email: 'ammarajeeb567@gmail.com', metadata: 'real', subPartnerId: 'macOS-app', ); diff --git a/lib/bloc/app_bloc.dart b/lib/bloc/app_bloc.dart index a09e8bba..831f58cb 100644 --- a/lib/bloc/app_bloc.dart +++ b/lib/bloc/app_bloc.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:ffi'; import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:genius_api/ffi/genius_api_ffi.dart'; @@ -77,37 +78,43 @@ class AppBloc extends Bloc { subscribeToWalletStatus: AppStatus.loaded, )); } - - void _startProcessingPolling() { +void _startProcessingPolling() { _processingTimer?.cancel(); _processingTimer = Timer.periodic( - const Duration(seconds: 1), + const Duration(milliseconds: 1000), (_) { add(ProcessingStatusTicked()); }, ); } + + FutureOr _onProcessingStatusTicked( ProcessingStatusTicked event, Emitter emit, - ) { + ) async { try { final statusInfo = api.getProcessingStatus(); - final isProcessing = - statusInfo.status == GeniusProcessingStatus.GENIUS_PR_STATUS_PROCESSING; + final isProcessing = statusInfo.status == + GeniusProcessingStatus.GENIUS_PR_STATUS_PROCESSING.value; if (state.isProcessing != isProcessing) { emit(state.copyWith(isProcessing: isProcessing)); } + + if (isProcessing) { + double percentage = statusInfo.percentage; + emit(state.copyWith(processingPercentage: percentage)); + } } catch (_) { _processingTimer?.cancel(); - emit(state.copyWith(isProcessing: false)); + emit(state.copyWith(isProcessing: false, processingPercentage: 0.0)); } + } - Future _onFetchAccount( FetchAccount event, Emitter emit, diff --git a/lib/bloc/app_state.dart b/lib/bloc/app_state.dart index df780c6b..ecd2e16c 100644 --- a/lib/bloc/app_state.dart +++ b/lib/bloc/app_state.dart @@ -19,6 +19,7 @@ class AppState extends Equatable { final AppStatus accountStatus; final bool isProcessing; + final double? processingPercentage; const AppState( {this.wallets = const [], @@ -29,6 +30,7 @@ class AppState extends Equatable { this.testWallet, this.isProcessing = false, this.account, + this.processingPercentage, this.accountStatus = AppStatus.initial}); AppState copyWith( @@ -40,6 +42,7 @@ class AppState extends Equatable { Pointer? testWallet, bool? isProcessing, Account? account, + double? processingPercentage, AppStatus? accountStatus}) { return AppState( wallets: wallets ?? this.wallets, @@ -50,6 +53,8 @@ class AppState extends Equatable { ffiString: ffiString ?? this.ffiString, testWallet: testWallet, account: account ?? this.account, + processingPercentage: + processingPercentage ?? this.processingPercentage, isProcessing: isProcessing ?? this.isProcessing, accountStatus: accountStatus ?? this.accountStatus); } @@ -64,7 +69,8 @@ class AppState extends Equatable { testWallet, account, accountStatus, - isProcessing + isProcessing, + processingPercentage ]; } diff --git a/lib/components/loading/loading.dart b/lib/components/loading/loading.dart index d7f10aec..c6cccff8 100644 --- a/lib/components/loading/loading.dart +++ b/lib/components/loading/loading.dart @@ -20,7 +20,7 @@ class Loading extends StatelessWidget { ), AutoSizeText( text ?? "", - style: const TextStyle(fontSize: 24), + style: const TextStyle(fontSize: 14), ) ]); } diff --git a/lib/components/overlay/responsive_overlay.dart b/lib/components/overlay/responsive_overlay.dart index 1d62b237..dfb1c6df 100644 --- a/lib/components/overlay/responsive_overlay.dart +++ b/lib/components/overlay/responsive_overlay.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:genius_wallet/bloc/app_bloc.dart'; import 'package:genius_wallet/bloc/overlay/navigation_overlay_cubit.dart'; import 'package:genius_wallet/bloc/overlay/navigation_overlay_state.dart'; -import 'package:genius_wallet/components/loading/loading.dart'; import 'package:genius_wallet/squid_router/swap_screen.dart'; import 'package:genius_wallet/utils/breakpoints.dart'; import 'package:genius_wallet/components/overlay/desktop_overlay.dart'; @@ -24,64 +22,35 @@ class ResponsiveOverlay extends StatelessWidget { context.read().navigationTapped(selectedScreen!); } - return BlocBuilder( - builder: (context, appState) { - return BlocBuilder( - builder: (context, navState) { - final platform = GeniusBreakpoints.getPlaform(context); - - final screenMap = { - NavigationScreen.dashboard: const DashboardScreen(), - NavigationScreen.transactions: const TransactionsScreen(), - NavigationScreen.swap: const SwapScreen(), - NavigationScreen.news: const CryptoNewsScreen(), - NavigationScreen.markets: const MarketsScreen(), - NavigationScreen.web: - const WebViewScreen(url: "https://app.uniswap.org"), - }; - - final selected = navState.selectedScreen; - final currentIndex = screenMap.keys.toList().indexOf(selected); - - final content = IndexedStack( - index: currentIndex, - children: screenMap.values.toList(), - ); - - final overlay = (!GeniusBreakpoints.useDesktopOverlay(context) || - platform == Platforms.mobile) - ? MobileOverlay(child: content) - : DesktopOverlay(child: content); - - return Stack( - children: [ - overlay, - if (appState.isProcessing) - Positioned.fill( - child: AbsorbPointer( - absorbing: true, - child: Container( - color: Colors.black.withAlpha(115), - child: const Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Loading(), - SizedBox(height: 12), - Text( - 'Genius Wallet is processing…', - - ), - ], - ), - ), - ), - ), - ), - ], - ); - }, + return BlocBuilder( + builder: (context, state) { + final platform = GeniusBreakpoints.getPlaform(context); + + // Map screen enum to actual widget + final screenMap = { + NavigationScreen.dashboard: const DashboardScreen(), + NavigationScreen.transactions: const TransactionsScreen(), + NavigationScreen.swap: const SwapScreen(), + NavigationScreen.news: const CryptoNewsScreen(), + NavigationScreen.markets: const MarketsScreen(), + NavigationScreen.web: + const WebViewScreen(url: "https://app.uniswap.org"), + }; + + final selected = state.selectedScreen; + final currentIndex = screenMap.keys.toList().indexOf(selected); + + final child = IndexedStack( + index: currentIndex, + children: screenMap.values.toList(), ); + + if (!GeniusBreakpoints.useDesktopOverlay(context) || + platform == Platforms.mobile) { + return MobileOverlay(child: child); + } else { + return DesktopOverlay(child: child); + } }, ); } diff --git a/lib/components/sgnus/sgnus_connection_widget.dart b/lib/components/sgnus/sgnus_connection_widget.dart index 8c2a1172..00ed1944 100644 --- a/lib/components/sgnus/sgnus_connection_widget.dart +++ b/lib/components/sgnus/sgnus_connection_widget.dart @@ -4,8 +4,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:genius_api/genius_api.dart'; import 'package:genius_api/models/sgnus_connection.dart'; +import 'package:genius_wallet/bloc/app_bloc.dart'; import 'package:genius_wallet/components/animation/checkmark_animation.dart'; import 'package:genius_wallet/components/animation/x_animation.dart'; +import 'package:genius_wallet/components/loading/loading.dart'; import 'package:go_router/go_router.dart'; class SGNUSConnectionWidget extends StatefulWidget { @@ -103,3 +105,54 @@ class SGNUSConnectionMobileState extends State { ); } } +class SGNUSConnectionStatusWidget extends StatelessWidget { + final bool? isSmallScreen; + + const SGNUSConnectionStatusWidget({ + Key? key, + this.isSmallScreen, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final alignment = + isSmallScreen == true ? Alignment.center : Alignment.centerRight; + + return BlocBuilder( + builder: (context, appState) { + final isProcessing = appState.isProcessing; + + final statusText = isProcessing + ? '${appState.processingPercentage?.toStringAsFixed(2) ?? "0.00"}%' + : 'idle'; + + return Align( + alignment: alignment, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isProcessing) ...[ + const Loading(text: "processing"), + const SizedBox(width: 8), + ], + SizedBox( + width: 60, + child: AutoSizeText( + statusText, + maxLines: 1, + textAlign: TextAlign.right, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: isProcessing ? Colors.white : Colors.white70, + ), + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/components/wallet_information.g.dart b/lib/components/wallet_information.g.dart index 4b2958b6..4cc8929a 100644 --- a/lib/components/wallet_information.g.dart +++ b/lib/components/wallet_information.g.dart @@ -98,6 +98,10 @@ class WalletInformationState extends State { ), const SizedBox(height: 8), const SGNUSConnectionMobileWidget(), + const SizedBox(height: 8), + SGNUSConnectionStatusWidget( + isSmallScreen: true, + ) ], ), const SizedBox(height: 20), @@ -197,7 +201,7 @@ class WalletInformationState extends State { final connection = snapshot.data; return SubmitJobButton( onPressed: () { - Navigator.of(context).pop(); // closes drawer + Navigator.of(context).pop(); }, walletDetailsCubit: walletDetailsCubit, walletAddress: state.selectedWallet?.address ?? "", diff --git a/lib/components/wallets_overview.g.dart b/lib/components/wallets_overview.g.dart index 1ffa18e4..aadeaf3e 100644 --- a/lib/components/wallets_overview.g.dart +++ b/lib/components/wallets_overview.g.dart @@ -110,6 +110,10 @@ class WalletsOverviewState extends State { ), Column(crossAxisAlignment: CrossAxisAlignment.end, children: [ const Row(children: [Flexible(child: SGNUSConnectionWidget())]), + SizedBox( + height: 8, + ), + SGNUSConnectionStatusWidget(), BlocBuilder( builder: (context, state) { if (state.selectedWallet != null) {