Files
koins/apps/ios

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/                   libkoins_monero_merged.a (device + simulator arm64)
    include/                monero-cpp headers
  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

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:

xcrun simctl install <udid> /tmp/koins-dd/Build/Products/Debug-iphonesimulator/Koins.app
xcrun simctl launch <udid> com.koins.app

Re-run xcodegen generate after adding or removing source files. No CocoaPods and no Swift packages are used.

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):

xcrun simctl launch <udid> com.koins.app -koinsSelfTest
xcrun simctl spawn <udid> 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):

xcrun simctl launch <udid> 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.