Commit Graph

179 Commits

Author SHA1 Message Date
Claude 6e7f6eccf1 refactor: reorganize NIP-BE into subpackages and add README
Restructured nipBEBle/ into logical subpackages:
- Root: public API surface (BleNostrMesh, BleConfig, BlePeer, BleRole)
- protocol/: wire format (BleMessageChunker, BleChunkAssembler)
- transport/: platform BLE abstraction (BleTransport, AndroidBleTransport)
- relay/: Nostr protocol over BLE (BleNostrClient, BleNostrServer, BleMeshManager)

Added README.md with quick start guide, package structure overview,
advanced usage examples, and wire protocol reference.

https://claude.ai/code/session_01Tz5E73Rj7tL48A3qUGS5DT
2026-03-30 02:23:49 +00:00
Claude 57aec95e8d fix: align NIP-BE chunk format with KoalaSat/samiz reference implementation
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
2026-03-30 02:12:52 +00:00
Claude fb78c1a4c4 feat: implement NIP-BE Nostr BLE Communications Protocol in Quartz
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
2026-03-30 01:58:26 +00:00
Vitor Pamplona 974b4fcfb8 Removing a hex scheme-less urldetector test to leave it for later. 2026-03-29 21:55:33 -04:00
Vitor Pamplona 03c692a8cf Merge pull request #2005 from davotoula/Introduce-log-level-filtering
Introduce log level filtering
2026-03-29 09:56:21 -04:00
davotoula 380026c7be optimise imports 2026-03-29 15:38:51 +02:00
davotoula 6d89de9444 refactor: simplify PlatformLog actuals and convert remaining interpolated log calls to lambdas
- 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>
2026-03-29 10:58:11 +02:00
Vitor Pamplona ff9b619d26 Merge branch 'main' of https://github.com/vitorpamplona/amethyst
* '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
2026-03-28 19:25:29 -04:00
Vitor Pamplona dbd0fe03fa Adds another test case for NIP-11 2026-03-28 18:42:04 -04:00
Claude 4be617e64a revert: keep INostrClient/NostrClient naming and restore onEose/isLive
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
2026-03-28 16:43:30 +00:00
Claude 4e2717c5c5 refactor: simplify NostrClient API for beginner-friendliness
Comprehensive rename of the NostrClient relay infrastructure to use
intuitive, self-documenting names instead of protocol-level jargon.

Interface/class renames:
- INostrClient → NostrClient (interface)
- NostrClient → DefaultNostrClient (implementation)
- IRequestListener → SubscriptionListener
- IRelayClientListener → RelayConnectionListener
- IOpenNostrRequest → SubscriptionHandle
- NostrClientStaticReq → StaticSubscription
- NostrClientDynamicReq → DynamicSubscription

Method renames:
- openReqSubscription() → subscribe()
- close(subId) → unsubscribe(subId)
- send() → publish()
- queryCount() → count()
- subscribe/unsubscribe(listener) → addConnectionListener/removeConnectionListener
- renewFilters() → syncFilters()

Callback renames:
- onEose → onCaughtUp
- isLive → isRealTime
- onStartReq → onSubscriptionStarted
- onCloseReq → onSubscriptionClosed

Extension function renames:
- query() → fetchAll()
- downloadFirstEvent() → fetchFirst()
- req() → subscribe()
- reqAsFlow() → subscribeAsFlow()
- reqUntilEoseAsFlow() → fetchAsFlow()
- sendAndWaitForResponse() → publishAndConfirm()
- queryCountSuspend() → count()
- queryCountMergedHll() → countMerged()
- reqBypassingRelayLimits() → fetchAllPages()
- updateFilter() → refresh() on SubscriptionHandle

https://claude.ai/code/session_01JPcYCcRx5eZN4GvgGxGwbf
2026-03-28 16:43:30 +00:00
Claude d299b65c8a feat: make forEachDB action suspending, remove redundant runBlocking
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
2026-03-28 16:15:23 +00:00
Claude 0889473c15 feat: parallelize BaseDBTest forEachDB using coroutines
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
2026-03-28 16:12:44 +00:00
Vitor Pamplona 4c5606cd8d Merge branch 'main' of https://github.com/vitorpamplona/amethyst
* 'main' of https://github.com/vitorpamplona/amethyst:
  feat: complete NIP-85 Trusted Assertions implementation in quartz
2026-03-28 11:51:50 -04:00
Vitor Pamplona dd2ec3f05f moves the initialization of the Secp lib to the setup of the test to make sure it doesn't affect the expiration timing tests. 2026-03-28 11:50:43 -04:00
Vitor Pamplona b51efb5caf Merge branch 'main' into claude/implement-nip-85-hBlbp 2026-03-28 11:35:19 -04:00
Claude d40dccde11 feat: complete NIP-85 Trusted Assertions implementation in quartz
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
2026-03-28 13:59:12 +00:00
Vitor Pamplona 3b15242a02 Merge pull request #1978 from vitorpamplona/claude/nip-a4-compliance-mftpU
Add NIP-A4 support: k tag in zap requests and e tag filtering
2026-03-28 09:53:15 -04:00
Claude 5db9330306 fix: update test packages after nipA4PublicMessages rename
Move test files from experimental.publicMessages to nipA4PublicMessages
to match the package rename on main.

https://claude.ai/code/session_019JsSsTTXivnNWiAtE5DE1R
2026-03-28 13:52:02 +00:00
Vitor Pamplona 3ad42d2d8b Merge pull request #1979 from vitorpamplona/claude/nip24-compliance-check-WvjhO
Add birthday field support to UserMetadata
2026-03-28 09:48:35 -04:00
Claude b465785c27 feat: NIP-A4 compliance - add k tag to zap requests and enforce e tag prohibition
- 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
2026-03-28 13:48:29 +00:00
Vitor Pamplona 9b483f903d Merge branch 'main' of https://github.com/vitorpamplona/amethyst
* 'main' of https://github.com/vitorpamplona/amethyst:
  New Crowdin translations by GitHub Action
  feat: implement NIP-32 Labeling protocol in quartz
2026-03-28 09:41:26 -04:00
Claude 46fd8c651c feat: add NIP-24 birthday field to UserMetadata
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
2026-03-28 13:30:51 +00:00
Vitor Pamplona 5d281c34d5 Moves trusted assertions out of experimental 2026-03-28 09:16:44 -04:00
Claude aa15085f40 feat: implement NIP-32 Labeling protocol in quartz
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
2026-03-28 03:57:46 +00:00
Vitor Pamplona ea8fbd4af9 Making a localhost:3030 string work correctly in the URL Detector 2026-03-27 19:34:55 -04:00
Vitor Pamplona c068fe38be Fixes tests 2026-03-27 16:36:42 -04:00
Vitor Pamplona 009b5655f9 Merge branch 'main' into claude/add-negentropy-support-PcTpR 2026-03-27 08:15:24 -04:00
Vitor Pamplona 75a8e461ad 20x Faster Rfc3986Normalizer and way less objects being created. 2026-03-26 19:04:18 -04:00
Claude 70baf55e1c feat: add NIP-77 negentropy sync support
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
2026-03-26 04:23:32 +00:00
Vitor Pamplona c903996cc2 Merge pull request #1939 from vitorpamplona/claude/nip89-client-tag-LZYhd
feat: NIP-89 client tag on all signed events
2026-03-25 15:42:31 -04:00
Vitor Pamplona fc560d2752 reuse hex methods. 2026-03-25 13:22:02 -04:00
Vitor Pamplona 0d92c86459 Merge branch 'main' into claude/remove-libsodium-dependency-DjtWa 2026-03-25 11:50:07 -04:00
Vitor Pamplona 9e9f6c3164 Completing the transition from NIP-44 architecture specific tests to commontTest 2026-03-25 11:48:37 -04:00
Vitor Pamplona d84d146981 Merge branch 'main' into claude/remove-libsodium-dependency-DjtWa 2026-03-25 11:24:55 -04:00
Vitor Pamplona 7583f7f8e1 Moves some of the nip-44 based tests to commonTest 2026-03-25 08:33:04 -04:00
Claude 36af9e2346 feat: add NIP-89 client tag to all signed events via NostrSignerWithClientTag decorator
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
2026-03-25 03:24:49 +00:00
Vitor Pamplona cef07a2460 Fixes single label domains with non ascii chars around them 2026-03-24 13:33:14 -04:00
Vitor Pamplona 514e90ff17 Fixes non http uris in the references tag 2026-03-24 09:13:48 -04:00
Claude 7ea5557828 test: fix UrlTest to use 今北産業 as the crash input (PR #1907)
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 21:02:41 +00:00
Claude 3a93c4b075 test: add UrlTest for getPart() boundary conditions fixed in PR #1907
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
2026-03-23 20:57:49 +00:00
Claude 9ebc4a1e67 style: remove trailing blank line in UrlMarkerTest
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:56:58 +00:00
Claude 9202b60dcf test: add regression tests for 今北産業 URL crash (PR #1907)
Verifies that the Japanese phrase "今北産業" does not cause a
StringIndexOutOfBoundsException in Url.getPart() and is not
detected as a URL.

https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 20:46:59 +00:00
Claude e31e3829a6 test: add regression tests for PR #1907 URL crash fix
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
2026-03-23 20:31:28 +00:00
Claude 2e1bcf3e52 style: apply spotless formatting to ChaCha20/Poly1305 sources
https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-23 17:57:31 +00:00
Claude d586a0dc25 feat: replace libsodium with pure Kotlin ChaCha20/Poly1305 implementation
Remove LazySodium/JNA/libsodium native dependencies and replace with
pure Kotlin implementations of ChaCha20, HChaCha20, XChaCha20,
Poly1305 MAC, and XChaCha20-Poly1305 AEAD. This eliminates platform-
specific native binaries while maintaining full NIP-44 compatibility.

- Add ChaCha20Core with RFC 8439 block function, IETF stream XOR,
  HChaCha20, and XChaCha20
- Add Poly1305 MAC (RFC 8439 §2.5)
- Add XChaCha20Poly1305 AEAD encrypt/decrypt
- Convert LibSodiumInstance from expect/actual to commonMain object
- Delete platform-specific LibSodiumInstance actuals (android/jvm/ios)
- Remove iOS native interop (cinterop, linker opts, .a libraries)
- Remove lazysodium-java, lazysodium-android, JNA from build deps
- Clean up ProGuard rules (remove JNA/LazySodium keep rules)
- Add RFC 8439 + libsodium test vectors for ChaCha20 and XChaCha20
- Update benchmark to use simplified ChaCha20 API

https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-23 17:40:29 +00:00
Vitor Pamplona ed3390f64a Fixes weird import 2026-03-23 10:16:59 -04:00
Vitor Pamplona 439b392aa0 Moves EmptyNostrClient to a class to avoid auto-import issues 2026-03-22 15:14:49 -04:00
Vitor Pamplona cfead47d71 Improves design of the policy 2026-03-21 13:21:21 -04:00
Claude b0a8cae194 refactor: extract AuthPolicy interface from requireAuth boolean
Replace the requireAuth: Boolean parameter in NostrServer with a
pluggable AuthPolicy interface. Each policy has trigger points for
EVENT (acceptEvent), REQ (acceptReq with filter rewriting), COUNT
(acceptCount), and live event delivery (canSendToSession).

Built-in policies: OpenPolicy (allow all) and RequireAuthPolicy
(require auth for all commands, matching the previous behavior).

https://claude.ai/code/session_017vdjbdxdYK1oJMH66koVZE
2026-03-20 22:40:18 +00:00