mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
Quartz now lives in github.com/vitorpamplona/quartz, split into quartz-core, quartz-social, quartz-relay-client and the other quartz-* libraries, with history kept. Amethyst depends on the `quartz` umbrella artifact at a released version (1.20.0) instead of the :quartz project. - Remove the quartz/ module, jitpack.yml and the Quartz CI, release and pre-push steps; tools/unicode-nfkc moved with it. - Point every module at libs.quartz. - Move the device-test fixtures the benchmark and relayBench still read to testdata/. - NostrConnectLoginUseCase parses bunker messages with BunkerJson, which now owns NIP-46 JSON. - Repoint docs and skills at the Quartz repository; the nostr-expert scripts read a Quartz checkout (QUARTZ_REPO, default ../quartz). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ZR5ZBfhFzRiXubJc5Evyv
2.6 KiB
2.6 KiB
NIP-55 Android external signer
Another Android app (Amber, …) holds the key; Amethyst asks it through Intents
(foreground, with UI) or its ContentProvider (background, pre-approved). Android only.
Layout (nip55-android-signer/src/androidMain/kotlin/com/vitorpamplona/quartz/nip55AndroidSigner/)
api/CommandType.kt—sign_event,nip04_encrypt/decrypt,nip44_encrypt/decrypt,get_public_key,decrypt_zap_event,derive_key,sign_psbt.api/foreground/—IntentRequestManager(id → channel, launches the intent, waitsforegroundApprovalTimeout= 30 s) andintents/requests|responses|results/per command.api/background/queries/— oneContentResolverquery per command (SignQuery,Nip44EncryptQuery,LoginQuery, …).api/permission/—Permission+ its serializers (the permissions requested at login).client/—NostrSignerExternal(pubKey, packageName, contentResolver)(theNostrSigner),ExternalSignerLogin(createIntent(permissions, packageName),parseResult(intent)),IActivityLauncher(registerForegroundLauncher,unregisterForegroundLauncher,newResponse,hasForegroundActivity),IsExternalSignerInstalled.kt(isExternalSignerInstalled(context),getExternalSignersInstalled(context)),handlers/BackgroundRequestHandler+ForegroundRequestHandler.SignString.kt,JsonMapperNip55.kt.
Flow
- Login:
ExternalSignerLogin.createIntent(...)→ the signer app returns pubkey + package →parseResult(data)→NostrSignerExternal(pubKey, packageName, contentResolver). - Each call tries the background query first; if the signer has not pre-approved that command, it falls back to a foreground intent through the registered launcher.
- No registered Activity →
SignerExceptions.RunningOnBackgroundWithoutAutomaticPermissionException; no answer in 30 s →TimedOutException.
The Android entry point is
amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/login/ExternalSignerButton.kt.
Gotchas
- Without "always allow", every reaction or zap is an Activity round-trip — bad UX; ask for the permissions at login.
- Desktop has no NIP-55; it uses
NostrSignerInternalorNostrSignerRemote. - Tests, in the Quartz repository: nip55-android-signer/src/androidHostTest (JVM host) and
quartz/src/androidDeviceTest/.../nip55AndroidSigner/in its umbrella module (device/emulator only).