Skip to content

feat: cross-chain swap support via THORChain + Pioneer API#15

Draft
BitHighlander wants to merge 10 commits intodevelopfrom
feature-swaps
Draft

feat: cross-chain swap support via THORChain + Pioneer API#15
BitHighlander wants to merge 10 commits intodevelopfrom
feature-swaps

Conversation

@BitHighlander
Copy link
Collaborator

Summary

  • Full cross-chain swap flow: asset selection, quoting (Pioneer-aggregated), review, hardware signing, broadcast, and live tracking
  • EVM swaps use THORChain router depositWithExpiry() with ERC-20 approve + allowance checks, dynamic gas estimation
  • UTXO/Cosmos swaps route through txbuilder with memo injection (OP_RETURN / tx metadata)
  • Swap tracker polls Pioneer GetPendingSwap per-txHash with adaptive intervals (10s→20s→30s)
  • SQLite-persisted swap history with filtering, stats, and PDF/CSV export
  • Floating SwapTracker bubble + SwapHistoryDialog with live status, stage indicators, explorer links
  • 85 i18n keys for swap UI
  • Safety: xpub-in-memo rejection, router allowlist (warn-only), memo length limits, balance/gas pre-checks

New files

  • swap.ts — Pioneer integration (assets, quotes, execution with EVM/UTXO/Cosmos branching)
  • swap-parsing.ts — Pure parsing functions (testable without side effects)
  • swap-tracker.ts — Adaptive polling + Pioneer registration + SQLite persistence
  • swap-report.ts — PDF/CSV export for swap history
  • SwapDialog.tsx — Full-screen swap flow (1387 LOC)
  • SwapHistoryDialog.tsx — History + active swaps dialog (787 LOC)
  • SwapTracker.tsx — Floating status bubble

Modified files

  • db.ts — swap_history table + CRUD + stats queries
  • index.ts — RPC handlers for swap endpoints
  • rpc-schema.ts — 8 new RPC methods
  • types.ts — 10 new swap-related type interfaces
  • chains.tsgetExplorerTxUrl() helper
  • evm-rpc.tsestimateGas, waitForTxReceipt, getErc20Allowance/Decimals
  • txbuilder/evm.tsencodeDepositWithExpiry, encodeApprove
  • txbuilder/cosmos.tsMsgDeposit support for THORChain/Maya swaps
  • AssetPage.tsx — Swap button integration
  • Dashboard.tsx — SwapTracker mount
  • App.tsx — swap i18n namespace

Test plan

  • Load swap assets from Pioneer — verify BTC, ETH, RUNE, ERC-20 tokens appear
  • Get quote for BTC→ETH — verify output amount, fees, memo, vault address
  • Execute native ETH→BTC swap — confirm on device, verify broadcast + tracking
  • Execute ERC-20 swap (e.g. USDT→ETH) — verify approve tx + deposit tx
  • Verify UTXO swap (BTC→ETH) — OP_RETURN memo, correct vault
  • Verify Cosmos/THORChain swap — MsgDeposit with correct asset
  • Check swap tracker shows live status updates (pending→confirming→completed)
  • Check swap history persists across app restart (SQLite)
  • Export swap history as CSV and PDF — verify file content
  • Verify xpub-in-memo safety check rejects bad memos
  • Test swap with insufficient gas — verify pre-flight rejection

BitHighlander and others added 10 commits March 9, 2026 00:34
…s access in watch-only

- Engine: auto-trigger promptPin() on needs_passphrase so device sends PASSPHRASE_REQUEST
- Engine: route applySettings through updateState so passphrase toggle triggers full flow
- PassphraseEntry: show "Confirm on your KeepKey" spinner after submit instead of dismissing
- App: auto-dismiss passphrase overlay when device transitions away from needs_passphrase
- App: show needs_pin/needs_passphrase as splash (not ready) to prevent dashboard flash
- App: enable settings gear + drawer in watch-only/claimed mode
- TopNav: remove watchOnly disable on settings button
- i18n: add passphrase.confirmOnDevice strings (10 languages)
- i18n: enable partialBundledLanguages for graceful fallback
- Bump version to 1.1.2
- Rename build folder to _build (electrobun.config, collect-externals, build-windows-production.ps1)
- Add cross-platform window drag to TopNav (useWindowDrag on Windows, CSS class on Mac)
- Update Makefile verify/clean targets to match _build rename

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xcrun stapler staple fails with relative paths — it can't resolve
the file. Using $(pwd) ensures all tools (hdiutil, codesign, stapler)
get a consistent absolute path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- engine-controller: updatePhase = 'idle' (not null) on reboot poll timeout,
  emit disconnected state so UI recovers; reduce poll log frequency to every 30s
- reports: add safeRoundSats() guard for satoshi values near MAX_SAFE_INTEGER,
  validate Pioneer API response shapes, export SECTION_TITLES constants
- tax-export: use shared SECTION_TITLES constants, add row bounds checking
  to prevent silent data corruption on schema changes
- PassphraseEntry: catch onSubmit errors to reset spinner (device disconnect
  during confirm no longer leaves overlay stuck)
- App: suppress PIN auto-show during all firmware phases (not just rebooting)
- index: post-decode firmware size validation (7.5MB binary limit)
release: v1.1.2 — passphrase flow, Windows drag, build fixes
- SwapDialog with quote, review, sign, broadcast flow
- SwapTracker floating bubble + SwapHistoryDialog for tracking
- swap-tracker polls Pioneer GetPendingSwap per-txHash (avoids server route conflict with GetAllPendingSwaps)
- swap-parsing for THORChain asset/CAIP conversion
- Fail-fast: app crashes on startup if Pioneer SDK missing required methods
- UI shows 'submitted' (not 'complete') after broadcast — only complete when outbound confirmed
- EVM tx builder + cosmos tx builder swap memo support
- RPC schema + types for swap operations
- i18n swap translations
Expand SwapDialog with improved quote display, fee breakdown, and
affiliate fee handling. Add swap history persistence to SQLite with
detailed status tracking and reporting. Improve tx builders for
cosmos, UTXO, and XRP chains. Add swap-report module and EVM RPC
gas estimation support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix feeLevel falsy-zero check (use != null instead of &&)
- Add formatWei() for precision-safe bigint→string conversion
- Remove non-null assertions on params.router
- Type SwapContext.wallet with SwapWallet interface
- Add clearSwapCache() for cache invalidation
- Replace setInterval with setTimeout recursion to prevent poll stacking
- Rehydrate active swaps from SQLite on app restart
- Replace fragile SQL string concat with structured setClauses pattern
- Fix O(n²) indexOf in swap-report PDF generation
- Remove `as any` cast in SwapHistoryDialog
- Improve getErc20Decimals fallback comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant