TZGyn 357f707180 move tx detail caching into sync engine, cache during history sync
- new sync-tx-details.ts: extracts tx+receipt caching from get-details.ts
- sync-tx-history: calls syncTxDetails per transfer hash during sync
- get-details: remove on-the-fly viem fetch + DB write (now handled
  by sync); returns null placeholder
- index: import syncTxDetails; simplify getTransactionDetails handler
2026-05-22 10:18:33 +08:00
2026-05-09 15:27:01 +08:00
2026-05-09 15:27:01 +08:00
2026-05-09 15:27:01 +08:00
2026-05-09 15:27:01 +08:00
2026-05-20 14:31:10 +08:00

Koins

Multi-chain desktop wallet for Ethereum, BSC, Polygon, and Monero. Built with Bun + Electrobun + Svelte.

Features

  • Multi-coin mode: ETH, BSC, Polygon wallet with seed phrase vault stored in system keychain
  • Monero mode: Self-contained Monero wallet — auto-downloads monero-wallet-rpc binary on first launch, no manual binary install
  • Touch ID unlock: Biometric auth via Swift helper, no node-gyp or FFI dylib
  • Password fallback: PBKDF2-salted password stored in keychain, used when biometric is unavailable
  • QR codes: Address QR with chain logo overlay
  • Transaction history: Cached in local SQLite via Drizzle ORM
  • Settings: Reset app clears all DB tables and keychain entries

Prerequisites

Getting Started

bun install
cd apps/desktop
bun run dev

Architecture

apps/desktop/
├── src/
│   ├── bun/                    # Backend (Electrobun main process)
│   │   ├── index.ts            # RPC handlers
│   │   ├── lib/
│   │   │   ├── monero/         # Monero RPC management
│   │   │   │   ├── binary.ts   # Download/extract monero-wallet-rpc
│   │   │   │   └── wallet.ts   # Child process + RPC client
│   │   │   ├── alchemy/        # Alchemy API calls
│   │   │   ├── viem/           # viem chain calls
│   │   │   ├── tokens/         # Token metadata (DB-first cache)
│   │   │   ├── transactions/   # Tx history + details (DB-first cache)
│   │   │   ├── db/             # Drizzle ORM + SQLite schema
│   │   │   └── biometric.ts    # Biometric auth (Swift subprocess)
│   │   └── native/
│   │       └── biometric-helper.swift  # Touch ID prompt binary
│   ├── lib/
│   │   ├── states/
│   │   │   └── wallet.svelte.ts        # Wallet state (singleton)
│   │   ├── components/
│   │   │   └── EvmDashboard.svelte     # Shared EVM dashboard
│   │   └── electrobun.ts               # RPC type definitions
│   └── routes/
│       ├── index.svelte       # Login/welcome page
│       ├── multicoin/         # ETH / BSC / Polygon routes
│       ├── monero/            # Monero dashboard
│       ├── settings.svelte    # App settings
│       └── tx/                # Transaction details
└── package.json

Key Decisions

  • Monero via RPC, not WASM: monero-ts's WASM wallet (MoneroWalletFull) doesn't work in Bun because the C++ HTTP client fails at runtime. Instead, monero-wallet-rpc runs as a child process.
  • SQLite cache: All chain data (tx history, receipts, token metadata) cached in SQLite via Drizzle, not localStorage.
  • Biometric auth: Uses a Swift binary spawned via Bun.spawnSync() (not dlopen — Bun crashes on ObjC runtime; not node-mac-auth — fragile node-gyp chain).
  • Separate account types: EVM and Monero are separate account types with their own seed formats and auth flows.

Dependencies

Scripts

bun run dev       # Start development server
bun run db:push   # Push Drizzle schema to SQLite
S
Description
No description provided
Readme
46 MiB
v0.0.12
Latest
2026-08-04 14:19:25 +00:00
Languages
C++ 57%
Svelte 18.8%
Swift 13.6%
TypeScript 7.7%
Objective-C++ 1.3%
Other 1.5%