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-projectwallet2+ monero-cpp, built foraarch64-apple-iosand the arm64 simulator).KoinsMoneroWalletserialises 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/TXNhash prefixes, matchingripple-binary-codec. - Network: JSON-RPC against public XRP Ledger endpoints with failover.
- Recovery phrase: a 12 word BIP-39 mnemonic, derived to the standard XRP
account path
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. 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):
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:18081with two fallbacks;MoneroServicereconnects 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
/tmpis cleared: the intermediate build products live in/tmp/koins-dd.