SPB Git

spb/os-vault Public

Self-custody, multi-chain crypto wallet for macOS. One recovery phrase, six chain families, zero API keys — nothing leaves your Mac.

Swift 96% Shell 3.4% Makefile 0.6%
6.6 KB · 94 lines markdown
Rendered Raw Blame History
1<!--2  RESEARCH-MULTICHAIN.md3  OS Vault45  Author: Simon-Pierre Boucher6  Mail: contact@spboucher.ai7-->89# Multi-chain implementation research — synthesis (2026-08-05)1011Five parallel research tracks (wallet-core/architecture, Bitcoin, non-EVM12chains, EVM expansion, keyless infra), all endpoint/address claims **verified13live** during research. This file is the implementation blueprint; statuses14below reflect what is already shipped in the code.1516## Verdicts at a glance1718| Track | Verdict | Status in OS Vault |19|---|---|---|20| EVM multichain | Data-driven: 11 chains, 4 real fee models, PublicNode primary keyless RPC + failover | ✅ **Implemented** (`Network.swift`, `TransactionService.swift`) |21| Native coin send | Always `eth_estimateGas` (never 21000); OP-stack/Scroll L1 data fee via oracle | ✅ **Implemented** |22| Stablecoin matrix | Verified per-chain addresses; BNB peg = 18 decimals; USDC.e ≠ USDC by address only | ✅ **Implemented** (`Token.swift`) |23| Bitcoin | **bdk-swift 3.0.0** — only maintained macOS+SPM option; BIP-84; keyless Esplora (mempool.space) | ✅ **Implemented** (`BitcoinService.swift`, watch-only + transient signer) |24| Fiat prices | CoinGecko keyless batched (`/simple/price`, USD/CAD/EUR); DefiLlama fallback; prices-OFF mode | ✅ **Implemented** (`PriceService.swift`) |25| wallet-core (Tron/TON/XRPL signing) | Vendored at `vendor/WalletCoreSPM` (binaryTarget; duplicate Rust `_rust_eh_personality` vs bdkFFI demoted surgically in the archive — see vendor script) | ✅ **Vendored + tested** (ETH vector, Tron cross-stack, XRP/TON derive) |26| Solana | `p2p-org/solana-swift` vendored (`vendor/solana-swift` — its Boilertalk secp256k1 dep clashed with web3swift's target name; CKSecp256k1 re-backed by Web3Core); PublicNode RPC keyless; ATA rent surfaced pre-send | ✅ **Implemented** (`SolanaService.swift`, SOL + USDC, devnet default) |27| Tron | wallet-core `TransferContract`/`TransferTRC20Contract` + TronGrid keyless; energy burn estimated pre-send via `triggerconstantcontract`, fee_limit 100 TRX; Nile default (USDT `TXYZ…AeBf` verified live) | ✅ **Implemented** (`TronService.swift`) |28| TON | tonkeeper/ton-swift + toncenter (1 req/s keyless); jetton indirection; BIP-39 path m/44'/607' (Tonkeeper won't import directly — document) | ⏭ Next |29| XRPL | wallet-core signer (TrustSet + issued currencies = RLUSD); xrplcluster.com genuinely free; 1 XRP base reserve + 0.2/trustline | ⏭ Next |30| Stellar | Soneso stellar-ios-mac-sdk — best non-EVM Swift SDK, nearly free to add | ⏭ Bonus |31| History indexing | No keyless multi-chain indexer exists. Per chain: Blockscout v2 (7 EVM chains), Routescan (Avalanche/Mantle/Blast), mempool.space (BTC), else eth_getLogs incremental. BNB/Linea = optional user key | ⏭ Next |32| Fiat FX | Frankfurter (ECB, keyless, unlimited); avoid exchangerate.host (keyed now) | Covered via CoinGecko native CAD/EUR |33| Auto-update | Sparkle 2 via SPM, EdDSA + notarization, static appcast on GitHub Releases | ⏭ When distribution starts |3435## Key implementation facts (already coded)3637- **Fee models** (`Network.FeeModel`): `eip1559` · `zeroBaseFee` (BSC/BEP-226:38  price via `eth_gasPrice`) · `opStackL1Fee` (Base/OP: add39  `GasPriceOracle.getL1Fee(unsigned tx)` at `0x42…0F` to the confirm total) ·40  `scrollL1Fee` (oracle `0x5300…0002`) · `arbitrumInclusive` (estimate already41  includes L1 buffer, tip 0, use verbatim) · `lineaPinnedBase` (base pinned at42  7 wei, cost rides in the tip).43- **RPC failover** (`RPCService`): ordered keyless endpoints per chain44  (PublicNode primary — all 11 verified; official RPC fallback), sticky45  primary, 60 s demotion cooldown, node-side errors surface immediately.46  Dead/keyed providers found in research: llamarpc (521), Ankr (key now),47  1rpc (quota), polygon-rpc.com (401 intermittent).48- **Registry traps**: BNB USDT/USDC are 18 decimals (separate Token entries);49  USDC.e shares `symbol()` with native USDC on Arb/OP/Polygon (distinguish by50  address, display "USDC.e"); Arbitrum/Polygon USDT upgraded in place to USDT051  (same address/decimals — never assert symbol strings); Gnosis native xDAI is52  itself dollar-pegged.53- **Bitcoin** (`BitcoinService`): BIP-84 descriptors from the same vault54  mnemonic (BIP-84 spec vector unit-tested); watch-only persisted wallet55  (public descriptors, BDK SQLite) for sync/balance/receive with address56  rotation; sends build the PSBT on the watch wallet, then a throwaway57  in-memory signer wallet (secret descriptors re-derived from the password)58  signs and is discarded. Esplora keyless: mempool.space (+ blockstream.info59  broadcast fallback on mainnet); fees from `/api/v1/fees/recommended`.60  Default network **signet** (testnet-first), mainnet behind the switch.61- **Prices** (`PriceService`): one batched CoinGecko call for every asset ×62  USD/CAD/EUR at ≥120 s TTL (≈0.5 calls/min vs 5–15/min keyless budget);63  stale-while-revalidate JSON cache; Settings toggle removes the only64  non-blockchain egress. CoinCap and CryptoCompare are dead as keyless65  options; Binance geoblocks; Coinbase spot is the per-pair fallback.6667## wallet-core vendoring (next phase enabler)6869Upstream declined macOS SPM support (PR #3529), but the **official CocoaPods70tarball** (`TrustWalletCore-<v>.tar.xz` on GitHub releases) contains71`WalletCoreCommon.xcframework` with a `macos-arm64_x86_64` slice plus the72Swift wrappers. `scripts/vendor-walletcore.sh` automates: download → verify →73C-headers target (incl. the **security-critical `SecRandom.m`** RNG shim) →74sed module imports → local SPM package in `vendor/WalletCoreSPM`. Proven by a75local build that derived BTC/ETH/Solana/Tron/TON/XRP addresses from one76runtime mnemonic. Cost: ~33 MB binary. One library then signs every remaining77chain (Tron `TransferTRC20Contract`, TON `JettonTransfer` + wallet v5R1, XRPL78`TrustSet`/issued currencies, Solana `CreateAndTransferToken`).7980## Non-EVM priority order (stablecoin volume × cost)81821. **Solana / USDC** — cheapest build (solana-swift is macOS-native) and top83   USDC venue; pipe-cleaner for the adapter pattern.842. **Tron / USDT-TRC20** — largest USDT corridor on earth; energy-fee UX is85   the main work (estimate via `triggerconstantcontract`, `fee_limit` 100 TRX).863. **TON / USDT jetton** — jetton-wallet indirection, 1 rps toncenter queue.874. **XRPL / RLUSD + XRP** — trustline UX (one-tap TrustSet, check recipient88   `account_lines` pre-send), reserves surfaced as non-spendable.895. **Stellar / USDC** — Soneso SDK, trustlines like XRPL, nearly free to add.9091Full per-chain details (curves, derivation paths, endpoints, faucets, rate92limits, sources) live in the research transcripts; the numbers used in code93are restated in comments at their point of use.94