The plan's first design kept public keys in a plaintext file beside
nostr-keys.dat, app-side, so that nothing touched the library. Review asked
why the key file was not simply made a credentials file with a read-only
kind, and the answer is that it should be. The upgrade -- pasting the nsec
of a key held read-only -- was the one operation spanning both files, so it
was two writes with a crash window between them and a "secret wins" rule in
merge to repair it; with one file keyed by pubkey it is a single write that
replaces {type: public} with {type: secret}. Forget collapses to one path
with it. And the advantage that paid for the two-file design was worth less
than it looked: the library commit that introduced nostr-keys.dat is
untagged, so a credentials format rides the tag that work already owes.
Phase 2 is rewritten for nostr-credentials.dat: a typed entry per pubkey in
the same envelope, renamed rather than versioned in place because an older
build's listIdentities returns on SerializationError before it publishes
anything and would list no wallets at all; a migration that reads the v1
file once and deletes it, since a frozen copy would resurrect a forgotten
key on a downgrade; and the one upgrade that still spans two files -- a
recovery phrase over a public credential -- with its order stated. The
header, Phases 3, 6, 7 and 8, the estimate and the appendix follow, where
the two-file design now sits as the rejected alternative with the reason.
One overclaim of the revision's own is corrected in it: the library does not
use a class discriminator anywhere -- its cloud payloads pick a variant by a
version field -- so the plan says the discriminator is chosen here, not
inherited.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pulled-From: curated/curated@dc8a1091d3
This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).
-
/composeApp is for code that will be shared across your Compose Multiplatform applications. It contains several subfolders:
- commonMain is for code that’s common for all targets.
- Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, the iosMain folder would be the right place for such calls. Similarly, if you want to edit the Desktop (JVM) specific part, the jvmMain folder is the appropriate location.
-
/iosApp contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.
Build and Run Android Application
To build and run the development version of the Android app, use the run configuration from the run widget in your IDE’s toolbar or build it directly from the terminal:
- on macOS/Linux
./gradlew :composeApp:assembleDebug - on Windows
.\gradlew.bat :composeApp:assembleDebug
Build and Run Desktop (JVM) Application
To build and run the development version of the desktop app, use the run configuration from the run widget in your IDE’s toolbar or run it directly from the terminal:
- on macOS/Linux
./gradlew :composeApp:run - on Windows
.\gradlew.bat :composeApp:run
Build and Run iOS Application
To build and run the development version of the iOS app, use the run configuration from the run widget in your IDE’s toolbar or open the /iosApp directory in Xcode and run it from there.
Learn more about Kotlin Multiplatform…