Fix PlatformLinkTag.parse() off-by-one bug where tag indices were shifted
(platform/uri/entityType read from wrong positions). Add missing TagArrayExt
and EventExt files for definition and recommendation packages to align with
the modern pattern used by nip88Polls. Parameterize DiscoverNIP89FeedFilter
by targetKind and create NIP-89 poll app discovery infrastructure linking
NIP-88 polls (kind 1068) to the NIP-89 app handler discovery system.
https://claude.ai/code/session_013r2LXj11SieWa5PaLesKfC
Reviewed the samiz BLE implementation and fixed compatibility issues:
- Chunk index: changed from 2 bytes to 1 byte (matching samiz/NIP-BE example)
- Chunk overhead: 2 bytes total (1 index + 1 total count), not 3
- chunkSize parameter now means payload size (500), not total chunk size
- Android: TX power HIGH, advertise timeout indefinite (matching samiz)
- Android: request MTU 512 and CONNECTION_PRIORITY_HIGH on connect
- Android: discover services after MTU negotiation (samiz flow)
- Android: set WRITE_TYPE_DEFAULT on write characteristic
- MTU-to-chunkSize: properly accounts for ATT overhead (3) + chunk overhead (2)
These changes ensure wire-level compatibility with samiz devices.
https://claude.ai/code/session_01Tz5E73Rj7tL48A3qUGS5DT
Adds full NIP-BE implementation for BLE-based Nostr peer-to-peer
messaging and synchronization with KMP support across all targets.
Protocol layer (commonMain):
- BleConfig: NIP-BE constants (service UUID, characteristic UUIDs)
- BleMessageChunker: DEFLATE compression + chunk splitting/joining
- BleRole/assignRole: Role assignment based on UUID comparison
- BleTransport: Platform-agnostic BLE transport interface
- BleNostrClient: IRelayClient implementation over BLE
- BleNostrServer: Relay server over BLE with notification support
- BleMeshManager: High-level mesh manager with auto-discovery,
role assignment, and event broadcasting
- BleChunkAssembler: Thread-safe chunk reassembly
Platform support:
- Deflate expect/actual for jvmAndroid, apple, and linux targets
- AndroidBleTransport: Full Android BLE implementation using GATT
server/client APIs with scanning, advertising, and MTU negotiation
Tests: Deflate compression, message chunking, role assignment,
and chunk assembly (25 tests passing).
https://claude.ai/code/session_01Tz5E73Rj7tL48A3qUGS5DT
- Extract private log() helper in JVM and iOS PlatformLog to reduce
copy-paste branching
- Fix JVM formatter to be private and non-nullable
- Convert 60+ interpolated Log.w/e/i calls to lambda overloads,
including hot-path Filter.kt toJson() and LocalCache event processing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 'main' of https://github.com/vitorpamplona/amethyst:
fix: keep screen on during PiP playback and survive screen lock
feat: add RelayDiscoveryEvent renderer for feed display
feat: add OpenGraph preview to WebBookmark cards
revert: keep INostrClient/NostrClient naming and restore onEose/isLive
refactor: simplify NostrClient API for beginner-friendliness
Reverts three naming changes from the previous refactor:
- Interface stays INostrClient (not NostrClient)
- Class stays NostrClient (not DefaultNostrClient)
- onEose stays onEose (not onCaughtUp)
- isLive stays isLive (not isRealTime)
All other renames from the API simplification are preserved:
subscribe, unsubscribe, publish, count, fetchAll, fetchFirst, etc.
https://claude.ai/code/session_01JPcYCcRx5eZN4GvgGxGwbf
Change the action lambda to `suspend (EventStore) -> Unit` so callers
can use suspend functions directly. Remove the now-unnecessary
runBlocking wrapper around delay() in ExpirationTest.
https://claude.ai/code/session_01TQRzVTAXBVWRGstcsapA5F
Each EventStore uses an independent in-memory SQLite database, so tests
can safely run concurrently. This launches all 16 DB configurations in
parallel via coroutines on Dispatchers.Default instead of running them
sequentially.
https://claude.ai/code/session_01TQRzVTAXBVWRGstcsapA5F
Add full compliance with NIP-85 by implementing all four assertion event
kinds and their associated tag types in the nip85TrustedAssertions package:
- Kind 30382 (User Assertions): Add all 15 missing tag parsers and
builders (first_created_at, post_cnt, reply_cnt, reactions_cnt, all
zap/report/topic/active_hours tags) to ContactCardEvent
- Kind 30383 (Event Assertions): New EventAssertionEvent with rank,
comment_cnt, quote_cnt, repost_cnt, reaction_cnt, zap_cnt, zap_amount
- Kind 30384 (Addressable Event Assertions): New
AddressableAssertionEvent with same tags as 30383
- Kind 30385 (External ID Assertions): New ExternalIdAssertionEvent
with rank, comment_cnt, reaction_cnt
- Add ProviderTypes for all new assertion kinds (30383/30384/30385)
- Register all new event kinds in EventFactory
- Add comprehensive tests for all assertion event types
https://claude.ai/code/session_01XZQsSnkHJ6tFiPS7fRLzPJ
- Add KindTag to LnZapRequestEvent.create() when zapping events, as required
by NIP-A4 ("NIP-57 zaps MUST include the k tag to 24")
- Enforce e tag prohibition in all PublicMessageEvent.build() methods by
stripping any e tags from the tag builder output (NIP-A4: "e tags must not
be used")
- Add comprehensive tests for both changes
https://claude.ai/code/session_019JsSsTTXivnNWiAtE5DE1R
NIP-24 defines an optional birthday object with year, month, and day
fields for kind 0 metadata events. This was the only NIP-24 field
missing from Quartz's UserMetadata model.
https://claude.ai/code/session_01Sbj2DF5XDtEuDCeJ7yR6oS
Add kind 1985 LabelEvent with L (namespace) and l (label) tag support
for distributed moderation, content classification, and license assignment.
Includes tag parsers, builder extensions, self-reporting helpers, and tests.
https://claude.ai/code/session_011t5ZoP1BdgZTT5Cen9GH5z
Add support for NIP-77 (Negentropy Syncing) protocol messages using
the negentropy-kmp library for efficient set reconciliation between
client and relay.
New files:
- NegOpenCmd, NegMsgCmd, NegCloseCmd: Client-to-relay commands
- NegMsgMessage, NegErrMessage: Relay-to-client messages
- NegentropySession: Client-side reconciliation orchestrator
- NegentropyServerSession: Server-side reconciliation handler
- NegentropyManager: High-level sync manager with listener callbacks
Updated serializers:
- Jackson MessageSerializer/Deserializer for NEG-MSG, NEG-ERR
- Jackson CommandSerializer/Deserializer for NEG-OPEN, NEG-MSG, NEG-CLOSE
- Kotlin MessageKSerializer/CommandKSerializer for all NIP-77 types
Compatible with strfry relay's negentropy implementation via the
negentropy-kmp library which implements the same Protocol V1 spec.
https://claude.ai/code/session_01Dc6W1G1jURAAR9kzyVvk6g
Introduces a signer decorator that automatically appends the NIP-89
client tag to every event before signing, ensuring all events carry
client identification without modifying individual event creation sites.
Works transparently with internal, external (NIP-55), and remote (NIP-46) signers.
https://claude.ai/code/session_01WRtuk1ySCfqXzfFrieKsDs
Tests the StringIndexOutOfBoundsException fix in Url.getPart() by directly
constructing Url objects with UrlMarker indices that exceed the trimmed
originalUrl length — the exact scenario that occurs when readEnd() strips
a trailing character (e.g. ':') while the PORT/QUERY marker still points
to the original buffer position.
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
Tests cover the StringIndexOutOfBoundsException in Url.getPart() that
occurred when readEnd() trimmed trailing characters (e.g. ':') from a
detected URL but urlMarker indices remained pointing past the trimmed
string's end.
- UrlMarkerTest: three cases testing PORT/QUERY index at or beyond
string length (the boundary conditions fixed by minOf clamping and
the startIndex >= length guard)
- UrlsDetectorTest: regression for "今北産業" (no crash, 0 URLs) and
for a bare "example.com:" host
- UrlParserTest: end-to-end regression for "今北産業" and "example.com:"
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2