91 lines
3.5 KiB
Markdown
91 lines
3.5 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/ 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
|
|
|
|
```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.
|
|
|
|
## 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`. |