3.5 KiB
3.5 KiB
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-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.
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.