mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
Audit of what still reflects now that obfuscation is on. Two live defects, both
invisible in a debug build:
1. AmethystAppFunctions.requireInProcessSigner() compared
`signer::class.qualifiedName` against the fully-qualified name of
NostrSignerExternal, with a comment explaining that this avoided an import.
R8 renames that class — `NostrSignerExternal -> nbc` in the release mapping —
so the comparison never matched and the external-signer branch stopped
running the moment obfuscation was enabled. A user on Amber invoking a write
AppFunction from Gemini would fall through to the write attempt instead of
the typed "not supported here" message. It is a plain `is` check now; the
class is already imported directly by two other files in this source set.
2. The reflection contract listed AmethystCastOptionsProvider unscoped, but that
class only exists in the play flavor, and the release workflow runs the
verifier for playRelease AND fdroidRelease. Absent from a mapping reads as
"R8 deleted it", so the next release would have failed on fdroid. Measured,
not guessed: the old contract reports 2 of 21 checks failed against a real
fdroidRelease mapping. Contract lines may now open with @play / @fdroid, the
verifier derives the flavor from the mapping directory, and an unrecognised
directory still checks everything.
Also from the audit:
- Deleted 16 keep rules that matched nothing: libscrypt (com.lambdaworks),
NetCipher (info.guardianproject), LazySodium and the whole JNA block.
None of those artifacts appear in mapping.txt, usage.txt or seeds.txt —
quartz replaced libsodium with LibSodiumInstance and Tor runs through arti
now. Two of them were `-keep class * implements …` wildcards.
- Added NwcErrorCode to the contract. Its constant names are the NIP-47 wire
strings: the response parser calls NwcErrorCode.valueOf() on a string
another wallet wrote, inside a try/catch that falls back to null. The
blanket enum rule covers it today, which is exactly why it needs recording
before that rule is retired.
- Added AmethystAppFunctions (@play), so the one package keep that had no
contract line is no longer unverified.
Everything else that reflects is either a library that ships its own consumer
rules (appfunctions, kotlinx-serialization companions, WorkManager, lifecycle
ViewModel constructors, Startup, Cast, AppSearch) or names a class R8 cannot
rename: quic's JdkCertificateValidator probes the *platform* trust manager for
the 3-arg checkServerTrusted, and every setClassName() target is a
manifest-declared component that AAPT2 already generates a keep for.
Verified: 21/21 on a fresh playRelease, 19/19 + 2 skipped on fdroidRelease,
both from full assembles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEoxktEZyTrAS33vVZBiwm