Files

94 lines
3.8 KiB
Markdown

# 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 <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):
```sh
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):
```sh
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`.