Background
The 2026-08-05 external security assessment raised C2 and C3:
- C2 — the fee-payer key is derivable from the credential id, which is public
- C3 — the derived secret is persisted in plaintext local storage
Both were fixed on web by deriving the fee-payer seed from a WebAuthn PRF extension output and holding it in memory / sessionStorage, cleared on lock. See docs/adr/0003-fee-payer-key-from-webauthn-prf.md.
The mobile port was never done. frontend/mobile still uses legacy fee-payer derivation, so C2 and C3 are live there.
docs/MAINNET_READINESS.md records the consequence:
Mobile — ❌ Not mainnet-safe. C2/C3 PRF fix never ported to mobile; still legacy fee-payer derivation.
→ Launch web-only on mainnet; mobile waits for the PRF port.
So this single issue is what keeps the mobile app off mainnet. It is the highest-value security work outstanding in the repo.
What to build
Bring mobile to the same derivation the web wallet uses, or — if the platform genuinely cannot — a documented equivalent with the same properties.
Key files
docs/adr/0003-fee-payer-key-from-webauthn-prf.md — the design to match
frontend/mobile/ — passkey registration/assertion and fee-payer derivation
sdk/src/ — the shared derivation, if it can be lifted rather than duplicated
The hard part, stated up front
PRF support on native passkey APIs is not guaranteed the way it is in browsers, and differs across iOS and Android and across authenticators. Establishing what is actually available on device is part of this issue, not a preliminary.
That means the first deliverable is a findings note, not code: which platforms expose PRF (or an equivalent HMAC secret), at which OS versions, and what the fallback must be when unavailable.
A fallback that quietly restores C2/C3 is not acceptable. If a device cannot derive securely, the wallet should say so and refuse mainnet rather than pretend.
Acceptance criteria
Notes
- The cross-platform key-agreement criterion is the one most likely to be missed and the most expensive to discover later.
frontend/mobile uses plain npm, not --legacy-peer-deps; the latter corrupts the lockfile. Tests run via jest-expo. The Maestro e2e job is pre-existing-red on main — not your fault, do not chase it.
- Related but separate: M3 (on-curve pubkey validation compiled out of production) is the other mainnet security blocker and is tracked on its own.
Drips Wave · Complexity: Advanced · 200 points
Required: Before submitting, join the contributor Telegram so your work can be tracked and counted toward the Stellar Wave: https://t.me/+fxHXq8f1SwlkZDBk
Background
The 2026-08-05 external security assessment raised C2 and C3:
Both were fixed on web by deriving the fee-payer seed from a WebAuthn PRF extension output and holding it in memory /
sessionStorage, cleared on lock. Seedocs/adr/0003-fee-payer-key-from-webauthn-prf.md.The mobile port was never done.
frontend/mobilestill uses legacy fee-payer derivation, so C2 and C3 are live there.docs/MAINNET_READINESS.mdrecords the consequence:So this single issue is what keeps the mobile app off mainnet. It is the highest-value security work outstanding in the repo.
What to build
Bring mobile to the same derivation the web wallet uses, or — if the platform genuinely cannot — a documented equivalent with the same properties.
Key files
docs/adr/0003-fee-payer-key-from-webauthn-prf.md— the design to matchfrontend/mobile/— passkey registration/assertion and fee-payer derivationsdk/src/— the shared derivation, if it can be lifted rather than duplicatedThe hard part, stated up front
PRF support on native passkey APIs is not guaranteed the way it is in browsers, and differs across iOS and Android and across authenticators. Establishing what is actually available on device is part of this issue, not a preliminary.
That means the first deliverable is a findings note, not code: which platforms expose PRF (or an equivalent HMAC secret), at which OS versions, and what the fallback must be when unavailable.
A fallback that quietly restores C2/C3 is not acceptable. If a device cannot derive securely, the wallet should say so and refuse mainnet rather than pretend.
Acceptance criteria
docs/recording PRF (or equivalent) availability on iOS and Android, with the OS/authenticator versions tested — including the negative resultsdocs/MAINNET_READINESS.mdupdated: the mobile row moves off "not mainnet-safe", or states precisely what still blocks itNotes
frontend/mobileuses plainnpm, not--legacy-peer-deps; the latter corrupts the lockfile. Tests run viajest-expo. The Maestro e2e job is pre-existing-red onmain— not your fault, do not chase it.Required: Before submitting, join the contributor Telegram so your work can be tracked and counted toward the Stellar Wave: https://t.me/+fxHXq8f1SwlkZDBk