# Koins iOS Native SwiftUI wallet for Monero and XRP. iOS only, no JavaScript runtime. ## Layout ``` Koins/ KoinsApp.swift App entry point AppModel.swift Observable state, orchestrates both chains Models.swift Chain / wallet / transaction models SelfTest.swift Launch-time verification (see below) Bridge/ Koins-Bridging-Header.h KoinsMoneroWallet.h/.mm ObjC++ bridge to the monero-cpp wallet KoinsSecp256k1.h/.mm secp256k1 via the OpenSSL bundled in the monero lib Monero/ libs/ prebuilt monero archives (simulator + device) include/ monero-cpp headers toolchain/ how those archives are built, plus the depends patches Support/ Base58, RIPEMD-160, hashing, Keychain, wallet store Wallet/ XRP keys, binary codec, RPC client, services Views/ SwiftUI screens ``` ## How the chains are implemented - **Monero**: the wallet runs on device through `libkoins_monero_merged.a` (monero-project `wallet2` + monero-cpp, built for `aarch64-apple-ios` and the arm64 simulator). `KoinsMoneroWallet` serialises all C++ work on a private queue and exchanges JSON with Swift. Wallet files live in the app's Documents directory; the recovery seed is stored in the Keychain. - **XRP**: implemented directly in Swift, no third-party package. - Recovery phrase: a 12 word BIP-39 mnemonic, derived to the standard XRP account path `m/44'/144'/0'/0/0` (BIP-32, secp256k1), so the same words restore the same account in hardware and other mobile wallets. - Imports also accept legacy XRP family seeds (`sEd…` / `s…`), including the Ed25519 and secp256k1 variants. - Key derivation and signing: Ed25519 via CryptoKit and secp256k1 via the OpenSSL build embedded in the monero static library. - Transaction serialization: canonical XRP binary encoding plus the `STX`/`TXN` hash prefixes, matching `ripple-binary-codec`. - Network: JSON-RPC against public XRP Ledger endpoints with failover. ## Build ```sh cd apps/ios xcodegen generate xcodebuild -project Koins.xcodeproj -scheme Koins -configuration Debug \ -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' \ ARCHS=arm64 ONLY_ACTIVE_ARCH=NO -derivedDataPath /tmp/koins-dd build ``` Install and run on a booted simulator: ```sh xcrun simctl install /tmp/koins-dd/Build/Products/Debug-iphonesimulator/Koins.app xcrun simctl launch com.koins.app ``` Re-run `xcodegen generate` after adding or removing source files. No CocoaPods and no Swift packages are used. The same commands work for a device: pass `-sdk iphoneos -destination 'generic/platform=iOS'` and Xcode links the device Monero archive automatically. ## Verification The XRP implementation is checked against vectors produced by the reference JavaScript stack (`xrpl`, `ripple-keypairs`, `ripple-binary-codec`). Cryptography and serialization (no network): ```sh xcrun simctl launch com.koins.app -koinsSelfTest xcrun simctl spawn log show --last 1m --predicate 'subsystem == "com.koins.app"' --style compact ``` Live network check (creates and then removes a temporary wallet on both chains, talks to a Monero daemon and the XRP Ledger): ```sh xcrun simctl launch com.koins.app -koinsSelfTestNetwork ``` ## Notes - The Monero daemon default is `xmr-node.cakewallet.com:18081` with two fallbacks; `MoneroService` reconnects on demand. - Ed25519 and OpenSSL ECDSA both use randomised nonces, so signatures are valid but not byte-identical to deterministic implementations such as `ripple-keypairs`. Signatures are verified rather than compared. - Refresh the simulator build when `/tmp` is cleared: the intermediate build products live in `/tmp/koins-dd`.