feat(mining): mining page, iOS/Android builds, continuous mining#1373
Open
InspektorKek wants to merge 128 commits intomasterfrom
Open
feat(mining): mining page, iOS/Android builds, continuous mining#1373InspektorKek wants to merge 128 commits intomasterfrom
InspektorKek wants to merge 128 commits intomasterfrom
Conversation
… feat/tauri-app
… feat/tauri-app
…ess/cyb-ts into feat/tauri-app
…wnload and signing flow fixes
… feat/tauri-app
- chore(tauri-app): use IS_TAURI env var instead of window.__TAURI__ - fix(cyb): request persistens storage permission error handling
… feat/tauri-app
… feat/tauri-app
…ring mining The react-force-graph-3d library's D3-timer module creates setInterval(poke, 1000) on every animation frame. WebKit accumulates these instead of replacing them, causing 85% CPU usage on every page (graph is in the global footer). Fix: intercept setInterval in CyberlinksGraph, track all IDs created by the ForceGraph3D internals, and aggressively sweep them every 100ms. This keeps the built-in animation loop running (correct visuals) while preventing the timer cascade. Also: unmount the 3D graph entirely during active mining via Redux state (mining.active), dropping WebKit from 85% to 6-9% during mining. Other changes in this commit: - Tauri: RunEvent::Exit handler for IPFS/mining cleanup - Mining: stabilize polling with processQueueRef pattern - Mining: replace react-query refetchInterval with manual 30s timer - Mining: add emission simulator, staking/referral sections - Mining hooks: fetchRef pattern to avoid interval churn Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…endering bug
The global CSS rules `input:focus::-webkit-input-placeholder { opacity: 0 }`
triggered a WebKit compositing bug in Tauri where the entire input element
stopped painting when focused and empty. Also changed global placeholder
color from teal (#3ab793) to gray (#777). Added focus box-shadow and
min-height to mining staking inputs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Mining process persists across page navigation (Tauri backend keeps running, WASM miner moved to module scope) - New useMiningMonitor hook in App.tsx polls backend every 1s, stores full MiningStatus in Redux as single source of truth - MiningBadge in header always shows correct hashrate via Redux - Mining page reads status from Redux instead of local state - Click-through guard prevents stale ActionBar clicks from stopping mining - Replace SimulatorSection with live ConfigPanel (admin config management) - Add StakingSection with CW20 balance, APR formatting (T/B/M/K tiers) - Add ReferralSection, ConfigPanel, WebSocket block subscription - Generated lithium contract TypeScript clients - Tauri: GPU backend selection, metrics tracking, proof relay support - Fix splashscreen overlap (both windows start hidden) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bufferTime(0) in RxBroadcastChannelListener caused RxJS AsyncScheduler to create/clear ~144K setInterval(fn, 0) calls per second, consuming 85% CPU in WebKit. Changed to bufferTime(200) for reasonable batching. Also removed the useIntervalSweep hack from CyberlinksGraph that was a workaround for this bug (incorrectly attributed to d3-timer). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Regenerate all platform icons (macOS, iOS, Android, Windows) - Swap portal menu: small icon uses glow SVG, large uses original - Update favicon - Menu component styling improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t Logs button Relay was broken: contract requires sender==miner but relay signed as activator. Changed to account activation flow — relay sends 1boot to create new accounts, then cyb-ts retries proof submission directly. Added Export Logs button on Mining page for testers to copy full session diagnostics (config, hashrate, proof log, network stats) to clipboard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- cyb-boot Rust binary: decrypts boot.dat, writes bootstrap.json, downloads .pkg - Distribution server integration: web encrypts wallet, server returns zip with signed binary + boot.dat - DownloadSection component: platform detection, AES-256-GCM encryption, download trigger - Tauri bootstrap import: read_bootstrap command imports wallet on first launch - macOS release CI: GitHub Actions workflow with code signing + notarization - Artifacts: .dmg, .pkg, cyb-boot published to GitHub Releases Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines
+21
to
+209
| runs-on: macos-14 # Apple Silicon (M1) | ||
| timeout-minutes: 120 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| # ── Toolchain ─────────────────────────────────────────────── | ||
| - name: Setup Deno | ||
| uses: denoland/setup-deno@v2 | ||
| with: | ||
| deno-version: ${{ env.DENO_VERSION }} | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ env.NODE_VERSION }} | ||
|
|
||
| - name: Setup Rust | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| targets: aarch64-apple-darwin | ||
|
|
||
| - name: Rust cache | ||
| uses: Swatinem/rust-cache@v2 | ||
| with: | ||
| workspaces: | | ||
| src-tauri -> target | ||
| cyb-boot -> target | ||
|
|
||
| # ── Apple Code Signing ────────────────────────────────────── | ||
| - name: Import Apple certificates | ||
| env: | ||
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | ||
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | ||
| APPLE_INSTALLER_CERTIFICATE: ${{ secrets.APPLE_INSTALLER_CERTIFICATE }} | ||
| APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }} | ||
| run: | | ||
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | ||
| KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | ||
|
|
||
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | ||
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | ||
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | ||
|
|
||
| # Import Developer ID Application certificate | ||
| echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/app-cert.p12 | ||
| security import $RUNNER_TEMP/app-cert.p12 \ | ||
| -P "$APPLE_CERTIFICATE_PASSWORD" \ | ||
| -A -t cert -f pkcs12 \ | ||
| -k "$KEYCHAIN_PATH" | ||
| rm -f $RUNNER_TEMP/app-cert.p12 | ||
|
|
||
| # Import Developer ID Installer certificate (for .pkg signing) | ||
| echo "$APPLE_INSTALLER_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/pkg-cert.p12 | ||
| security import $RUNNER_TEMP/pkg-cert.p12 \ | ||
| -P "$APPLE_INSTALLER_CERTIFICATE_PASSWORD" \ | ||
| -A -t cert -f pkcs12 \ | ||
| -k "$KEYCHAIN_PATH" | ||
| rm -f $RUNNER_TEMP/pkg-cert.p12 | ||
|
|
||
| # Make keychain available for codesign | ||
| security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db | ||
| security default-keychain -s "$KEYCHAIN_PATH" | ||
| security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: \ | ||
| -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | ||
|
|
||
| # Auto-detect signing identities from imported certs | ||
| APP_IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" \ | ||
| | grep 'Developer ID Application' | head -1 | sed 's/.*"\(.*\)"/\1/') | ||
| PKG_IDENTITY=$(security find-identity -v -p basic "$KEYCHAIN_PATH" \ | ||
| | grep 'Developer ID Installer' | head -1 | sed 's/.*"\(.*\)"/\1/') | ||
|
|
||
| # Fall back to secrets if auto-detection fails | ||
| APP_IDENTITY="${APP_IDENTITY:-${{ secrets.APPLE_SIGNING_IDENTITY }}}" | ||
| PKG_IDENTITY="${PKG_IDENTITY:-${{ secrets.PKG_SIGNING_IDENTITY }}}" | ||
|
|
||
| echo "APPLE_SIGNING_IDENTITY=$APP_IDENTITY" >> $GITHUB_ENV | ||
| echo "PKG_SIGNING_IDENTITY=$PKG_IDENTITY" >> $GITHUB_ENV | ||
| echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> $GITHUB_ENV | ||
|
|
||
| echo "App signing identity: $APP_IDENTITY" | ||
| echo "Pkg signing identity: $PKG_IDENTITY" | ||
|
|
||
| - name: Setup Apple API key | ||
| env: | ||
| APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | ||
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | ||
| run: | | ||
| mkdir -p $RUNNER_TEMP/private_keys | ||
| echo "$APPLE_API_KEY_BASE64" | base64 --decode \ | ||
| > $RUNNER_TEMP/private_keys/AuthKey_${APPLE_API_KEY}.p8 | ||
|
|
||
| echo "APPLE_API_KEY=$APPLE_API_KEY" >> $GITHUB_ENV | ||
| echo "APPLE_API_ISSUER=${{ secrets.APPLE_API_ISSUER }}" >> $GITHUB_ENV | ||
| echo "APPLE_API_KEY_PATH=$RUNNER_TEMP/private_keys/AuthKey_${APPLE_API_KEY}.p8" >> $GITHUB_ENV | ||
|
|
||
| # ── Dependencies ──────────────────────────────────────────── | ||
| - name: Install JS dependencies | ||
| run: deno install | ||
|
|
||
| - name: Download Kubo sidecar | ||
| run: | | ||
| TAURI_TARGET_TRIPLE=aarch64-apple-darwin \ | ||
| src-tauri/scripts/download-kubo.sh ${{ env.KUBO_VERSION }} | ||
|
|
||
| # ── Build ─────────────────────────────────────────────────── | ||
| - name: Build web frontend | ||
| run: deno task build-tauri | ||
| env: | ||
| NODE_OPTIONS: '--max-old-space-size=8192' | ||
|
|
||
| - name: Build Tauri app (sign + notarize) | ||
| run: | | ||
| npx @tauri-apps/cli build \ | ||
| --target aarch64-apple-darwin \ | ||
| --config '{"build":{"beforeBuildCommand":""},"bundle":{"macOS":{"signingIdentity":"'"$APPLE_SIGNING_IDENTITY"'"}}}' \ | ||
| -- --features gpu-metal | ||
|
|
||
| - name: Build .pkg (sign + notarize) | ||
| run: | | ||
| src-tauri/scripts/macos-pkg.sh \ | ||
| --app-path src-tauri/target/aarch64-apple-darwin/release/bundle/macos/cyb.app \ | ||
| --output-dir src-tauri/target/aarch64-apple-darwin/release/bundle/pkg | ||
|
|
||
| - name: Build cyb-boot (sign + notarize) | ||
| run: | | ||
| cd cyb-boot && cargo build --release --target aarch64-apple-darwin | ||
| cd .. | ||
|
|
||
| codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" \ | ||
| cyb-boot/target/aarch64-apple-darwin/release/cyb-boot | ||
|
|
||
| ditto -c -k --keepParent \ | ||
| cyb-boot/target/aarch64-apple-darwin/release/cyb-boot \ | ||
| $RUNNER_TEMP/cyb-boot-notarize.zip | ||
|
|
||
| xcrun notarytool submit $RUNNER_TEMP/cyb-boot-notarize.zip \ | ||
| --key "$APPLE_API_KEY_PATH" \ | ||
| --key-id "$APPLE_API_KEY" \ | ||
| --issuer "$APPLE_API_ISSUER" \ | ||
| --wait | ||
|
|
||
| rm -f $RUNNER_TEMP/cyb-boot-notarize.zip | ||
|
|
||
| # ── Artifacts ─────────────────────────────────────────────── | ||
| - name: Collect release artifacts | ||
| run: | | ||
| mkdir -p release-artifacts | ||
|
|
||
| # .dmg | ||
| cp src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg \ | ||
| release-artifacts/ | ||
|
|
||
| # .pkg (for GitHub Releases — cyb-boot downloads this) | ||
| cp src-tauri/target/aarch64-apple-darwin/release/bundle/pkg/*.pkg \ | ||
| release-artifacts/cyb.pkg | ||
|
|
||
| # cyb-boot binary (for distribution server) | ||
| cp cyb-boot/target/aarch64-apple-darwin/release/cyb-boot \ | ||
| release-artifacts/cyb-boot-aarch64-apple-darwin | ||
|
|
||
| echo "=== Release artifacts ===" | ||
| ls -lh release-artifacts/ | ||
|
|
||
| - name: Create GitHub Release | ||
| if: startsWith(github.ref, 'refs/tags/') || inputs.create_release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| tag_name: ${{ github.ref_name || format('v{0}', github.sha) }} | ||
| files: release-artifacts/* | ||
| generate_release_notes: true | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Upload build artifacts | ||
| if: ${{ !startsWith(github.ref, 'refs/tags/') && !inputs.create_release }} | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: macos-release-aarch64 | ||
| path: release-artifacts/ | ||
|
|
||
| # ── Cleanup ───────────────────────────────────────────────── | ||
| - name: Cleanup keychain | ||
| if: always() | ||
| run: | | ||
| if [ -n "${KEYCHAIN_PATH:-}" ]; then | ||
| security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true | ||
| fi |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
In general, the problem is fixed by adding an explicit permissions block that grants only the scopes required by the workflow. This can be added at the root of the workflow (applies to all jobs) or at the job level. Here, the only steps that need write access to the repository via GITHUB_TOKEN are:
Create GitHub Releaseusingsoftprops/action-gh-release@v2(needscontents: writeto create/update releases on tags/commits).actions/upload-artifact@v4uses the workflow’sGITHUB_TOKENinternally but works withcontents: read; it doesn’t need repo write permissions.
The best minimal fix without changing behavior is therefore:
- Add a workflow-level
permissionsblock settingcontents: readas the default for all jobs/steps. - Add a job-level
permissionsblock formacos-releaseoverridingcontentstowrite, since the job creates GitHub Releases. This keeps permissions narrow while still allowing the existingCreate GitHub Releasestep to function.
We will modify .github/workflows/macos_release.yml as follows:
- After line 15 (after the
on:block), insert a root-levelpermissions:block withcontents: read. - After line 22 (inside
jobs:, undermacos-release:and at the same indentation asruns-on), insert a job-levelpermissions:block withcontents: write.
No imports or additional methods are needed; GitHub Actions understands permissions natively.
Suggested changeset
1
.github/workflows/macos_release.yml
| @@ -13,6 +13,9 @@ | ||
| tags: | ||
| - 'v*' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| env: | ||
| DENO_VERSION: v2.x | ||
| NODE_VERSION: '22' | ||
| @@ -20,6 +23,8 @@ | ||
|
|
||
| jobs: | ||
| macos-release: | ||
| permissions: | ||
| contents: write | ||
| runs-on: macos-14 # Apple Silicon (M1) | ||
| timeout-minutes: 120 | ||
|
|
Copilot is powered by AI and may make mistakes. Always verify output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tauri-plugin-deep-link for iOS/Android Universal Links (cyb.ai URLs open in app, preserving ?ref= referrer) - Handle deep link URLs at app init via getCurrent() + onOpenUrl() - Fix cyb-boot PKG download URL to use cyberia-to/cyb repo - Enrich mining log export with device info, Tauri backend metrics, uhash params, block context, proof summary stats - Switch log export from clipboard to file download Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace SCP deploy to Jupiter with HMAC-authenticated webhook trigger - Server now runs locally on Cyberproxy (no Jupiter proxy hop) - Rename Install-cyb.zip → boot-cyb.zip, Install cyb.app → boot cyb.app - API path: POST /api/boot (was /api/boot/boot) - Server handler: / (was /boot) - Add boot server Go source and docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t.dat discovery - Rename boot-cyb.zip → boot_cyb.zip and boot cyb.app → Boot Cyb.app everywhere - Add ~/Desktop as boot.dat search path - Scan immediate subdirectories of ~/Downloads and ~/Desktop for boot.dat Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check bootstrap.json before localStorage so that wallet imported via cyb-boot takes priority over any previously generated wallet. The file is deleted after reading, so this only applies once. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Headline: "Mine 10x faster in app" - Desktop: platform-detected download button - Mobile: "coming soon" button for iOS/Android Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tauri-plugin-dialog and tauri-plugin-fs for native file operations. Export logs now opens a Save dialog on desktop instead of copying to clipboard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hashrate was jumping wildly due to bursty counter + double smoothing: - Backend 5s rolling window was shorter than batch time (~7s) - Frontend EMA re-derived rate from total_hashes delta, seeing mostly zeros between batches then a spike when a batch completed Fixes: - Backend: increase rolling window from 5s to 30s (fits multiple batches) - Backend: record snapshots on proof-found path (was missing) - Frontend: remove EMA re-derivation, use backend's rolling hashrate directly - Add session average display below main hashrate as stable anchor - Downsample sparkline to 5s intervals instead of every render Also adds: - Proof retry queue with exponential backoff for transport errors - RPC connection health tracking with offline indicator - Sleep/wake and network reconnection recovery - Native save dialog capability for log export Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…port Replace timer polling (10s/120s) with event-driven refresh: - New block (WS) triggers refetchAll for all display data - resyncAfterProof fetches config + balance after proof submit - 30s fallback interval only when WebSocket is disconnected - Wake/resume/online handlers use refetchAll + refetchConfig Local sequence tracking eliminates account sequence mismatch errors: - Track accountNumber + sequence in seqRef, increment on success - Use sign() + broadcastTx() instead of execute() to pass explicit SignerData - On sequence mismatch: re-fetch from chain and retry once - Reset sequence on unknown errors or account activation Fix cooldown bypass after failed submissions: - Set lastSubmitTimeRef before await (was only set on success) - Prevents rapid-fire cascade of failures at 1s intervals Other: - Export logs filtered to current app session only - Tx details page polls until confirmed - Embed challenge in Rust FoundProof for stale-proof tracking - Refresh badge shows 'reconnecting...' instead of countdown Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removing setSessionLiMined(0) from handleStartMining prevents the "LI Mined" counter from resetting when changing difficulty or restarting mining mid-session. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…conomy section - Remove emission rate cards (mining/staking/gross) — these are internal PID controller values (atomic LI/s), not actual token emission rates - Add Economy section: supply (minted/cap), PoW/PoS share, fees, burned - Add total_minted query from core contract - Replace Alpha/Beta with PoW/PoS share (computed from emission ratios) - Replace D-rate with Net. throughput (bits/hr) - Add Your share (miner's network share %) - Add window progress bar with fill indicator - Fix horizontal scroll (overflow-x: hidden, min-width: 0) - Add P (peta) tier to compactLi for supply cap display - StatCard: add children prop for progress bar Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full mining integration for the Cyb app — adds a mining dashboard, native iOS/Android builds, and continuous mining (no pause during proof submission).
Mining Dashboard (
src/pages/Mining/)uhash-webfor browser mining when not in TauriTauri Native Backend (
src-tauri/src/mining.rs)uhash-corewith hardware AES/SHA256 accelerationseed_raw_32B || address_utf8 || timestamp_8B_LE || nonce_8B_LEstart_mining,stop_mining,get_mining_status,take_proofs,mining_benchmark,get_mining_paramscommandsContinuous Mining (key improvement)
Vec<FoundProof>, polling loop drains queue viatake_proofs, submits async (fire-and-forget).iOS Build
tauri.ios.conf.json) — single window, no splash screen#[cfg(desktop)]guards on all desktop-only code (IPFS, CozoDb, warp server, splash screen)Android Build
tauri.android.conf.json) — single window[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]npx @tauri-apps/cliinstead ofnpm run tauricpufeaturescrate doesn't support armv7 (32-bit ARM). All modern phones are 64-bit.Mobile UX Fixes
isMobileTauricheck inbackend.tsxviewport-fit=covermeta tag +env(safe-area-inset-*)on header (notch), footer, action bars, modals, mobile menumobileAllowedRoutesmaxWidth: calc(100vw - 32px), mnemonic gridrepeat(auto-fill, minmax(100px, 1fr))New Files
src/pages/Mining/Mining.tsxsrc/pages/Mining/wasmMiner.tssrc/pages/Mining/miningWorker.tssrc/pages/Mining/MiningActionBar.tsxsrc/pages/Mining/hooks/*src/pages/Mining/components/*src-tauri/src/mining.rssrc-tauri/src/lib.rssrc-tauri/tauri.ios.conf.jsonsrc-tauri/tauri.android.conf.jsonsrc/constants/mining.tssrc/utils/tauri.tsisTauri()detection helperModified Files (key changes)
src-tauri/Cargo.tomlsrc/contexts/backend/backend.tsxisMobileTauri)src/components/actionBar/index.tsxsrc/containers/application/mobileAllowedRoutes.tssrc/index.htmlviewport-fit=coverfor safe areas.scss/.style.tsfilesTest plan
npx @tauri-apps/cli dev— mining page works, hashrate displays, proofs submitAPPLE_DEVELOPMENT_TEAM=<ID> npx @tauri-apps/cli ios build— install on iPhone, connect wallet, start miningnpx @tauri-apps/cli android build --apk --target aarch64— sign APK, install, test miningyarn start— WASM mining fallback works without Tauri🤖 Generated with Claude Code