What changed. Why it matters.
Every desktop release since 1.0.0 — grouped by theme so you can see the trajectory.
- v1.0.38 + Mobile v0.1.12026-05-21
Pairing actually works end-to-end — desktop unlocks + APK rewrite
- Fix
Desktop wouldn't launch after 1.0.33: the Tauri v2 updater plugin rejects HTTP endpoints at config deserialization, which panicked the Rust process before the window could ever show. Disabled the updater (active:false + empty endpoints) until HTTPS lands on EC2. Auto-update is paused; manual installer downloads for now.
- Fix
Login → immediate logout. Two server-side route bugs combined with an overly aggressive 401 interceptor: /api/mobile/devices was mounted as an alias that stripped its own prefix and fell through to 401, and the desktop client treated any 401 as a dead session. Now the interceptor verifies against /auth/me before clearing the token, and /devices has explicit handlers.
- New
Mobile companion listener (port 6002) is now enabled by default in the desktop sidecar — end users can't set process env vars, so the previous MOBILE_API_ENABLED=1 requirement broke pairing for everyone. Pair → New device → scan QR works the moment the desktop is open on the same Wi-Fi.
- Fix
Pair manual entry: the desktop dialog now shows the full 64-char pairing token (with a Copy button) instead of only the 6-char shortCode. The short code was visual-only — the phone's manual flow has always required all 64 hex chars.
- Fix
Server route order: unauthenticated POST /api/mobile/pair/complete was being intercepted by the auth-guarded /pair sub-router (mounted earlier). Phones got 401 instead of token validation. Declared /pair/complete BEFORE the auth-guarded /pair mount.
- Fix
Mobile crypto rewrite. Three layered bridge failures on Expo SDK 55 / RN 0.83 / Hermes new arch: expo-crypto.digest(ArrayBuffer) crashed with 'Cannot convert ArrayBuffer to a Kotlin type'; the fallback used TextDecoder('latin1') which Hermes doesn't ship ('unknown encoding: latin1'); fetch + AbortController.signal hit the same JSI marshalling issue. Replaced SHA-256 + HMAC with @noble/hashes (pure JS, audited, ~30 KB) and rewrote fetchWithTimeout to use Promise.race instead of AbortController. Byte-exact compatibility with the Node server's HMAC scheme preserved.
- Fix
Pair POST got 'Network request failed' even with a working LAN path. Android 9+ blocks cleartext HTTP by default and the LAN pairing target is http://<lan-ip>:6002 (no TLS — same physical network, every request is HMAC-signed). Added android:usesCleartextTraffic=true to the manifest + app.json so OkHttp permits the call.
- Improved
Mobile bottom tab bar height and paddingBottom now derive from useSafeAreaInsets so the tab buttons sit above the phone's gesture pill / 3-button nav (previously the system nav clipped them on most Android devices). Every tab screen bumps contentContainer paddingBottom from 80 to 140 so scroll content clears the new (taller) tab bar.
- Fix
- vMobile companion v0.1.02026-05-19
Android companion app — pair, approve, monitor on the go
- New
Android companion app shipping as a sideloadable APK. Pairs with your desktop install over LAN via a QR-coded HMAC handshake; once paired the phone signs every request with a per-device key. Exchange API keys NEVER reach the phone — every authenticated call still happens on the desktop. Tabs: Home (24h P&L + sessions) · Sessions (live MM + Auto-Arb with pause) · Spreads (live cross-exchange feed) · Approvals (biometric-gated cross-ex gates) · More (Wallet, Alerts, Notification preferences, Pairing).
- New
Push notifications via Expo Push → FCM for approval-needed gates, stop-loss fires, auto-pause, deposit confirmations. Approval-needed routes through a high-priority Android channel so it bypasses Doze. Tap the notification → app opens directly on the right tab (Approvals / Sessions / Spreads). Notification preferences toggle which event types push to this device.
- New
Biometric gates: every approve action requires a fresh Face/fingerprint check; withdraw gate adds an extra Alert.alert confirmation because it moves on-chain funds. Optional biometric-lock-on-launch from More tab — 5-minute foreground grace window so tab changes don't re-prompt.
- New
Built with Android Studio + gradle. No EAS, no Expo cloud, no third-party CI. Native android/ committed to the repo; release signing reads from android/app/release-signing.properties (gitignored). Distributed as a self-hosted APK at http://3.109.21.114/downloads/CryptoRoute-mobile.apk — same pattern as the desktop installer.
- Security
Mobile API listener (port 6002) is opt-in via MOBILE_API_ENABLED=1 on the desktop. Stays bound only when the user explicitly enables it; off by default, so existing installs have no new exposed surface. HMAC-SHA256 signing scheme uses sha256(deviceKey) as the verifier key so the desktop can verify signatures without ever holding the raw key the phone derived.
- Improved
Migration 023 + SQLite patches add paired_devices (HMAC key hash, status, last seen, push token) and mobile_event_queue (events the desktop wanted to push but couldn't deliver immediately — drained on next /events poll).
- New
- v1.0.332026-05-13
Auto-update + idle GC + API key health + fee sync + sidebar prune
- New
Tauri auto-updater — desktop builds now check http://3.109.21.114/downloads/latest.json on startup (and every 6h while open). When a newer signed bundle is available, a snackbar prompt downloads and installs it, then relaunches. Signatures are verified against an embedded public key — unsigned bundles are rejected. Future releases ship via this channel; no more manual installer downloads.
- New
Idle-session watchdog auto-pauses Market Making sessions inactive for 4h, Auto-Arb for 8h, and cross-exchange (auto mode only) for 6h. Thresholds are env-tunable for operators who legitimately wait longer between fills. Catches the weekend-drift case where an MM session goes quiet and the position quietly walks underwater.
- New
API key health monitor — every 15 minutes the server probes each saved credential with a cheap authenticated read (testConnection / getBalances) and records last_health_ok, last_health_error, latency_ms. Settings → API Key Health shows a per-credential status dot plus a Probe button for on-demand re-check. Turns 'my key stopped working' tickets into self-serve diagnoses.
- New
Per-exchange fee schedule sync — server fetches your live maker/taker rate every 6h using the first active credential per exchange (Binance /api/v3/account, Gate.io /wallet/fee, KuCoin /base-fee). Settings → Exchange Fee Schedule shows the table. Falls back to public defaults for exchanges without a credential so the page is never blank. Stops VIP/promo tier shifts from silently eroding the slippage math.
- Improved
Sidebar prune — DEX/CEX and Funding Rates removed from nav (routes still accessible). Screener / Heatmap / Volatility Scanner / Spread Chart consolidated into a single 'Market Scan' page with tabs. Net effect: ~8 items dropped from the sidebar so the trading flow is the obvious thing.
- Improved
Migration 022 + matching SQLite patches add last_health_* and last_activity_at columns plus the exchange_fee_schedules table. Existing desktop installs patch on next launch — no manual db reset needed.
- New
- v1.0.322026-05-12
Reliability hardening — circuit breakers, graceful shutdown, separated secrets
- Security
GateIO signed-request debug logging removed — full signatures and timestamps were being written to stdout on every API call. Production logs no longer leak signing material.
- Security
ENCRYPTION_SECRET is now required separately from JWT_SECRET in production. The vault still tries both for decryption so existing credentials still load, but new encryptions always use ENCRYPTION_SECRET. Startup aborts if it's missing in NODE_ENV=production.
- Security
Startup config validation — server refuses to boot in production when JWT_SECRET / ENCRYPTION_SECRET / DATABASE_PASSWORD are still set to dev defaults. No more silent misconfigurations leaking into a live deploy.
- Improved
Per-exchange circuit breakers on Binance and Gate.io signed requests. After 5 consecutive failures the breaker opens for 30s and fast-fails instead of hammering a degraded exchange. One probe request transitions back to closed on success.
- Improved
Cross-exchange deposit polling now uses exponential backoff with jitter (15s → 180s) instead of a fixed 30s interval. Burns far fewer rate-limit credits when a deposit takes 90+ minutes to confirm and avoids tripping the new breakers.
- Improved
Graceful SIGTERM / SIGINT shutdown — pollers stop, in-flight HTTP requests drain, then the process exits. Up to 15s grace period before forced exit. PM2 reloads and container restarts no longer drop responses mid-trade.
- Improved
/api/health/ready readiness probe checks DB connectivity and surfaces the live circuit-breaker snapshot. Returns 503 when degraded so orchestrators can drain traffic. /api/health stays as a cheap liveness probe.
- Improved
Request correlation IDs (X-Request-Id header, also reflected in the response) attached by middleware and prefixed into every log line. Cross-exchange failures can now be traced end-to-end across server logs and the audit table.
- New
First automated test suite — 16 tests across RiskManager (consecutive-loss limits, position sizing, spread protection), triangular-arbitrage slippage math, exponential backoff, and the circuit breaker state machine. Runs via `npm test -w packages/server` on Node's built-in test runner — zero new dependencies.
- Security
- v1.0.312026-05-08
Hotfix: Cross-Exchange Monitor SSE + native-alert removal + paper-trade report
- Fix
Cross-Exchange Monitor stream — EventSource was opening with a relative URL that resolved to tauri.localhost in desktop instead of the sidecar at __API_BASE__. 'Stream disconnected — retrying…' is gone. Same root cause as the earlier /prices/stream fix; this endpoint was missed.
- Fix
Replaced every window.alert() call with a proper Snackbar-based toast service (success / error / warning / info). The 'tauri.localhost says…' native dialog no longer appears. New ToastHost mounted at app root + global toast.* API for any future call sites.
- Fix
Paper-Trade Accuracy Report — same camelCase/snake_case bug as the auto-cross-exchange page. Row interface and field accesses were snake_case but the db client transforms responses to camelCase, so opened_at became undefined → 'Invalid Date', predicted_net_pct → undefined → 'NaN%'. Added normalizeRow() that accepts either shape and coerces numbers to safe defaults. Date guard renders '—' for invalid timestamps.
- Fix
- v1.0.302026-05-08
TransferValidator — pre-flight gate against contract / memo / network mismatches
- New
Cross-exchange execute now runs a TransferValidator before withdrawal: confirms both exchanges list the asset on the same chain, contract addresses match (EVM chains), withdraw/deposit are enabled, and memo requirements line up. Hard blocks on contract mismatch — the rule that would have caught the CITY/Chiliz incident on 2026-05-07.
- New
POST /api/cross-exchange/preflight endpoint mirrors the engine's pre-flight gate so the UI can show contract addresses, memo flags, and any block reasons before the user clicks Execute. Same code path the engine runs at trade time — UI and engine can never disagree.
- New
Network-name aliasing layer — recognises ETH/ERC20/Ethereum, BSC/BEP20, TRX/TRC20, POLYGON/MATIC, ARBITRUM/ARB and ~45 other chain pairs as the same network. Fixes false 'X does not list Y on Z' refusals between exchanges that label chains differently.
- New
Chain-tax surcharge in the cross-exchange scanner — Terra Classic 0.5% LUNC burn tax (and USTC) now factored into transport cost. Stops the scanner from showing fake-profitable rows at sub-0.5% spreads on these chains.
- Fix
Binance signed-request clock sync. Fetches /api/v3/time on first call, caches the offset for 5 min, auto re-syncs on timestamp errors. recvWindow bumped 5s → 30s. Eliminates the 'Timestamp 1000ms ahead of server time' rejections from Windows clock drift.
- Fix
Cross-Exchange page no longer white-screens when an active session is loaded. Root cause was snake_case vs camelCase field-name mismatch after the db client's auto-transform — fetchSession + events mapper now read both shapes defensively. Plus an ErrorBoundary so render crashes show the error instead of a blank page.
- Fix
Validator panel cached across rows — opening Execute on a different row no longer shows the previous row's verdict. Dialog state resets on (asset, sourceExchange, destExchange) change.
- Fix
Validator over-blocking LUNC. Contract equality now only enforced on EVM chains (hardcoded allowlist); Cosmos SDK denom strings like 'uluna' are no longer mistaken for EVM contracts. Memo requirement check switched to destination-only — source's memo opinion is irrelevant for outbound transfers.
- Fix
SQLite schema patches for cross_exchange_sessions.mode, cross_exchange_trades.events, and cross_exchange_events table. Mirrors postgres migration 017 — fixes the 'no such column: mode' crash on auto-trade start.
- Fix
Find-Opportunities Execute modal showed 'Failed to start' instead of the real server reason — the apiClient interceptor unwraps responses to {success, error} but the catch block was reading axios shape. Now reads err.error first, falls back to axios shape. The actual reason (key permissions, balance, etc.) surfaces immediately.
- New
- v1.0.212026-05-06
Hotfix: SSE auth + SQLite-native queries + settings route mounting
- Fix
Cross-Exchange Monitor SSE — switched ?_t= to ?token= so authMiddleware's existing SSE-fallback recognizes the JWT (matches the /api/prices/stream pattern). 'Stream disconnected — retrying…' is gone.
- Fix
Paper-Trade Report — replaced Postgres-only INTERVAL '...' arithmetic with ISO-8601 string lower-bounds, and COUNT(*) FILTER WHERE with portable CASE-WHEN-SUM. Works against the SQLite sidecar on desktop.
- Fix
SQLite schema patches added in migrate-sqlite for paper_trade_simulations and audit_log tables, plus user_settings.{india_tds_enabled, min_net_spread_pct, trade_notional_usd}. Existing desktop installs auto-patch on next launch — no manual db wipe needed.
- Fix
Mounted /api/settings — the route file existed but was never wired into the Express app. Settings page + Cross-Exchange Monitor's settings load now both work.
- Fix
- v1.0.202026-05-06
Cross-exchange POC: spread monitor + paper-trade engine
- New
Cross-Exchange Monitor — live spread dashboard across Binance, Gate.io, KuCoin, Bybit, OKX, MEXC. Net of maker fees × 2, TRC20 transport fee, slippage, and optional 1% India TDS. SSE feed updates every 5 s. Color-coded rows + per-row cost-breakdown tooltip.
- New
Paper-Trade Engine — one click opens paper trades for every viable opportunity above your net threshold. Server-side accuracy tracker revisits each at +60 s and writes realized PnL back. De-duped within 60 s so a 5 s scan loop doesn't spam the table.
- New
Paper-Trade Accuracy Report — predicted vs realized PnL with matched-rate hero number, filterable detail table, CSV export. The deliverable that converts curious prospects into pilots.
- New
CoinStatusService — per-exchange deposit/withdraw status with 60 s cache; flags routes where one side has the asset suspended. Fail-open on rate-limit so the scanner never goes blind.
- New
user_settings: india_tds_enabled / min_net_spread_pct / trade_notional_usd. Defaults safe for Indian-resident operators (TDS on, 0.1% min, $1000 notional).
- Improved
Trading audit log — every authenticated mutating request is recorded with sanitized body + IP + status + duration. Admin viewer at /admin/audit-log.
- Improved
Zod input validation on credential save, quick-trade execute, and auto-arbitrage start. Structured 400s with errors[].
- Improved
Telegram bot health endpoint at /api/admin/telegram-status — verifies TELEGRAM_BOT_TOKEN before relying on alerts.
- New
- v1.0.192026-04-20
Partial profit take + breakeven-stop display fix
- Fix
Breakeven-stop events now display correctly in the session log — previously showed as 'HARD STOP-LOSS: hit stop $0.00 (undefined% from entry)' because the client formatter didn't handle the breakeven_stop type.
- New
Partial profit take: after holding a position for 90 s, if mid is above entry but below the full fee-floor target, the sell minimum steps down to breakeven (entry + sell fee). Previously the sell stayed pinned at the full spread target, price peaked and retreated, and the breakeven stop fired at a loss.
- Fix
- v1.0.172026-04-20
MM emergency-sell race fix + AutoLearner
- Fix
Emergency-sell no longer races the strategic sell loop — stop-loss now reliably liquidates via 3-tier MARKET fallback instead of leaving inventory locked.
- Fix
MM sessions auto-restart 3 min after a stop-loss (60 s for ratchet/kill) so overnight runs keep working after a single SL event.
- New
AutoLearner — every session feeds round-trip outcomes into mm_learned_configs and adaptively tunes gamma / spread / stop-loss for future sessions on the same pair.
- New
Wallet force-sell now lets you pick the exchange when the same asset sits on multiple venues.
- New
Cross-exchange search filters persist across navigation (localStorage).
- New
Global refresh button in the app bar.
- Fix
- v1.0.162026-04-18
Alert delivery fix + expanded marketing
- Fix
Alert notifications now persist with correct user_id — Windows toasts fire reliably after price alerts trigger.
- Fix
Alert SSE stream now uses absolute __API_BASE__ URL — works correctly inside the Tauri webview origin.
- New
Marketing site expanded to multi-page — Strategies, Market Making, Security, Platforms, Pricing.
- Fix
- v1.0.14–1.0.152026-04-18
Market Making v3 polish
- Improved
Auto-tuner adjusts γ and κ over a 30-minute rolling window.
- Improved
Momentum detector suppresses aggressive buys for 60s after a sell — reduces buy-into-dump incidents.
- Fix
Sell-stale timer extended to 45s to avoid unnecessary order churn on quiet pairs.
- Improved
- v1.0.10–1.0.132026-04-17
Lead-lag detection & volatility scaling
- New
LeadLagDetector watches a correlated venue (Binance) and widens the spread 3× on danger signals.
- New
VolatilityTracker scales spreads by √variance — quiet pairs get tight quotes, volatile pairs get safe ones.
- Improved
Loss-cut timeout introduced at 120s — hard stop if inventory lingers underwater.
- New
- v1.0.5–1.0.92026-04-17
LIMIT_MAKER post-only & fee floor
- New
All market making orders now use LIMIT_MAKER — unlocks the 0.075% maker fee on Binance.
- New
Fee floor introduced: `makerFee × 2 × 1.2` — sells never price below round-trip cost.
- Improved
Post-fill cooldown dropped to 10s — faster re-entry after a completed cycle.
- New
- v1.0.1–1.0.42026-04-17
3-gate cross-exchange approval flow
- New
Cross-exchange trades now gate at Buy → Withdraw → Sell with explicit user approval at each step.
- Security
Address verification before withdrawal. No auto-submit. No hidden defaults.
- Improved
Network gas estimate baked into profit projection.
- New
- v1.0.02026-04-16
Initial desktop release
- New
Tauri v2 shell wrapping the full Node sidecar — 33 MB installer, bundled runtime, no external server needed.
- New
11 trading exchanges + 2 pricing-only feeds integrated.
- New
Quick Trade (triangular), Auto Arb, Snake Arb, Stat Arb, DEX-CEX scanners live.
- Security
AES-256-GCM credential vault with scrypt-derived per-user keys.
- New
Pre-1.0.0 builds were internal-only. macOS desktop build is tracked separately — join the access list to be notified when it ships.
Upgrade notifications?
Request access and we'll email you when a new build drops — with the changelog delta.