Zeus Research Frontier
Open problems where Zeus can advance the state of the art in self-custodial Lightning wallets, plus the standards for claiming anything publicly. Four directions below are maintainer-endorsed (2026-07-06); everything labeled candidate or open is discovery output, not endorsed roadmap.
When to use / When NOT to use
Use this skill when:
- Deciding what research or frontier work to pick up next in this repo.
- Picking up a stalled thread named here (LSPS7 refund UI,
bip-321 branch, payLightningInvoiceStreaming, android-16kb-page-size, NUT-15 upstreaming).
- Writing anything external-facing that makes a claim about Zeus (novelty, "first", benchmarks, privacy properties).
- Evaluating whether a feature idea is genuinely novel vs. already known in the ecosystem.
Do NOT use this skill for:
- How to turn a hunch into an accepted change (evidence bar, idea lifecycle) → zeus-research-methodology.
- Concrete analysis recipes (race analysis, dispatch audits, migration proofs) → zeus-proof-and-analysis-toolkit.
- The node-lifecycle-races problem specifically → zeus-node-lifecycle-campaign (it has its own executable campaign).
- Backend capability mechanics and adding an RPC → zeus-backends-and-capabilities.
- Storage/migration changes (several steps below touch defaults or persisted data — those are gated) → zeus-storage-and-migrations and zeus-change-control.
- Domain theory (what BOLT12/LSPS/Cashu are in depth) → zeus-lightning-reference. This skill defines terms only enough to scope the work.
Glossary (first-use definitions)
| Term |
Meaning here |
| LSP |
Lightning Service Provider — a well-connected node that sells inbound capacity (channels) to wallets |
| LSPS1 / LSPS7 |
Interop specs for buying channels from an LSP (LSPS1) and extending a channel lease (LSPS7) |
| JIT channel |
"Just-in-time" channel an LSP opens while a payment is in flight, so a fresh wallet can receive |
| BOLT11 / BOLT12 |
Lightning invoice formats; BOLT12 "offers" are static, reusable payment codes |
| NWC |
Nostr Wallet Connect (NIP-47) — remote-control a wallet over nostr relays |
| Cashu / ecash / NUT-15 |
Chaumian ecash protocol; a "mint" is its custodian; NUT-15 = paying one invoice from multiple mints via MPP |
| MPP |
Multi-part payment — one invoice paid in several HTLC shards |
| CLINK / noffer |
Nostr-based payment negotiation (noffer1… bech32 codes, kind-21001 events) |
| BIP-321 |
Successor to BIP-21 bitcoin: payment URIs (unified on-chain + Lightning QR) |
| hodl invoice / preimage |
Invoice whose settlement is deferred until a chosen secret (preimage) is released — lets a third party hold payments for an offline wallet |
| Tor / .onion |
Anonymity network / its hidden-service addresses; Zeus embeds Tor via react-native-nitro-tor |
| Embedded node |
A full Lightning node compiled into the app: embedded-lnd (Go, gomobile) or ldk-node (Rust, uniffi) |
| supports*() |
Per-backend capability flags in backends/*.ts, dispatched through utils/BackendUtils.ts — the gate for every feature |
Direction 1 — Self-custodial UX parity (zero-config receive, background payments, swaps)
Why current SOTA fails. Custodial wallets receive instantly with zero setup and work while the app is closed. Self-custodial mobile wallets need inbound liquidity (a channel) before first receive, and the node is offline whenever the OS suspends the app — so unattended receive/pay is unreliable. No shipping wallet has closed both gaps without custody.
Zeus's specific assets.
- Two embedded node engines behind one UI:
embedded-lnd (gomobile AAR/xcframework) and ldk-node (uniffi FFI, ZeusLN fork v0.7.0-zeus-pathfinder-config per fetch-libraries-versions.json).
- A three-generation LSP stack in
stores/LSPStore.ts: Olympus Flow 2.0 REST (default https://0conf.lnolymp.us, JIT invoice wrapping via jit_bolt11), LSPS1 over three transports (custom message type 37913, REST, native — chosen per backend via supportsLSPScustomMessage / supportsLSPS1rest / supportsLSPS1native), and LSPS7 lease extension (supportsLSPS7native, currently true only on backends/LdkNode.ts).
- ZEUS Pay lightning address (
stores/LightningAddressStore.ts) with three receive modes — zaplocker, cashu, nwc — giving offline receive without custody of keys.
- Boltz-protocol swaps (
stores/SwapStore.ts, default host https://swaps.zeuslsp.com/api/v2 defined in stores/SettingsStore.ts) with deterministic rescue keys (DERIVATION_PATH = 'm/44/0/0/0').
First three concrete steps in this repo.
- Finish LSPS7. The refund-address UI in
views/LSPS7/index.tsx is disabled behind {false && ( with the comment TODO add conditions for refund onchain address (search: grep -n "false && (" views/LSPS7/index.tsx). Note state.refundOnchainAddress is ALREADY plumbed into both LSPS7 order paths (stores/LSPStore.ts lines ~1174 and ~1207); because the input is fenced, the value is always ''. The remaining work is defining when the LSP requires a refund address and enabling the fenced input block — not re-implementing the wiring.
- Measure NWC background delivery before changing it.
stores/NostrWalletConnectStore.ts (3232 lines, zero tests) runs the wallet-service side; iOS keep-alive is a background-audio hack (ios/zeus/NWCAudioKeepAlive.m + bundled ambient .m4a files in ios/zeus/), Android uses a persistent foreground service gated by the AsyncStorage flag persistentNWCServicesEnabled (constant NWC_PERSISTENT_SERVICE_ENABLED in the store). Build a delivery-success-rate harness (N payment attempts against a backgrounded device, per platform, per keep-alive mode) so improvements are measurable. Measurement recipes: zeus-diagnostics-and-tooling.
- Map the fresh-install receive funnel. Instrument the path from new embedded wallet → first receive:
views/Wallet/Wallet.tsx post-connect LSP init (getLSPInfo, initChannelAcceptor), Flow JIT wrapping in stores/LSPStore.ts (note: wrapping mutates the invoice amount by subtracting the zero-conf fee and silently degrades to unwrapped on failure), and views/Receive.tsx. Record where users stall and what fees they pay.
You have a result when: a fresh install on both platforms receives a Lightning payment within a bounded time (pick and publish the bound, e.g. 5 minutes) with zero manual channel-management screens, and the measured all-in fee vs. a custodial baseline is documented. Falsified if any step requires the user to understand channels, or if background NWC payment delivery stays below the published target rate.
Direction 2 — Protocol leadership (BOLT12, Cashu NUT-15, CLINK, BIP-321)
Why current SOTA fails. BOLT12 offers barely exist on mobile: receiving to an offer needs an online node with blinded-path support, so most wallets ship nothing. Multimint ecash payments (NUT-15) are unimplemented in mainstream client libraries. Unified payment URIs (BIP-321) are stalled ecosystem-wide.
Zeus's specific assets. Offers already work on two backends — supportsOffers() is true only in backends/CLNRest.ts and backends/LdkNode.ts (verify: grep -rn supportsOffers backends/); Zeus maintains its own ldk-node fork; the Cashu integration is CDK-FFI-based with a working NUT-15 client that CDK itself lacks.
Concrete threads, file-level.
- BOLT12 beyond cln-rest/ldk-node. LDK Node cannot persist offers —
listOffers in backends/LdkNode.ts hard-returns { offers: [] } with the comment "LDK Node doesn't store offers natively". Local offer persistence (per-node, keychain- or SQLite-backed) is the missing piece for real offer management on the embedded backend. Any persisted-key addition is a gated storage change → zeus-storage-and-migrations.
- Cashu multimint NUT-15 — upstream or standardize.
stores/CashuStore.ts queryMeltQuoteMpp bypasses CDK entirely, POSTing raw {mint}/v1/melt/quote/bolt11 with options.mpp, then classifying rejections (classifyMppRejection). CDK is pinned at 0.14.2 (fetch-libraries-versions.json). Either upstream multimint melt to CDK (removing the bypass) or publish the probe/rejection-classification approach as a client-interop note.
- CLINK/noffer.
utils/ClinkUtils.ts: noffer1… bech32 TLV, CLINK_KIND = 21001, NIP-44 encryption, and a hard ONION_NOT_SUPPORTED error (no .onion relay support — overlaps Direction 4).
- BIP-321 pickup. Local branch
bip-321 (one commit 3c1210922, 2025-08-20, unmerged: git branch --list bip-321; diff vs master touches views/Receive.tsx, utils/AmountUtils.ts + test, stores/InvoicesStore.ts). Concrete pickup: rebase onto current master and re-test the receive flow.
payLightningInvoiceStreaming — resolve the dead dispatch. Declared in utils/BackendUtils.ts but implemented by NO backend (verify: grep -rn payLightningInvoiceStreaming backends/ utils/ — only BackendUtils hits). Because missing methods return sync false (see Direction 3), every call would silently no-op. Decide: delete the wrapper, or implement streaming payment progress on the LND family. This is a design decision to surface to the maintainer, not a drive-by fix — payment-path changes must be minimal diffs (zeus-change-control).
First three steps: (1) rebase and revive bip-321; (2) write the maintainer proposal for payLightningInvoiceStreaming (delete vs. implement, with call-site evidence); (3) open the CDK upstream issue for multimint melt with Zeus's queryMeltQuoteMpp as the reference client.
You have a result when: (a) a mainnet BOLT12 offer created on an embedded ldk-node wallet survives app restart and receives a payment from a third-party wallet, or (b) the NUT-15 bypass is deleted because an upstream CDK release covers it, or (c) BIP-321 receive ships and a third-party wallet parses the QR. Each is binary and externally checkable.
Direction 3 — Multi-backend robustness (the 7-backend matrix, crash-free)
Why current SOTA fails. No other wallet drives 7 heterogeneous backends (embedded-lnd, ldk-node, lnd, lightning-node-connect, cln-rest, lndhub, nostr-wallet-connect) behind one UI. The cost is silent capability drift: BackendUtils.call() returns synchronous false when the active backend lacks a method (utils/BackendUtils.ts: if (!cls[funcName]) return false;), so a typo'd or unimplemented dispatch never throws — it no-ops, and false.then(...) crashes at the call site. Missing supports* gates are historically the top cross-backend crash source.
Zeus's specific assets. The supports* capability system already exists: 55 distinct supports* flags dispatched through utils/BackendUtils.ts (count: grep -o 'supports[A-Za-z0-9]*' utils/BackendUtils.ts | sort -u | wc -l), including composites like supportsLightningAddress = supportsCustomPreimages() || supportsCashuWallet() computed in the dispatcher itself.
First three concrete steps in this repo.
- Dispatch-completeness audit tooling. Mechanically enumerate every wrapper in
utils/BackendUtils.ts, check which of the 7 backend classes implement it, and flag call sites lacking a supports* guard. Known true-positive the tool must catch: payLightningInvoiceStreaming (zero implementers); known cosmetic finding: backends/NostrWalletConnect.ts declares supportsLSPS1customMessage (typo — the dispatched name is supportsLSPScustomMessage; harmless only because both resolve to false). The audit recipe with worked examples lives in zeus-proof-and-analysis-toolkit — build the runnable version there, not here.
- Store test scaffolding. There are zero tests under
stores/ today — all 49 test files live in utils/ (45), models/ (2), lndmobile/ (1), plus root check-styles.test.ts (verify: ls stores/*.test.ts → no matches). Start with a keychain-mocking harness for SettingsStore (everything depends on it), then the dispatch-heavy stores. Jest ESM/transform traps → zeus-validation-and-qa.
- Typed dispatcher (candidate design, not started). Replace the stringly
call(funcName: string) with a typed interface over the backend classes so a missing implementation is a compile error, and absence must be expressed as an explicit capability. This changes payment-path plumbing — proposal first, minimal diff, maintainer sign-off (zeus-change-control).
You have a result when: the audit tool runs in CI and reports zero dispatched methods that are both unimplemented on some backend AND unguarded by supports* at every call site — and adding a new unguarded wrapper fails the build. Falsified if the tool exists but the matrix still produces a missing-method crash in release testing.
Direction 4 — Privacy leadership (Tor gaps, TLS defaults, ecash, stealth)
Why current SOTA fails. "Tor support" in wallets is usually partial: some code paths route through Tor, others silently leak to clearnet, and users can't tell the difference. Zeus is closest to full Tor-by-default among self-custodial wallets but has verified gaps.
Verified gaps in this repo (2026-07-06).
| Gap |
Evidence |
Verify |
| WebSocket streams bypass Tor entirely |
backends/LND.ts constructs new WebSocket(url, …) directly in 4 places; only the REST path goes through doTorRequest |
grep -n "new WebSocket" backends/LND.ts |
| .onion LNURL params unfetchable |
3 identical // TODO handle fetching of params with internal Tor sites |
grep -rn "internal Tor" utils/ components/ → utils/handleAnything.ts, components/LayerBalances/LightningSwipeableRow.tsx, components/LayerBalances/EcashSwipeableRow.tsx |
| TLS verification OFF by default |
@observable certVerification: boolean = false in stores/SettingsStore.ts; passed as trusty: !certVerification to react-native-blob-util |
grep -n "certVerification: boolean = " stores/SettingsStore.ts |
| CLINK refuses .onion relays |
ONION_NOT_SUPPORTED error in utils/ClinkUtils.ts |
grep -n ONION_NOT_SUPPORTED utils/ClinkUtils.ts |
Zeus's specific assets. Embedded Tor (react-native-nitro-tor 0.6.0 in package.json); the hardened Tor TLS rule (cert bypass only for HTTPS .onion — the invariant and its incident history belong to zeus-failure-archaeology FA-5); Android Stealth Mode (three disabled-by-default activity-alias app disguises — calculator, VPN, QR scanner — in android/app/src/main/AndroidManifest.xml); an ecash small-balance model already wired (settings.ecash defaults in stores/SettingsStore.ts: enableCashu: false, enableMultiMint: false, automaticallySweep: false, sweepThresholdSats: 10000 — ecash holds small change, auto-sweeps to Lightning above threshold).
First three concrete steps in this repo.
- Close the .onion LNURL gap: implement Tor fetching of LNURL params at the 3 TODO sites using
utils/TorUtils.ts (doTorRequest), respecting the .onion-HTTPS-only TLS rule.
- Route or fence the WebSocket gap: either proxy
backends/LND.ts WS streams through the embedded Tor SOCKS layer, or make the UI state explicitly that streaming falls back to clearnet when Tor is enabled — today it leaks silently.
certVerification default-flip campaign: flipping the default to true for existing users is a settings-default change requiring a MOD_KEY migration and maintainer sign-off — scope the breakage first (self-signed home-node certs are the common case), design the migration + UX (pin-on-first-use?), and route through zeus-storage-and-migrations + zeus-change-control. Do not just flip the initializer.
You have a result when: with Tor enabled, a full send+receive+stream session on a device under packet capture shows zero clearnet connections (WS included), and the LNURL flows work against a .onion service. Falsified by a single observed clearnet packet.
Candidate infrastructure problems (discovery output — NOT maintainer-endorsed roadmap)
| Problem |
Status |
Evidence / verify |
Supply-chain hash gaps in fetch-libraries.sh |
candidate |
CDK and zeus-cashu-restore SHA256 checks are conditional: [ -n "$CDK_ANDROID_SHA256" ] etc. — an empty hash field in fetch-libraries-versions.json silently skips verification (all four hashes ARE currently populated: cat fetch-libraries-versions.json). Worse: the uniffi binding SOURCE downloads (CashuDevKit.swift, zeus_cashu_restore.swift/.kt — grep -n curl fetch-libraries.sh) have no checksum at all. Fix = pin binding-source hashes + fail on empty hash. Maintainer intent unknown (open question: deliberate dev escape hatch?). |
android-16kb-page-size branch |
open/stalled |
Single commit fa2212457 (2025-10-10), touches 3 gradle files, unmerged; android/check_elf_alignment.sh exists in master but no build script invokes it (grep -rn check_elf_alignment --include='*.gradle' --include='*.yml' . → no hits). Google Play's 16 KB page-size requirement makes this time-sensitive — check current Play policy before scoping. |
| Test coverage for the 5 largest untested stores |
candidate (feeds Direction 3 step 2) |
wc -l stores/*.ts | sort -rn | head: CashuStore.ts 5591, NostrWalletConnectStore.ts 3232, SettingsStore.ts 2248, LightningAddressStore.ts 1486, LSPStore.ts 1330 — all with zero tests. |
External positioning: novelty claims and proof obligations
Three things in Zeus are candidates for genuine novelty. For each, the proof obligation before ANY public "first"/"only" claim:
| Candidate claim |
What's actually in the repo |
Known prior art to check |
Proof obligation before claiming |
| Self-custodial lightning address at scale (ZEUS Pay zaplocker mode) |
stores/LightningAddressStore.ts: 250 pre-generated preimages, schnorr-signed hash submission to zeuspay.com, redemption by creating an invoice with a fixed preimage, nostr kind-55869 attestations (>1 attestation per hash = fraud signal). Requires supportsCustomPreimages() (true on LND family only). |
The Zaplocker scheme itself is supertestnet's prior work — Zeus's contribution is the production implementation + attestation-based fraud detection, NOT the scheme |
Prior-art survey vs. Zaplocker repo and any LSP-held-invoice services; then claim "production deployment of" not "invention of" |
| Multimint NUT-15 MPP melt (pay one invoice from multiple mints) |
stores/CashuStore.ts queryMeltQuoteMpp + per-mint NUT-15 probing and rejection classification, bypassing CDK |
NUT-15 is specified; nutshell implements the mint side. Survey client wallets (Minibits, eNuts, cashu-ts consumers) for client-side multi-mint orchestration before claiming first |
Working mainnet demo across ≥2 public mints, reproducible by a third party from a tagged release |
| NWC as a full wallet backend (not just a service) |
backends/NostrWalletConnect.ts is one of the 7 dispatched backends; Zeus is simultaneously an NWC wallet-service (stores/NostrWalletConnectStore.ts) |
Alby Go and others are NWC-native clients — "NWC as one of N interchangeable backends" is the defensible framing, plain "NWC client" is not novel |
Comparative table vs. named wallets, dated |
Standing proof obligations for ANY published claim:
- Prior-art survey artifact — dated, named projects checked, kept with the claim. No survey → no novelty claim.
- Third-party reproducibility — the demo must work from a public tagged release, on mainnet where applicable, without Zeus-internal infrastructure knowledge.
- Verifiable builds — Android releases are reproducible via
./build.sh (Docker image pinned by sha256 digest, SOURCE_DATE_EPOCH=0; procedure in docs/ReproducibleBuilds.md — Android only, there is no iOS reproducibility story; don't imply one). Releases/commits are PGP-signed — key fingerprint 96C225207F2137E278C31CF7AAC48DE8AB8DEE84 (long ID AAC48DE8AB8DEE84, PGP.txt).
- AGPLv3 obligations (see
LICENSE): derivative works and network-served modifications must publish source. Any published benchmark/claim about Zeus must be checkable from the public repo.
- No-oversell rule: "Zeus supports X" is only claimable when a
supports* gate returns true on at least one shipping backend AND the feature passed the maintainer's mandatory hands-on iOS+Android testing. Benchmarks ship with methodology. Disabled code ({false && ...}), stalled branches, and dead dispatches are never "supported" — they are "in progress" at most. When in doubt, the framing standard is Bitcoin-Core-style conservatism: understate, link evidence.
Provenance and maintenance
Facts verified 2026-07-06 against master c5fd094fb (v13.1.3-alpha) by direct file reads and read-only commands in this repo. Maintainer endorsement of the four directions dated 2026-07-06. Expensive claims (build reproducibility procedure) verified by source read of build.sh/docs/ReproducibleBuilds.md, not executed.
Re-verify volatile facts before relying on them:
| Fact |
Re-verify with |
| LSPS7 refund UI still disabled |
grep -n "false && (" views/LSPS7/index.tsx |
payLightningInvoiceStreaming still unimplemented |
grep -rn payLightningInvoiceStreaming backends/ utils/ (backends/ hits = implemented) |
| Offers backends (cln-rest, ldk-node only) |
grep -rn "supportsOffers" backends/ |
| LDK Node offers not persisted |
grep -n -A2 "listOffers" backends/LdkNode.ts |
| NUT-15 CDK bypass still present |
grep -n "v1/melt/quote/bolt11" stores/CashuStore.ts |
| CDK / ldk-node / lnd pinned versions |
cat fetch-libraries-versions.json |
| Empty-hash skip + unchecked binding downloads |
grep -n 'SHA256" ]' fetch-libraries.sh; grep -n curl fetch-libraries.sh |
| Stalled branches exist |
git branch --list | grep -E 'bip-321|16kb' |
| Zero store tests |
ls stores/*.test.ts (expect: no matches) |
| Largest untested stores |
wc -l stores/*.ts | sort -rn | head -6 |
certVerification default |
grep -n "certVerification: boolean = " stores/SettingsStore.ts |
| WS-bypasses-Tor |
grep -n "new WebSocket" backends/LND.ts |
| .onion LNURL TODO count (3) |
grep -rn "internal Tor" utils/ components/ |
| ecash defaults (enableCashu false, sweep 10000) |
grep -n -A4 "ecash: {" stores/SettingsStore.ts |
| CLINK kind 21001 / onion unsupported |
grep -n "CLINK_KIND|ONION_NOT_SUPPORTED" utils/ClinkUtils.ts |
| supports* flag count (55) |
grep -o 'supports[A-Za-z0-9]*' utils/BackendUtils.ts | sort -u | wc -l |
| NWC typo flag |
grep -n supportsLSPS1customMessage backends/NostrWalletConnect.ts |
| nitro-tor version (0.6.0) |
grep -n nitro-tor package.json |
| PGP key fingerprint |
gpg --show-keys PGP.txt |
| Zaplocker constants (250 preimages, kind 55869, zeuspay.com) |
grep -n "i < 250|55869|zeuspay.com" stores/LightningAddressStore.ts |
| Stealth aliases disabled by default |
grep -n -A2 activity-alias android/app/src/main/AndroidManifest.xml |
| Reproducible-build pins |
head -12 build.sh |
1---2name: zeus-research-frontier3description: Load when the task is choosing or scoping research/roadmap work on Zeus — "what should we build next", "where can Zeus advance the state of the art", "is this feature/scheme novel", "can we claim X publicly", picking up stalled work (bip-321, android-16kb-page-size, LSPS7 refund UI, payLightningInvoiceStreaming), or writing external-facing claims (blog posts, release notes, conference talks, comparisons with other wallets). Covers the four maintainer-endorsed research directions (self-custodial UX parity, protocol leadership, multi-backend robustness, privacy leadership), candidate infrastructure problems, and the proof/reproducibility standards required before any public novelty claim.4---56# Zeus Research Frontier78Open problems where Zeus can advance the state of the art in self-custodial Lightning wallets, plus the standards for claiming anything publicly. Four directions below are maintainer-endorsed (2026-07-06); everything labeled **candidate** or **open** is discovery output, not endorsed roadmap.910## When to use / When NOT to use1112**Use this skill when:**13- Deciding what research or frontier work to pick up next in this repo.14- Picking up a stalled thread named here (LSPS7 refund UI, `bip-321` branch, `payLightningInvoiceStreaming`, `android-16kb-page-size`, NUT-15 upstreaming).15- Writing anything external-facing that makes a claim about Zeus (novelty, "first", benchmarks, privacy properties).16- Evaluating whether a feature idea is genuinely novel vs. already known in the ecosystem.1718**Do NOT use this skill for:**19- *How* to turn a hunch into an accepted change (evidence bar, idea lifecycle) → **zeus-research-methodology**.20- Concrete analysis recipes (race analysis, dispatch audits, migration proofs) → **zeus-proof-and-analysis-toolkit**.21- The node-lifecycle-races problem specifically → **zeus-node-lifecycle-campaign** (it has its own executable campaign).22- Backend capability mechanics and adding an RPC → **zeus-backends-and-capabilities**.23- Storage/migration changes (several steps below touch defaults or persisted data — those are gated) → **zeus-storage-and-migrations** and **zeus-change-control**.24- Domain theory (what BOLT12/LSPS/Cashu *are* in depth) → **zeus-lightning-reference**. This skill defines terms only enough to scope the work.2526## Glossary (first-use definitions)2728| Term | Meaning here |29|---|---|30| LSP | Lightning Service Provider — a well-connected node that sells inbound capacity (channels) to wallets |31| LSPS1 / LSPS7 | Interop specs for buying channels from an LSP (LSPS1) and extending a channel lease (LSPS7) |32| JIT channel | "Just-in-time" channel an LSP opens while a payment is in flight, so a fresh wallet can receive |33| BOLT11 / BOLT12 | Lightning invoice formats; BOLT12 "offers" are static, reusable payment codes |34| NWC | Nostr Wallet Connect (NIP-47) — remote-control a wallet over nostr relays |35| Cashu / ecash / NUT-15 | Chaumian ecash protocol; a "mint" is its custodian; NUT-15 = paying one invoice from multiple mints via MPP |36| MPP | Multi-part payment — one invoice paid in several HTLC shards |37| CLINK / noffer | Nostr-based payment negotiation (`noffer1…` bech32 codes, kind-21001 events) |38| BIP-321 | Successor to BIP-21 `bitcoin:` payment URIs (unified on-chain + Lightning QR) |39| hodl invoice / preimage | Invoice whose settlement is deferred until a chosen secret (preimage) is released — lets a third party hold payments for an offline wallet |40| Tor / .onion | Anonymity network / its hidden-service addresses; Zeus embeds Tor via `react-native-nitro-tor` |41| Embedded node | A full Lightning node compiled into the app: `embedded-lnd` (Go, gomobile) or `ldk-node` (Rust, uniffi) |42| supports\*() | Per-backend capability flags in `backends/*.ts`, dispatched through `utils/BackendUtils.ts` — the gate for every feature |4344---4546## Direction 1 — Self-custodial UX parity (zero-config receive, background payments, swaps)4748**Why current SOTA fails.** Custodial wallets receive instantly with zero setup and work while the app is closed. Self-custodial mobile wallets need inbound liquidity (a channel) before first receive, and the node is offline whenever the OS suspends the app — so unattended receive/pay is unreliable. No shipping wallet has closed both gaps without custody.4950**Zeus's specific assets.**51- Two embedded node engines behind one UI: `embedded-lnd` (gomobile AAR/xcframework) and `ldk-node` (uniffi FFI, ZeusLN fork `v0.7.0-zeus-pathfinder-config` per `fetch-libraries-versions.json`).52- A three-generation LSP stack in `stores/LSPStore.ts`: Olympus Flow 2.0 REST (default `https://0conf.lnolymp.us`, JIT invoice wrapping via `jit_bolt11`), LSPS1 over three transports (custom message type `37913`, REST, native — chosen per backend via `supportsLSPScustomMessage` / `supportsLSPS1rest` / `supportsLSPS1native`), and LSPS7 lease extension (`supportsLSPS7native`, currently `true` only on `backends/LdkNode.ts`).53- ZEUS Pay lightning address (`stores/LightningAddressStore.ts`) with three receive modes — `zaplocker`, `cashu`, `nwc` — giving offline receive without custody of keys.54- Boltz-protocol swaps (`stores/SwapStore.ts`, default host `https://swaps.zeuslsp.com/api/v2` defined in `stores/SettingsStore.ts`) with deterministic rescue keys (`DERIVATION_PATH = 'm/44/0/0/0'`).5556**First three concrete steps in this repo.**571. **Finish LSPS7.** The refund-address UI in `views/LSPS7/index.tsx` is disabled behind `{false && (` with the comment `TODO add conditions for refund onchain address` (search: `grep -n "false && (" views/LSPS7/index.tsx`). Note `state.refundOnchainAddress` is ALREADY plumbed into both LSPS7 order paths (`stores/LSPStore.ts` lines ~1174 and ~1207); because the input is fenced, the value is always `''`. The remaining work is defining when the LSP requires a refund address and enabling the fenced input block — not re-implementing the wiring.582. **Measure NWC background delivery before changing it.** `stores/NostrWalletConnectStore.ts` (3232 lines, zero tests) runs the wallet-service side; iOS keep-alive is a background-audio hack (`ios/zeus/NWCAudioKeepAlive.m` + bundled ambient `.m4a` files in `ios/zeus/`), Android uses a persistent foreground service gated by the AsyncStorage flag `persistentNWCServicesEnabled` (constant `NWC_PERSISTENT_SERVICE_ENABLED` in the store). Build a delivery-success-rate harness (N payment attempts against a backgrounded device, per platform, per keep-alive mode) so improvements are measurable. Measurement recipes: **zeus-diagnostics-and-tooling**.593. **Map the fresh-install receive funnel.** Instrument the path from new embedded wallet → first receive: `views/Wallet/Wallet.tsx` post-connect LSP init (`getLSPInfo`, `initChannelAcceptor`), Flow JIT wrapping in `stores/LSPStore.ts` (note: wrapping mutates the invoice amount by subtracting the zero-conf fee and silently degrades to unwrapped on failure), and `views/Receive.tsx`. Record where users stall and what fees they pay.6061**You have a result when:** a fresh install on both platforms receives a Lightning payment within a bounded time (pick and publish the bound, e.g. 5 minutes) with zero manual channel-management screens, and the measured all-in fee vs. a custodial baseline is documented. Falsified if any step requires the user to understand channels, or if background NWC payment delivery stays below the published target rate.6263---6465## Direction 2 — Protocol leadership (BOLT12, Cashu NUT-15, CLINK, BIP-321)6667**Why current SOTA fails.** BOLT12 offers barely exist on mobile: receiving to an offer needs an online node with blinded-path support, so most wallets ship nothing. Multimint ecash payments (NUT-15) are unimplemented in mainstream client libraries. Unified payment URIs (BIP-321) are stalled ecosystem-wide.6869**Zeus's specific assets.** Offers already work on two backends — `supportsOffers()` is `true` only in `backends/CLNRest.ts` and `backends/LdkNode.ts` (verify: `grep -rn supportsOffers backends/`); Zeus maintains its own ldk-node fork; the Cashu integration is CDK-FFI-based with a working NUT-15 client that CDK itself lacks.7071**Concrete threads, file-level.**72- **BOLT12 beyond cln-rest/ldk-node.** LDK Node cannot persist offers — `listOffers` in `backends/LdkNode.ts` hard-returns `{ offers: [] }` with the comment "LDK Node doesn't store offers natively". Local offer persistence (per-node, keychain- or SQLite-backed) is the missing piece for real offer management on the embedded backend. Any persisted-key addition is a gated storage change → **zeus-storage-and-migrations**.73- **Cashu multimint NUT-15 — upstream or standardize.** `stores/CashuStore.ts` `queryMeltQuoteMpp` bypasses CDK entirely, POSTing raw `{mint}/v1/melt/quote/bolt11` with `options.mpp`, then classifying rejections (`classifyMppRejection`). CDK is pinned at `0.14.2` (`fetch-libraries-versions.json`). Either upstream multimint melt to CDK (removing the bypass) or publish the probe/rejection-classification approach as a client-interop note.74- **CLINK/noffer.** `utils/ClinkUtils.ts`: `noffer1…` bech32 TLV, `CLINK_KIND = 21001`, NIP-44 encryption, and a hard `ONION_NOT_SUPPORTED` error (no .onion relay support — overlaps Direction 4).75- **BIP-321 pickup.** Local branch `bip-321` (one commit `3c1210922`, 2025-08-20, unmerged: `git branch --list bip-321`; diff vs master touches `views/Receive.tsx`, `utils/AmountUtils.ts` + test, `stores/InvoicesStore.ts`). Concrete pickup: rebase onto current master and re-test the receive flow.76- **`payLightningInvoiceStreaming` — resolve the dead dispatch.** Declared in `utils/BackendUtils.ts` but implemented by NO backend (verify: `grep -rn payLightningInvoiceStreaming backends/ utils/` — only BackendUtils hits). Because missing methods return sync `false` (see Direction 3), every call would silently no-op. Decide: delete the wrapper, or implement streaming payment progress on the LND family. This is a design decision to surface to the maintainer, not a drive-by fix — payment-path changes must be minimal diffs (**zeus-change-control**).7778**First three steps:** (1) rebase and revive `bip-321`; (2) write the maintainer proposal for `payLightningInvoiceStreaming` (delete vs. implement, with call-site evidence); (3) open the CDK upstream issue for multimint melt with Zeus's `queryMeltQuoteMpp` as the reference client.7980**You have a result when:** (a) a mainnet BOLT12 offer created on an embedded ldk-node wallet survives app restart and receives a payment from a third-party wallet, or (b) the NUT-15 bypass is deleted because an upstream CDK release covers it, or (c) BIP-321 receive ships and a third-party wallet parses the QR. Each is binary and externally checkable.8182---8384## Direction 3 — Multi-backend robustness (the 7-backend matrix, crash-free)8586**Why current SOTA fails.** No other wallet drives 7 heterogeneous backends (`embedded-lnd`, `ldk-node`, `lnd`, `lightning-node-connect`, `cln-rest`, `lndhub`, `nostr-wallet-connect`) behind one UI. The cost is silent capability drift: `BackendUtils.call()` returns **synchronous `false`** when the active backend lacks a method (`utils/BackendUtils.ts`: `if (!cls[funcName]) return false;`), so a typo'd or unimplemented dispatch never throws — it no-ops, and `false.then(...)` crashes at the call site. Missing `supports*` gates are historically the top cross-backend crash source.8788**Zeus's specific assets.** The `supports*` capability system already exists: 55 distinct `supports*` flags dispatched through `utils/BackendUtils.ts` (count: `grep -o 'supports[A-Za-z0-9]*' utils/BackendUtils.ts | sort -u | wc -l`), including composites like `supportsLightningAddress = supportsCustomPreimages() || supportsCashuWallet()` computed in the dispatcher itself.8990**First three concrete steps in this repo.**911. **Dispatch-completeness audit tooling.** Mechanically enumerate every wrapper in `utils/BackendUtils.ts`, check which of the 7 backend classes implement it, and flag call sites lacking a `supports*` guard. Known true-positive the tool must catch: `payLightningInvoiceStreaming` (zero implementers); known cosmetic finding: `backends/NostrWalletConnect.ts` declares `supportsLSPS1customMessage` (typo — the dispatched name is `supportsLSPScustomMessage`; harmless only because both resolve to `false`). The audit recipe with worked examples lives in **zeus-proof-and-analysis-toolkit** — build the runnable version there, not here.922. **Store test scaffolding.** There are zero tests under `stores/` today — all 49 test files live in `utils/` (45), `models/` (2), `lndmobile/` (1), plus root `check-styles.test.ts` (verify: `ls stores/*.test.ts` → no matches). Start with a keychain-mocking harness for `SettingsStore` (everything depends on it), then the dispatch-heavy stores. Jest ESM/transform traps → **zeus-validation-and-qa**.933. **Typed dispatcher (candidate design, not started).** Replace the stringly `call(funcName: string)` with a typed interface over the backend classes so a missing implementation is a compile error, and absence must be expressed as an explicit capability. This changes payment-path plumbing — proposal first, minimal diff, maintainer sign-off (**zeus-change-control**).9495**You have a result when:** the audit tool runs in CI and reports zero dispatched methods that are both unimplemented on some backend AND unguarded by `supports*` at every call site — and adding a new unguarded wrapper fails the build. Falsified if the tool exists but the matrix still produces a missing-method crash in release testing.9697---9899## Direction 4 — Privacy leadership (Tor gaps, TLS defaults, ecash, stealth)100101**Why current SOTA fails.** "Tor support" in wallets is usually partial: some code paths route through Tor, others silently leak to clearnet, and users can't tell the difference. Zeus is closest to full Tor-by-default among self-custodial wallets but has verified gaps.102103**Verified gaps in this repo (2026-07-06).**104| Gap | Evidence | Verify |105|---|---|---|106| WebSocket streams bypass Tor entirely | `backends/LND.ts` constructs `new WebSocket(url, …)` directly in 4 places; only the REST path goes through `doTorRequest` | `grep -n "new WebSocket" backends/LND.ts` |107| .onion LNURL params unfetchable | 3 identical `// TODO handle fetching of params with internal Tor` sites | `grep -rn "internal Tor" utils/ components/` → `utils/handleAnything.ts`, `components/LayerBalances/LightningSwipeableRow.tsx`, `components/LayerBalances/EcashSwipeableRow.tsx` |108| TLS verification OFF by default | `@observable certVerification: boolean = false` in `stores/SettingsStore.ts`; passed as `trusty: !certVerification` to react-native-blob-util | `grep -n "certVerification: boolean = " stores/SettingsStore.ts` |109| CLINK refuses .onion relays | `ONION_NOT_SUPPORTED` error in `utils/ClinkUtils.ts` | `grep -n ONION_NOT_SUPPORTED utils/ClinkUtils.ts` |110111**Zeus's specific assets.** Embedded Tor (`react-native-nitro-tor` `0.6.0` in `package.json`); the hardened Tor TLS rule (cert bypass only for HTTPS .onion — the invariant and its incident history belong to **zeus-failure-archaeology** FA-5); Android Stealth Mode (three disabled-by-default `activity-alias` app disguises — calculator, VPN, QR scanner — in `android/app/src/main/AndroidManifest.xml`); an ecash small-balance model already wired (`settings.ecash` defaults in `stores/SettingsStore.ts`: `enableCashu: false`, `enableMultiMint: false`, `automaticallySweep: false`, `sweepThresholdSats: 10000` — ecash holds small change, auto-sweeps to Lightning above threshold).112113**First three concrete steps in this repo.**1141. **Close the .onion LNURL gap:** implement Tor fetching of LNURL params at the 3 TODO sites using `utils/TorUtils.ts` (`doTorRequest`), respecting the .onion-HTTPS-only TLS rule.1152. **Route or fence the WebSocket gap:** either proxy `backends/LND.ts` WS streams through the embedded Tor SOCKS layer, or make the UI state explicitly that streaming falls back to clearnet when Tor is enabled — today it leaks silently.1163. **`certVerification` default-flip campaign:** flipping the default to `true` for existing users is a settings-default change requiring a MOD_KEY migration and maintainer sign-off — scope the breakage first (self-signed home-node certs are the common case), design the migration + UX (pin-on-first-use?), and route through **zeus-storage-and-migrations** + **zeus-change-control**. Do not just flip the initializer.117118**You have a result when:** with Tor enabled, a full send+receive+stream session on a device under packet capture shows zero clearnet connections (WS included), and the LNURL flows work against a .onion service. Falsified by a single observed clearnet packet.119120---121122## Candidate infrastructure problems (discovery output — NOT maintainer-endorsed roadmap)123124| Problem | Status | Evidence / verify |125|---|---|---|126| Supply-chain hash gaps in `fetch-libraries.sh` | **candidate** | CDK and zeus-cashu-restore SHA256 checks are conditional: `[ -n "$CDK_ANDROID_SHA256" ]` etc. — an empty hash field in `fetch-libraries-versions.json` silently skips verification (all four hashes ARE currently populated: `cat fetch-libraries-versions.json`). Worse: the uniffi binding SOURCE downloads (`CashuDevKit.swift`, `zeus_cashu_restore.swift`/`.kt` — `grep -n curl fetch-libraries.sh`) have no checksum at all. Fix = pin binding-source hashes + fail on empty hash. Maintainer intent unknown (open question: deliberate dev escape hatch?). |127| `android-16kb-page-size` branch | **open/stalled** | Single commit `fa2212457` (2025-10-10), touches 3 gradle files, unmerged; `android/check_elf_alignment.sh` exists in master but no build script invokes it (`grep -rn check_elf_alignment --include='*.gradle' --include='*.yml' .` → no hits). Google Play's 16 KB page-size requirement makes this time-sensitive — check current Play policy before scoping. |128| Test coverage for the 5 largest untested stores | **candidate** (feeds Direction 3 step 2) | `wc -l stores/*.ts \| sort -rn \| head`: `CashuStore.ts` 5591, `NostrWalletConnectStore.ts` 3232, `SettingsStore.ts` 2248, `LightningAddressStore.ts` 1486, `LSPStore.ts` 1330 — all with zero tests. |129130---131132## External positioning: novelty claims and proof obligations133134Three things in Zeus are *candidates* for genuine novelty. For each, the proof obligation before ANY public "first"/"only" claim:135136| Candidate claim | What's actually in the repo | Known prior art to check | Proof obligation before claiming |137|---|---|---|---|138| Self-custodial lightning address at scale (ZEUS Pay zaplocker mode) | `stores/LightningAddressStore.ts`: 250 pre-generated preimages, schnorr-signed hash submission to `zeuspay.com`, redemption by creating an invoice with a fixed preimage, nostr kind-`55869` attestations (>1 attestation per hash = fraud signal). Requires `supportsCustomPreimages()` (true on LND family only). | The Zaplocker scheme itself is supertestnet's prior work — Zeus's contribution is the production implementation + attestation-based fraud detection, NOT the scheme | Prior-art survey vs. Zaplocker repo and any LSP-held-invoice services; then claim "production deployment of" not "invention of" |139| Multimint NUT-15 MPP melt (pay one invoice from multiple mints) | `stores/CashuStore.ts` `queryMeltQuoteMpp` + per-mint NUT-15 probing and rejection classification, bypassing CDK | NUT-15 is specified; nutshell implements the mint side. Survey client wallets (Minibits, eNuts, cashu-ts consumers) for client-side multi-mint orchestration before claiming first | Working mainnet demo across ≥2 public mints, reproducible by a third party from a tagged release |140| NWC as a full wallet backend (not just a service) | `backends/NostrWalletConnect.ts` is one of the 7 dispatched backends; Zeus is simultaneously an NWC wallet-service (`stores/NostrWalletConnectStore.ts`) | Alby Go and others are NWC-native clients — "NWC as one of N interchangeable backends" is the defensible framing, plain "NWC client" is not novel | Comparative table vs. named wallets, dated |141142**Standing proof obligations for ANY published claim:**1431. **Prior-art survey artifact** — dated, named projects checked, kept with the claim. No survey → no novelty claim.1442. **Third-party reproducibility** — the demo must work from a public tagged release, on mainnet where applicable, without Zeus-internal infrastructure knowledge.1453. **Verifiable builds** — Android releases are reproducible via `./build.sh` (Docker image pinned by sha256 digest, `SOURCE_DATE_EPOCH=0`; procedure in `docs/ReproducibleBuilds.md` — **Android only, there is no iOS reproducibility story**; don't imply one). Releases/commits are PGP-signed — key fingerprint `96C225207F2137E278C31CF7AAC48DE8AB8DEE84` (long ID `AAC48DE8AB8DEE84`, `PGP.txt`).1464. **AGPLv3 obligations** (see `LICENSE`): derivative works and network-served modifications must publish source. Any published benchmark/claim about Zeus must be checkable from the public repo.1475. **No-oversell rule:** "Zeus supports X" is only claimable when a `supports*` gate returns `true` on at least one shipping backend AND the feature passed the maintainer's mandatory hands-on iOS+Android testing. Benchmarks ship with methodology. Disabled code (`{false && ...}`), stalled branches, and dead dispatches are never "supported" — they are "in progress" at most. When in doubt, the framing standard is Bitcoin-Core-style conservatism: understate, link evidence.148149---150151## Provenance and maintenance152153Facts verified 2026-07-06 against master `c5fd094fb` (v13.1.3-alpha) by direct file reads and read-only commands in this repo. Maintainer endorsement of the four directions dated 2026-07-06. Expensive claims (build reproducibility procedure) verified by source read of `build.sh`/`docs/ReproducibleBuilds.md`, not executed.154155Re-verify volatile facts before relying on them:156157| Fact | Re-verify with |158|---|---|159| LSPS7 refund UI still disabled | `grep -n "false && (" views/LSPS7/index.tsx` |160| `payLightningInvoiceStreaming` still unimplemented | `grep -rn payLightningInvoiceStreaming backends/ utils/` (backends/ hits = implemented) |161| Offers backends (cln-rest, ldk-node only) | `grep -rn "supportsOffers" backends/` |162| LDK Node offers not persisted | `grep -n -A2 "listOffers" backends/LdkNode.ts` |163| NUT-15 CDK bypass still present | `grep -n "v1/melt/quote/bolt11" stores/CashuStore.ts` |164| CDK / ldk-node / lnd pinned versions | `cat fetch-libraries-versions.json` |165| Empty-hash skip + unchecked binding downloads | `grep -n 'SHA256" ]' fetch-libraries.sh; grep -n curl fetch-libraries.sh` |166| Stalled branches exist | `git branch --list \| grep -E 'bip-321\|16kb'` |167| Zero store tests | `ls stores/*.test.ts` (expect: no matches) |168| Largest untested stores | `wc -l stores/*.ts \| sort -rn \| head -6` |169| `certVerification` default | `grep -n "certVerification: boolean = " stores/SettingsStore.ts` |170| WS-bypasses-Tor | `grep -n "new WebSocket" backends/LND.ts` |171| .onion LNURL TODO count (3) | `grep -rn "internal Tor" utils/ components/` |172| ecash defaults (enableCashu false, sweep 10000) | `grep -n -A4 "ecash: {" stores/SettingsStore.ts` |173| CLINK kind 21001 / onion unsupported | `grep -n "CLINK_KIND\|ONION_NOT_SUPPORTED" utils/ClinkUtils.ts` |174| supports\* flag count (55) | `grep -o 'supports[A-Za-z0-9]*' utils/BackendUtils.ts \| sort -u \| wc -l` |175| NWC typo flag | `grep -n supportsLSPS1customMessage backends/NostrWalletConnect.ts` |176| nitro-tor version (0.6.0) | `grep -n nitro-tor package.json` |177| PGP key fingerprint | `gpg --show-keys PGP.txt` |178| Zaplocker constants (250 preimages, kind 55869, zeuspay.com) | `grep -n "i < 250\|55869\|zeuspay.com" stores/LightningAddressStore.ts` |179| Stealth aliases disabled by default | `grep -n -A2 activity-alias android/app/src/main/AndroidManifest.xml` |180| Reproducible-build pins | `head -12 build.sh` |