Skip to content

Commit ed20a3d

Browse files
committed
Align DarkFi pin to tip and migrate FFI off SQLCipher overlay.
Track upstream master a76639f0 with turso/aegis256 wallet APIs, drop the unused SQLCipher link path, and refresh vendor/build docs for TestFlight readiness.
1 parent db99ccd commit ed20a3d

24 files changed

Lines changed: 1568 additions & 436 deletions

artifacts/darkirc/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ artifacts/darkirc/armeabi-v7a/darkirc_exec
1010

1111
## How to populate
1212

13-
Cross-compile from DarkFi locally (see **`scripts/build-darkirc-android.sh`**) — it installs into **`artifacts/darkirc/`**.
13+
```bash
14+
./scripts/vendor-darkfi.sh
15+
./scripts/build-darkirc-android.sh
16+
```
1417

15-
The script vendors pinned DarkFi (`scripts/vendor-darkfi.sh`), stages **`artifacts/sqlcipher/<abi>/`** static libs into upstream `bin/darkirc/sqlcipher/` (upstream Android linker expects `libsqlite3.a`), and builds **arm64-v8a** + **x86_64** (emulator). Run **`scripts/build-sqlcipher-android.sh`** first if SQLCipher artifacts are missing.
18+
Tip DarkFi `darkirc` uses sled-overlay (no SQLCipher staging). The script builds
19+
**arm64-v8a** + **x86_64** into this directory.
1620

1721
CI should run that script (or unzip a secured build artifact here) **before** `./gradlew :app:assemble*`.
1822

artifacts/sqlcipher/README.md

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,11 @@
1-
# SQLCipher for Android NDK
1+
# SQLCipher for Android NDK (legacy)
22

3-
`drk` links **`rusqlite`** with the **`sqlcipher`** feature. Android cross-compiles fail with `unable to find library -lsqlcipher` until per-ABI static libraries are installed here:
3+
**Not required** for tip UniFFI / `drk` / `darkirc` builds. Upstream wallet storage is
4+
turso + experimental aegis256; tip `darkirc` uses sled-overlay only.
45

5-
```
6-
artifacts/sqlcipher/arm64-v8a/libsqlcipher.a
7-
artifacts/sqlcipher/arm64-v8a/libcrypto.a
8-
artifacts/sqlcipher/armeabi-v7a/libsqlcipher.a
9-
artifacts/sqlcipher/armeabi-v7a/libcrypto.a
10-
11-
```
6+
This tree and `scripts/build-sqlcipher-android.sh` remain only for experimental or
7+
out-of-tree work that still links `rusqlite` with the `sqlcipher` feature (e.g.
8+
historical darkirc Android notes in upstream README).
129

13-
Build both with:
14-
15-
```bash
16-
./scripts/build-sqlcipher-android.sh
17-
```
18-
19-
The script cross-compiles **OpenSSL `libcrypto.a`** per ABI (SQLCipher’s codec backend), then **`ndk-build`** for `libsqlcipher.a` with `-DSQLCIPHER_CRYPTO_OPENSSL`.
20-
21-
`rust/darkfi-mobile-ffi/build.rs` links `sqlcipher` and `crypto` when those files exist.
22-
23-
If a previous run failed with `openssl/crypto.h not found`, remove the stale tree and rebuild:
24-
25-
```bash
26-
rm -rf .build/sqlcipher-android
27-
./scripts/build-sqlcipher-android.sh
28-
```
10+
Moonshine’s CLI wallet keeps its own SQLCipher dependency in the `moonshine`
11+
repo and does not use these artifacts.

darkfi-android-sdk/src/main/java/com/nighthawkapps/lib/android/sdk/wallet/DrkWalletPassStore.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import java.io.File
1616
import java.security.SecureRandom
1717

1818
/**
19-
* SQLCipher **`wallet_pass`** for future **`Drk::new`**. Generated once per install and stored in
20-
* secure datastore (not derived from the seed — upstream expects an independent passphrase).
19+
* Independent **`wallet_pass`** for **`Drk::new`** (turso/aegis256 key material).
20+
* Generated once per install and stored in secure datastore (not derived from the seed).
2121
*/
2222
internal object DrkWalletPassStore {
2323
private const val PREFS_FILE = "darkfi_wallet_secure.preferences_pb"

docs/alpha-testnet-connection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This documents how Nighthawk connects to the **DarkFi alpha testnet** (App **0.3
77
| Layer | Daemon | What it does | Default testnet port |
88
|-------|--------|--------------|----------------------|
99
| **Chain / P2P** | `darkfid` | Syncs blocks from the network; serves JSON-RPC to wallets | P2P **18340** (clearnet `tcp+tls`), RPC **18345** |
10-
| **Wallet** | `drk` (in APK via UniFFI) | Local SQLCipher wallet; scans blocks via `darkfid` JSON-RPC | Connects to **18345** |
10+
| **Wallet** | `drk` (in APK via UniFFI) | Local turso/aegis256 wallet; scans blocks via `darkfid` JSON-RPC | Connects to **18345** |
1111

1212
Nighthawk embeds **`drk`** via UniFFI and can embed **`darkfid`** (packaged `darkfid_exec`) like upstream expects an external fullnode on loopback **18345**. Without the binary, run `darkfid` elsewhere or use **`adb reverse`** — see below.
1313

docs/app-features.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Canonical list of **Android** capabilities for the DarkFi wallet APK (`com.night
2323
|---------|---------|---------------|
2424
| Create new wallet (BIP39-style mnemonic) || DarkFi uses **22-word** upstream mnemonic via UniFFI `generateDarkfiMnemonic` |
2525
| Restore from seed phrase || Import path in onboarding |
26-
| Wallet encrypted at rest || Encrypted prefs + SQLCipher `wallet.db` (native `drk`) |
26+
| Wallet encrypted at rest || Encrypted prefs + turso/aegis256 `wallet.db` (native `drk`) |
2727
| PIN / app lock || PIN setup and gate |
2828
| Backup reminder / seed backup flow || Settings → backup wallet |
2929
| Birthday height (faster restore) | 🟡 | `birthdayHeight` in persist model; FFI bootstrap supports it |
@@ -136,7 +136,7 @@ Canonical list of **Android** capabilities for the DarkFi wallet APK (`com.night
136136
| `libdarkfi_mobile_ffi.so` | ✅ (build per ABI) | `darkfi_mobile_ffi` XCFramework or static lib |
137137
| UniFFI `DarkfiWalletHandle` || Same UDL → Swift |
138138
| `StubDarkfiSynchronizer` fallback || Graceful degrade without native lib |
139-
| SQLCipher-linked `drk` || Same Rust crate |
139+
| Tip `drk` (turso + aegis256) || Same Rust crate / pin |
140140
| Payment memo FFI || `payment_memo` on transfer + `transaction_payment_memo` |
141141

142142
---

docs/cache-encryption.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
# Compact-block cache encryption (P2 follow-up)
1+
# Compact-block cache encryption (P4 follow-up)
22

3-
Wallet DB uses SQLCipher. Compact-block / Merkle side caches under `cache_path`
4-
remain recoverable by full resync and are sandboxed by the OS.
3+
Wallet DB uses upstream **turso + experimental aegis256** (keyed from
4+
`wallet_pass` via `blake3`). Compact-block / Merkle side caches under
5+
`cache_path` remain recoverable by full resync and are sandboxed by the OS.
56

67
**Status:** tracked. Full at-rest encryption of `compact_blocks.db` should land
78
after upstream settles an encrypted-cache primitive (see

docs/drk-native-implementation.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ This document maps upstream **`bin/app/src/plugin/drk.rs`** and **`bin/drk`** to
77
| Upstream | Role |
88
|----------|------|
99
| [`bin/app/src/plugin/drk.rs`](https://github.com/darkrenaissance/darkfi/blob/master/bin/app/src/plugin/drk.rs) | In-process plugin: paths, `Drk::new`, scan loop, balance UI hooks |
10-
| [`bin/drk/src/lib.rs`](https://github.com/darkrenaissance/darkfi/blob/master/bin/drk/src/lib.rs) | Wallet core: SQLCipher `wallet.db`, money contracts, RPC to `darkfid` |
10+
| [`bin/drk/src/lib.rs`](https://github.com/darkrenaissance/darkfi/blob/master/bin/drk/src/lib.rs) | Wallet core: turso + aegis256 `wallet.db`, money contracts, RPC to `darkfid` |
1111
| [`bin/drk/drk_config.toml`](https://github.com/darkrenaissance/darkfi/blob/master/bin/drk/drk_config.toml) | Default endpoints / network |
1212
| [`bin/darkfid/src/rpc/`](https://github.com/darkrenaissance/darkfi/tree/master/bin/darkfid/src/rpc) | Chain JSON-RPC consumed by `drk` |
1313

14-
Pinned revision: **`docs/upstream/darkfi-revision.txt`** (currently `c4d1776` on upstream `master`, matching the vendored tree).
14+
Pinned revision: **`docs/upstream/darkfi-revision.txt`** (full tip SHA; no `bin/drk` overlay).
1515

1616
## Current Nighthawk state (this PR)
1717

1818
| Layer | Status |
1919
|-------|--------|
2020
| Kotlin **`PersistableDarkfiWallet`** | Seed, network, `DarkfiEndpoint`, optional birthday |
2121
| **`DrkWalletPaths`** | `filesDir/drk/wallet.db`, `filesDir/drk/cache` (mirrors Android plugin paths) |
22-
| **`DrkWalletPassStore`** | Random SQLCipher passphrase in encrypted prefs |
22+
| **`DrkWalletPassStore`** | Random `wallet_pass` in encrypted prefs (turso/aegis key material) |
2323
| UniFFI **`DrkBootstrapConfig`** + **`DarkfiWalletHandle::new`** | `Drk::new`, wallet/money init, mnemonic import |
2424
| **`NativeDarkfiSynchronizer`** | Probe-gated; balance, address, scan via FFI |
2525
| **`DarkfiSynchronizerFactory`** | Native when probe OK; stub fallback on open failure |
@@ -33,7 +33,8 @@ Phase 1 — Link upstream `drk` in `darkfi-mobile-ffi` — **done**
3333
4. **`DarkfiWalletHandle::new`** calls `Drk::new`, `initialize_wallet`, `initialize_money`, mnemonic key import.
3434
5. Android: `./scripts/build-darkfi-mobile-ffi-android.sh` (uses repo-local `CARGO_HOME=.cargo-home`).
3535

36-
**Android SQLCipher:** place `libsqlcipher.a` per ABI under `artifacts/sqlcipher/` (see `artifacts/sqlcipher/README.md`) or run `./scripts/build-sqlcipher-android.sh` before the NDK link step succeeds.
36+
**Wallet crypto:** tip `drk` encrypts with turso experimental `aegis256`. Wipe any
37+
pre-tip local `wallet.db` files after the pin bump (format is not SQLCipher-compatible).
3738

3839
## Phase 2 — Scan + balance (plugin parity)
3940

docs/upstream/DARKFI_PROPOSALS.md

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
# Upstream DarkFi proposals (crypto / wallet)
22

33
Nighthawk cannot land these directly in `darkrenaissance/darkfi`. This list is
4-
for upstream discussion / PRs. Local mobile clients keep a `bin/drk` SQLCipher
5-
overlay at vendor pin `ae0339804` + `bin/drk @ c4d1776` until resolved.
4+
for upstream discussion / PRs.
65

7-
## P1 — Wallet storage encryption for mobile
6+
**Client pin policy (pre-release):** Android / iOS / desktop UniFFI track tip
7+
`bin/drk` (turso + experimental aegis256). There is no SQLCipher overlay.
8+
Moonshine keeps its own SQLCipher pruned DB by design (not `drk`).
89

9-
**Problem.** Upstream replaced `drk` rusqlite/SQLCipher with turso + aegis256.
10-
Mobile wallets require SQLCipher (`PRAGMA key`) for existing threat models and
11-
App Store / Play storage expectations. Turso encryption is not SQLCipher-compatible;
12-
existing wallet DBs would not open.
10+
## P1 — Wallet storage encryption (resolved for Nighthawk UniFFI)
1311

14-
**Recommended fix.** Either:
15-
1. Restore optional `rusqlite` + `sqlcipher` feature on `bin/drk` alongside turso
16-
(feature-gated backends), or
17-
2. Document a migration path from SQLCipher → turso with explicit re-encrypt
18-
tooling and a stable KDF, then give clients time to migrate.
12+
**Status.** Adopted upstream tip: `WalletDb` uses turso with experimental
13+
`aegis256` and `hexkey = blake3(wallet_pass)`. Mobile/desktop pass the same
14+
`wallet_pass` through `Drk::new`; OS sandbox + encrypted prefs / Keychain /
15+
desktop PIN vault still protect the passphrase.
1916

20-
**Why.** Without a SQLCipher-compatible path, mobile cannot track upstream `drk`
21-
without breaking encrypted-at-rest wallets.
17+
**Residual upstream asks.**
18+
1. Stabilize turso encryption API (today marked experimental).
19+
2. Document KDF / cipher parameters as a compatibility contract for light clients.
20+
3. Optional: feature-gated SQLCipher backend only if a migration story is needed
21+
for third-party wallets that already shipped SQLCipher (Nighthawk has not).
2222

2323
## P2 — Secret zeroization in wallet key paths
2424

@@ -78,15 +78,5 @@ metadata), so light servers can reject unbound clues.
7878

7979
## P7 — Net / RPC hardening already upstream
8080

81-
Recent upstream work (bounded broadcasts, subscriber teardown, host registry
82-
retention, inbound slot leak fix) is valuable. Mobile FFI vendors should track
83-
these once the wallet-DB strategy (P1) is settled — no additional proposal
84-
beyond “keep merging net/rpc hardening”.
85-
86-
---
87-
88-
### Out of scope for upstream (stay Nighthawk-layer)
89-
90-
- UniFFI surface (`darkfi-mobile-ffi`)
91-
- UnifOMR Param2 / LWD gRPC / decoy clue directory
92-
- TLS pin policy for lightwalletd clients
81+
Track upstream net acceptor/connector and seed-address updates when bumping the
82+
client pin; no Nighthawk fork required.

docs/upstream/darkfi-revision.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
ae0339804 (master) + bin/drk overlay @ c4d1776 (rusqlite/SQLCipher for mobile)
1+
a76639f020a55473ee786deb584d603d968d4db6
2+
# darkrenaissance/darkfi master tip (2026-07-27)
3+
# Wallet: upstream bin/drk turso + experimental aegis256 (blake3(wallet_pass) hex key).
4+
# No SQLCipher overlay — nothing shipped; clients track tip threat model.

docs/verification-checklist.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Use against **standalone** `darkfi-lightwalletd` with `fhe-omr`. Tick when prove
4141
- [x] Android `useTor` follows `routeOutboundThroughTor`
4242
- [x] Android `generateDmKeypair` uses UniFFI
4343
- [x] Reorg callback wired (iOS `SDKSynchronizerLive`, Android `NativeDarkfiSynchronizer`)
44-
- [x] Docs state UnifOMR `0x05`, no pool, no SQLCipher overclaim
44+
- [x] Docs state UnifOMR `0x05`, no pool; UniFFI wallet = tip turso/aegis256 (Moonshine SQLCipher is separate)
4545
- [ ] No PII/keys/addresses/txids in **release** builds (manual log review)
4646
- [ ] Secrets only in Keychain / encrypted DataStore (manual review)
4747
- [x] Documented MVP limits accepted for ship (`doc/unifomr_mvp_limits.md`)

0 commit comments

Comments
 (0)