From 199764fd5ec6898ad2911cce1957bd418384af80 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sun, 12 Oct 2025 02:06:38 +0100 Subject: [PATCH 1/2] chore(version): bump to 1.0.1-SNAPSHOT across all modules --- .github/workflows/release.yml | 9 + QODANA_TODOS.md | 526 ++++++++++++++++++ docs/README.md | 1 + docs/howto/configure-release-secrets.md | 49 ++ nostr-java-api/pom.xml | 2 +- .../src/main/java/nostr/api/EventNostr.java | 7 +- .../src/main/java/nostr/api/NIP01.java | 5 +- .../src/main/java/nostr/api/NIP02.java | 3 +- .../src/main/java/nostr/api/NIP04.java | 9 +- .../src/main/java/nostr/api/NIP05.java | 11 +- .../src/main/java/nostr/api/NIP09.java | 46 +- .../src/main/java/nostr/api/NIP12.java | 5 +- .../src/main/java/nostr/api/NIP14.java | 3 +- .../src/main/java/nostr/api/NIP15.java | 3 +- .../src/main/java/nostr/api/NIP23.java | 3 +- .../src/main/java/nostr/api/NIP25.java | 7 +- .../src/main/java/nostr/api/NIP28.java | 12 +- .../src/main/java/nostr/api/NIP42.java | 5 +- .../src/main/java/nostr/api/NIP44.java | 5 +- .../src/main/java/nostr/api/NIP46.java | 44 +- .../src/main/java/nostr/api/NIP52.java | 21 +- .../src/main/java/nostr/api/NIP57.java | 3 +- .../src/main/java/nostr/api/NIP60.java | 37 +- .../src/main/java/nostr/api/NIP61.java | 9 +- .../src/main/java/nostr/api/NIP65.java | 7 +- .../src/main/java/nostr/api/NIP99.java | 21 +- .../src/main/java/nostr/api/NostrIF.java | 9 +- .../nostr/api/NostrSpringWebSocketClient.java | 19 +- .../nostr/api/WebSocketClientHandler.java | 17 +- .../api/client/NostrEventDispatcher.java | 17 +- .../nostr/api/client/NostrRelayRegistry.java | 15 +- .../api/client/NostrRequestDispatcher.java | 8 +- .../api/client/NostrSubscriptionManager.java | 7 +- .../client/WebSocketClientHandlerFactory.java | 3 +- .../java/nostr/api/factory/EventFactory.java | 5 +- .../api/factory/impl/BaseTagFactory.java | 9 +- .../api/factory/impl/EventMessageFactory.java | 3 +- .../api/factory/impl/GenericEventFactory.java | 5 +- .../nostr/api/nip01/NIP01EventBuilder.java | 3 +- .../nostr/api/nip01/NIP01MessageFactory.java | 5 +- .../java/nostr/api/nip01/NIP01TagFactory.java | 12 +- .../java/nostr/api/nip57/NIP57TagFactory.java | 5 +- .../api/nip57/NIP57ZapReceiptBuilder.java | 6 +- .../api/nip57/NIP57ZapRequestBuilder.java | 13 +- .../nostr/api/nip57/ZapRequestParameters.java | 3 +- .../java/nostr/api/service/NoteService.java | 5 +- .../api/service/impl/DefaultNoteService.java | 9 +- .../src/main/java/nostr/config/Constants.java | 10 +- .../main/java/nostr/config/RelayConfig.java | 16 +- .../java/nostr/config/RelaysProperties.java | 3 +- .../test/java/nostr/api/NIP46RequestTest.java | 24 + .../java/nostr/api/TestHandlerFactory.java | 7 +- .../api/TestableWebSocketClientHandler.java | 7 +- ...strRequestDispatcherEnsureClientsTest.java | 14 +- .../client/NostrRequestDispatcherTest.java | 18 +- ...SpringWebSocketClientCloseLoggingTest.java | 23 +- ...WebSocketClientHandlerIntegrationTest.java | 20 +- ...NostrSpringWebSocketClientLoggingTest.java | 8 +- .../NostrSpringWebSocketClientRelaysTest.java | 7 +- ...ngWebSocketClientSubscribeLoggingTest.java | 23 +- .../NostrSubscriptionManagerCloseTest.java | 15 +- .../WebSocketHandlerCloseIdempotentTest.java | 19 +- .../WebSocketHandlerCloseSequencingTest.java | 20 +- .../WebSocketHandlerRequestErrorTest.java | 19 +- .../WebSocketHandlerSendCloseFrameTest.java | 17 +- .../WebSocketHandlerSendRequestTest.java | 21 +- .../nostr/api/integration/ApiEventIT.java | 33 +- ...EventTestUsingSpringWebSocketClientIT.java | 17 +- .../api/integration/ApiNIP52EventIT.java | 13 +- .../api/integration/ApiNIP52RequestIT.java | 15 +- .../api/integration/ApiNIP99EventIT.java | 15 +- .../api/integration/ApiNIP99RequestIT.java | 17 +- .../integration/BaseRelayIntegrationTest.java | 7 +- .../nostr/api/integration/MultiRelayIT.java | 13 +- ...trSpringWebSocketClientSubscriptionIT.java | 29 +- .../integration/SubscriptionLifecycleIT.java | 14 +- .../integration/ZDoLastApiNIP09EventIT.java | 15 +- .../support/FakeWebSocketClient.java | 11 +- .../support/FakeWebSocketClientFactory.java | 7 +- .../java/nostr/api/unit/Bolt11UtilTest.java | 6 +- .../api/unit/CalendarTimeBasedEventTest.java | 17 +- .../java/nostr/api/unit/ConstantsTest.java | 6 +- .../java/nostr/api/unit/JsonParseTest.java | 21 +- .../nostr/api/unit/NIP01MessagesTest.java | 7 +- .../test/java/nostr/api/unit/NIP01Test.java | 15 +- .../test/java/nostr/api/unit/NIP02Test.java | 15 +- .../test/java/nostr/api/unit/NIP03Test.java | 8 +- .../test/java/nostr/api/unit/NIP04Test.java | 13 +- .../test/java/nostr/api/unit/NIP05Test.java | 11 +- .../test/java/nostr/api/unit/NIP09Test.java | 9 +- .../test/java/nostr/api/unit/NIP12Test.java | 7 +- .../test/java/nostr/api/unit/NIP14Test.java | 4 +- .../test/java/nostr/api/unit/NIP15Test.java | 7 +- .../test/java/nostr/api/unit/NIP20Test.java | 6 +- .../test/java/nostr/api/unit/NIP23Test.java | 9 +- .../test/java/nostr/api/unit/NIP25Test.java | 6 +- .../test/java/nostr/api/unit/NIP28Test.java | 8 +- .../test/java/nostr/api/unit/NIP30Test.java | 4 +- .../test/java/nostr/api/unit/NIP31Test.java | 4 +- .../test/java/nostr/api/unit/NIP32Test.java | 4 +- .../test/java/nostr/api/unit/NIP40Test.java | 4 +- .../test/java/nostr/api/unit/NIP42Test.java | 8 +- .../test/java/nostr/api/unit/NIP44Test.java | 15 +- .../test/java/nostr/api/unit/NIP46Test.java | 7 +- .../java/nostr/api/unit/NIP52ImplTest.java | 11 +- .../java/nostr/api/unit/NIP57ImplTest.java | 16 +- .../test/java/nostr/api/unit/NIP60Test.java | 9 +- .../test/java/nostr/api/unit/NIP61Test.java | 13 +- .../test/java/nostr/api/unit/NIP65Test.java | 11 +- .../java/nostr/api/unit/NIP99ImplTest.java | 17 +- .../test/java/nostr/api/unit/NIP99Test.java | 15 +- ...gWebSocketClientEventVerificationTest.java | 17 +- .../unit/NostrSpringWebSocketClientTest.java | 15 +- .../api/util/CommonTestObjectsFactory.java | 9 +- .../java/nostr/api/util/JsonComparator.java | 7 +- nostr-java-base/pom.xml | 2 +- .../src/main/java/nostr/base/BaseKey.java | 3 +- .../src/main/java/nostr/base/Kind.java | 3 +- .../src/main/java/nostr/base/Relay.java | 5 +- .../src/main/java/nostr/base/RelayUri.java | 5 +- .../src/test/java/nostr/base/BaseKeyTest.java | 7 +- .../src/test/java/nostr/base/CommandTest.java | 4 +- .../src/test/java/nostr/base/KindTest.java | 4 +- .../src/test/java/nostr/base/MarkerTest.java | 4 +- .../src/test/java/nostr/base/RelayTest.java | 4 +- .../test/java/nostr/base/RelayUriTest.java | 22 + nostr-java-client/pom.xml | 2 +- .../nostr/client/WebSocketClientFactory.java | 3 +- .../springwebsocket/NostrRetryable.java | 5 +- .../SpringWebSocketClient.java | 13 +- .../SpringWebSocketClientFactory.java | 3 +- .../StandardWebSocketClient.java | 25 +- .../springwebsocket/WebSocketClientIF.java | 3 +- .../SpringWebSocketClientSubscribeTest.java | 13 +- .../SpringWebSocketClientTest.java | 13 +- ...andardWebSocketClientSubscriptionTest.java | 13 +- .../StandardWebSocketClientTimeoutTest.java | 7 +- nostr-java-crypto/pom.xml | 2 +- .../src/main/java/nostr/crypto/Point.java | 21 +- .../main/java/nostr/crypto/bech32/Bech32.java | 3 +- .../crypto/nip04/EncryptedDirectMessage.java | 15 +- .../nostr/crypto/nip44/EncryptedPayloads.java | 19 +- .../java/nostr/crypto/schnorr/Schnorr.java | 151 ++--- .../src/test/java/nostr/crypto/PointTest.java | 29 + .../java/nostr/crypto/bech32/Bech32Test.java | 7 +- .../nostr/crypto/schnorr/SchnorrTest.java | 9 +- nostr-java-encryption/pom.xml | 2 +- .../nostr/encryption/MessageCipher04.java | 7 +- .../nostr/encryption/MessageCipher44.java | 5 +- .../nostr/encryption/MessageCipherTest.java | 4 +- nostr-java-event/pom.xml | 2 +- .../src/main/java/nostr/event/BaseTag.java | 23 +- .../main/java/nostr/event/JsonContent.java | 4 +- .../src/main/java/nostr/event/NIP01Event.java | 3 +- .../src/main/java/nostr/event/NIP04Event.java | 3 +- .../src/main/java/nostr/event/NIP09Event.java | 3 +- .../src/main/java/nostr/event/NIP25Event.java | 3 +- .../src/main/java/nostr/event/NIP52Event.java | 3 +- .../src/main/java/nostr/event/NIP99Event.java | 3 +- .../main/java/nostr/event/Nip05Content.java | 5 +- .../nostr/event/entities/CalendarContent.java | 13 +- .../event/entities/CalendarRsvpContent.java | 3 +- .../java/nostr/event/entities/CashuMint.java | 3 +- .../java/nostr/event/entities/CashuProof.java | 4 +- .../java/nostr/event/entities/CashuToken.java | 27 +- .../nostr/event/entities/CashuWallet.java | 9 +- .../nostr/event/entities/ChannelProfile.java | 7 +- .../nostr/event/entities/CustomerOrder.java | 7 +- .../java/nostr/event/entities/NutZap.java | 12 +- .../event/entities/NutZapInformation.java | 5 +- .../nostr/event/entities/PaymentRequest.java | 7 +- .../event/entities/PaymentShipmentStatus.java | 3 +- .../java/nostr/event/entities/Product.java | 7 +- .../java/nostr/event/entities/Profile.java | 3 +- .../nostr/event/entities/SpendingHistory.java | 12 +- .../main/java/nostr/event/entities/Stall.java | 7 +- .../nostr/event/entities/UserProfile.java | 7 +- .../nostr/event/filter/AddressTagFilter.java | 23 +- .../java/nostr/event/filter/AuthorFilter.java | 5 +- .../java/nostr/event/filter/EventFilter.java | 5 +- .../java/nostr/event/filter/Filterable.java | 11 +- .../main/java/nostr/event/filter/Filters.java | 11 +- .../event/filter/GenericTagQueryFilter.java | 5 +- .../nostr/event/filter/GeohashTagFilter.java | 5 +- .../nostr/event/filter/HashtagTagFilter.java | 5 +- .../event/filter/IdentifierTagFilter.java | 5 +- .../java/nostr/event/filter/KindFilter.java | 9 +- .../event/filter/ReferencedEventFilter.java | 5 +- .../filter/ReferencedPublicKeyFilter.java | 5 +- .../java/nostr/event/filter/SinceFilter.java | 9 +- .../java/nostr/event/filter/UntilFilter.java | 9 +- .../java/nostr/event/filter/UrlTagFilter.java | 5 +- .../nostr/event/filter/VoteTagFilter.java | 5 +- .../event/impl/AbstractBaseCalendarEvent.java | 3 +- .../impl/AbstractBaseNostrConnectEvent.java | 3 +- .../nostr/event/impl/AddressableEvent.java | 24 +- .../event/impl/CalendarDateBasedEvent.java | 7 +- .../java/nostr/event/impl/CalendarEvent.java | 4 +- .../nostr/event/impl/CalendarRsvpEvent.java | 5 +- .../event/impl/CalendarTimeBasedEvent.java | 5 +- .../impl/CanonicalAuthenticationEvent.java | 3 +- .../nostr/event/impl/ChannelCreateEvent.java | 6 +- .../nostr/event/impl/ChannelMessageEvent.java | 22 +- .../event/impl/ChannelMetadataEvent.java | 12 +- .../java/nostr/event/impl/CheckoutEvent.java | 3 +- .../event/impl/ClassifiedListingEvent.java | 17 +- .../nostr/event/impl/ContactListEvent.java | 3 +- .../impl/CreateOrUpdateProductEvent.java | 7 +- .../event/impl/CreateOrUpdateStallEvent.java | 7 +- .../nostr/event/impl/CustomerOrderEvent.java | 7 +- .../java/nostr/event/impl/DeletionEvent.java | 3 +- .../nostr/event/impl/DirectMessageEvent.java | 3 +- .../java/nostr/event/impl/EphemeralEvent.java | 3 +- .../java/nostr/event/impl/GenericEvent.java | 25 +- .../nostr/event/impl/HideMessageEvent.java | 3 +- .../impl/InternetIdentifierMetadataEvent.java | 3 +- .../java/nostr/event/impl/MentionsEvent.java | 5 +- .../java/nostr/event/impl/MerchantEvent.java | 3 +- .../impl/MerchantRequestPaymentEvent.java | 7 +- .../java/nostr/event/impl/MuteUserEvent.java | 3 +- .../nostr/event/impl/NostrConnectEvent.java | 3 +- .../event/impl/NostrConnectRequestEvent.java | 3 +- .../event/impl/NostrConnectResponseEvent.java | 3 +- .../event/impl/NostrMarketplaceEvent.java | 7 +- .../java/nostr/event/impl/NutZapEvent.java | 7 +- .../event/impl/NutZapInformationalEvent.java | 3 +- .../main/java/nostr/event/impl/OtsEvent.java | 3 +- .../java/nostr/event/impl/ReactionEvent.java | 3 +- .../nostr/event/impl/ReplaceableEvent.java | 3 +- .../java/nostr/event/impl/TextNoteEvent.java | 3 +- .../impl/VerifyPaymentOrShippedEvent.java | 7 +- .../nostr/event/impl/ZapReceiptEvent.java | 3 +- .../nostr/event/impl/ZapRequestEvent.java | 3 +- .../event/json/codec/BaseMessageDecoder.java | 14 +- .../event/json/codec/BaseTagDecoder.java | 4 +- .../event/json/codec/FilterableProvider.java | 7 +- .../event/json/codec/FiltersDecoder.java | 11 +- .../event/json/codec/GenericTagDecoder.java | 25 +- .../event/json/codec/Nip05ContentDecoder.java | 4 +- .../CalendarDateBasedEventDeserializer.java | 5 +- .../CalendarEventDeserializer.java | 5 +- .../CalendarRsvpEventDeserializer.java | 5 +- .../CalendarTimeBasedEventDeserializer.java | 5 +- .../ClassifiedListingEventDeserializer.java | 15 +- .../deserializer/PublicKeyDeserializer.java | 3 +- .../deserializer/SignatureDeserializer.java | 3 +- .../json/deserializer/TagDeserializer.java | 13 +- .../serializer/AbstractTagSerializer.java | 7 +- .../json/serializer/AddressTagSerializer.java | 14 +- .../json/serializer/BaseTagSerializer.java | 3 - .../serializer/ExpirationTagSerializer.java | 3 +- .../json/serializer/GenericTagSerializer.java | 3 - .../serializer/IdentifierTagSerializer.java | 3 +- .../serializer/ReferenceTagSerializer.java | 13 +- .../json/serializer/RelaysTagSerializer.java | 3 +- .../event/json/serializer/TagSerializer.java | 3 - .../CanonicalAuthenticationMessage.java | 30 +- .../nostr/event/message/CloseMessage.java | 3 +- .../java/nostr/event/message/EoseMessage.java | 8 +- .../nostr/event/message/EventMessage.java | 28 +- .../nostr/event/message/GenericMessage.java | 13 +- .../nostr/event/message/NoticeMessage.java | 8 +- .../java/nostr/event/message/OkMessage.java | 11 +- .../message/RelayAuthenticationMessage.java | 3 +- .../java/nostr/event/message/ReqMessage.java | 43 +- .../event/serializer/EventSerializer.java | 9 +- .../event/support/GenericEventConverter.java | 3 +- .../event/support/GenericEventUpdater.java | 7 +- .../event/support/GenericEventValidator.java | 5 +- .../main/java/nostr/event/tag/AddressTag.java | 32 +- .../java/nostr/event/tag/DelegationTag.java | 11 +- .../main/java/nostr/event/tag/EmojiTag.java | 11 +- .../main/java/nostr/event/tag/EventTag.java | 23 +- .../java/nostr/event/tag/ExpirationTag.java | 12 +- .../main/java/nostr/event/tag/GenericTag.java | 5 +- .../main/java/nostr/event/tag/GeohashTag.java | 11 +- .../main/java/nostr/event/tag/HashtagTag.java | 16 +- .../java/nostr/event/tag/IdentifierTag.java | 11 +- .../nostr/event/tag/LabelNamespaceTag.java | 8 +- .../main/java/nostr/event/tag/LabelTag.java | 15 +- .../main/java/nostr/event/tag/NonceTag.java | 17 +- .../main/java/nostr/event/tag/PriceTag.java | 39 +- .../main/java/nostr/event/tag/PubKeyTag.java | 20 +- .../java/nostr/event/tag/ReferenceTag.java | 40 +- .../main/java/nostr/event/tag/RelaysTag.java | 22 +- .../main/java/nostr/event/tag/SubjectTag.java | 17 +- .../java/nostr/event/tag/TagRegistry.java | 3 +- .../src/main/java/nostr/event/tag/UrlTag.java | 14 +- .../main/java/nostr/event/tag/VoteTag.java | 11 +- .../nostr/event/validator/EventValidator.java | 5 +- .../event/impl/AddressableEventTest.java | 67 +++ .../impl/AddressableEventValidateTest.java | 11 +- .../impl/ChannelMessageEventValidateTest.java | 11 +- .../impl/ClassifiedListingEventTest.java | 37 ++ .../impl/ContactListEventValidateTest.java | 13 +- .../event/impl/DeletionEventValidateTest.java | 13 +- .../impl/DirectMessageEventValidateTest.java | 11 +- .../nostr/event/impl/EphemeralEventTest.java | 36 ++ .../impl/EphemeralEventValidateTest.java | 11 +- .../event/impl/GenericEventValidateTest.java | 9 +- .../impl/HideMessageEventValidateTest.java | 13 +- .../event/impl/MuteUserEventValidateTest.java | 15 +- .../event/impl/ReactionEventValidateTest.java | 15 +- .../impl/ReplaceableEventValidateTest.java | 13 +- .../event/impl/TextNoteEventValidateTest.java | 15 +- .../impl/ZapRequestEventValidateTest.java | 13 +- .../nostr/event/json/EventJsonMapperTest.java | 5 +- .../json/codec/BaseEventEncoderTest.java | 7 +- .../event/serializer/EventSerializerTest.java | 11 +- .../support/GenericEventSupportTest.java | 16 +- .../unit/BaseMessageCommandMapperTest.java | 19 +- .../event/unit/BaseMessageDecoderTest.java | 19 +- .../java/nostr/event/unit/BaseTagTest.java | 9 +- .../event/unit/CalendarContentAddTagTest.java | 11 +- .../event/unit/CalendarContentDecodeTest.java | 4 +- .../event/unit/CalendarDeserializerTest.java | 9 +- .../unit/ClassifiedListingDecodeTest.java | 4 +- .../java/nostr/event/unit/DecodeTest.java | 13 +- .../java/nostr/event/unit/EventTagTest.java | 21 +- .../event/unit/EventWithAddressTagTest.java | 13 +- .../nostr/event/unit/FiltersDecoderTest.java | 11 +- .../nostr/event/unit/FiltersEncoderTest.java | 15 +- .../java/nostr/event/unit/FiltersTest.java | 17 +- .../event/unit/GenericEventBuilderTest.java | 9 +- .../java/nostr/event/unit/GenericTagTest.java | 9 +- .../event/unit/JsonContentValidationTest.java | 7 +- .../nostr/event/unit/KindMappingTest.java | 6 +- .../java/nostr/event/unit/PriceTagTest.java | 9 +- .../event/unit/ProductSerializationTest.java | 11 +- .../java/nostr/event/unit/PubkeyTagTest.java | 9 +- .../java/nostr/event/unit/RelaysTagTest.java | 11 +- .../java/nostr/event/unit/SignatureTest.java | 6 +- .../nostr/event/unit/TagDeserializerTest.java | 13 +- .../nostr/event/unit/TagRegistryTest.java | 6 +- .../nostr/event/unit/ValidateKindTest.java | 7 +- .../event/util/EventTypeCheckerTest.java | 6 +- nostr-java-examples/pom.xml | 2 +- .../examples/ExpirationEventExample.java | 5 +- .../java/nostr/examples/FilterExample.java | 5 +- .../java/nostr/examples/NostrApiExamples.java | 15 +- .../SpringClientTextEventExample.java | 3 +- .../examples/SpringSubscriptionExample.java | 5 +- .../nostr/examples/TextNoteEventExample.java | 3 +- nostr-java-id/pom.xml | 2 +- .../src/main/java/nostr/id/Identity.java | 5 +- .../nostr/id/ClassifiedListingEventTest.java | 11 +- .../src/test/java/nostr/id/EntityFactory.java | 13 +- .../src/test/java/nostr/id/EventTest.java | 22 +- .../src/test/java/nostr/id/IdentityTest.java | 65 +-- .../test/java/nostr/id/ReactionEventTest.java | 9 +- .../java/nostr/id/ZapRequestEventTest.java | 7 +- nostr-java-util/pom.xml | 2 +- .../src/main/java/nostr/util/NostrUtil.java | 3 +- .../util/validator/HexStringValidator.java | 5 +- .../nostr/util/validator/Nip05Content.java | 5 +- .../nostr/util/validator/Nip05Validator.java | 13 +- .../nostr/util/NostrUtilExtendedTest.java | 11 +- .../java/nostr/util/NostrUtilRandomTest.java | 7 +- .../test/java/nostr/util/NostrUtilTest.java | 4 +- .../validator/HexStringValidatorTest.java | 4 +- .../util/validator/Nip05ValidatorTest.java | 12 +- pom.xml | 2 +- 362 files changed, 2796 insertions(+), 1628 deletions(-) create mode 100644 QODANA_TODOS.md create mode 100644 docs/howto/configure-release-secrets.md create mode 100644 nostr-java-api/src/test/java/nostr/api/NIP46RequestTest.java create mode 100644 nostr-java-base/src/test/java/nostr/base/RelayUriTest.java create mode 100644 nostr-java-crypto/src/test/java/nostr/crypto/PointTest.java create mode 100644 nostr-java-event/src/test/java/nostr/event/impl/AddressableEventTest.java create mode 100644 nostr-java-event/src/test/java/nostr/event/impl/ClassifiedListingEventTest.java create mode 100644 nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventTest.java diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 01c45a5bb..74dc91c93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,10 +14,19 @@ jobs: build-and-publish: runs-on: ubuntu-latest timeout-minutes: 45 + env: + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} steps: - name: Checkout uses: actions/checkout@v4 + - name: Check required secrets are present + if: ${{ !secrets.CENTRAL_USERNAME || !secrets.CENTRAL_PASSWORD || !secrets.GPG_PRIVATE_KEY || !secrets.GPG_PASSPHRASE }} + run: | + echo "One or more required secrets are missing: CENTRAL_USERNAME, CENTRAL_PASSWORD, GPG_PRIVATE_KEY, GPG_PASSPHRASE" >&2 + exit 1 + - name: Setup Java 21 with Maven Central credentials and GPG uses: actions/setup-java@v4 with: diff --git a/QODANA_TODOS.md b/QODANA_TODOS.md new file mode 100644 index 000000000..6eb70388d --- /dev/null +++ b/QODANA_TODOS.md @@ -0,0 +1,526 @@ +# Qodana Code Quality Issues - TODO List + +Generated: 2025-10-11 +Version: 1.0.0-SNAPSHOT +Total Issues: 293 (all warnings, 0 errors) + +--- + +## Summary Statistics + +- **Total Issues**: 293 +- **Severity**: 292 warnings, 1 note +- **Affected Files**: Main source code only (no test files) +- **Top Issue Categories**: + - JavadocReference: 158 (54%) + - FieldCanBeLocal: 55 (19%) + - FieldMayBeFinal: 18 (6%) + - UnnecessaryLocalVariable: 12 (4%) + - UNCHECKED_WARNING: 11 (4%) + +--- + +## Priority 1: Critical Issues (Immediate Action Required) + +### 1.1 Potential NullPointerException + +**Status**: ⚠️ NEEDS REVIEW +**File**: `nostr-java-api/src/main/java/nostr/api/nip01/NIP01TagFactory.java:78` + +**Issue**: Method invocation `getUuid()` may produce NullPointerException + +**Current Code**: +```java +if (idTag instanceof IdentifierTag identifierTag) { + param += identifierTag.getUuid(); // Line 78 +} +``` + +**Analysis**: The pattern matching ensures `identifierTag` is not null, but `getUuid()` might return null. + +**Action Required**: +- [ ] Verify `IdentifierTag.getUuid()` return type and nullability +- [ ] Add null check: `String uuid = identifierTag.getUuid(); if (uuid != null) param += uuid;` +- [ ] Or use `Objects.requireNonNullElse(identifierTag.getUuid(), "")` + +--- + +### 1.2 Suspicious Name Combination + +**Status**: 🔴 HIGH PRIORITY +**File**: `nostr-java-crypto/src/main/java/nostr/crypto/Point.java:24` + +**Issue**: Variable 'y' should probably not be passed as parameter 'elementRight' + +**Action Required**: +- [ ] Review the `Pair.of(x, y)` call at line 24 +- [ ] Verify parameter order matches expected x/y coordinates +- [ ] Check if `Pair` constructor parameters are correctly named +- [ ] Add documentation/comments clarifying the coordinate system + +--- + +### 1.3 Dead Code - Always False Conditions + +**Status**: 🔴 HIGH PRIORITY (Logic Bugs) + +#### 1.3.1 AddressableEvent.java:27 +**File**: `nostr-java-event/src/main/java/nostr/event/impl/AddressableEvent.java` + +**Issue**: Condition `30_000 <= n && n < 40_000` is always false + +**Action Required**: +- [ ] Review event kind range validation logic +- [ ] Fix or remove the always-false condition +- [ ] Verify against Nostr protocol specification (NIP-01) + +#### 1.3.2 ClassifiedListingEvent.java:159 +**File**: `nostr-java-event/src/main/java/nostr/event/impl/ClassifiedListingEvent.java` + +**Issue**: Condition `30402 <= n && n <= 30403` is always false + +**Action Required**: +- [ ] Review classified listing event kind validation +- [ ] Fix or remove the always-false condition +- [ ] Verify against NIP-99 specification + +#### 1.3.3 EphemeralEvent.java:33 +**File**: `nostr-java-event/src/main/java/nostr/event/impl/EphemeralEvent.java` + +**Issue**: Condition `20_000 <= n && n < 30_000` is always false + +**Action Required**: +- [ ] Review ephemeral event kind range validation +- [ ] Fix or remove the always-false condition +- [ ] Verify against Nostr protocol specification + +--- + +## Priority 2: Important Issues (Short-term) + +### 2.1 Mismatched Collection Query/Update (Potential Bugs) + +**Status**: 🟡 MEDIUM PRIORITY +**Impact**: Possible logic errors or dead code + +#### 2.1.1 CashuToken.java:22 +**File**: `nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java` + +**Issue**: Collection `proofs` is queried but never populated + +**Action Required**: +- [ ] Review if `proofs` should be populated somewhere +- [ ] Add initialization logic if needed +- [ ] Remove query code if not needed + +#### 2.1.2 NutZap.java:15 +**File**: `nostr-java-event/src/main/java/nostr/event/entities/NutZap.java` + +**Issue**: Collection `proofs` is updated but never queried + +**Action Required**: +- [ ] Review if `proofs` should be queried somewhere +- [ ] Add query logic if needed +- [ ] Remove update code if not needed + +#### 2.1.3 SpendingHistory.java:21 +**File**: `nostr-java-event/src/main/java/nostr/event/entities/SpendingHistory.java` + +**Issue**: Collection `eventTags` is updated but never queried + +**Action Required**: +- [ ] Review if `eventTags` should be queried somewhere +- [ ] Add query logic if needed +- [ ] Remove update code if not needed + +#### 2.1.4 NIP46.java:71 +**File**: `nostr-java-api/src/main/java/nostr/api/NIP46.java` + +**Issue**: Collection `params` is updated but never queried + +**Action Required**: +- [ ] Review if `params` should be queried somewhere +- [ ] Add query logic if needed +- [ ] Remove update code if not needed + +#### 2.1.5 CashuToken.java:24 +**File**: `nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java` + +**Issue**: Collection `destroyed` is updated but never queried + +**Action Required**: +- [ ] Review if `destroyed` should be queried somewhere +- [ ] Add query logic if needed +- [ ] Remove update code if not needed + +--- + +### 2.2 Non-Serializable with serialVersionUID Field + +**Status**: 🟢 LOW PRIORITY (Code Cleanliness) +**Effort**: Easy fix + +#### Files Affected: +1. `nostr-java-event/src/main/java/nostr/event/json/serializer/TagSerializer.java:13` +2. `nostr-java-event/src/main/java/nostr/event/json/serializer/GenericTagSerializer.java:7` +3. `nostr-java-event/src/main/java/nostr/event/json/serializer/BaseTagSerializer.java:6` + +**Issue**: Classes define `serialVersionUID` but don't implement `Serializable` + +**Action Required**: +- [ ] Remove `serialVersionUID` fields (recommended) +- [ ] OR implement `Serializable` interface if serialization is needed + +**Example Fix**: +```java +// Before +public class TagSerializer extends StdSerializer { + private static final long serialVersionUID = 1L; // Remove this + +// After +public class TagSerializer extends StdSerializer { + // serialVersionUID removed +``` + +--- + +### 2.3 Pointless Null Check + +**Status**: 🟢 LOW PRIORITY +**File**: `nostr-java-base/src/main/java/nostr/base/RelayUri.java:19` + +**Issue**: Unnecessary null check before `equalsIgnoreCase()` call + +**Action Required**: +- [ ] Review code at line 19 +- [ ] Remove redundant null check +- [ ] Simplify conditional logic + +--- + +### 2.4 DataFlow Issues (Redundant Conditions) + +**Status**: 🟡 MEDIUM PRIORITY + +#### 2.4.1 NIP09.java:61 +**File**: `nostr-java-api/src/main/java/nostr/api/NIP09.java` + +**Issue**: Condition `GenericEvent.class::isInstance` is redundant + +**Action Required**: +- [ ] Replace with simple null check +- [ ] Simplify conditional logic + +#### 2.4.2 NIP09.java:55 +**File**: `nostr-java-api/src/main/java/nostr/api/NIP09.java` + +**Issue**: Same as above + +**Action Required**: +- [ ] Replace with simple null check +- [ ] Simplify conditional logic + +--- + +## Priority 3: Documentation Issues (Long-term) + +### 3.1 JavadocReference Errors + +**Status**: 📚 DOCUMENTATION +**Effort**: Large (158 issues) +**Impact**: Medium (documentation quality) + +**Top Affected File**: `nostr-java-api/src/main/java/nostr/config/Constants.java` (82 issues) + +#### Common Issues: +- Cannot resolve symbol (e.g., 'NipConstants', 'GenericEvent') +- Inaccessible symbols (e.g., private fields, wrong imports) +- Missing fully qualified names + +**Action Required**: +- [ ] Review Constants.java Javadoc (82 issues) +- [ ] Fix inaccessible symbol references +- [ ] Add proper imports or use fully qualified names +- [ ] Verify all `@link` and `@see` tags + +**Distribution**: +- Constants.java: 82 issues +- CalendarContent.java: 12 issues +- NIP60.java: 8 issues +- Identity.java: 7 issues +- Other files: 49 issues + +--- + +### 3.2 Javadoc Declaration Issues + +**Status**: 📚 DOCUMENTATION +**Count**: 12 occurrences + +**Issue**: Javadoc syntax/structure problems + +**Action Required**: +- [ ] Review all Javadoc syntax errors +- [ ] Fix malformed tags +- [ ] Ensure proper Javadoc structure + +--- + +### 3.3 Javadoc Link as Plain Text + +**Status**: 📚 DOCUMENTATION +**Count**: 2 occurrences + +**Issue**: Javadoc links not using proper `{@link}` syntax + +**Action Required**: +- [ ] Convert plain text links to `{@link}` tags +- [ ] Ensure proper link formatting + +--- + +## Priority 4: Code Quality Improvements (Nice-to-have) + +### 4.1 Field Can Be Local + +**Status**: ♻️ REFACTORING +**Count**: 55 occurrences +**Effort**: Medium +**Impact**: Reduces class state complexity + +**Top Affected Files**: +- `nostr-java-event/src/main/java/nostr/event/message/OkMessage.java` (3 issues) +- Various entity classes in `nostr-java-event/src/main/java/nostr/event/entities/` (3 each) + +**Action Required**: +- [ ] Review each field usage +- [ ] Convert to local variables where appropriate +- [ ] Reduce class state complexity + +**Example**: +```java +// Before +private String tempResult; + +public void process() { + tempResult = calculate(); + return tempResult; +} + +// After +public void process() { + String tempResult = calculate(); + return tempResult; +} +``` + +--- + +### 4.2 Field May Be Final + +**Status**: ♻️ REFACTORING +**Count**: 18 occurrences +**Effort**: Easy +**Impact**: Improves immutability + +**Action Required**: +- [ ] Review fields that are never reassigned +- [ ] Add `final` modifier where appropriate +- [ ] Document why fields can't be final if needed + +**Example**: +```java +// Before +private String id; // Never reassigned after constructor + +// After +private final String id; +``` + +--- + +### 4.3 Unnecessary Local Variable + +**Status**: ♻️ REFACTORING +**Count**: 12 occurrences +**Effort**: Easy +**Impact**: Code simplification + +**Action Required**: +- [ ] Remove variables that are immediately returned +- [ ] Simplify method bodies + +**Example**: +```java +// Before +public String getId() { + String result = this.id; + return result; +} + +// After +public String getId() { + return this.id; +} +``` + +--- + +### 4.4 Unchecked Warnings + +**Status**: ⚠️ TYPE SAFETY +**Count**: 11 occurrences +**Impact**: Type safety + +**Top Affected Files**: +- CalendarContent.java +- NIP02.java +- NIP09.java + +**Action Required**: +- [ ] Review all raw type usage +- [ ] Add proper generic type parameters +- [ ] Use `@SuppressWarnings("unchecked")` only when truly necessary with justification + +**Example**: +```java +// Before +List items = new ArrayList(); // Raw type + +// After +List items = new ArrayList<>(); // Generic type +``` + +--- + +### 4.5 Deprecated Usage + +**Status**: 🔧 MAINTENANCE +**Count**: 4 occurrences + +**Issue**: Deprecated members still being referenced + +**Action Required**: +- [ ] Identify deprecated API usage +- [ ] Migrate to replacement APIs +- [ ] Remove deprecated references + +--- + +### 4.6 Unused Imports + +**Status**: 🧹 CLEANUP +**Count**: 2 occurrences +**Effort**: Trivial + +**Action Required**: +- [ ] Remove unused import statements +- [ ] Configure IDE to auto-remove on save + +--- + +## Implementation Plan + +### Phase 1: Critical Fixes (Week 1) +- [ ] Fix NullPointerException risk in NIP01TagFactory +- [ ] Verify Point.java coordinate parameter order +- [ ] Fix dead code conditions in event validators +- [ ] Test all changes + +### Phase 2: Important Fixes (Week 2) +- [ ] Address mismatched collection issues +- [ ] Remove serialVersionUID from non-Serializable classes +- [ ] Fix redundant null checks +- [ ] Fix redundant conditions in NIP09 + +### Phase 3: Documentation (Week 3-4) +- [ ] Fix Constants.java Javadoc (82 issues) +- [ ] Fix remaining Javadoc reference errors (76 issues) +- [ ] Fix Javadoc declaration issues +- [ ] Fix Javadoc link formatting + +### Phase 4: Code Quality (Week 5-6) +- [ ] Convert fields to local variables (55 issues) +- [ ] Add final modifiers (18 issues) +- [ ] Remove unnecessary local variables (12 issues) +- [ ] Fix unchecked warnings (11 issues) +- [ ] Address deprecated usage (4 issues) +- [ ] Remove unused imports (2 issues) + +--- + +## Testing Requirements + +For each fix: +- [ ] Ensure existing unit tests pass +- [ ] Add new tests if logic changes +- [ ] Verify no regressions +- [ ] Update integration tests if needed + +--- + +## Files Requiring Most Attention + +### Top 10 Files by Issue Count + +1. **Constants.java** (85 issues) + - 82 JavadocReference + - 2 FieldMayBeFinal + - 1 Other + +2. **CalendarContent.java** (12 issues) + - Javadoc + Unchecked warnings + +3. **NIP60.java** (8 issues) + - Javadoc references + +4. **Identity.java** (7 issues) + - Mixed issues + +5. **NostrCryptoException.java** (6 issues) + - Documentation + +6. **Bech32Prefix.java** (6 issues) + - Code quality + +7. **NIP46.java** (6 issues) + - Collection + Javadoc + +8. **Product.java** (5 issues) + - Entity class issues + +9. **NIP01.java** (5 issues) + - Mixed issues + +10. **PubKeyTag.java** (4 issues) + - Code quality + +--- + +## Estimated Effort + +| Priority | Issue Count | Estimated Hours | Difficulty | +|----------|-------------|-----------------|------------| +| P1 - Critical | 6 | 8-12 hours | Medium-High | +| P2 - Important | 14 | 6-8 hours | Low-Medium | +| P3 - Documentation | 172 | 20-30 hours | Low | +| P4 - Code Quality | 101 | 15-20 hours | Low | +| **Total** | **293** | **49-70 hours** | **Mixed** | + +--- + +## Notes + +- All issues are warnings (no errors blocking compilation) +- No critical security vulnerabilities detected +- Focus on P1 and P2 issues for immediate release +- P3 and P4 can be addressed incrementally +- Consider adding Qodana to CI/CD pipeline + +--- + +## References + +- Qodana Report: `.qodana/qodana.sarif.json` +- Project Version: 1.0.0-SNAPSHOT +- Analysis Date: 2025-10-11 diff --git a/docs/README.md b/docs/README.md index 3cda28c1e..31e407edf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,7 @@ Quick links to the most relevant guides and references. - [howto/custom-events.md](howto/custom-events.md) — Creating custom event types - [howto/manage-roadmap-project.md](howto/manage-roadmap-project.md) — Sync the GitHub Project with the 1.0 backlog - [howto/version-uplift-workflow.md](howto/version-uplift-workflow.md) — Tagging, publishing, and BOM alignment for releases +- [howto/configure-release-secrets.md](howto/configure-release-secrets.md) — Configure Maven Central and GPG secrets for releases - [howto/ci-it-stability.md](howto/ci-it-stability.md) — Keep CI green and stabilize Docker-based ITs ## Operations diff --git a/docs/howto/configure-release-secrets.md b/docs/howto/configure-release-secrets.md new file mode 100644 index 000000000..fff298ae0 --- /dev/null +++ b/docs/howto/configure-release-secrets.md @@ -0,0 +1,49 @@ +# Configure Release Secrets + +This guide explains how to configure the GitHub secrets required to publish releases to Maven Central and sign artifacts. + +The release workflow reads the following secrets: + +- `CENTRAL_USERNAME` — Sonatype (OSSRH) username +- `CENTRAL_PASSWORD` — Sonatype (OSSRH) password +- `GPG_PRIVATE_KEY` — ASCII‑armored GPG private key used for signing +- `GPG_PASSPHRASE` — Passphrase for the above private key + +Prerequisites: + +- A Sonatype (OSSRH) account with publishing permissions for this groupId +- A GPG keypair suitable for signing (RSA/ECC) + +Steps: + +1) Export your GPG private key in ASCII‑armored form + + - List keys: `gpg --list-secret-keys --keyid-format LONG` + - Export: `gpg --armor --export-secret-keys > private.key.asc` + +2) Add repository secrets + + - Open GitHub → Settings → Secrets and variables → Actions → New repository secret + - Add the following secrets: + - `CENTRAL_USERNAME` — your Sonatype username + - `CENTRAL_PASSWORD` — your Sonatype password + - `GPG_PRIVATE_KEY` — contents of `private.key.asc` + - `GPG_PASSPHRASE` — your GPG key passphrase + +3) Verify workflow configuration + + - The workflow `.github/workflows/release.yml` verifies that all four secrets are present + - It configures Maven settings and GPG using `actions/setup-java@v4` + +4) Trigger a release + + - Tag the repo: `git tag v` where `` matches the POM version + - Push the tag: `git push origin v` + - The workflow validates tag/version parity and publishes artifacts if tests pass + +Troubleshooting: + +- Missing secret: the workflow fails early with a clear error message +- GPG key format: ensure the key is ASCII‑armored, not binary +- Staging errors on Central: check Sonatype UI for staging repository status + diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index eca7442e8..692d0ccf0 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-api/src/main/java/nostr/api/EventNostr.java b/nostr-java-api/src/main/java/nostr/api/EventNostr.java index 960e32150..ec4a5947b 100644 --- a/nostr-java-api/src/main/java/nostr/api/EventNostr.java +++ b/nostr-java-api/src/main/java/nostr/api/EventNostr.java @@ -1,8 +1,5 @@ package nostr.api; -import java.util.List; -import java.util.Map; -import java.util.Objects; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -15,6 +12,10 @@ import nostr.id.Identity; import org.apache.commons.lang3.stream.Streams.FailableStream; +import java.util.List; +import java.util.Map; +import java.util.Objects; + /** * Base helper for building, signing, and sending Nostr events over WebSocket. */ diff --git a/nostr-java-api/src/main/java/nostr/api/NIP01.java b/nostr-java-api/src/main/java/nostr/api/NIP01.java index f3605153f..21f85f8ba 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP01.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP01.java @@ -1,7 +1,5 @@ package nostr.api; -import java.util.List; -import java.util.Optional; import lombok.NonNull; import nostr.api.nip01.NIP01EventBuilder; import nostr.api.nip01.NIP01MessageFactory; @@ -22,6 +20,9 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; +import java.util.List; +import java.util.Optional; + /** * Facade for NIP-01 (Basic Protocol Flow) - the fundamental building blocks of Nostr. * diff --git a/nostr-java-api/src/main/java/nostr/api/NIP02.java b/nostr-java-api/src/main/java/nostr/api/NIP02.java index 0743856a5..0be351ca5 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP02.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP02.java @@ -1,6 +1,5 @@ package nostr.api; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; @@ -9,6 +8,8 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.util.List; + /** * NIP-02 helpers (Contact List). Create and manage kind 3 contact lists and p-tags. * Spec: NIP-02 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP04.java b/nostr-java-api/src/main/java/nostr/api/NIP04.java index 46f50e93f..5ccd9d063 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP04.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP04.java @@ -1,8 +1,5 @@ package nostr.api; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Objects; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import nostr.api.factory.impl.GenericEventFactory; @@ -11,12 +8,16 @@ import nostr.encryption.MessageCipher; import nostr.encryption.MessageCipher04; import nostr.event.BaseTag; -import nostr.event.impl.GenericEvent; import nostr.event.filter.Filterable; +import nostr.event.impl.GenericEvent; import nostr.event.tag.GenericTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + /** * NIP-04: Encrypted Direct Messages. * diff --git a/nostr-java-api/src/main/java/nostr/api/NIP05.java b/nostr-java-api/src/main/java/nostr/api/NIP05.java index 78a83c1b8..a1f9fdf56 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP05.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP05.java @@ -1,18 +1,19 @@ package nostr.api; -import static nostr.base.json.EventJsonMapper.mapper; -import static nostr.util.NostrUtil.escapeJsonString; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; import nostr.event.entities.UserProfile; import nostr.event.impl.GenericEvent; +import nostr.event.json.codec.EventEncodingException; import nostr.id.Identity; import nostr.util.validator.Nip05Validator; -import nostr.event.json.codec.EventEncodingException; + +import java.util.ArrayList; + +import static nostr.base.json.EventJsonMapper.mapper; +import static nostr.util.NostrUtil.escapeJsonString; /** * NIP-05 helpers (DNS-based verification). Create internet identifier metadata events. diff --git a/nostr-java-api/src/main/java/nostr/api/NIP09.java b/nostr-java-api/src/main/java/nostr/api/NIP09.java index 079f38163..4657afeaa 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP09.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP09.java @@ -1,7 +1,5 @@ package nostr.api; -import java.util.ArrayList; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; @@ -12,6 +10,9 @@ import nostr.event.tag.EventTag; import nostr.id.Identity; +import java.util.ArrayList; +import java.util.List; + /** * NIP-09 helpers (Event Deletion). Build deletion events targeting events or addresses. * Spec: NIP-09 @@ -50,30 +51,23 @@ public NIP09 createDeletionEvent(@NonNull List deleteables) { private List getTags(List deleteables) { List tags = new ArrayList<>(); - // Handle GenericEvents - deleteables.stream() - .filter(GenericEvent.class::isInstance) - .map(GenericEvent.class::cast) - .forEach(event -> tags.add(new EventTag(event.getId()))); - - // Handle AddressTags - deleteables.stream() - .filter(GenericEvent.class::isInstance) - .map(GenericEvent.class::cast) - .map(GenericEvent::getTags) - .forEach( - t -> - t.stream() - .filter(tag -> tag instanceof AddressTag) - .map(AddressTag.class::cast) - .forEach( - tag -> { - tags.add(tag); - tags.add(NIP25.createKindTag(tag.getKind())); - })); - - // Add kind tags for all deleteables - deleteables.forEach(d -> tags.add(NIP25.createKindTag(d.getKind()))); + for (Deleteable d : deleteables) { + if (d instanceof GenericEvent event) { + // Event IDs + tags.add(new EventTag(event.getId())); + // Address tags contained in the event + event.getTags().stream() + .filter(tag -> tag instanceof AddressTag) + .map(AddressTag.class::cast) + .forEach( + tag -> { + tags.add(tag); + tags.add(NIP25.createKindTag(tag.getKind())); + }); + } + // Always include kind tag for each deleteable + tags.add(NIP25.createKindTag(d.getKind())); + } return tags; } diff --git a/nostr-java-api/src/main/java/nostr/api/NIP12.java b/nostr-java-api/src/main/java/nostr/api/NIP12.java index 30311c3c3..d3adf5f6d 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP12.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP12.java @@ -1,12 +1,13 @@ package nostr.api; -import java.net.URL; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.config.Constants; import nostr.event.BaseTag; +import java.net.URL; +import java.util.List; + /** * NIP-12 helpers (Generic Tag Queries). Convenience creators for hashtag, reference and geohash tags. * Spec: NIP-12 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP14.java b/nostr-java-api/src/main/java/nostr/api/NIP14.java index 6ecfe3276..98a32cd9a 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP14.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP14.java @@ -1,11 +1,12 @@ package nostr.api; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.config.Constants; import nostr.event.BaseTag; +import java.util.List; + /** * NIP-14 helpers (Subject tag in text notes). Create subject tags for threads. * Spec: NIP-14 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP15.java b/nostr-java-api/src/main/java/nostr/api/NIP15.java index 9e11f86c2..60bf2ab74 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP15.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP15.java @@ -1,6 +1,5 @@ package nostr.api; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; @@ -11,6 +10,8 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.util.List; + /** * NIP-15 helpers (Endorsements/Marketplace). Build stall/product metadata and encrypted order flows. * Spec: NIP-15 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP23.java b/nostr-java-api/src/main/java/nostr/api/NIP23.java index 88bb69564..8f31decc9 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP23.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP23.java @@ -1,6 +1,5 @@ package nostr.api; -import java.net.URL; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -10,6 +9,8 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.net.URL; + /** * NIP-23 helpers (Long-form content). Build long-form notes and related tags. * Spec: NIP-23 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP25.java b/nostr-java-api/src/main/java/nostr/api/NIP25.java index 07e97e9a6..a4f530de4 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP25.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP25.java @@ -1,8 +1,5 @@ package nostr.api; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -16,6 +13,10 @@ import nostr.event.tag.EventTag; import nostr.id.Identity; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + /** * NIP-25 helpers (Reactions). Build reaction events and custom emoji tags. * Spec: NIP-25 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP28.java b/nostr-java-api/src/main/java/nostr/api/NIP28.java index da14b590a..c3c03b70a 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP28.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP28.java @@ -1,28 +1,26 @@ package nostr.api; -import nostr.base.json.EventJsonMapper; - -import static nostr.api.NIP12.createHashtagTag; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.Marker; import nostr.base.PublicKey; import nostr.base.Relay; -import nostr.config.Constants; +import nostr.base.json.EventJsonMapper; import nostr.event.entities.ChannelProfile; import nostr.event.impl.GenericEvent; import nostr.id.Identity; import org.apache.commons.text.StringEscapeUtils; +import java.util.List; + +import static nostr.api.NIP12.createHashtagTag; + /** * NIP-28 helpers (Public chat). Build channel create/metadata/message and moderation events. * Spec: NIP-28 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP42.java b/nostr-java-api/src/main/java/nostr/api/NIP42.java index 970447eaf..980e47ed6 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP42.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP42.java @@ -1,7 +1,5 @@ package nostr.api; -import java.util.ArrayList; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -16,6 +14,9 @@ import nostr.event.message.CanonicalAuthenticationMessage; import nostr.event.message.GenericMessage; +import java.util.ArrayList; +import java.util.List; + /** * NIP-42 helpers (Authentication). Build auth events and AUTH messages. * Spec: NIP-42 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP44.java b/nostr-java-api/src/main/java/nostr/api/NIP44.java index 3b3abeda0..91616d13b 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP44.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP44.java @@ -1,7 +1,5 @@ package nostr.api; -import java.util.NoSuchElementException; -import java.util.Objects; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import nostr.base.PublicKey; @@ -12,6 +10,9 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; +import java.util.NoSuchElementException; +import java.util.Objects; + /** * NIP-44: Encrypted Payloads (Versioned Encrypted Messages). * diff --git a/nostr-java-api/src/main/java/nostr/api/NIP46.java b/nostr-java-api/src/main/java/nostr/api/NIP46.java index 1549a077f..5d25d5656 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP46.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP46.java @@ -1,11 +1,7 @@ package nostr.api; -import static nostr.base.json.EventJsonMapper.mapper; - +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; -import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -17,9 +13,15 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.io.Serializable; +import java.util.LinkedHashSet; +import java.util.Set; + +import static nostr.base.json.EventJsonMapper.mapper; + /** * NIP-46 helpers (Nostr Connect). Build app requests and signer responses. - * Spec: https://github.com/nostr-protocol/nips/blob/master/46.md + * Spec: NIP-46 */ @Slf4j public final class NIP46 extends EventNostr { @@ -36,9 +38,12 @@ public NIP46(@NonNull Identity sender) { * @return this instance for chaining */ public NIP46 createRequestEvent(@NonNull NIP46.Request request, @NonNull PublicKey signer) { - String content = NIP44.encrypt(getSender(), request.toString(), signer); GenericEvent genericEvent = - new GenericEventFactory(getSender(), Kind.NOSTR_CONNECT.getValue(), content).create(); + new GenericEventFactory( + getSender(), + Kind.NOSTR_CONNECT.getValue(), + NIP44.encrypt(getSender(), request.toString(), signer)) + .create(); genericEvent.addTag(NIP01.createPubKeyTag(signer)); this.updateEvent(genericEvent); return this; @@ -52,9 +57,12 @@ public NIP46 createRequestEvent(@NonNull NIP46.Request request, @NonNull PublicK * @return this instance for chaining */ public NIP46 createResponseEvent(@NonNull NIP46.Response response, @NonNull PublicKey app) { - String content = NIP44.encrypt(getSender(), response.toString(), app); GenericEvent genericEvent = - new GenericEventFactory(getSender(), Kind.NOSTR_CONNECT.getValue(), content).create(); + new GenericEventFactory( + getSender(), + Kind.NOSTR_CONNECT.getValue(), + NIP44.encrypt(getSender(), response.toString(), app)) + .create(); genericEvent.addTag(NIP01.createPubKeyTag(app)); this.updateEvent(genericEvent); return this; @@ -87,6 +95,22 @@ public void addParam(String param) { this.params.add(param); } + /** + * Number of parameters currently present. + */ + @JsonIgnore + public int getParamCount() { + return this.params.size(); + } + + /** + * Tests whether the given parameter exists. + */ + @JsonIgnore + public boolean containsParam(String param) { + return this.params.contains(param); + } + /** * Serialize this request to JSON. * diff --git a/nostr-java-api/src/main/java/nostr/api/NIP52.java b/nostr-java-api/src/main/java/nostr/api/NIP52.java index a959e3370..9a453ab9e 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP52.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP52.java @@ -1,15 +1,5 @@ package nostr.api; -import static nostr.api.NIP01.createIdentifierTag; -import static nostr.api.NIP23.createImageTag; -import static nostr.api.NIP23.createSummaryTag; -import static nostr.api.NIP23.createTitleTag; -import static nostr.api.NIP99.createLocationTag; -import static nostr.api.NIP99.createStatusTag; - -import java.net.URI; -import java.util.List; -import java.util.Optional; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -24,6 +14,17 @@ import nostr.id.Identity; import org.apache.commons.lang3.stream.Streams; +import java.net.URI; +import java.util.List; +import java.util.Optional; + +import static nostr.api.NIP01.createIdentifierTag; +import static nostr.api.NIP23.createImageTag; +import static nostr.api.NIP23.createSummaryTag; +import static nostr.api.NIP23.createTitleTag; +import static nostr.api.NIP99.createLocationTag; +import static nostr.api.NIP99.createStatusTag; + /** * NIP-52 helpers (Calendar Events). Build time/date-based calendar events and RSVP. * Spec: NIP-52 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP57.java b/nostr-java-api/src/main/java/nostr/api/NIP57.java index 8d473cf60..6ecc592c2 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP57.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP57.java @@ -1,6 +1,5 @@ package nostr.api; -import java.util.List; import lombok.NonNull; import nostr.api.nip01.NIP01TagFactory; import nostr.api.nip57.NIP57TagFactory; @@ -16,6 +15,8 @@ import nostr.event.tag.RelaysTag; import nostr.id.Identity; +import java.util.List; + /** * NIP-57: Lightning Zaps. * diff --git a/nostr-java-api/src/main/java/nostr/api/NIP60.java b/nostr-java-api/src/main/java/nostr/api/NIP60.java index 126e9931b..6ea224c3d 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP60.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP60.java @@ -1,14 +1,6 @@ package nostr.api; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -27,6 +19,15 @@ import nostr.event.json.codec.EventEncodingException; import nostr.id.Identity; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static nostr.base.json.EventJsonMapper.mapper; + /** * NIP-60: Cashu Wallet over Nostr. * @@ -229,7 +230,6 @@ public NIP60(@NonNull Identity sender) { setSender(sender); } - @SuppressWarnings("unchecked") public NIP60 createWalletEvent(@NonNull CashuWallet wallet) { GenericEvent walletEvent = new GenericEventFactory( @@ -242,7 +242,6 @@ public NIP60 createWalletEvent(@NonNull CashuWallet wallet) { return this; } - @SuppressWarnings("unchecked") public NIP60 createTokenEvent(@NonNull CashuToken token, @NonNull CashuWallet wallet) { GenericEvent tokenEvent = new GenericEventFactory( @@ -255,7 +254,6 @@ public NIP60 createTokenEvent(@NonNull CashuToken token, @NonNull CashuWallet wa return this; } - @SuppressWarnings("unchecked") public NIP60 createSpendingHistoryEvent( @NonNull SpendingHistory spendingHistory, @NonNull CashuWallet wallet) { GenericEvent spendingHistoryEvent = @@ -269,7 +267,6 @@ public NIP60 createSpendingHistoryEvent( return this; } - @SuppressWarnings("unchecked") public NIP60 createRedemptionQuoteEvent(@NonNull CashuQuote quote) { GenericEvent redemptionQuoteEvent = new GenericEventFactory( @@ -289,8 +286,8 @@ public NIP60 createRedemptionQuoteEvent(@NonNull CashuQuote quote) { * @return the created mint tag */ public static BaseTag createMintTag(@NonNull CashuMint mint) { - List units = mint.getUnits(); - return createMintTag(mint.getUrl(), units != null ? units.toArray(new String[0]) : null); + return createMintTag( + mint.getUrl(), mint.getUnits() != null ? mint.getUnits().toArray(new String[0]) : null); } /** @@ -378,8 +375,8 @@ private String getWalletEventContent(@NonNull CashuWallet wallet) { tags.add(NIP60.createPrivKeyTag(wallet.getPrivateKey())); try { - String serializedTags = mapper().writeValueAsString(tags); - return NIP44.encrypt(getSender(), serializedTags, getSender().getPublicKey()); + return NIP44.encrypt( + getSender(), mapper().writeValueAsString(tags), getSender().getPublicKey()); } catch (JsonProcessingException ex) { throw new EventEncodingException("Failed to encode wallet content", ex); } @@ -387,8 +384,8 @@ private String getWalletEventContent(@NonNull CashuWallet wallet) { private String getTokenEventContent(@NonNull CashuToken token) { try { - String serializedToken = mapper().writeValueAsString(token); - return NIP44.encrypt(getSender(), serializedToken, getSender().getPublicKey()); + return NIP44.encrypt( + getSender(), mapper().writeValueAsString(token), getSender().getPublicKey()); } catch (JsonProcessingException ex) { throw new EventEncodingException("Failed to encode token content", ex); } @@ -404,9 +401,7 @@ private String getSpendingHistoryEventContent(@NonNull SpendingHistory spendingH tags.add(NIP60.createAmountTag(spendingHistory.getAmount())); tags.addAll(spendingHistory.getEventTags()); - String content = getContent(tags); - - return NIP44.encrypt(getSender(), content, getSender().getPublicKey()); + return NIP44.encrypt(getSender(), getContent(tags), getSender().getPublicKey()); } /** diff --git a/nostr-java-api/src/main/java/nostr/api/NIP61.java b/nostr-java-api/src/main/java/nostr/api/NIP61.java index e36021b9e..6b74b8a4e 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP61.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP61.java @@ -1,9 +1,5 @@ package nostr.api; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -20,6 +16,11 @@ import nostr.event.tag.EventTag; import nostr.id.Identity; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + /** * NIP-61 helpers (Cashu Nutzap). Build informational and payment events for Cashu zaps. * Spec: NIP-61 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP65.java b/nostr-java-api/src/main/java/nostr/api/NIP65.java index 9c926c404..db2bbb99e 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP65.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP65.java @@ -1,8 +1,5 @@ package nostr.api; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; @@ -12,6 +9,10 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + /** * NIP-65 helpers (Relay List Metadata). Build relay list events and r-tags. * Spec: NIP-65 diff --git a/nostr-java-api/src/main/java/nostr/api/NIP99.java b/nostr-java-api/src/main/java/nostr/api/NIP99.java index 613e22725..f68d59f08 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP99.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP99.java @@ -1,14 +1,5 @@ package nostr.api; -import static nostr.api.NIP12.createGeohashTag; -import static nostr.api.NIP12.createHashtagTag; -import static nostr.api.NIP23.createImageTag; -import static nostr.api.NIP23.createPublishedAtTag; -import static nostr.api.NIP23.createSummaryTag; -import static nostr.api.NIP23.createTitleTag; - -import java.net.URL; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.api.factory.impl.GenericEventFactory; @@ -19,9 +10,19 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.net.URL; +import java.util.List; + +import static nostr.api.NIP12.createGeohashTag; +import static nostr.api.NIP12.createHashtagTag; +import static nostr.api.NIP23.createImageTag; +import static nostr.api.NIP23.createPublishedAtTag; +import static nostr.api.NIP23.createSummaryTag; +import static nostr.api.NIP23.createTitleTag; + /** * NIP-99 helpers (Classified Listings). Build classified listing events and tags. - * Spec: https://github.com/nostr-protocol/nips/blob/master/99.md + * Spec: NIP-99 */ public class NIP99 extends EventNostr { diff --git a/nostr-java-api/src/main/java/nostr/api/NostrIF.java b/nostr-java-api/src/main/java/nostr/api/NostrIF.java index 54d6e6d0c..e2ef733de 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrIF.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrIF.java @@ -1,9 +1,5 @@ package nostr.api; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; import lombok.NonNull; import nostr.base.IEvent; import nostr.base.ISignable; @@ -11,6 +7,11 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + /** * Core client interface for sending Nostr events and REQ messages to relays, signing and verifying * events, and managing sender/relay configuration. diff --git a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java index 042a2a4a0..133315968 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java @@ -1,11 +1,5 @@ package nostr.api; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -27,6 +21,13 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; + /** * Default Nostr client using Spring WebSocket clients to send events and requests to relays. */ @@ -38,7 +39,7 @@ public class NostrSpringWebSocketClient implements NostrIF { private final NostrRequestDispatcher requestDispatcher; private final NostrSubscriptionManager subscriptionManager; private final WebSocketClientFactory clientFactory; - private NoteService noteService; + private final NoteService noteService; @Getter private Identity sender; @@ -247,8 +248,8 @@ public Map getLastSendFailureDetails() { /** * Registers a failure listener when using {@link DefaultNoteService}. No‑op otherwise. * - *

The listener receives a relay‑name → exception map after each call to {@link - * #sendEvent(nostr.base.IEvent)}. + *

The listener receives a relay‑name → exception map after each call to + * {@link #sendEvent(nostr.base.IEvent)}. * * @param listener consumer of last failures (may be {@code null} to clear) * @return this client for chaining diff --git a/nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java b/nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java index 260b92aa8..368a19a63 100644 --- a/nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java +++ b/nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java @@ -1,12 +1,5 @@ package nostr.api; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; -import java.util.function.Function; import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -18,9 +11,17 @@ import nostr.client.springwebsocket.SpringWebSocketClientFactory; import nostr.event.filter.Filters; import nostr.event.impl.GenericEvent; +import nostr.event.message.CloseMessage; import nostr.event.message.EventMessage; import nostr.event.message.ReqMessage; -import nostr.event.message.CloseMessage; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; +import java.util.function.Function; /** * Internal helper managing a relay connection and per-subscription request clients. diff --git a/nostr-java-api/src/main/java/nostr/api/client/NostrEventDispatcher.java b/nostr-java-api/src/main/java/nostr/api/client/NostrEventDispatcher.java index 8c4baffde..b09f69355 100644 --- a/nostr-java-api/src/main/java/nostr/api/client/NostrEventDispatcher.java +++ b/nostr-java-api/src/main/java/nostr/api/client/NostrEventDispatcher.java @@ -1,7 +1,5 @@ package nostr.api.client; -import java.security.NoSuchAlgorithmException; -import java.util.List; import lombok.NonNull; import nostr.api.service.NoteService; import nostr.base.IEvent; @@ -10,8 +8,17 @@ import nostr.event.impl.GenericEvent; import nostr.util.NostrUtil; +import java.security.NoSuchAlgorithmException; +import java.util.List; + /** * Handles event verification and dispatching to relays. + * + *

Performs BIP-340 Schnorr signature verification before forwarding events to all configured + * relays. + * + * @see nostr.crypto.schnorr.Schnorr + * @see NIP-01 */ public final class NostrEventDispatcher { @@ -57,8 +64,10 @@ public boolean verify(@NonNull GenericEvent event) { throw new IllegalStateException("The event is not signed"); } try { - var message = NostrUtil.sha256(event.getSerializedEventCache()); - return Schnorr.verify(message, event.getPubKey().getRawData(), event.getSignature().getRawData()); + return Schnorr.verify( + NostrUtil.sha256(event.getSerializedEventCache()), + event.getPubKey().getRawData(), + event.getSignature().getRawData()); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("SHA-256 algorithm not available", e); } catch (SchnorrException e) { diff --git a/nostr-java-api/src/main/java/nostr/api/client/NostrRelayRegistry.java b/nostr-java-api/src/main/java/nostr/api/client/NostrRelayRegistry.java index 2f715b08d..2376d7259 100644 --- a/nostr-java-api/src/main/java/nostr/api/client/NostrRelayRegistry.java +++ b/nostr-java-api/src/main/java/nostr/api/client/NostrRelayRegistry.java @@ -1,5 +1,9 @@ package nostr.api.client; +import nostr.api.WebSocketClientHandler; +import nostr.base.RelayUri; +import nostr.base.SubscriptionId; + import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -8,9 +12,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; -import nostr.api.WebSocketClientHandler; -import nostr.base.RelayUri; -import nostr.base.SubscriptionId; /** * Manages the lifecycle of {@link WebSocketClientHandler} instances keyed by relay name. @@ -45,10 +46,9 @@ public Map getClientMap() { */ public void registerRelays(Map relays) { for (Entry relayEntry : relays.entrySet()) { - RelayUri relayUri = new RelayUri(relayEntry.getValue()); clientMap.computeIfAbsent( relayEntry.getKey(), - key -> createHandler(relayEntry.getKey(), relayUri)); + key -> createHandler(key, new RelayUri(relayEntry.getValue()))); } } @@ -99,10 +99,9 @@ public List requestHandlers(SubscriptionId subscriptionI */ public void ensureRequestClients(SubscriptionId subscriptionId) { for (WebSocketClientHandler baseHandler : baseHandlers()) { - String requestKey = baseHandler.getRelayName() + ":" + subscriptionId.value(); clientMap.computeIfAbsent( - requestKey, - key -> createHandler(requestKey, baseHandler.getRelayUri())); + baseHandler.getRelayName() + ":" + subscriptionId.value(), + key -> createHandler(key, baseHandler.getRelayUri())); } } diff --git a/nostr-java-api/src/main/java/nostr/api/client/NostrRequestDispatcher.java b/nostr-java-api/src/main/java/nostr/api/client/NostrRequestDispatcher.java index 6c9e78aec..01032ae50 100644 --- a/nostr-java-api/src/main/java/nostr/api/client/NostrRequestDispatcher.java +++ b/nostr-java-api/src/main/java/nostr/api/client/NostrRequestDispatcher.java @@ -1,15 +1,19 @@ package nostr.api.client; -import java.io.IOException; -import java.util.List; import lombok.NonNull; import nostr.base.SubscriptionId; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.filter.Filters; import nostr.event.message.ReqMessage; +import java.io.IOException; +import java.util.List; + /** * Coordinates REQ message dispatch across registered relay clients. + * + *

REQ is the standard subscribe request defined by + * NIP-01. */ public final class NostrRequestDispatcher { diff --git a/nostr-java-api/src/main/java/nostr/api/client/NostrSubscriptionManager.java b/nostr-java-api/src/main/java/nostr/api/client/NostrSubscriptionManager.java index 1925289a0..941039790 100644 --- a/nostr-java-api/src/main/java/nostr/api/client/NostrSubscriptionManager.java +++ b/nostr-java-api/src/main/java/nostr/api/client/NostrSubscriptionManager.java @@ -1,12 +1,13 @@ package nostr.api.client; +import lombok.NonNull; +import nostr.base.SubscriptionId; +import nostr.event.filter.Filters; + import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -import lombok.NonNull; -import nostr.base.SubscriptionId; -import nostr.event.filter.Filters; /** * Manages subscription lifecycles across multiple relay handlers. diff --git a/nostr-java-api/src/main/java/nostr/api/client/WebSocketClientHandlerFactory.java b/nostr-java-api/src/main/java/nostr/api/client/WebSocketClientHandlerFactory.java index 12ffa5932..b7dd6d194 100644 --- a/nostr-java-api/src/main/java/nostr/api/client/WebSocketClientHandlerFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/client/WebSocketClientHandlerFactory.java @@ -1,9 +1,10 @@ package nostr.api.client; -import java.util.concurrent.ExecutionException; import nostr.api.WebSocketClientHandler; import nostr.base.RelayUri; +import java.util.concurrent.ExecutionException; + /** * Factory for creating {@link WebSocketClientHandler} instances. */ diff --git a/nostr-java-api/src/main/java/nostr/api/factory/EventFactory.java b/nostr-java-api/src/main/java/nostr/api/factory/EventFactory.java index 589825450..6f2706a77 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/EventFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/EventFactory.java @@ -1,13 +1,14 @@ package nostr.api.factory; -import java.util.ArrayList; -import java.util.List; import lombok.Data; import nostr.base.PublicKey; import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.util.ArrayList; +import java.util.List; + /** * Base event factory collecting sender, tags, and content to build events. */ diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/BaseTagFactory.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/BaseTagFactory.java index 07baac6bd..e0f67b500 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/BaseTagFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/BaseTagFactory.java @@ -2,15 +2,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import nostr.event.BaseTag; -import nostr.event.tag.GenericTag; import nostr.event.json.codec.EventEncodingException; +import nostr.event.tag.GenericTag; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; /** * Utility to create {@link BaseTag} instances from code and parameters or from JSON. diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/EventMessageFactory.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/EventMessageFactory.java index 9b7fb5278..8c3545620 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/EventMessageFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/EventMessageFactory.java @@ -1,6 +1,5 @@ package nostr.api.factory.impl; -import java.util.Optional; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -8,6 +7,8 @@ import nostr.event.impl.GenericEvent; import nostr.event.message.EventMessage; +import java.util.Optional; + @Data @EqualsAndHashCode(callSuper = false) public class EventMessageFactory extends BaseMessageFactory { diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/GenericEventFactory.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/GenericEventFactory.java index 1e5c1536f..426ce7eb9 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/GenericEventFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/GenericEventFactory.java @@ -1,7 +1,5 @@ package nostr.api.factory.impl; -import java.util.ArrayList; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -10,6 +8,9 @@ import nostr.event.impl.GenericEvent; import nostr.id.Identity; +import java.util.ArrayList; +import java.util.List; + /** * Factory for creating generic Nostr events with a specified kind. * diff --git a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01EventBuilder.java b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01EventBuilder.java index 427675c71..117af10bb 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01EventBuilder.java +++ b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01EventBuilder.java @@ -1,6 +1,5 @@ package nostr.api.nip01; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.base.Kind; @@ -10,6 +9,8 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; +import java.util.List; + /** * Builds common NIP-01 events while keeping {@link nostr.api.NIP01} focused on orchestration. */ diff --git a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01MessageFactory.java b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01MessageFactory.java index 601f6637a..6e771b45c 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01MessageFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01MessageFactory.java @@ -1,15 +1,16 @@ package nostr.api.nip01; -import java.util.List; import lombok.NonNull; -import nostr.event.impl.GenericEvent; import nostr.event.filter.Filters; +import nostr.event.impl.GenericEvent; import nostr.event.message.CloseMessage; import nostr.event.message.EoseMessage; import nostr.event.message.EventMessage; import nostr.event.message.NoticeMessage; import nostr.event.message.ReqMessage; +import java.util.List; + /** * Creates protocol messages referenced by {@link nostr.api.NIP01}. */ diff --git a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01TagFactory.java b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01TagFactory.java index 7969cfff1..cddab00c7 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip01/NIP01TagFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/nip01/NIP01TagFactory.java @@ -1,7 +1,5 @@ package nostr.api.nip01; -import java.util.ArrayList; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.base.Marker; @@ -11,8 +9,15 @@ import nostr.event.BaseTag; import nostr.event.tag.IdentifierTag; +import java.util.ArrayList; +import java.util.List; + /** * Creates the canonical tags used by NIP-01 helpers. + * + *

These tags follow the standard defined in + * NIP-01 and are used + * throughout the API builders for consistency. */ public final class NIP01TagFactory { @@ -39,8 +44,7 @@ public static BaseTag eventTag(@NonNull String idEvent, Marker marker) { } public static BaseTag eventTag(@NonNull String idEvent, Relay recommendedRelay, Marker marker) { - String relayUri = recommendedRelay != null ? recommendedRelay.getUri() : null; - return eventTag(idEvent, relayUri, marker); + return eventTag(idEvent, recommendedRelay != null ? recommendedRelay.getUri() : null, marker); } public static BaseTag pubKeyTag(@NonNull PublicKey publicKey) { diff --git a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57TagFactory.java b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57TagFactory.java index c314f2a02..31b829f36 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57TagFactory.java +++ b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57TagFactory.java @@ -1,7 +1,5 @@ package nostr.api.nip57; -import java.util.ArrayList; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.BaseTagFactory; import nostr.base.PublicKey; @@ -9,6 +7,9 @@ import nostr.config.Constants; import nostr.event.BaseTag; +import java.util.ArrayList; +import java.util.List; + /** * Centralizes construction of NIP-57 related tags. */ diff --git a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapReceiptBuilder.java b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapReceiptBuilder.java index 1c6aa13c2..664c251a9 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapReceiptBuilder.java +++ b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapReceiptBuilder.java @@ -1,18 +1,16 @@ package nostr.api.nip57; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.api.nip01.NIP01TagFactory; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; +import nostr.base.json.EventJsonMapper; import nostr.event.filter.Filterable; import nostr.event.impl.GenericEvent; -import nostr.event.tag.AddressTag; import nostr.event.json.codec.EventEncodingException; +import nostr.event.tag.AddressTag; import nostr.id.Identity; import org.apache.commons.text.StringEscapeUtils; diff --git a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapRequestBuilder.java b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapRequestBuilder.java index 8ac427e1a..f3e31adfb 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapRequestBuilder.java +++ b/nostr-java-api/src/main/java/nostr/api/nip57/NIP57ZapRequestBuilder.java @@ -1,10 +1,8 @@ package nostr.api.nip57; -import java.util.List; import lombok.NonNull; import nostr.api.factory.impl.GenericEventFactory; import nostr.api.nip01.NIP01TagFactory; -import nostr.api.nip57.NIP57TagFactory; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.Relay; @@ -15,6 +13,8 @@ import nostr.event.tag.RelaysTag; import nostr.id.Identity; +import java.util.List; + /** * Builds zap request events for {@link nostr.api.NIP57}. */ @@ -118,10 +118,11 @@ public GenericEvent buildSimpleZapRequest( } private GenericEvent initialiseZapRequest(Identity sender, String content) { - Identity resolved = resolveSender(sender); - GenericEventFactory factory = - new GenericEventFactory(resolved, Kind.ZAP_REQUEST.getValue(), content == null ? "" : content); - return factory.create(); + return new GenericEventFactory( + resolveSender(sender), + Kind.ZAP_REQUEST.getValue(), + content == null ? "" : content) + .create(); } private void populateCommonZapRequestTags( diff --git a/nostr-java-api/src/main/java/nostr/api/nip57/ZapRequestParameters.java b/nostr-java-api/src/main/java/nostr/api/nip57/ZapRequestParameters.java index 7879c35d8..ebe8e4df0 100644 --- a/nostr-java-api/src/main/java/nostr/api/nip57/ZapRequestParameters.java +++ b/nostr-java-api/src/main/java/nostr/api/nip57/ZapRequestParameters.java @@ -1,6 +1,5 @@ package nostr.api.nip57; -import java.util.List; import lombok.Builder; import lombok.Getter; import lombok.NonNull; @@ -12,6 +11,8 @@ import nostr.event.tag.RelaysTag; import nostr.id.Identity; +import java.util.List; + /** * Parameter object for building zap request events. Reduces long argument lists in {@link nostr.api.NIP57}. */ diff --git a/nostr-java-api/src/main/java/nostr/api/service/NoteService.java b/nostr-java-api/src/main/java/nostr/api/service/NoteService.java index 1024d65c1..67f3819a2 100644 --- a/nostr-java-api/src/main/java/nostr/api/service/NoteService.java +++ b/nostr-java-api/src/main/java/nostr/api/service/NoteService.java @@ -1,11 +1,12 @@ package nostr.api.service; -import java.util.List; -import java.util.Map; import lombok.NonNull; import nostr.api.WebSocketClientHandler; import nostr.base.IEvent; +import java.util.List; +import java.util.Map; + public interface NoteService { List send(@NonNull IEvent event, @NonNull Map clients); } diff --git a/nostr-java-api/src/main/java/nostr/api/service/impl/DefaultNoteService.java b/nostr-java-api/src/main/java/nostr/api/service/impl/DefaultNoteService.java index 25c67fa3b..66d389b15 100644 --- a/nostr-java-api/src/main/java/nostr/api/service/impl/DefaultNoteService.java +++ b/nostr-java-api/src/main/java/nostr/api/service/impl/DefaultNoteService.java @@ -1,15 +1,16 @@ package nostr.api.service.impl; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import nostr.api.WebSocketClientHandler; import nostr.api.service.NoteService; import nostr.base.IEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** Default implementation that dispatches notes through all WebSocket clients. */ @Slf4j public class DefaultNoteService implements NoteService { diff --git a/nostr-java-api/src/main/java/nostr/config/Constants.java b/nostr-java-api/src/main/java/nostr/config/Constants.java index 6bd075646..049d7a3fa 100644 --- a/nostr-java-api/src/main/java/nostr/config/Constants.java +++ b/nostr-java-api/src/main/java/nostr/config/Constants.java @@ -1,6 +1,13 @@ package nostr.config; -/** Collection of common constants used across the API. */ +/** + * Collection of common constants used across the API. + * + *

Includes well-known tag codes defined by NIP-01 and used throughout the + * library to build and parse event tags. + * + * @see NIP-01 + */ public final class Constants { private Constants() {} @@ -56,4 +63,3 @@ private Tag() {} public static final String FREE_BUSY_CODE = "fb"; } } - diff --git a/nostr-java-api/src/main/java/nostr/config/RelayConfig.java b/nostr-java-api/src/main/java/nostr/config/RelayConfig.java index 76f1d6411..503ecbee8 100644 --- a/nostr-java-api/src/main/java/nostr/config/RelayConfig.java +++ b/nostr-java-api/src/main/java/nostr/config/RelayConfig.java @@ -1,13 +1,12 @@ package nostr.config; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.stream.Collectors; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; +import java.util.Map; + @Configuration @PropertySource("classpath:relays.properties") @EnableConfigurationProperties(RelaysProperties.class) @@ -18,14 +17,5 @@ public Map relays(RelaysProperties relaysProperties) { return relaysProperties; } - /** - * @deprecated Use {@link RelaysProperties} instead for relay configuration. - * This method will be removed in version 1.0.0. - */ - @Deprecated(forRemoval = true, since = "0.6.2") - private Map legacyRelays() { - var relaysBundle = ResourceBundle.getBundle("relays"); - return relaysBundle.keySet().stream() - .collect(Collectors.toMap(key -> key, relaysBundle::getString)); - } + // Legacy property loader removed in 1.0.0. Use RelaysProperties bean instead. } diff --git a/nostr-java-api/src/main/java/nostr/config/RelaysProperties.java b/nostr-java-api/src/main/java/nostr/config/RelaysProperties.java index 591082e11..8b3fed949 100644 --- a/nostr-java-api/src/main/java/nostr/config/RelaysProperties.java +++ b/nostr-java-api/src/main/java/nostr/config/RelaysProperties.java @@ -1,8 +1,9 @@ package nostr.config; +import org.springframework.boot.context.properties.ConfigurationProperties; + import java.io.Serial; import java.util.HashMap; -import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "relays") public class RelaysProperties extends HashMap { diff --git a/nostr-java-api/src/test/java/nostr/api/NIP46RequestTest.java b/nostr-java-api/src/test/java/nostr/api/NIP46RequestTest.java new file mode 100644 index 000000000..23fe2c2d8 --- /dev/null +++ b/nostr-java-api/src/test/java/nostr/api/NIP46RequestTest.java @@ -0,0 +1,24 @@ +package nostr.api; + +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class NIP46RequestTest { + + // Ensures params can be added and queried reliably. + @Test + void addAndQueryParams() { + NIP46.Request req = new NIP46.Request("id-1", "sign_event", Set.of("a")); + req.addParam("b"); + assertEquals(2, req.getParamCount()); + assertTrue(req.containsParam("a")); + assertTrue(req.containsParam("b")); + assertFalse(req.containsParam("c")); + } +} + diff --git a/nostr-java-api/src/test/java/nostr/api/TestHandlerFactory.java b/nostr-java-api/src/test/java/nostr/api/TestHandlerFactory.java index 1228e42b1..dc4e767ab 100644 --- a/nostr-java-api/src/test/java/nostr/api/TestHandlerFactory.java +++ b/nostr-java-api/src/test/java/nostr/api/TestHandlerFactory.java @@ -1,14 +1,15 @@ package nostr.api; -import java.util.HashMap; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; import lombok.NonNull; import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; +import java.util.HashMap; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + /** * Test-only factory to construct {@link WebSocketClientHandler} while staying inside the * {@code nostr.api} package to access package-private constructor. diff --git a/nostr-java-api/src/test/java/nostr/api/TestableWebSocketClientHandler.java b/nostr-java-api/src/test/java/nostr/api/TestableWebSocketClientHandler.java index 4860afea6..6e7072643 100644 --- a/nostr-java-api/src/test/java/nostr/api/TestableWebSocketClientHandler.java +++ b/nostr-java-api/src/test/java/nostr/api/TestableWebSocketClientHandler.java @@ -1,13 +1,12 @@ package nostr.api; -import java.util.Map; -import java.util.function.Function; import nostr.base.RelayUri; -import nostr.base.SubscriptionId; -import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.client.springwebsocket.SpringWebSocketClientFactory; +import java.util.Map; +import java.util.function.Function; + public class TestableWebSocketClientHandler extends WebSocketClientHandler { public TestableWebSocketClientHandler( String relayName, diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherEnsureClientsTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherEnsureClientsTest.java index 88f80955d..0b9eb4f24 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherEnsureClientsTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherEnsureClientsTest.java @@ -1,17 +1,19 @@ package nostr.api.client; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -import java.util.List; - import nostr.api.WebSocketClientHandler; import nostr.base.SubscriptionId; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Verifies ensureRequestClients() is invoked per dispatcher call as expected. */ public class NostrRequestDispatcherEnsureClientsTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherTest.java index 57e69738d..f51e763c4 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrRequestDispatcherTest.java @@ -1,18 +1,22 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -import java.util.List; - import nostr.api.WebSocketClientHandler; import nostr.base.SubscriptionId; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Tests for NostrRequestDispatcher multi-filter dispatch and aggregation. */ public class NostrRequestDispatcherTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientCloseLoggingTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientCloseLoggingTest.java index ac9f77ccc..679aab628 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientCloseLoggingTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientCloseLoggingTest.java @@ -1,18 +1,7 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; - import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; -import lombok.NonNull; import nostr.api.NostrSpringWebSocketClient; import nostr.api.WebSocketClientHandler; import nostr.base.RelayUri; @@ -25,6 +14,18 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** Verifies default error listener logs WARN lines when close path encounters exceptions. */ public class NostrSpringWebSocketClientCloseLoggingTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientHandlerIntegrationTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientHandlerIntegrationTest.java index f08c53706..fcb44cee8 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientHandlerIntegrationTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientHandlerIntegrationTest.java @@ -1,22 +1,24 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; -import lombok.NonNull; import nostr.api.NostrSpringWebSocketClient; import nostr.api.WebSocketClientHandler; import nostr.base.RelayUri; -import nostr.client.WebSocketClientFactory; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Wires NostrSpringWebSocketClient to a mocked handler and verifies subscribe/close flow. */ public class NostrSpringWebSocketClientHandlerIntegrationTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientLoggingTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientLoggingTest.java index 7fa3d04ad..7a6761e44 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientLoggingTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientLoggingTest.java @@ -1,9 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Map; - import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import nostr.api.NostrSpringWebSocketClient; @@ -16,6 +12,10 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Verifies default error listener path emits a WARN log entry. */ public class NostrSpringWebSocketClientLoggingTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientRelaysTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientRelaysTest.java index 46bc0b17e..6d695f686 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientRelaysTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientRelaysTest.java @@ -1,14 +1,15 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Map; import nostr.api.NostrSpringWebSocketClient; import nostr.api.integration.support.FakeWebSocketClientFactory; import nostr.api.service.impl.DefaultNoteService; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** Verifies getRelays returns the snapshot of relay names to URIs. */ public class NostrSpringWebSocketClientRelaysTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientSubscribeLoggingTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientSubscribeLoggingTest.java index c449020f8..a9c183587 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientSubscribeLoggingTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSpringWebSocketClientSubscribeLoggingTest.java @@ -1,29 +1,30 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; - import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; +import nostr.api.NostrSpringWebSocketClient; import nostr.api.WebSocketClientHandler; import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; -import nostr.api.NostrSpringWebSocketClient; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; import nostr.id.Identity; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** Verifies default error listener emits WARN logs when subscribe path throws. */ public class NostrSpringWebSocketClientSubscribeLoggingTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/NostrSubscriptionManagerCloseTest.java b/nostr-java-api/src/test/java/nostr/api/client/NostrSubscriptionManagerCloseTest.java index 5935224c1..df67efb91 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/NostrSubscriptionManagerCloseTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/NostrSubscriptionManagerCloseTest.java @@ -1,15 +1,22 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import nostr.api.WebSocketClientHandler; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import nostr.api.WebSocketClientHandler; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** Tests close semantics and error aggregation in NostrSubscriptionManager. */ public class NostrSubscriptionManagerCloseTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseIdempotentTest.java b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseIdempotentTest.java index d5a8307c2..a0bf86316 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseIdempotentTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseIdempotentTest.java @@ -1,13 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -15,6 +7,17 @@ import nostr.event.filter.KindFilter; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Verifies calling close twice on a subscription handle does not throw. */ public class WebSocketHandlerCloseIdempotentTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseSequencingTest.java b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseSequencingTest.java index 5a0bd6b80..2b0ee65dc 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseSequencingTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerCloseSequencingTest.java @@ -1,13 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -16,6 +8,18 @@ import org.junit.jupiter.api.Test; import org.mockito.InOrder; +import java.io.IOException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Ensures CLOSE frame is sent before delegate and client close, even on exceptions. */ public class WebSocketHandlerCloseSequencingTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerRequestErrorTest.java b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerRequestErrorTest.java index e06bd8d74..2855f5961 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerRequestErrorTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerRequestErrorTest.java @@ -1,14 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -16,6 +7,16 @@ import nostr.event.filter.KindFilter; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** Ensures sendRequest wraps IOExceptions as RuntimeException with context. */ public class WebSocketHandlerRequestErrorTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendCloseFrameTest.java b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendCloseFrameTest.java index 575e46445..a436d1c15 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendCloseFrameTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendCloseFrameTest.java @@ -1,13 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -18,6 +10,15 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Verifies WebSocketClientHandler close sends CLOSE frame and closes client. */ public class WebSocketHandlerSendCloseFrameTest { diff --git a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendRequestTest.java b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendRequestTest.java index 777fd07b6..2b31bf4b3 100644 --- a/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendRequestTest.java +++ b/nostr-java-api/src/test/java/nostr/api/client/WebSocketHandlerSendRequestTest.java @@ -1,14 +1,5 @@ package nostr.api.client; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import nostr.base.RelayUri; import nostr.base.SubscriptionId; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -17,6 +8,18 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** Tests sendRequest for multiple sub ids and verifying subscription id usage. */ public class WebSocketHandlerSendRequestTest { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java index 222a85645..264197f6a 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java @@ -1,22 +1,6 @@ package nostr.api.integration; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.io.IOException; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; import lombok.extern.slf4j.Slf4j; import nostr.api.EventNostr; import nostr.api.NIP01; @@ -62,6 +46,23 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import java.io.IOException; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + @SpringJUnitConfig(RelayConfig.class) @Slf4j public class ApiEventIT extends BaseRelayIntegrationTest { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java index 3b37a1ace..cf3b42b19 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java @@ -1,15 +1,7 @@ package nostr.api.integration; -import static nostr.api.integration.ApiEventIT.createProduct; -import static nostr.api.integration.ApiEventIT.createStall; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import nostr.api.NIP15; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -25,6 +17,15 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static nostr.api.integration.ApiEventIT.createProduct; +import static nostr.api.integration.ApiEventIT.createStall; +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + @SpringJUnitConfig(RelayConfig.class) @ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientIT extends BaseRelayIntegrationTest { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java index 5b54ab7c8..2be58fc52 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java @@ -1,11 +1,5 @@ package nostr.api.integration; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import nostr.api.NIP52; import nostr.api.util.JsonComparator; import nostr.base.PrivateKey; @@ -23,6 +17,13 @@ import org.junit.jupiter.api.Test; import org.springframework.test.context.ActiveProfiles; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertTrue; + @ActiveProfiles("test") class ApiNIP52EventIT extends BaseRelayIntegrationTest { private SpringWebSocketClient springWebSocketClient; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java index 50200d991..947cd2cb9 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java @@ -1,12 +1,5 @@ package nostr.api.integration; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -25,6 +18,14 @@ import org.junit.jupiter.api.Test; import org.springframework.test.context.ActiveProfiles; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + @ActiveProfiles("test") class ApiNIP52RequestIT extends BaseRelayIntegrationTest { private static final String PRV_KEY_VALUE = diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java index c805c1736..1e69ebd15 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java @@ -1,12 +1,5 @@ package nostr.api.integration; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; import nostr.api.NIP99; import nostr.base.PrivateKey; import nostr.base.PublicKey; @@ -27,6 +20,14 @@ import org.junit.jupiter.api.Test; import org.springframework.test.context.ActiveProfiles; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + @ActiveProfiles("test") class ApiNIP99EventIT extends BaseRelayIntegrationTest { public static final String CLASSIFIED_LISTING_CONTENT = "classified listing content"; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java index 55ac2305f..76ea9ba59 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java @@ -1,14 +1,6 @@ package nostr.api.integration; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.fasterxml.jackson.databind.JsonNode; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import nostr.api.NIP99; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -27,6 +19,15 @@ import org.junit.jupiter.api.Test; import org.springframework.test.context.ActiveProfiles; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + @ActiveProfiles("test") class ApiNIP99RequestIT extends BaseRelayIntegrationTest { private static final String PRV_KEY_VALUE = diff --git a/nostr-java-api/src/test/java/nostr/api/integration/BaseRelayIntegrationTest.java b/nostr-java-api/src/test/java/nostr/api/integration/BaseRelayIntegrationTest.java index cbcd62f38..818bd5e6e 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/BaseRelayIntegrationTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/BaseRelayIntegrationTest.java @@ -1,18 +1,19 @@ package nostr.api.integration; -import java.time.Duration; -import java.util.ResourceBundle; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import java.time.Duration; +import java.util.ResourceBundle; + /** * Base class for Testcontainers-backed relay integration tests. * diff --git a/nostr-java-api/src/test/java/nostr/api/integration/MultiRelayIT.java b/nostr-java-api/src/test/java/nostr/api/integration/MultiRelayIT.java index ea6330c4b..4f398b5cd 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/MultiRelayIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/MultiRelayIT.java @@ -1,11 +1,5 @@ package nostr.api.integration; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import nostr.api.NostrSpringWebSocketClient; import nostr.api.integration.support.FakeWebSocketClient; import nostr.api.integration.support.FakeWebSocketClientFactory; @@ -15,6 +9,13 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Integration tests covering multi-relay behavior using a fake WebSocket client factory. */ diff --git a/nostr-java-api/src/test/java/nostr/api/integration/NostrSpringWebSocketClientSubscriptionIT.java b/nostr-java-api/src/test/java/nostr/api/integration/NostrSpringWebSocketClientSubscriptionIT.java index 662e99523..3169fe661 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/NostrSpringWebSocketClientSubscriptionIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/NostrSpringWebSocketClientSubscriptionIT.java @@ -1,30 +1,31 @@ package nostr.api.integration; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; import lombok.NonNull; import nostr.api.NostrSpringWebSocketClient; import nostr.api.TestableWebSocketClientHandler; import nostr.api.WebSocketClientHandler; +import nostr.base.Kind; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.client.springwebsocket.WebSocketClientIF; import nostr.event.BaseMessage; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; -import nostr.base.Kind; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + class NostrSpringWebSocketClientSubscriptionIT { // Ensures that long-lived subscriptions stream events and send CLOSE frames on cancellation. diff --git a/nostr-java-api/src/test/java/nostr/api/integration/SubscriptionLifecycleIT.java b/nostr-java-api/src/test/java/nostr/api/integration/SubscriptionLifecycleIT.java index 0a2de93b5..c97dfb63e 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/SubscriptionLifecycleIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/SubscriptionLifecycleIT.java @@ -1,12 +1,5 @@ package nostr.api.integration; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import nostr.api.NostrSpringWebSocketClient; import nostr.api.integration.support.FakeWebSocketClient; import nostr.api.integration.support.FakeWebSocketClientFactory; @@ -17,6 +10,13 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Integration tests for subscription lifecycle using a fake WebSocket client. */ diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java index 07e3c3753..f8821703b 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java @@ -1,12 +1,5 @@ package nostr.api.integration; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; -import java.util.UUID; import nostr.api.NIP01; import nostr.api.NIP09; import nostr.base.Kind; @@ -30,6 +23,14 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; + @SpringJUnitConfig(RelayConfig.class) @ActiveProfiles("test") public class ZDoLastApiNIP09EventIT extends BaseRelayIntegrationTest { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClient.java b/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClient.java index af405c23e..fbc6af6d9 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClient.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClient.java @@ -1,5 +1,11 @@ package nostr.api.integration.support; +import lombok.Getter; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import nostr.client.springwebsocket.WebSocketClientIF; +import nostr.event.BaseMessage; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -9,11 +15,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Consumer; -import lombok.Getter; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import nostr.client.springwebsocket.WebSocketClientIF; -import nostr.event.BaseMessage; /** * Minimal in‑memory WebSocket client used by integration tests to simulate relay behavior. diff --git a/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClientFactory.java b/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClientFactory.java index b0f17609a..9de7c2c66 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClientFactory.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/support/FakeWebSocketClientFactory.java @@ -1,13 +1,14 @@ package nostr.api.integration.support; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; import lombok.NonNull; import nostr.base.RelayUri; import nostr.client.WebSocketClientFactory; import nostr.client.springwebsocket.WebSocketClientIF; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; + /** * In-memory {@link WebSocketClientFactory} for tests. * diff --git a/nostr-java-api/src/test/java/nostr/api/unit/Bolt11UtilTest.java b/nostr-java-api/src/test/java/nostr/api/unit/Bolt11UtilTest.java index 203bcda44..11afc298d 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/Bolt11UtilTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/Bolt11UtilTest.java @@ -1,11 +1,11 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import nostr.api.nip57.Bolt11Util; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + /** * Unit tests for Bolt11Util amount parsing. */ diff --git a/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java b/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java index 6d92fb6a7..1b35fe255 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java @@ -1,15 +1,7 @@ package nostr.api.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.base.Signature; @@ -27,6 +19,15 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + @TestInstance(TestInstance.Lifecycle.PER_CLASS) class CalendarTimeBasedEventTest { // required fields diff --git a/nostr-java-api/src/test/java/nostr/api/unit/ConstantsTest.java b/nostr-java-api/src/test/java/nostr/api/unit/ConstantsTest.java index 447b605ff..7b65b2892 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/ConstantsTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/ConstantsTest.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.base.Kind; import nostr.config.Constants; import nostr.event.impl.GenericEvent; @@ -10,6 +7,9 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class ConstantsTest { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java b/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java index 898241616..91bbd1be4 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java @@ -1,16 +1,6 @@ package nostr.api.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.math.BigDecimal; -import java.util.List; import lombok.extern.slf4j.Slf4j; import nostr.api.NIP01; import nostr.api.util.JsonComparator; @@ -57,6 +47,17 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * @author eric */ diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP01MessagesTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP01MessagesTest.java index f22b52211..94e81cf6f 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP01MessagesTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP01MessagesTest.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; import nostr.api.NIP01; import nostr.base.Kind; import nostr.event.filter.Filters; @@ -16,6 +13,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Unit tests for NIP-01 message creation and encoding. */ public class NIP01MessagesTest { diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP01Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP01Test.java index 2b8a0518a..1e2faf750 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP01Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP01Test.java @@ -1,12 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -import java.net.MalformedURLException; -import java.net.URI; -import java.util.List; import nostr.api.NIP01; import nostr.event.BaseTag; import nostr.event.entities.UserProfile; @@ -22,6 +15,14 @@ import nostr.util.NostrException; import org.junit.jupiter.api.Test; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + public class NIP01Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP02Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP02Test.java index e5535e219..ad6f62fea 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP02Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP02Test.java @@ -1,12 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; import nostr.api.NIP02; import nostr.base.Kind; import nostr.config.Constants; @@ -16,6 +9,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP02Test { private Identity sender; diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP03Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP03Test.java index f49720fae..6bae548ba 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP03Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP03Test.java @@ -1,9 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP01; import nostr.api.NIP03; import nostr.event.impl.GenericEvent; @@ -11,6 +7,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP03Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP04Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP04Test.java index 6b889cd90..14fcbfa09 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP04Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP04Test.java @@ -1,20 +1,19 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP04; import nostr.base.Kind; -import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Unit tests for NIP-04 (Encrypted Direct Messages). * diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP05Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP05Test.java index aef01a98a..21fb30d06 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP05Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP05Test.java @@ -1,16 +1,17 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.net.URI; import nostr.api.NIP05; import nostr.event.entities.UserProfile; import nostr.event.impl.GenericEvent; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.net.URI; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP05Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP09Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP09Test.java index 81567e305..b2954af40 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP09Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP09Test.java @@ -1,9 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; import nostr.api.NIP01; import nostr.api.NIP09; import nostr.base.Kind; @@ -11,6 +7,11 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP09Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP12Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP12Test.java index 72518ab88..5e471af1c 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP12Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP12Test.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.net.URL; import nostr.api.NIP12; import nostr.event.BaseTag; import nostr.event.tag.GeohashTag; @@ -10,6 +7,10 @@ import nostr.event.tag.ReferenceTag; import org.junit.jupiter.api.Test; +import java.net.URL; + +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP12Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP14Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP14Test.java index 24a591f41..ef2c2aaa4 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP14Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP14Test.java @@ -1,12 +1,12 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.api.NIP14; import nostr.event.BaseTag; import nostr.event.tag.SubjectTag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP14Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP15Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP15Test.java index 3b7820e83..54c940a2c 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP15Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP15Test.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; import nostr.api.NIP15; import nostr.event.entities.Product; import nostr.event.entities.Stall; @@ -11,6 +8,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class NIP15Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP20Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP20Test.java index 9c540bbe5..57a26cf91 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP20Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP20Test.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP01; import nostr.api.NIP20; import nostr.event.impl.GenericEvent; @@ -10,6 +7,9 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP20Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP23Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP23Test.java index 0c36a94da..6d1326e10 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP23Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP23Test.java @@ -1,15 +1,16 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.net.URL; import nostr.api.NIP23; import nostr.base.Kind; import nostr.event.impl.GenericEvent; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.net.URL; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP23Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP25Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP25Test.java index 8f15b367f..da7fcd900 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP25Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP25Test.java @@ -1,8 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP01; import nostr.api.NIP25; import nostr.event.entities.Reaction; @@ -11,6 +8,9 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP25Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP28Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP28Test.java index 149047d50..af79f7954 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP28Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP28Test.java @@ -1,9 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP28; import nostr.base.Kind; import nostr.event.entities.ChannelProfile; @@ -11,6 +7,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP28Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP30Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP30Test.java index 783dd18ea..e26933196 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP30Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP30Test.java @@ -1,12 +1,12 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.api.NIP30; import nostr.event.BaseTag; import nostr.event.tag.EmojiTag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP30Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP31Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP31Test.java index 376b41cc1..7352c042e 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP31Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP31Test.java @@ -1,12 +1,12 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.api.NIP31; import nostr.event.BaseTag; import nostr.event.tag.GenericTag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP31Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP32Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP32Test.java index f0e5ffddb..f176b14de 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP32Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP32Test.java @@ -1,13 +1,13 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.api.NIP32; import nostr.event.BaseTag; import nostr.event.tag.LabelNamespaceTag; import nostr.event.tag.LabelTag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP32Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP40Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP40Test.java index 809402ab8..2cda66ae2 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP40Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP40Test.java @@ -1,12 +1,12 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.api.NIP40; import nostr.event.BaseTag; import nostr.event.tag.ExpirationTag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class NIP40Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP42Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP42Test.java index 0df1c155b..ab74b2506 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP42Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP42Test.java @@ -1,9 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import nostr.api.NIP42; import nostr.base.Kind; import nostr.base.Relay; @@ -15,6 +11,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP42Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP44Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP44Test.java index c5a21c21d..b72c65b56 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP44Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP44Test.java @@ -1,12 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; import nostr.api.NIP44; import nostr.event.impl.GenericEvent; import nostr.event.tag.PubKeyTag; @@ -14,6 +7,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Unit tests for NIP-44 (Encrypted Payloads - Versioned Encrypted Messages). * diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP46Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP46Test.java index 533d884e0..e10750d11 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP46Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP46Test.java @@ -1,11 +1,14 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.*; - import nostr.api.NIP46; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP46Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java index 9f27ec032..0d4717a57 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java @@ -1,10 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.event.BaseTag; @@ -19,6 +14,12 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + class NIP52ImplTest { public static final String TIME_BASED_EVENT_CONTENT = "CalendarTimeBasedEvent unit test content"; public static final String TIME_BASED_TITLE = "CalendarTimeBasedEvent title"; diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java index 2ccea9d8e..643f6cf2c 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java @@ -1,12 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; import lombok.extern.slf4j.Slf4j; import nostr.api.NIP57; import nostr.api.nip57.ZapRequestParameters; @@ -17,13 +10,20 @@ import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; import nostr.event.impl.ZapRequestEvent; -import nostr.event.tag.EventTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import nostr.util.NostrException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Unit tests for NIP-57 (Zaps - Lightning Payment Protocol). * diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java index 163e2b755..ff5c2ed20 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java @@ -1,11 +1,6 @@ package nostr.api.unit; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; -import java.util.Map; -import java.util.Set; import lombok.NonNull; import nostr.api.NIP44; import nostr.api.NIP60; @@ -28,6 +23,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; + public class NIP60Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java index ac734a773..c0fba66a5 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java @@ -1,11 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -import java.net.MalformedURLException; -import java.net.URI; -import java.util.Arrays; -import java.util.List; import nostr.api.NIP60; import nostr.api.NIP61; import nostr.base.Relay; @@ -22,6 +16,13 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + public class NIP61Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP65Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP65Test.java index 3d8ee0330..84ae36e7d 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP65Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP65Test.java @@ -1,10 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.Map; import nostr.api.NIP65; import nostr.base.Marker; import nostr.base.Relay; @@ -12,6 +7,12 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NIP65Test { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java index 1d1ced23e..4f24a8178 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java @@ -1,13 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; import nostr.api.NIP99; import nostr.event.BaseTag; import nostr.event.entities.ClassifiedListing; @@ -17,6 +9,15 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + class NIP99ImplTest { public static final String CONTENT = "ClassifiedListingEvent unit test content"; public static final String UNIT_TEST_TITLE = "unit test title"; diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NIP99Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP99Test.java index 3fb36f3f5..b8d8cb177 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NIP99Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP99Test.java @@ -1,12 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; import nostr.api.NIP99; import nostr.base.Kind; import nostr.config.Constants; @@ -17,6 +10,14 @@ import nostr.id.Identity; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Unit tests for NIP-99 classified listings (event building and required tags). */ public class NIP99Test { diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientEventVerificationTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientEventVerificationTest.java index 97fbbfee6..365aa4b91 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientEventVerificationTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientEventVerificationTest.java @@ -1,13 +1,5 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; import nostr.api.NostrSpringWebSocketClient; import nostr.api.service.NoteService; import nostr.base.ISignable; @@ -19,6 +11,15 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class NostrSpringWebSocketClientEventVerificationTest { @Test diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java index bc9fef893..051d04619 100644 --- a/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java @@ -1,17 +1,18 @@ package nostr.api.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; +import nostr.api.NostrSpringWebSocketClient; +import nostr.api.WebSocketClientHandler; +import org.junit.jupiter.api.Test; +import sun.misc.Unsafe; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import nostr.api.NostrSpringWebSocketClient; -import nostr.api.WebSocketClientHandler; -import org.junit.jupiter.api.Test; -import sun.misc.Unsafe; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; public class NostrSpringWebSocketClientTest { diff --git a/nostr-java-api/src/test/java/nostr/api/util/CommonTestObjectsFactory.java b/nostr-java-api/src/test/java/nostr/api/util/CommonTestObjectsFactory.java index 425b9041c..1490bb01a 100644 --- a/nostr-java-api/src/test/java/nostr/api/util/CommonTestObjectsFactory.java +++ b/nostr-java-api/src/test/java/nostr/api/util/CommonTestObjectsFactory.java @@ -1,9 +1,5 @@ package nostr.api.util; -import java.math.BigDecimal; -import java.util.List; -import java.util.Random; -import java.util.UUID; import lombok.Getter; import nostr.api.NIP01; import nostr.api.NIP99; @@ -21,6 +17,11 @@ import nostr.util.NostrException; import org.apache.commons.lang3.RandomStringUtils; +import java.math.BigDecimal; +import java.util.List; +import java.util.Random; +import java.util.UUID; + public class CommonTestObjectsFactory { public static Identity createNewIdentity() { diff --git a/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java b/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java index b34136590..fb92beede 100644 --- a/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java +++ b/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java @@ -1,16 +1,17 @@ package nostr.api.util; -import static java.util.Spliterators.spliteratorUnknownSize; -import static java.util.stream.StreamSupport.stream; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeType; import com.google.common.collect.Sets; + import java.util.Collection; import java.util.Comparator; import java.util.Optional; import java.util.Spliterator; +import static java.util.Spliterators.spliteratorUnknownSize; +import static java.util.stream.StreamSupport.stream; + public class JsonComparator implements Comparator> { private boolean ignoreElementOrderInArrays = true; diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 031a70e22..716f2c856 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-base/src/main/java/nostr/base/BaseKey.java b/nostr-java-base/src/main/java/nostr/base/BaseKey.java index 8c9d2a91d..939b6614d 100644 --- a/nostr-java-base/src/main/java/nostr/base/BaseKey.java +++ b/nostr-java-base/src/main/java/nostr/base/BaseKey.java @@ -1,7 +1,6 @@ package nostr.base; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.Arrays; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,6 +11,8 @@ import nostr.crypto.bech32.Bech32Prefix; import nostr.util.NostrUtil; +import java.util.Arrays; + /** * @author squirrel */ diff --git a/nostr-java-base/src/main/java/nostr/base/Kind.java b/nostr-java-base/src/main/java/nostr/base/Kind.java index 9e9f6e184..da768d014 100644 --- a/nostr-java-base/src/main/java/nostr/base/Kind.java +++ b/nostr-java-base/src/main/java/nostr/base/Kind.java @@ -2,10 +2,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import java.time.temporal.ValueRange; import lombok.AllArgsConstructor; import lombok.Getter; +import java.time.temporal.ValueRange; + /** * @author squirrel */ diff --git a/nostr-java-base/src/main/java/nostr/base/Relay.java b/nostr-java-base/src/main/java/nostr/base/Relay.java index 6c639b6ef..5b920fd44 100644 --- a/nostr-java-base/src/main/java/nostr/base/Relay.java +++ b/nostr-java-base/src/main/java/nostr/base/Relay.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -13,6 +11,9 @@ import lombok.ToString; import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-base/src/main/java/nostr/base/RelayUri.java b/nostr-java-base/src/main/java/nostr/base/RelayUri.java index 01441bedb..167b21139 100644 --- a/nostr-java-base/src/main/java/nostr/base/RelayUri.java +++ b/nostr-java-base/src/main/java/nostr/base/RelayUri.java @@ -1,9 +1,10 @@ package nostr.base; -import java.net.URI; import lombok.EqualsAndHashCode; import lombok.NonNull; +import java.net.URI; + /** * Value object that encapsulates validation of relay URIs. */ @@ -16,7 +17,7 @@ public RelayUri(@NonNull String value) { try { URI uri = URI.create(value); String scheme = uri.getScheme(); - if (scheme == null || !("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) { + if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) { throw new IllegalArgumentException("Relay URI must use ws or wss scheme"); } } catch (IllegalArgumentException ex) { diff --git a/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java index 5f9837c2f..9ddc204a2 100644 --- a/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java +++ b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java @@ -1,14 +1,15 @@ package nostr.base; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; + import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.nio.charset.StandardCharsets; -import org.junit.jupiter.api.Test; - class BaseKeyTest { public static final String VALID_HEXPUBKEY = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; diff --git a/nostr-java-base/src/test/java/nostr/base/CommandTest.java b/nostr-java-base/src/test/java/nostr/base/CommandTest.java index 32986db65..151f69e63 100644 --- a/nostr-java-base/src/test/java/nostr/base/CommandTest.java +++ b/nostr-java-base/src/test/java/nostr/base/CommandTest.java @@ -1,9 +1,9 @@ package nostr.base; -import static org.junit.jupiter.api.Assertions.assertNotNull; - import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; + class CommandTest { @Test diff --git a/nostr-java-base/src/test/java/nostr/base/KindTest.java b/nostr-java-base/src/test/java/nostr/base/KindTest.java index 0ddbd3b89..9128001dc 100644 --- a/nostr-java-base/src/test/java/nostr/base/KindTest.java +++ b/nostr-java-base/src/test/java/nostr/base/KindTest.java @@ -1,11 +1,11 @@ package nostr.base; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; - class KindTest { @Test diff --git a/nostr-java-base/src/test/java/nostr/base/MarkerTest.java b/nostr-java-base/src/test/java/nostr/base/MarkerTest.java index ca02debaf..9ff07177c 100644 --- a/nostr-java-base/src/test/java/nostr/base/MarkerTest.java +++ b/nostr-java-base/src/test/java/nostr/base/MarkerTest.java @@ -1,10 +1,10 @@ package nostr.base; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; - class MarkerTest { @Test diff --git a/nostr-java-base/src/test/java/nostr/base/RelayTest.java b/nostr-java-base/src/test/java/nostr/base/RelayTest.java index 69997067b..3a10b4e95 100644 --- a/nostr-java-base/src/test/java/nostr/base/RelayTest.java +++ b/nostr-java-base/src/test/java/nostr/base/RelayTest.java @@ -1,10 +1,10 @@ package nostr.base; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; - class RelayTest { @Test diff --git a/nostr-java-base/src/test/java/nostr/base/RelayUriTest.java b/nostr-java-base/src/test/java/nostr/base/RelayUriTest.java new file mode 100644 index 000000000..e78c55e0a --- /dev/null +++ b/nostr-java-base/src/test/java/nostr/base/RelayUriTest.java @@ -0,0 +1,22 @@ +package nostr.base; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class RelayUriTest { + // Accept only ws/wss schemes. + @Test + void validSchemes() { + assertDoesNotThrow(() -> new RelayUri("ws://example")); + assertDoesNotThrow(() -> new RelayUri("wss://example")); + } + + // Reject non-websocket schemes. + @Test + void invalidScheme() { + assertThrows(IllegalArgumentException.class, () -> new RelayUri("http://example")); + } +} + diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index a934c56fc..627ad6837 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-client/src/main/java/nostr/client/WebSocketClientFactory.java b/nostr-java-client/src/main/java/nostr/client/WebSocketClientFactory.java index 9bfeda02f..e82fc7cda 100644 --- a/nostr-java-client/src/main/java/nostr/client/WebSocketClientFactory.java +++ b/nostr-java-client/src/main/java/nostr/client/WebSocketClientFactory.java @@ -1,9 +1,10 @@ package nostr.client; -import java.util.concurrent.ExecutionException; import nostr.base.RelayUri; import nostr.client.springwebsocket.WebSocketClientIF; +import java.util.concurrent.ExecutionException; + /** * Abstraction for creating WebSocket clients for relay URIs. */ diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/NostrRetryable.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/NostrRetryable.java index cc52cc496..aa74d78a9 100644 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/NostrRetryable.java +++ b/nostr-java-client/src/main/java/nostr/client/springwebsocket/NostrRetryable.java @@ -1,12 +1,13 @@ package nostr.client.springwebsocket; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; + import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.springframework.retry.annotation.Backoff; -import org.springframework.retry.annotation.Retryable; /** Common retry configuration for WebSocket send operations. */ @Target(ElementType.METHOD) diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClient.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClient.java index 77c221432..0ff091725 100644 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClient.java +++ b/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClient.java @@ -1,9 +1,5 @@ package nostr.client.springwebsocket; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -12,6 +8,11 @@ import org.springframework.retry.annotation.Recover; import org.springframework.stereotype.Component; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; + @Component @Slf4j public class SpringWebSocketClient implements AutoCloseable { @@ -173,8 +174,8 @@ public AutoCloseable recoverSubscription( } /** - * This method is invoked by Spring Retry after all retry attempts for the {@link - * #send(BaseMessage)} method are exhausted. It logs the failure and rethrows the exception. + * This method is invoked by Spring Retry after all retry attempts for the {@link #send(BaseMessage)} + * method are exhausted. It logs the failure and rethrows the exception. * * @param ex the IOException that caused the retries to fail * @param eventMessage the BaseMessage that failed to send diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClientFactory.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClientFactory.java index 7647a53e8..328710051 100644 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClientFactory.java +++ b/nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClientFactory.java @@ -1,9 +1,10 @@ package nostr.client.springwebsocket; -import java.util.concurrent.ExecutionException; import nostr.base.RelayUri; import nostr.client.WebSocketClientFactory; +import java.util.concurrent.ExecutionException; + /** * Default factory creating Spring-based WebSocket clients. */ diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/StandardWebSocketClient.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/StandardWebSocketClient.java index 600fc717f..1a46ddda7 100644 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/StandardWebSocketClient.java +++ b/nostr-java-client/src/main/java/nostr/client/springwebsocket/StandardWebSocketClient.java @@ -1,17 +1,5 @@ package nostr.client.springwebsocket; -import static org.awaitility.Awaitility.await; - -import java.io.IOException; -import java.net.URI; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import nostr.event.BaseMessage; @@ -26,6 +14,19 @@ import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; +import java.io.IOException; +import java.net.URI; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import static org.awaitility.Awaitility.await; + @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) @Slf4j diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/WebSocketClientIF.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/WebSocketClientIF.java index 98f636473..d1da585ea 100644 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/WebSocketClientIF.java +++ b/nostr-java-client/src/main/java/nostr/client/springwebsocket/WebSocketClientIF.java @@ -1,10 +1,11 @@ package nostr.client.springwebsocket; +import nostr.event.BaseMessage; + import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.function.Consumer; -import nostr.event.BaseMessage; /** * Abstraction of a client-owned WebSocket connection to a Nostr relay. diff --git a/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientSubscribeTest.java b/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientSubscribeTest.java index cdb13fe3b..54a1ba885 100644 --- a/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientSubscribeTest.java +++ b/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientSubscribeTest.java @@ -1,11 +1,5 @@ package nostr.client.springwebsocket; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; import lombok.Getter; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +8,13 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + @SpringJUnitConfig( classes = { RetryConfig.class, diff --git a/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientTest.java b/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientTest.java index 0eae7342d..4442186fa 100644 --- a/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientTest.java +++ b/nostr-java-client/src/test/java/nostr/client/springwebsocket/SpringWebSocketClientTest.java @@ -1,11 +1,5 @@ package nostr.client.springwebsocket; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.io.IOException; -import java.util.List; -import java.util.function.Consumer; import lombok.Getter; import lombok.Setter; import nostr.event.BaseMessage; @@ -17,6 +11,13 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + @SpringJUnitConfig( classes = { RetryConfig.class, diff --git a/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientSubscriptionTest.java b/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientSubscriptionTest.java index 42db535b1..0aab79b21 100644 --- a/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientSubscriptionTest.java +++ b/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientSubscriptionTest.java @@ -1,17 +1,18 @@ package nostr.client.springwebsocket; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + class StandardWebSocketClientSubscriptionTest { // Verifies that subscription listeners receive multiple messages without blocking the caller. diff --git a/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientTimeoutTest.java b/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientTimeoutTest.java index 8af3bb7d0..014110e02 100644 --- a/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientTimeoutTest.java +++ b/nostr-java-client/src/test/java/nostr/client/springwebsocket/StandardWebSocketClientTimeoutTest.java @@ -1,13 +1,14 @@ package nostr.client.springwebsocket; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + public class StandardWebSocketClientTimeoutTest { @Test diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index 1024c2426..ab35abc9a 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/Point.java b/nostr-java-crypto/src/main/java/nostr/crypto/Point.java index 42c7f9260..bae1c018e 100644 --- a/nostr-java-crypto/src/main/java/nostr/crypto/Point.java +++ b/nostr-java-crypto/src/main/java/nostr/crypto/Point.java @@ -1,10 +1,19 @@ package nostr.crypto; -import java.math.BigInteger; -import java.security.NoSuchAlgorithmException; import lombok.NonNull; import nostr.util.NostrUtil; +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; + +/** + * Immutable affine point on secp256k1 used by nostr-java. + * + * Coordinate storage is ordered as Pair(left=x, right=y). Accessors + * {@link #getX()} and {@link #getY()} return the left and right elements + * respectively. This clarifies that constructor order is (x, y) and avoids + * ambiguity around Pair semantics. + */ public class Point { private static final BigInteger p = @@ -20,10 +29,18 @@ public class Point { private static final BigInteger BI_TWO = BigInteger.valueOf(2); private final Pair pair; + /** + * Construct a point from affine coordinates. + * Order is strictly (x, y). + */ public Point(BigInteger x, BigInteger y) { pair = Pair.of(x, y); } + /** + * Construct a point from big-endian byte arrays for (x, y). + * Order is strictly (x, y). + */ public Point(byte[] b0, byte[] b1) { pair = Pair.of(new BigInteger(1, b0), new BigInteger(1, b1)); } diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java b/nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java index 1d62133ea..5263b71f8 100644 --- a/nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java +++ b/nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java @@ -1,10 +1,11 @@ package nostr.crypto.bech32; +import nostr.util.NostrUtil; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; -import nostr.util.NostrUtil; /** * Bech32 and Bech32m encoding/decoding implementation for NIP-19. diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/nip04/EncryptedDirectMessage.java b/nostr-java-crypto/src/main/java/nostr/crypto/nip04/EncryptedDirectMessage.java index c81561dc4..0a8be7679 100644 --- a/nostr-java-crypto/src/main/java/nostr/crypto/nip04/EncryptedDirectMessage.java +++ b/nostr-java-crypto/src/main/java/nostr/crypto/nip04/EncryptedDirectMessage.java @@ -1,12 +1,5 @@ package nostr.crypto.nip04; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -18,6 +11,14 @@ import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Base64; + public class EncryptedDirectMessage { public static String encrypt(@NonNull String message, byte[] senderPrivKey, byte[] rcptPubKey) diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java b/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java index 9eb056bb7..8d05d3ca0 100644 --- a/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java +++ b/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java @@ -1,14 +1,5 @@ package nostr.crypto.nip44; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.util.Arrays; -import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKeyFactory; @@ -28,6 +19,16 @@ import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.FixedPointCombMultiplier; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Arrays; +import java.util.Base64; + @Slf4j public class EncryptedPayloads { diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/schnorr/Schnorr.java b/nostr-java-crypto/src/main/java/nostr/crypto/schnorr/Schnorr.java index a268b8a3c..a761c66a5 100644 --- a/nostr-java-crypto/src/main/java/nostr/crypto/schnorr/Schnorr.java +++ b/nostr-java-crypto/src/main/java/nostr/crypto/schnorr/Schnorr.java @@ -1,5 +1,9 @@ package nostr.crypto.schnorr; +import nostr.crypto.Point; +import nostr.util.NostrUtil; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; @@ -11,36 +15,33 @@ import java.security.interfaces.ECPrivateKey; import java.security.spec.ECGenParameterSpec; import java.util.Arrays; -import nostr.crypto.Point; -import nostr.util.NostrUtil; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -/** - * Utility methods for BIP-340 Schnorr signatures over secp256k1. - * - *

Implements signing, verification, and simple key derivation helpers used throughout the - * project. All methods operate on 32-byte inputs as mandated by the specification. - */ -public class Schnorr { - - /** - * Create a Schnorr signature for a 32-byte message. - * - * @param msg 32-byte message hash to sign - * @param secKey 32-byte secret key - * @param auxRand auxiliary 32 random bytes used for nonce derivation - * @return the 64-byte signature (R || s) - * @throws SchnorrException if inputs are invalid or signing fails - */ - public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws SchnorrException { +/** + * Utility methods for BIP-340 Schnorr signatures over secp256k1. + * + *

Implements signing, verification, and simple key derivation helpers used throughout the + * project. All methods operate on 32-byte inputs as mandated by the specification. + */ +public class Schnorr { + + /** + * Create a Schnorr signature for a 32-byte message. + * + * @param msg 32-byte message hash to sign + * @param secKey 32-byte secret key + * @param auxRand auxiliary 32 random bytes used for nonce derivation + * @return the 64-byte signature (R || s) + * @throws SchnorrException if inputs are invalid or signing fails + */ + public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws SchnorrException { if (msg.length != 32) { - throw new SchnorrException("The message must be a 32-byte array."); + throw new SchnorrException("The message must be a 32-byte array."); } BigInteger secKey0 = NostrUtil.bigIntFromBytes(secKey); if (!(BigInteger.ONE.compareTo(secKey0) <= 0 && secKey0.compareTo(Point.getn().subtract(BigInteger.ONE)) <= 0)) { - throw new SchnorrException("The secret key must be an integer in the range 1..n-1."); + throw new SchnorrException("The secret key must be an integer in the range 1..n-1."); } Point P = Point.mul(Point.getG(), secKey0); if (!P.hasEvenY()) { @@ -48,9 +49,9 @@ public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws Schn } int len = NostrUtil.bytesFromBigInteger(secKey0).length + P.toBytes().length + msg.length; byte[] buf = new byte[len]; - byte[] t = - NostrUtil.xor( - NostrUtil.bytesFromBigInteger(secKey0), taggedHashUnchecked("BIP0340/aux", auxRand)); + byte[] t = + NostrUtil.xor( + NostrUtil.bytesFromBigInteger(secKey0), taggedHashUnchecked("BIP0340/aux", auxRand)); if (t == null) { throw new RuntimeException("Unexpected error. Null array"); @@ -59,10 +60,10 @@ public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws Schn System.arraycopy(t, 0, buf, 0, t.length); System.arraycopy(P.toBytes(), 0, buf, t.length, P.toBytes().length); System.arraycopy(msg, 0, buf, t.length + P.toBytes().length, msg.length); - BigInteger k0 = - NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/nonce", buf)).mod(Point.getn()); + BigInteger k0 = + NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/nonce", buf)).mod(Point.getn()); if (k0.compareTo(BigInteger.ZERO) == 0) { - throw new SchnorrException("Failure. This happens only with negligible probability."); + throw new SchnorrException("Failure. This happens only with negligible probability."); } Point R = Point.mul(Point.getG(), k0); BigInteger k; @@ -76,8 +77,8 @@ public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws Schn System.arraycopy(R.toBytes(), 0, buf, 0, R.toBytes().length); System.arraycopy(P.toBytes(), 0, buf, R.toBytes().length, P.toBytes().length); System.arraycopy(msg, 0, buf, R.toBytes().length + P.toBytes().length, msg.length); - BigInteger e = - NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/challenge", buf)).mod(Point.getn()); + BigInteger e = + NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/challenge", buf)).mod(Point.getn()); BigInteger kes = k.add(e.multiply(secKey0)).mod(Point.getn()); len = R.toBytes().length + NostrUtil.bytesFromBigInteger(kes).length; byte[] sig = new byte[len]; @@ -89,31 +90,31 @@ public static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) throws Schn R.toBytes().length, NostrUtil.bytesFromBigInteger(kes).length); if (!verify(msg, P.toBytes(), sig)) { - throw new SchnorrException("The signature does not pass verification."); + throw new SchnorrException("The signature does not pass verification."); } return sig; } - /** - * Verify a Schnorr signature for a 32-byte message. - * - * @param msg 32-byte message hash to verify - * @param pubkey 32-byte x-only public key - * @param sig 64-byte signature (R || s) - * @return true if the signature is valid; false otherwise - * @throws SchnorrException if inputs are invalid - */ - public static boolean verify(byte[] msg, byte[] pubkey, byte[] sig) throws SchnorrException { + /** + * Verify a Schnorr signature for a 32-byte message. + * + * @param msg 32-byte message hash to verify + * @param pubkey 32-byte x-only public key + * @param sig 64-byte signature (R || s) + * @return true if the signature is valid; false otherwise + * @throws SchnorrException if inputs are invalid + */ + public static boolean verify(byte[] msg, byte[] pubkey, byte[] sig) throws SchnorrException { if (msg.length != 32) { - throw new SchnorrException("The message must be a 32-byte array."); + throw new SchnorrException("The message must be a 32-byte array."); } if (pubkey.length != 32) { - throw new SchnorrException("The public key must be a 32-byte array."); + throw new SchnorrException("The public key must be a 32-byte array."); } if (sig.length != 64) { - throw new SchnorrException("The signature must be a 64-byte array."); + throw new SchnorrException("The signature must be a 64-byte array."); } Point P = Point.liftX(pubkey); @@ -130,18 +131,18 @@ public static boolean verify(byte[] msg, byte[] pubkey, byte[] sig) throws Schno System.arraycopy(sig, 0, buf, 0, 32); System.arraycopy(pubkey, 0, buf, 32, pubkey.length); System.arraycopy(msg, 0, buf, 32 + pubkey.length, msg.length); - BigInteger e = - NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/challenge", buf)).mod(Point.getn()); + BigInteger e = + NostrUtil.bigIntFromBytes(taggedHashUnchecked("BIP0340/challenge", buf)).mod(Point.getn()); Point R = Point.add(Point.mul(Point.getG(), s), Point.mul(P, Point.getn().subtract(e))); return R != null && R.hasEvenY() && R.getX().compareTo(r) == 0; } - /** - * Generate a random private key suitable for secp256k1. - * - * @return a 32-byte private key - */ - public static byte[] generatePrivateKey() { + /** + * Generate a random private key suitable for secp256k1. + * + * @return a 32-byte private key + */ + public static byte[] generatePrivateKey() { try { Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); @@ -155,30 +156,30 @@ public static byte[] generatePrivateKey() { | NoSuchProviderException e) { throw new RuntimeException(e); } - } - - /** - * Derive the x-only public key bytes for a given private key. - * - * @param secKey 32-byte secret key - * @return the 32-byte x-only public key - * @throws SchnorrException if the private key is out of range - */ - public static byte[] genPubKey(byte[] secKey) throws SchnorrException { + } + + /** + * Derive the x-only public key bytes for a given private key. + * + * @param secKey 32-byte secret key + * @return the 32-byte x-only public key + * @throws SchnorrException if the private key is out of range + */ + public static byte[] genPubKey(byte[] secKey) throws SchnorrException { BigInteger x = NostrUtil.bigIntFromBytes(secKey); if (!(BigInteger.ONE.compareTo(x) <= 0 && x.compareTo(Point.getn().subtract(BigInteger.ONE)) <= 0)) { - throw new SchnorrException("The secret key must be an integer in the range 1..n-1."); + throw new SchnorrException("The secret key must be an integer in the range 1..n-1."); } Point ret = Point.mul(Point.G, x); - return Point.bytesFromPoint(ret); - } - - private static byte[] taggedHashUnchecked(String tag, byte[] msg) { - try { - return Point.taggedHash(tag, msg); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } -} + return Point.bytesFromPoint(ret); + } + + private static byte[] taggedHashUnchecked(String tag, byte[] msg) { + try { + return Point.taggedHash(tag, msg); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } +} diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/PointTest.java b/nostr-java-crypto/src/test/java/nostr/crypto/PointTest.java new file mode 100644 index 000000000..4c835af8a --- /dev/null +++ b/nostr-java-crypto/src/test/java/nostr/crypto/PointTest.java @@ -0,0 +1,29 @@ +package nostr.crypto; + +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PointTest { + + // Verifies constructor order (x,y) maps to getX/getY correctly. + @Test + void constructorOrderMatchesAccessors() { + BigInteger x = new BigInteger("12345678901234567890"); + BigInteger y = new BigInteger("98765432109876543210"); + Point p = new Point(x, y); + assertEquals(x, p.getX()); + assertEquals(y, p.getY()); + } + + // Ensures infinityPoint produces an infinite point. + @Test + void infinityPointIsInfinite() { + Point inf = Point.infinityPoint(); + assertTrue(inf.isInfinite()); + } +} + diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/bech32/Bech32Test.java b/nostr-java-crypto/src/test/java/nostr/crypto/bech32/Bech32Test.java index 5478f5b1f..d249fa676 100644 --- a/nostr-java-crypto/src/test/java/nostr/crypto/bech32/Bech32Test.java +++ b/nostr-java-crypto/src/test/java/nostr/crypto/bech32/Bech32Test.java @@ -1,11 +1,14 @@ package nostr.crypto.bech32; -import static org.junit.jupiter.api.Assertions.*; - import nostr.crypto.bech32.Bech32.Bech32Data; import nostr.crypto.bech32.Bech32.Encoding; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Tests for Bech32 encode/decode and NIP-19 helpers. */ public class Bech32Test { diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/schnorr/SchnorrTest.java b/nostr-java-crypto/src/test/java/nostr/crypto/schnorr/SchnorrTest.java index 07e7c777d..114a4cf9a 100644 --- a/nostr-java-crypto/src/test/java/nostr/crypto/schnorr/SchnorrTest.java +++ b/nostr-java-crypto/src/test/java/nostr/crypto/schnorr/SchnorrTest.java @@ -1,11 +1,14 @@ package nostr.crypto.schnorr; -import static org.junit.jupiter.api.Assertions.*; - -import java.security.NoSuchAlgorithmException; import nostr.util.NostrUtil; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Tests for Schnorr signing and verification helpers. */ public class SchnorrTest { diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 44110e908..e97e13964 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java index c3cbaf002..d08c624d6 100644 --- a/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java +++ b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java @@ -1,8 +1,5 @@ package nostr.encryption; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; @@ -11,6 +8,10 @@ import lombok.NonNull; import nostr.crypto.nip04.EncryptedDirectMessage; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + @Data @AllArgsConstructor public class MessageCipher04 implements MessageCipher { diff --git a/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java index 256d7988d..c393131f5 100644 --- a/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java +++ b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java @@ -1,13 +1,14 @@ package nostr.encryption; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; import nostr.crypto.nip44.EncryptedPayloads; import nostr.util.NostrUtil; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + @Data @AllArgsConstructor public class MessageCipher44 implements MessageCipher { diff --git a/nostr-java-encryption/src/test/java/nostr/encryption/MessageCipherTest.java b/nostr-java-encryption/src/test/java/nostr/encryption/MessageCipherTest.java index ae7f04501..c1b61069c 100644 --- a/nostr-java-encryption/src/test/java/nostr/encryption/MessageCipherTest.java +++ b/nostr-java-encryption/src/test/java/nostr/encryption/MessageCipherTest.java @@ -1,11 +1,11 @@ package nostr.encryption; -import static org.junit.jupiter.api.Assertions.assertEquals; - import nostr.crypto.schnorr.Schnorr; import nostr.crypto.schnorr.SchnorrException; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + class MessageCipherTest { @Test diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 0ba9c4ad6..137d19341 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-event/src/main/java/nostr/event/BaseTag.java b/nostr-java-event/src/main/java/nostr/event/BaseTag.java index da23db91e..60dfe86c7 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -3,17 +3,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -29,6 +18,18 @@ import nostr.event.tag.TagRegistry; import org.apache.commons.lang3.stream.Streams; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + /** * Base class for all Nostr event tags. * diff --git a/nostr-java-event/src/main/java/nostr/event/JsonContent.java b/nostr-java-event/src/main/java/nostr/event/JsonContent.java index 16b25a0f0..9e0e2644e 100644 --- a/nostr-java-event/src/main/java/nostr/event/JsonContent.java +++ b/nostr-java-event/src/main/java/nostr/event/JsonContent.java @@ -1,9 +1,9 @@ package nostr.event; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; +import static nostr.base.json.EventJsonMapper.mapper; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/NIP01Event.java b/nostr-java-event/src/main/java/nostr/event/NIP01Event.java index 032d68938..3d33f16a3 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP01Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP01Event.java @@ -1,11 +1,12 @@ package nostr.event; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/NIP04Event.java b/nostr-java-event/src/main/java/nostr/event/NIP04Event.java index 28a417b3b..5764f0121 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP04Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP04Event.java @@ -1,12 +1,13 @@ package nostr.event; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/NIP09Event.java b/nostr-java-event/src/main/java/nostr/event/NIP09Event.java index 59da445ca..b05d02044 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP09Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP09Event.java @@ -1,11 +1,12 @@ package nostr.event; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/NIP25Event.java b/nostr-java-event/src/main/java/nostr/event/NIP25Event.java index ae2e85309..4010e20bd 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP25Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP25Event.java @@ -1,11 +1,12 @@ package nostr.event; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/NIP52Event.java b/nostr-java-event/src/main/java/nostr/event/NIP52Event.java index 39b2d42c7..7c6a6a6a4 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP52Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP52Event.java @@ -1,6 +1,5 @@ package nostr.event; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -8,6 +7,8 @@ import nostr.base.PublicKey; import nostr.event.impl.AddressableEvent; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @NoArgsConstructor public abstract class NIP52Event extends AddressableEvent { diff --git a/nostr-java-event/src/main/java/nostr/event/NIP99Event.java b/nostr-java-event/src/main/java/nostr/event/NIP99Event.java index fbb3f4691..0861b870a 100644 --- a/nostr-java-event/src/main/java/nostr/event/NIP99Event.java +++ b/nostr-java-event/src/main/java/nostr/event/NIP99Event.java @@ -1,12 +1,13 @@ package nostr.event; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @NoArgsConstructor public abstract class NIP99Event extends GenericEvent { diff --git a/nostr-java-event/src/main/java/nostr/event/Nip05Content.java b/nostr-java-event/src/main/java/nostr/event/Nip05Content.java index da847d4f3..b64dbbfbc 100644 --- a/nostr-java-event/src/main/java/nostr/event/Nip05Content.java +++ b/nostr-java-event/src/main/java/nostr/event/Nip05Content.java @@ -1,12 +1,13 @@ package nostr.event; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import java.util.Map; import lombok.Data; import lombok.NoArgsConstructor; import nostr.base.IElement; +import java.util.List; +import java.util.Map; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java b/nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java index c0e681d47..ab5d695bb 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java @@ -1,11 +1,5 @@ package nostr.event.entities; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -20,6 +14,13 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.ReferenceTag; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + @EqualsAndHashCode(callSuper = false) public class CalendarContent extends NIP42Content { diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CalendarRsvpContent.java b/nostr-java-event/src/main/java/nostr/event/entities/CalendarRsvpContent.java index 2ec4cefbc..84dc20972 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CalendarRsvpContent.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CalendarRsvpContent.java @@ -1,7 +1,6 @@ package nostr.event.entities; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.Optional; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -13,6 +12,8 @@ import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; +import java.util.Optional; + @Builder @JsonDeserialize(builder = CalendarRsvpContentBuilder.class) @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CashuMint.java b/nostr-java-event/src/main/java/nostr/event/entities/CashuMint.java index 56068c025..8f00d03e1 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CashuMint.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CashuMint.java @@ -1,13 +1,14 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.RequiredArgsConstructor; +import java.util.List; + @Data @RequiredArgsConstructor @AllArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CashuProof.java b/nostr-java-event/src/main/java/nostr/event/entities/CashuProof.java index fb3e9d16d..529bb4cfa 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CashuProof.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CashuProof.java @@ -1,7 +1,5 @@ package nostr.event.entities; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; @@ -12,6 +10,8 @@ import lombok.NoArgsConstructor; import nostr.event.json.codec.EventEncodingException; +import static nostr.base.json.EventJsonMapper.mapper; + @Data @NoArgsConstructor @AllArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java b/nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java index 9f2926a6a..3554ab8fc 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CashuToken.java @@ -1,8 +1,6 @@ package nostr.event.entities; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.util.ArrayList; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,6 +8,9 @@ import lombok.NonNull; import nostr.event.json.serializer.CashuTokenSerializer; +import java.util.ArrayList; +import java.util.List; + @Data @AllArgsConstructor @Builder @@ -19,11 +20,14 @@ public class CashuToken { @EqualsAndHashCode.Include private CashuMint mint; - @EqualsAndHashCode.Include private List proofs; + @EqualsAndHashCode.Include + @Builder.Default + private List proofs = new ArrayList<>(); - private List destroyed; + @Builder.Default private List destroyed = new ArrayList<>(); public CashuToken() { + this.proofs = new ArrayList<>(); this.destroyed = new ArrayList<>(); } @@ -40,6 +44,21 @@ public void removeDestroyed(@NonNull String eventId) { } public Integer calculateAmount() { + if (proofs == null || proofs.isEmpty()) return 0; return proofs.stream().mapToInt(CashuProof::getAmount).sum(); } + + /** + * Number of destroyed event references recorded in this token. + */ + public int getDestroyedCount() { + return this.destroyed != null ? this.destroyed.size() : 0; + } + + /** + * Checks whether a destroyed event id is recorded. + */ + public boolean containsDestroyed(@NonNull String eventId) { + return this.destroyed != null && this.destroyed.contains(eventId); + } } diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CashuWallet.java b/nostr-java-event/src/main/java/nostr/event/entities/CashuWallet.java index abb1df2a1..085aa5eaf 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CashuWallet.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CashuWallet.java @@ -1,9 +1,5 @@ package nostr.event.entities; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -11,6 +7,11 @@ import lombok.NonNull; import nostr.base.Relay; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true) @AllArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/entities/ChannelProfile.java b/nostr-java-event/src/main/java/nostr/event/entities/ChannelProfile.java index 3bdc8b460..42579c429 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/ChannelProfile.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/ChannelProfile.java @@ -1,12 +1,13 @@ package nostr.event.entities; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; /** * @author eric diff --git a/nostr-java-event/src/main/java/nostr/event/entities/CustomerOrder.java b/nostr-java-event/src/main/java/nostr/event/entities/CustomerOrder.java index 4870b16eb..30638e2bd 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/CustomerOrder.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/CustomerOrder.java @@ -1,9 +1,6 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -13,6 +10,10 @@ import lombok.ToString; import nostr.base.PublicKey; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Getter @Setter @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/NutZap.java b/nostr-java-event/src/main/java/nostr/event/entities/NutZap.java index 8a4169579..6cd4dc6a9 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/NutZap.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/NutZap.java @@ -1,12 +1,13 @@ package nostr.event.entities; -import java.util.List; import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.PublicKey; import nostr.event.tag.EventTag; +import java.util.List; + @Data @NoArgsConstructor public class NutZap { @@ -22,4 +23,13 @@ public void addProof(@NonNull CashuProof cashuProof) { } proofs.add(cashuProof); } + + /** + * Sum the amount contained in this zap's proofs. + * Returns 0 when no proofs exist. + */ + public int getTotalAmount() { + if (proofs == null || proofs.isEmpty()) return 0; + return proofs.stream().mapToInt(CashuProof::getAmount).sum(); + } } diff --git a/nostr-java-event/src/main/java/nostr/event/entities/NutZapInformation.java b/nostr-java-event/src/main/java/nostr/event/entities/NutZapInformation.java index 2e90926dc..eea2c6aae 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/NutZapInformation.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/NutZapInformation.java @@ -1,11 +1,12 @@ package nostr.event.entities; -import java.util.ArrayList; -import java.util.List; import lombok.Data; import lombok.NoArgsConstructor; import nostr.base.Relay; +import java.util.ArrayList; +import java.util.List; + @Data @NoArgsConstructor public class NutZapInformation { diff --git a/nostr-java-event/src/main/java/nostr/event/entities/PaymentRequest.java b/nostr-java-event/src/main/java/nostr/event/entities/PaymentRequest.java index bae8a9153..439137459 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/PaymentRequest.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/PaymentRequest.java @@ -2,9 +2,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -12,6 +9,10 @@ import lombok.Setter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Getter @Setter @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/PaymentShipmentStatus.java b/nostr-java-event/src/main/java/nostr/event/entities/PaymentShipmentStatus.java index 4596342f9..ea58c2028 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/PaymentShipmentStatus.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/PaymentShipmentStatus.java @@ -1,12 +1,13 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.UUID; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.UUID; + @Getter @Setter @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/Product.java b/nostr-java-event/src/main/java/nostr/event/entities/Product.java index 85ee04572..4c65a2ddb 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/Product.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/Product.java @@ -1,15 +1,16 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Getter @Setter @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/Profile.java b/nostr-java-event/src/main/java/nostr/event/entities/Profile.java index 8eb2a9f9d..6829bafa3 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/Profile.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/Profile.java @@ -1,6 +1,5 @@ package nostr.event.entities; -import java.net.URL; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -8,6 +7,8 @@ import lombok.ToString; import lombok.experimental.SuperBuilder; +import java.net.URL; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/entities/SpendingHistory.java b/nostr-java-event/src/main/java/nostr/event/entities/SpendingHistory.java index b7f99080a..ef830fa1f 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/SpendingHistory.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/SpendingHistory.java @@ -1,8 +1,6 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.ArrayList; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,6 +8,9 @@ import lombok.NonNull; import nostr.event.tag.EventTag; +import java.util.ArrayList; +import java.util.List; + @Data @NoArgsConstructor @AllArgsConstructor @@ -39,4 +40,11 @@ public String getValue() { public void addEventTag(@NonNull EventTag eventTag) { this.eventTags.add(eventTag); } + + /** + * Returns the number of associated event tags. + */ + public int getEventTagCount() { + return this.eventTags != null ? this.eventTags.size() : 0; + } } diff --git a/nostr-java-event/src/main/java/nostr/event/entities/Stall.java b/nostr-java-event/src/main/java/nostr/event/entities/Stall.java index d843485f4..c2d304880 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/Stall.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/Stall.java @@ -1,14 +1,15 @@ package nostr.event.entities; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Getter @Setter @EqualsAndHashCode(callSuper = false) diff --git a/nostr-java-event/src/main/java/nostr/event/entities/UserProfile.java b/nostr-java-event/src/main/java/nostr/event/entities/UserProfile.java index 96e4c7533..ebc1d104f 100644 --- a/nostr-java-event/src/main/java/nostr/event/entities/UserProfile.java +++ b/nostr-java-event/src/main/java/nostr/event/entities/UserProfile.java @@ -1,10 +1,7 @@ package nostr.event.entities; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; -import java.net.URL; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -16,6 +13,10 @@ import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; +import java.net.URL; + +import static nostr.base.json.EventJsonMapper.mapper; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/filter/AddressTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/AddressTagFilter.java index ddfaa78e5..b67c981e1 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/AddressTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/AddressTagFilter.java @@ -1,6 +1,14 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import nostr.base.PublicKey; +import nostr.base.Relay; +import nostr.event.impl.GenericEvent; +import nostr.event.tag.AddressTag; +import nostr.event.tag.IdentifierTag; + import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -9,14 +17,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import lombok.EqualsAndHashCode; -import lombok.NonNull; -import nostr.base.PublicKey; -import nostr.base.Relay; -import nostr.event.BaseTag; -import nostr.event.impl.GenericEvent; -import nostr.event.tag.AddressTag; -import nostr.event.tag.IdentifierTag; @EqualsAndHashCode(callSuper = true) public class AddressTagFilter extends AbstractFilterable { @@ -54,8 +54,7 @@ private T getAddressableTag() { public static Function fxn = node -> new AddressTagFilter<>(createAddressTag(node)); - @SuppressWarnings("unchecked") - protected static T createAddressTag(@NonNull JsonNode node) { + protected static AddressTag createAddressTag(@NonNull JsonNode node) { String[] nodes = node.asText().split(","); List list = Arrays.stream(nodes[0].split(":")).toList(); @@ -64,11 +63,11 @@ protected static T createAddressTag(@NonNull JsonNode node) addressTag.setPublicKey(new PublicKey(list.get(1))); addressTag.setIdentifierTag(new IdentifierTag(list.get(2))); - if (!Objects.equals(2, nodes.length)) return (T) addressTag; + if (!Objects.equals(2, nodes.length)) return addressTag; addressTag.setIdentifierTag(new IdentifierTag(list.get(2).replaceAll("\"$", ""))); addressTag.setRelay(new Relay(nodes[1].replaceAll("^\"", ""))); - return (T) addressTag; + return addressTag; } } diff --git a/nostr-java-event/src/main/java/nostr/event/filter/AuthorFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/AuthorFilter.java index c1742deff..71881816d 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/AuthorFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/AuthorFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class AuthorFilter extends AbstractFilterable { public static final String FILTER_KEY = "authors"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/EventFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/EventFilter.java index d02512b58..d3b564ba8 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/EventFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/EventFilter.java @@ -1,11 +1,12 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class EventFilter extends AbstractFilterable { public static final String FILTER_KEY = "ids"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/Filterable.java b/nostr-java-event/src/main/java/nostr/event/filter/Filterable.java index fc44bd89d..50a5d17f5 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/Filterable.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/Filterable.java @@ -1,16 +1,17 @@ package nostr.event.filter; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; import lombok.NonNull; import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +import static nostr.base.json.EventJsonMapper.mapper; + public interface Filterable { Predicate getPredicate(); diff --git a/nostr-java-event/src/main/java/nostr/event/filter/Filters.java b/nostr-java-event/src/main/java/nostr/event/filter/Filters.java index 2b688dc0b..1c91b767e 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/Filters.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/Filters.java @@ -1,16 +1,17 @@ package nostr.event.filter; -import static java.util.stream.Collectors.groupingBy; - -import java.util.List; -import java.util.Map; -import java.util.Objects; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; import lombok.ToString; import nostr.base.IElement; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static java.util.stream.Collectors.groupingBy; + @Getter @EqualsAndHashCode @ToString diff --git a/nostr-java-event/src/main/java/nostr/event/filter/GenericTagQueryFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/GenericTagQueryFilter.java index 1c968d154..765982d95 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/GenericTagQueryFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/GenericTagQueryFilter.java @@ -1,14 +1,15 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; import nostr.event.impl.GenericEvent; import nostr.event.tag.GenericTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class GenericTagQueryFilter extends AbstractFilterable { public static final String HASH_PREFIX = "#"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/GeohashTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/GeohashTagFilter.java index ad6419603..5071a75b1 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/GeohashTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/GeohashTagFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; import nostr.event.tag.GeohashTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class GeohashTagFilter extends AbstractFilterable { public static final String FILTER_KEY = "#g"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/HashtagTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/HashtagTagFilter.java index 9985d7443..6b40f8caa 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/HashtagTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/HashtagTagFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; import nostr.event.tag.HashtagTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class HashtagTagFilter extends AbstractFilterable { public static final String FILTER_KEY = "#t"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/IdentifierTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/IdentifierTagFilter.java index 1cac5deb0..a924130d5 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/IdentifierTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/IdentifierTagFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; import nostr.event.tag.IdentifierTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class IdentifierTagFilter extends AbstractFilterable { public static final String FILTER_KEY = "#d"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/KindFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/KindFilter.java index 42235fcce..09d4f8694 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/KindFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/KindFilter.java @@ -1,15 +1,16 @@ package nostr.event.filter; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.base.Kind; import nostr.event.impl.GenericEvent; +import java.util.function.Function; +import java.util.function.Predicate; + +import static nostr.base.json.EventJsonMapper.mapper; + @EqualsAndHashCode(callSuper = true) public class KindFilter extends AbstractFilterable { public static final String FILTER_KEY = "kinds"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/ReferencedEventFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/ReferencedEventFilter.java index 668cb4e4d..ec121727b 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/ReferencedEventFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/ReferencedEventFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; import nostr.event.tag.EventTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class ReferencedEventFilter extends AbstractFilterable { public static final String FILTER_KEY = "#e"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/ReferencedPublicKeyFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/ReferencedPublicKeyFilter.java index dc1a75c97..4966e480a 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/ReferencedPublicKeyFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/ReferencedPublicKeyFilter.java @@ -1,13 +1,14 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.base.PublicKey; import nostr.event.impl.GenericEvent; import nostr.event.tag.PubKeyTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class ReferencedPublicKeyFilter extends AbstractFilterable { public static final String FILTER_KEY = "#p"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/SinceFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/SinceFilter.java index bf5abb2fc..d7f92b10b 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/SinceFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/SinceFilter.java @@ -1,14 +1,15 @@ package nostr.event.filter; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.EqualsAndHashCode; +import nostr.event.impl.GenericEvent; + import java.util.List; import java.util.function.Function; import java.util.function.Predicate; -import lombok.EqualsAndHashCode; -import nostr.event.impl.GenericEvent; + +import static nostr.base.json.EventJsonMapper.mapper; @EqualsAndHashCode(callSuper = true) public class SinceFilter extends AbstractFilterable { diff --git a/nostr-java-event/src/main/java/nostr/event/filter/UntilFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/UntilFilter.java index f7c1f11f6..0f20ff063 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/UntilFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/UntilFilter.java @@ -1,14 +1,15 @@ package nostr.event.filter; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.EqualsAndHashCode; +import nostr.event.impl.GenericEvent; + import java.util.List; import java.util.function.Function; import java.util.function.Predicate; -import lombok.EqualsAndHashCode; -import nostr.event.impl.GenericEvent; + +import static nostr.base.json.EventJsonMapper.mapper; @EqualsAndHashCode(callSuper = true) public class UntilFilter extends AbstractFilterable { diff --git a/nostr-java-event/src/main/java/nostr/event/filter/UrlTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/UrlTagFilter.java index 1237ec094..933745dcf 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/UrlTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/UrlTagFilter.java @@ -1,11 +1,12 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import nostr.event.impl.GenericEvent; import nostr.event.tag.UrlTag; +import java.util.function.Function; +import java.util.function.Predicate; + public class UrlTagFilter extends AbstractFilterable { public static final String FILTER_KEY = "#u"; diff --git a/nostr-java-event/src/main/java/nostr/event/filter/VoteTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/VoteTagFilter.java index 8bf1aea32..e63d844fd 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/VoteTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/VoteTagFilter.java @@ -1,12 +1,13 @@ package nostr.event.filter; import com.fasterxml.jackson.databind.JsonNode; -import java.util.function.Function; -import java.util.function.Predicate; import lombok.EqualsAndHashCode; import nostr.event.impl.GenericEvent; import nostr.event.tag.VoteTag; +import java.util.function.Function; +import java.util.function.Predicate; + @EqualsAndHashCode(callSuper = true) public class VoteTagFilter extends AbstractFilterable { public static final String FILTER_KEY = "#v"; diff --git a/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseCalendarEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseCalendarEvent.java index f088975f3..1acb0558f 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseCalendarEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseCalendarEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -9,6 +8,8 @@ import nostr.event.JsonContent; import nostr.event.NIP52Event; +import java.util.List; + @NoArgsConstructor public abstract class AbstractBaseCalendarEvent extends NIP52Event { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseNostrConnectEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseNostrConnectEvent.java index 10077919c..de10023f9 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseNostrConnectEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/AbstractBaseNostrConnectEvent.java @@ -1,11 +1,12 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.PublicKey; import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; +import java.util.List; + @NoArgsConstructor public abstract class AbstractBaseNostrConnectEvent extends EphemeralEvent { public AbstractBaseNostrConnectEvent( diff --git a/nostr-java-event/src/main/java/nostr/event/impl/AddressableEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/AddressableEvent.java index 5783165d4..400d4e44e 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/AddressableEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/AddressableEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -9,6 +8,8 @@ import nostr.event.BaseTag; import nostr.event.NIP01Event; +import java.util.List; + @Data @EqualsAndHashCode(callSuper = false) @Event(name = "Addressable Events") @@ -19,13 +20,28 @@ public AddressableEvent(PublicKey pubKey, Integer kind, List tags, Stri super(pubKey, kind, tags, content); } + /** + * Validates that the event kind is within the addressable event range. + * + *

Per NIP-01, addressable events (also called parameterized replaceable events) must have + * kinds in the range [30000, 40000). These events are replaceable and addressable via the + * combination of kind, pubkey, and 'd' tag. + * + * @throws AssertionError if kind is not in the valid range [30000, 40000) + */ @Override public void validateKind() { super.validateKind(); - var n = getKind(); - if (30_000 <= n && n < 40_000) return; + Integer n = getKind(); + // NIP-01: Addressable events must be in range [30000, 40000) + if (n >= 30_000 && n < 40_000) { + return; // Valid addressable event kind + } - throw new AssertionError("Invalid kind value. Must be between 30000 and 40000.", null); + throw new AssertionError( + String.format( + "Invalid kind value %d. Addressable events must be in range [30000, 40000).", n), + null); } } diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CalendarDateBasedEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CalendarDateBasedEvent.java index 0b89360ab..d28c85285 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CalendarDateBasedEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CalendarDateBasedEvent.java @@ -1,9 +1,6 @@ package nostr.event.impl; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.Date; -import java.util.List; -import java.util.Optional; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; @@ -18,6 +15,10 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.ReferenceTag; +import java.util.Date; +import java.util.List; +import java.util.Optional; + @Event(name = "Date-Based Calendar Event", nip = 52) @JsonDeserialize(using = CalendarDateBasedEventDeserializer.class) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CalendarEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CalendarEvent.java index ba2a183b4..0c7075ec5 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CalendarEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CalendarEvent.java @@ -1,8 +1,6 @@ package nostr.event.impl; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.List; -import java.util.Optional; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -16,6 +14,8 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.IdentifierTag; +import java.util.List; + @Event(name = "Calendar Event", nip = 52) @JsonDeserialize(using = CalendarEventDeserializer.class) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CalendarRsvpEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CalendarRsvpEvent.java index f02aab54a..40102d526 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CalendarRsvpEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CalendarRsvpEvent.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.List; -import java.util.Optional; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -19,6 +17,9 @@ import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; +import java.util.List; +import java.util.Optional; + @EqualsAndHashCode(callSuper = false) @Event(name = "CalendarRsvpEvent", nip = 52) @JsonDeserialize(using = CalendarRsvpEventDeserializer.class) diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CalendarTimeBasedEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CalendarTimeBasedEvent.java index 47f2fd111..da5240aa2 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CalendarTimeBasedEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CalendarTimeBasedEvent.java @@ -1,8 +1,6 @@ package nostr.event.impl; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.List; -import java.util.Optional; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -15,6 +13,9 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.LabelTag; +import java.util.List; +import java.util.Optional; + @EqualsAndHashCode(callSuper = false) @Event(name = "Time-Based Calendar Event", nip = 52) @JsonDeserialize(using = CalendarTimeBasedEventDeserializer.class) diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CanonicalAuthenticationEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CanonicalAuthenticationEvent.java index f5e73ecd4..e87c10dfd 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CanonicalAuthenticationEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CanonicalAuthenticationEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -10,6 +9,8 @@ import nostr.event.BaseTag; import nostr.event.tag.GenericTag; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ChannelCreateEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ChannelCreateEvent.java index f2f333efc..761f7bd26 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ChannelCreateEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ChannelCreateEvent.java @@ -1,16 +1,16 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.entities.ChannelProfile; import nostr.event.json.codec.EventEncodingException; +import java.util.ArrayList; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ChannelMessageEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ChannelMessageEvent.java index a282c1cb8..219448721 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ChannelMessageEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ChannelMessageEvent.java @@ -1,7 +1,5 @@ package nostr.event.impl; -import java.util.ArrayList; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -12,6 +10,9 @@ import nostr.event.BaseTag; import nostr.event.tag.EventTag; +import java.util.ArrayList; +import java.util.List; + /** * @author guilhermegps */ @@ -25,7 +26,7 @@ public ChannelMessageEvent(PublicKey pubKey, List baseTags, String cont public String getChannelCreateEventId() { return nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.ROOT) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.ROOT).isPresent()) .map(EventTag::getIdEvent) .findFirst() .orElseThrow(); @@ -33,7 +34,7 @@ public String getChannelCreateEventId() { public String getChannelMessageReplyEventId() { return nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.REPLY) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.REPLY).isPresent()) .map(EventTag::getIdEvent) .findFirst() .orElse(null); @@ -41,8 +42,9 @@ public String getChannelMessageReplyEventId() { public Relay getRootRecommendedRelay() { return nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.ROOT) - .map(EventTag::getRecommendedRelayUrl) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.ROOT).isPresent()) + .map(EventTag::getRecommendedRelayUrlOptional) + .flatMap(java.util.Optional::stream) .map(Relay::new) .findFirst() .orElse(null); @@ -50,8 +52,10 @@ public Relay getRootRecommendedRelay() { public Relay getReplyRecommendedRelay(@NonNull String eventId) { return nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.REPLY && tag.getIdEvent().equals(eventId)) - .map(EventTag::getRecommendedRelayUrl) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.REPLY).isPresent() + && tag.getIdEvent().equals(eventId)) + .map(EventTag::getRecommendedRelayUrlOptional) + .flatMap(java.util.Optional::stream) .map(Relay::new) .findFirst() .orElse(null); @@ -63,7 +67,7 @@ public void validate() { // Check 'e' root - tag EventTag rootTag = nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.ROOT) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.ROOT).isPresent()) .findFirst() .orElseThrow(() -> new AssertionError("Missing or invalid `e` root tag.")); } diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ChannelMetadataEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ChannelMetadataEvent.java index 214223de2..ed504fb09 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ChannelMetadataEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ChannelMetadataEvent.java @@ -1,19 +1,19 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.Marker; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.ChannelProfile; +import nostr.event.json.codec.EventEncodingException; import nostr.event.tag.EventTag; import nostr.event.tag.HashtagTag; -import nostr.event.json.codec.EventEncodingException; + +import java.util.List; /** * @author guilhermegps @@ -60,7 +60,7 @@ protected void validateContent() { public String getChannelCreateEventId() { return nostr.event.filter.Filterable.getTypeSpecificTags(EventTag.class, this).stream() - .filter(tag -> tag.getMarker() == Marker.ROOT) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.ROOT).isPresent()) .map(EventTag::getIdEvent) .findFirst() .orElseThrow(); @@ -80,7 +80,7 @@ protected void validateTags() { nostr.event.filter.Filterable .getTypeSpecificTags(EventTag.class, this) .stream() - .filter(tag -> tag.getMarker() == Marker.ROOT) + .filter(tag -> tag.getMarkerOptional().filter(m -> m == Marker.ROOT).isPresent()) .findFirst() .orElseThrow(() -> new AssertionError("Missing or invalid `e` root tag.")); } diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CheckoutEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CheckoutEvent.java index 4062aefdc..05e820d66 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CheckoutEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CheckoutEvent.java @@ -1,7 +1,6 @@ package nostr.event.impl; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -10,6 +9,8 @@ import nostr.event.BaseTag; import nostr.event.entities.NIP15Content; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ClassifiedListingEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ClassifiedListingEvent.java index 2e1ec9523..4a5b413d6 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ClassifiedListingEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ClassifiedListingEvent.java @@ -1,8 +1,6 @@ package nostr.event.impl; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.time.Instant; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -16,6 +14,9 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.PriceTag; +import java.time.Instant; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @Event(name = "ClassifiedListingEvent", nip = 99) @JsonDeserialize(using = ClassifiedListingEventDeserializer.class) @@ -100,7 +101,7 @@ public String getPrice() { return priceTag.getNumber().toString() + " " + priceTag.getCurrency() - + (priceTag.getFrequency() != null ? " " + priceTag.getFrequency() : ""); + + priceTag.getFrequencyOptional().map(f -> " " + f).orElse(""); } @Override @@ -156,11 +157,17 @@ protected void validateTags() { @Override public void validateKind() { var n = getKind(); - if (30402 <= n && n <= 30403) return; + // Accept only NIP-99 classified listing kinds + if (n == Kind.CLASSIFIED_LISTING.getValue() || n == Kind.CLASSIFIED_LISTING_INACTIVE.getValue()) { + return; + } throw new AssertionError( String.format( - "Invalid kind value [%s]. Classified Listing must be either 30402 or 30403", n), + "Invalid kind value [%s]. Classified Listing must be either %d or %d", + n, + Kind.CLASSIFIED_LISTING.getValue(), + Kind.CLASSIFIED_LISTING_INACTIVE.getValue()), null); } } diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ContactListEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ContactListEvent.java index 87c4aa696..11afd1b38 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ContactListEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ContactListEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -10,6 +9,8 @@ import nostr.base.annotation.Event; import nostr.event.BaseTag; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateProductEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateProductEvent.java index 3496baf3c..ddf2820c4 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateProductEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateProductEvent.java @@ -1,19 +1,18 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.Product; import nostr.event.json.codec.EventEncodingException; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateStallEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateStallEvent.java index 0dde5e467..bf83b2afe 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateStallEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateStallEvent.java @@ -1,21 +1,20 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.Stall; import nostr.event.json.codec.EventEncodingException; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/CustomerOrderEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/CustomerOrderEvent.java index 0d4377778..2eafa3838 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/CustomerOrderEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/CustomerOrderEvent.java @@ -1,21 +1,20 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.CustomerOrder; import nostr.event.json.codec.EventEncodingException; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/DeletionEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/DeletionEvent.java index 392d4f7e2..0efe3c6da 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/DeletionEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/DeletionEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -11,6 +10,8 @@ import nostr.event.NIP09Event; import nostr.event.tag.EventTag; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/DirectMessageEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/DirectMessageEvent.java index 4ca739f13..3841fa6f9 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/DirectMessageEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/DirectMessageEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -10,6 +9,8 @@ import nostr.event.NIP04Event; import nostr.event.tag.PubKeyTag; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/EphemeralEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/EphemeralEvent.java index 2a8f22a89..4f424889c 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/EphemeralEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/EphemeralEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -10,6 +9,8 @@ import nostr.event.BaseTag; import nostr.event.NIP01Event; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericEvent.java index 61c6a5bc8..c2019c8c5 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericEvent.java @@ -3,16 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.beans.Transient; -import java.lang.reflect.InvocationTargetException; -import java.nio.ByteBuffer; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Supplier; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -36,6 +26,17 @@ import nostr.util.NostrException; import nostr.util.validator.HexStringValidator; +import java.beans.Transient; +import java.lang.reflect.InvocationTargetException; +import java.nio.ByteBuffer; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; + /** * Generic implementation of a Nostr event as defined in NIP-01. * @@ -171,7 +172,9 @@ public GenericEvent( @NonNull List tags, @NonNull String content) { this.pubKey = pubKey; - this.kind = Kind.valueOf(kind).getValue(); + // Accept provided kind value verbatim for custom kinds (e.g., NIP-defined ranges). + // Use the Kind-typed constructor when mapping enum constants to values. + this.kind = kind; this.tags = new ArrayList<>(tags); this.content = content; diff --git a/nostr-java-event/src/main/java/nostr/event/impl/HideMessageEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/HideMessageEvent.java index ba6b4cc49..b6b7a1d5c 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/HideMessageEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/HideMessageEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; @@ -8,6 +7,8 @@ import nostr.event.BaseTag; import nostr.event.tag.EventTag; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/InternetIdentifierMetadataEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/InternetIdentifierMetadataEvent.java index 601da3ac4..79fa439dd 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/InternetIdentifierMetadataEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/InternetIdentifierMetadataEvent.java @@ -1,7 +1,5 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,6 +7,7 @@ import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.NIP05Event; import nostr.event.entities.UserProfile; import nostr.event.json.codec.EventEncodingException; diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MentionsEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MentionsEvent.java index 4c1de918a..011e9ecda 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MentionsEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MentionsEvent.java @@ -1,7 +1,5 @@ package nostr.event.impl; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -10,6 +8,9 @@ import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MerchantEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MerchantEvent.java index db3c62302..2dc18d6cd 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MerchantEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MerchantEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -10,6 +9,8 @@ import nostr.event.entities.NIP15Content; import nostr.event.tag.IdentifierTag; +import java.util.List; + @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MerchantRequestPaymentEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MerchantRequestPaymentEvent.java index eab7321da..2459a8b38 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MerchantRequestPaymentEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MerchantRequestPaymentEvent.java @@ -1,19 +1,18 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.PaymentRequest; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MuteUserEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MuteUserEvent.java index 5dbf16346..c5073c6c0 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MuteUserEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MuteUserEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.Kind; import nostr.base.PublicKey; @@ -8,6 +7,8 @@ import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; +import java.util.List; + /** * @author guilhermegps */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectEvent.java index 21c170493..d1eb64ca2 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectEvent.java @@ -1,12 +1,13 @@ package nostr.event.impl; -import java.util.ArrayList; import lombok.EqualsAndHashCode; import lombok.NonNull; import nostr.base.PublicKey; import nostr.base.annotation.Event; import nostr.event.tag.PubKeyTag; +import java.util.ArrayList; + @EqualsAndHashCode(callSuper = false) @Event(name = "Nostr Connect", nip = 46) public class NostrConnectEvent extends EphemeralEvent { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectRequestEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectRequestEvent.java index f54ac8c7a..a0d624c47 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectRequestEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectRequestEvent.java @@ -1,12 +1,13 @@ package nostr.event.impl; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import nostr.base.PublicKey; import nostr.base.annotation.Event; import nostr.event.BaseTag; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @Event(name = "Nostr Connect", nip = 46) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectResponseEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectResponseEvent.java index 8ee82bf12..0a157d89f 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectResponseEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NostrConnectResponseEvent.java @@ -1,11 +1,12 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import nostr.base.PublicKey; import nostr.base.annotation.Event; import nostr.event.BaseTag; +import java.util.List; + @Event(name = "Nostr Connect", nip = 46) @NoArgsConstructor public class NostrConnectResponseEvent extends AbstractBaseNostrConnectEvent { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NostrMarketplaceEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NostrMarketplaceEvent.java index d1a416816..45f202877 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NostrMarketplaceEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NostrMarketplaceEvent.java @@ -1,19 +1,18 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import nostr.base.IEvent; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.Product; import nostr.event.json.codec.EventEncodingException; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NutZapEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NutZapEvent.java index 3045a56b2..ea28de8f3 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NutZapEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NutZapEvent.java @@ -1,14 +1,11 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.CashuMint; import nostr.event.entities.CashuProof; @@ -17,6 +14,8 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.PubKeyTag; +import java.util.List; + @EqualsAndHashCode(callSuper = true) @Event(name = "Nut Zap Event", nip = 61) @Data diff --git a/nostr-java-event/src/main/java/nostr/event/impl/NutZapInformationalEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/NutZapInformationalEvent.java index f2151181d..64e114d9c 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/NutZapInformationalEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/NutZapInformationalEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NonNull; import nostr.base.Kind; import nostr.base.PublicKey; @@ -11,6 +10,8 @@ import nostr.event.entities.NutZapInformation; import nostr.event.tag.GenericTag; +import java.util.List; + @Event(name = "Nut Zap Informational Event", nip = 61) public class NutZapInformationalEvent extends ReplaceableEvent { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/OtsEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/OtsEvent.java index 0c6dbdc47..14ea39b15 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/OtsEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/OtsEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -8,6 +7,8 @@ import nostr.base.annotation.Event; import nostr.event.BaseTag; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ReactionEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ReactionEvent.java index f17e11f5d..22c10c3ce 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ReactionEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ReactionEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -11,6 +10,8 @@ import nostr.event.NIP25Event; import nostr.event.tag.EventTag; +import java.util.List; + @Data @EqualsAndHashCode(callSuper = false) @Event(name = "Reactions", nip = 25) diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ReplaceableEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ReplaceableEvent.java index 948dbf841..633ee3db3 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ReplaceableEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ReplaceableEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -11,6 +10,8 @@ import nostr.event.BaseTag; import nostr.event.NIP01Event; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/TextNoteEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/TextNoteEvent.java index ee3e630cb..afe89676f 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/TextNoteEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/TextNoteEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.Kind; @@ -10,6 +9,8 @@ import nostr.event.NIP01Event; import nostr.event.tag.PubKeyTag; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/VerifyPaymentOrShippedEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/VerifyPaymentOrShippedEvent.java index 37e50669d..9a97338af 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/VerifyPaymentOrShippedEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/VerifyPaymentOrShippedEvent.java @@ -1,19 +1,18 @@ package nostr.event.impl; -import nostr.base.json.EventJsonMapper; - -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.annotation.Event; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.entities.PaymentShipmentStatus; +import java.util.List; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ZapReceiptEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ZapReceiptEvent.java index e7d38da77..c8e42206e 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ZapReceiptEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ZapReceiptEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -12,6 +11,8 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.PubKeyTag; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @Event(name = "ZapReceiptEvent", nip = 57) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/impl/ZapRequestEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/ZapRequestEvent.java index fd910fa68..45165ad0c 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/ZapRequestEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/ZapRequestEvent.java @@ -1,6 +1,5 @@ package nostr.event.impl; -import java.util.List; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -14,6 +13,8 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.RelaysTag; +import java.util.List; + @EqualsAndHashCode(callSuper = false) @Event(name = "ZapRequestEvent", nip = 57) @NoArgsConstructor diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseMessageDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseMessageDecoder.java index 2e7b22b18..453979dbc 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseMessageDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseMessageDecoder.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import java.util.Map; import lombok.NoArgsConstructor; import lombok.NonNull; import nostr.base.IDecoder; @@ -16,6 +15,8 @@ import nostr.event.message.RelayAuthenticationMessage; import nostr.event.message.ReqMessage; +import java.util.Map; + /** * @author eric */ @@ -39,10 +40,13 @@ public T decode(@NonNull String jsonString) throws EventEncodingException { return switch (command) { // client <-> relay messages - case "AUTH" -> - subscriptionId instanceof Map map - ? CanonicalAuthenticationMessage.decode(map) - : RelayAuthenticationMessage.decode(subscriptionId); + case "AUTH" -> { + if (subscriptionId instanceof Map map) { + yield CanonicalAuthenticationMessage.decode((Map) map); + } else { + yield RelayAuthenticationMessage.decode(subscriptionId); + } + } case "EVENT" -> EventMessage.decode(jsonString); // missing client <-> relay handlers // case "COUNT" -> CountMessage.decode(subscriptionId); diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagDecoder.java index ffd8b1d13..2d4d25507 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagDecoder.java @@ -1,12 +1,12 @@ package nostr.event.json.codec; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; import nostr.base.IDecoder; import nostr.event.BaseTag; +import static nostr.base.json.EventJsonMapper.mapper; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/FilterableProvider.java b/nostr-java-event/src/main/java/nostr/event/json/codec/FilterableProvider.java index 9d66f5ca1..2e93fc1de 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/FilterableProvider.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/FilterableProvider.java @@ -1,9 +1,6 @@ package nostr.event.json.codec; import com.fasterxml.jackson.databind.JsonNode; -import java.util.List; -import java.util.function.Function; -import java.util.stream.StreamSupport; import lombok.NonNull; import nostr.event.filter.AddressTagFilter; import nostr.event.filter.AuthorFilter; @@ -20,6 +17,10 @@ import nostr.event.filter.UntilFilter; import nostr.event.filter.VoteTagFilter; +import java.util.List; +import java.util.function.Function; +import java.util.stream.StreamSupport; + public class FilterableProvider { protected static List getFilterFunction( @NonNull JsonNode node, @NonNull String type) { diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersDecoder.java index e67f94cfb..9f3ade744 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersDecoder.java @@ -1,19 +1,20 @@ package nostr.event.json.codec; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import lombok.Data; import lombok.NonNull; import nostr.base.IDecoder; import nostr.event.filter.Filterable; import nostr.event.filter.Filters; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static nostr.base.json.EventJsonMapper.mapper; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java index 4d042eac6..0c6c0edfb 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java @@ -1,7 +1,6 @@ package nostr.event.json.codec; import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; import lombok.Data; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -9,6 +8,8 @@ import nostr.base.IDecoder; import nostr.event.tag.GenericTag; +import java.util.ArrayList; + @Data @Slf4j public class GenericTagDecoder implements IDecoder { @@ -38,20 +39,14 @@ public GenericTagDecoder(@NonNull Class clazz) { public T decode(@NonNull String json) throws EventEncodingException { try { String[] jsonElements = I_DECODER_MAPPER_BLACKBIRD.readValue(json, String[].class); - GenericTag genericTag = - new GenericTag( - jsonElements[0], - new ArrayList<>() { - { - for (int i = 1; i < jsonElements.length; i++) { - ElementAttribute attribute = - new ElementAttribute("param" + (i - 1), jsonElements[i]); - if (!contains(attribute)) { - add(attribute); - } - } - } - }); + var attributes = new ArrayList(Math.max(0, jsonElements.length - 1)); + for (int i = 1; i < jsonElements.length; i++) { + ElementAttribute attribute = new ElementAttribute("param" + (i - 1), jsonElements[i]); + if (!attributes.contains(attribute)) { + attributes.add(attribute); + } + } + GenericTag genericTag = new GenericTag(jsonElements[0], attributes); log.debug("Decoded GenericTag: {}", genericTag); diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/Nip05ContentDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/Nip05ContentDecoder.java index f16c30156..929d11863 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/Nip05ContentDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/Nip05ContentDecoder.java @@ -1,12 +1,12 @@ package nostr.event.json.codec; -import static nostr.base.json.EventJsonMapper.mapper; - import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; import nostr.base.IDecoder; import nostr.event.Nip05Content; +import static nostr.base.json.EventJsonMapper.mapper; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarDateBasedEventDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarDateBasedEventDeserializer.java index 6ab83c6ac..cb9f43d92 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarDateBasedEventDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarDateBasedEventDeserializer.java @@ -1,17 +1,16 @@ package nostr.event.json.deserializer; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import java.io.IOException; import nostr.base.json.EventJsonMapper; import nostr.event.impl.CalendarDateBasedEvent; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; +import java.io.IOException; + public class CalendarDateBasedEventDeserializer extends StdDeserializer { public CalendarDateBasedEventDeserializer() { super(CalendarDateBasedEvent.class); diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarEventDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarEventDeserializer.java index 117437f88..38596488e 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarEventDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarEventDeserializer.java @@ -1,17 +1,16 @@ package nostr.event.json.deserializer; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import java.io.IOException; import nostr.base.json.EventJsonMapper; import nostr.event.impl.CalendarEvent; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; +import java.io.IOException; + public class CalendarEventDeserializer extends StdDeserializer { public CalendarEventDeserializer() { super(CalendarEvent.class); diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarRsvpEventDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarRsvpEventDeserializer.java index 5173107d9..3718e8a11 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarRsvpEventDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarRsvpEventDeserializer.java @@ -1,17 +1,16 @@ package nostr.event.json.deserializer; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import java.io.IOException; import nostr.base.json.EventJsonMapper; import nostr.event.impl.CalendarRsvpEvent; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; +import java.io.IOException; + public class CalendarRsvpEventDeserializer extends StdDeserializer { public CalendarRsvpEventDeserializer() { super(CalendarRsvpEvent.class); diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarTimeBasedEventDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarTimeBasedEventDeserializer.java index 73c734bc0..c951f74c6 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarTimeBasedEventDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CalendarTimeBasedEventDeserializer.java @@ -1,17 +1,16 @@ package nostr.event.json.deserializer; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import java.io.IOException; import nostr.base.json.EventJsonMapper; import nostr.event.impl.CalendarTimeBasedEvent; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; +import java.io.IOException; + public class CalendarTimeBasedEventDeserializer extends StdDeserializer { public CalendarTimeBasedEventDeserializer() { super(CalendarTimeBasedEvent.class); diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/ClassifiedListingEventDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/ClassifiedListingEventDeserializer.java index 355a9c4ae..e42af8782 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/ClassifiedListingEventDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/ClassifiedListingEventDeserializer.java @@ -1,24 +1,23 @@ package nostr.event.json.deserializer; -import nostr.base.json.EventJsonMapper; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.StreamSupport; -import nostr.base.IEvent; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.Signature; +import nostr.base.json.EventJsonMapper; import nostr.event.BaseTag; import nostr.event.impl.ClassifiedListingEvent; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.StreamSupport; + public class ClassifiedListingEventDeserializer extends StdDeserializer { public ClassifiedListingEventDeserializer() { super(ClassifiedListingEvent.class); diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/PublicKeyDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/PublicKeyDeserializer.java index 03a48c117..79a2cd51c 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/PublicKeyDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/PublicKeyDeserializer.java @@ -4,9 +4,10 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; -import java.io.IOException; import nostr.base.PublicKey; +import java.io.IOException; + public class PublicKeyDeserializer extends JsonDeserializer { @Override public PublicKey deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/SignatureDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/SignatureDeserializer.java index 9ce62927c..156f59e19 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/SignatureDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/SignatureDeserializer.java @@ -4,10 +4,11 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; -import java.io.IOException; import nostr.base.Signature; import nostr.util.NostrUtil; +import java.io.IOException; + public class SignatureDeserializer extends JsonDeserializer { @Override diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/TagDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/TagDeserializer.java index 2f8682210..a23f10a14 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/TagDeserializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/deserializer/TagDeserializer.java @@ -4,9 +4,6 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; -import java.io.IOException; -import java.util.Map; -import java.util.function.Function; import nostr.event.BaseTag; import nostr.event.json.codec.GenericTagDecoder; import nostr.event.tag.AddressTag; @@ -27,6 +24,10 @@ import nostr.event.tag.UrlTag; import nostr.event.tag.VoteTag; +import java.io.IOException; +import java.util.Map; +import java.util.function.Function; + public class TagDeserializer extends JsonDeserializer { private static final Map> TAG_DECODERS = @@ -50,8 +51,6 @@ public class TagDeserializer extends JsonDeserializer { Map.entry("subject", SubjectTag::deserialize)); @Override - // Generics are erased at runtime; cast is safe because decoder returns a BaseTag subtype - @SuppressWarnings("unchecked") public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { @@ -65,6 +64,8 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati BaseTag tag = decoder != null ? decoder.apply(node) : new GenericTagDecoder<>().decode(node.toString()); - return (T) tag; + @SuppressWarnings("unchecked") + T typed = (T) tag; + return typed; } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/AbstractTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/AbstractTagSerializer.java index f5d884ce3..83cd0e13c 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/AbstractTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/AbstractTagSerializer.java @@ -1,15 +1,16 @@ package nostr.event.json.serializer; -import static nostr.event.json.codec.BaseTagEncoder.BASETAG_ENCODER_MAPPER_BLACKBIRD; - import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; import nostr.event.BaseTag; +import java.io.IOException; + +import static nostr.event.json.codec.BaseTagEncoder.BASETAG_ENCODER_MAPPER_BLACKBIRD; + abstract class AbstractTagSerializer extends StdSerializer { protected AbstractTagSerializer(Class t) { super(t); diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/AddressTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/AddressTagSerializer.java index d924299f7..53c0263f4 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/AddressTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/AddressTagSerializer.java @@ -3,9 +3,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; import nostr.event.tag.AddressTag; +import java.io.IOException; + /** * @author eric */ @@ -24,9 +25,14 @@ public void serialize( + ":" + value.getIdentifierTag().getUuid()); - if (value.getRelay() != null) { - jsonGenerator.writeString("," + value.getRelay().getUri()); - } + value.getRelayOptional() + .ifPresent(relay -> { + try { + jsonGenerator.writeString("," + relay.getUri()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); jsonGenerator.writeEndArray(); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/BaseTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/BaseTagSerializer.java index 79adab2f4..a1004a397 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/BaseTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/BaseTagSerializer.java @@ -1,12 +1,9 @@ package nostr.event.json.serializer; -import java.io.Serial; import nostr.event.BaseTag; public class BaseTagSerializer extends AbstractTagSerializer { - @Serial private static final long serialVersionUID = -3877972991082754068L; - // Generics are erased at runtime; serializer is intentionally bound to BaseTag.class @SuppressWarnings("unchecked") public BaseTagSerializer() { diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/ExpirationTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/ExpirationTagSerializer.java index 97d9513f9..df9189033 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/ExpirationTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/ExpirationTagSerializer.java @@ -3,9 +3,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; import nostr.event.tag.ExpirationTag; +import java.io.IOException; + /** * @author eric */ diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/GenericTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/GenericTagSerializer.java index 6f1851f9c..2c4448b9a 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/GenericTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/GenericTagSerializer.java @@ -1,13 +1,10 @@ package nostr.event.json.serializer; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.io.Serial; import nostr.event.tag.GenericTag; public class GenericTagSerializer extends AbstractTagSerializer { - @Serial private static final long serialVersionUID = -5318614324350049034L; - // Generics are erased at runtime; serializer is intentionally bound to GenericTag.class @SuppressWarnings("unchecked") public GenericTagSerializer() { diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/IdentifierTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/IdentifierTagSerializer.java index 17f7b257e..f6393a2ce 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/IdentifierTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/IdentifierTagSerializer.java @@ -3,9 +3,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; import nostr.event.tag.IdentifierTag; +import java.io.IOException; + public class IdentifierTagSerializer extends JsonSerializer { @Override diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/ReferenceTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/ReferenceTagSerializer.java index 7e3a362bd..1d9fc7332 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/ReferenceTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/ReferenceTagSerializer.java @@ -3,9 +3,10 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; import nostr.event.tag.ReferenceTag; +import java.io.IOException; + /** * @author eric */ @@ -18,9 +19,13 @@ public void serialize( jsonGenerator.writeStartArray(); jsonGenerator.writeString("r"); jsonGenerator.writeString(refTag.getUri().toString()); - if (refTag.getMarker() != null) { - jsonGenerator.writeString(refTag.getMarker().getValue()); - } + refTag.getMarkerOptional().ifPresent(m -> { + try { + jsonGenerator.writeString(m.getValue()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); jsonGenerator.writeEndArray(); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/RelaysTagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/RelaysTagSerializer.java index 2a8b5033b..4944a7aad 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/RelaysTagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/RelaysTagSerializer.java @@ -3,10 +3,11 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; import lombok.NonNull; import nostr.event.tag.RelaysTag; +import java.io.IOException; + public class RelaysTagSerializer extends JsonSerializer { @Override diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/TagSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/TagSerializer.java index 9d9cd640f..6975774c7 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/TagSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/TagSerializer.java @@ -1,7 +1,6 @@ package nostr.event.json.serializer; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.io.Serial; import lombok.extern.slf4j.Slf4j; import nostr.event.BaseTag; import nostr.event.tag.GenericTag; @@ -12,8 +11,6 @@ @Slf4j public class TagSerializer extends AbstractTagSerializer { - @Serial private static final long serialVersionUID = -3877972991082754068L; - public TagSerializer() { super(BaseTag.class); } diff --git a/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java b/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java index 1e4946b25..0d4089fc4 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java @@ -1,14 +1,9 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; -import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import java.util.List; -import java.util.Map; import lombok.Getter; import lombok.NonNull; import lombok.Setter; @@ -17,10 +12,16 @@ import nostr.event.BaseTag; import nostr.event.impl.CanonicalAuthenticationEvent; import nostr.event.impl.GenericEvent; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.BaseEventEncoder; import nostr.event.json.codec.EventEncodingException; import nostr.event.tag.GenericTag; +import java.util.List; +import java.util.Map; + +import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; + /** * @author eric */ @@ -59,8 +60,7 @@ public String encode() throws EventEncodingException { * @return the decoded CanonicalAuthenticationMessage * @throws EventEncodingException if decoding fails */ - @SuppressWarnings("unchecked") - public static T decode(@NonNull Map map) { + public static T decode(@NonNull Map map) { try { var event = I_DECODER_MAPPER_BLACKBIRD.convertValue(map, new TypeReference() {}); @@ -70,22 +70,14 @@ public static T decode(@NonNull Map map) { CanonicalAuthenticationEvent canonEvent = new CanonicalAuthenticationEvent(event.getPubKey(), baseTags, ""); - canonEvent.setId(map.get("id").toString()); + canonEvent.setId(String.valueOf(map.get("id"))); - return (T) new CanonicalAuthenticationMessage(canonEvent); + @SuppressWarnings("unchecked") + T result = (T) new CanonicalAuthenticationMessage(canonEvent); + return result; } catch (IllegalArgumentException ex) { throw new EventEncodingException("Failed to decode canonical authentication message", ex); } } - private static String getAttributeValue(List genericTags, String attributeName) { - return genericTags.stream() - .filter(tag -> tag.getCode().equalsIgnoreCase(attributeName)) - .map(GenericTag::getAttributes) - .toList() - .get(0) - .get(0) - .value() - .toString(); - } } diff --git a/nostr-java-event/src/main/java/nostr/event/message/CloseMessage.java b/nostr-java-event/src/main/java/nostr/event/message/CloseMessage.java index 7ac8b42da..ea171d931 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/CloseMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/CloseMessage.java @@ -1,7 +1,5 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -10,6 +8,7 @@ import lombok.Setter; import nostr.base.Command; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; /** diff --git a/nostr-java-event/src/main/java/nostr/event/message/EoseMessage.java b/nostr-java-event/src/main/java/nostr/event/message/EoseMessage.java index df037948d..671807032 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/EoseMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/EoseMessage.java @@ -1,7 +1,5 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -10,6 +8,7 @@ import lombok.Setter; import nostr.base.Command; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; /** @@ -41,8 +40,9 @@ public String encode() throws EventEncodingException { } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") public static T decode(@NonNull Object arg) { - return (T) new EoseMessage(arg.toString()); + @SuppressWarnings("unchecked") + T result = (T) new EoseMessage(arg.toString()); + return result; } } diff --git a/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java b/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java index db33c0f7c..0a38f1615 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java @@ -1,16 +1,9 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; -import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Function; import lombok.Getter; import lombok.NonNull; import lombok.Setter; @@ -20,9 +13,17 @@ import nostr.event.BaseEvent; import nostr.event.BaseMessage; import nostr.event.impl.GenericEvent; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.BaseEventEncoder; import nostr.event.json.codec.EventEncodingException; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; + @Setter @Getter @Slf4j @@ -70,19 +71,20 @@ public static T decode(@NonNull String jsonString) } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") private static T processEvent(Object o) { - return (T) new EventMessage(convertValue((Map) o)); + @SuppressWarnings("unchecked") + T result = (T) new EventMessage(convertValue((Map) o)); + return result; } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") private static T processEvent(Object[] msgArr) { - return (T) - new EventMessage(convertValue((Map) msgArr[2]), msgArr[1].toString()); + @SuppressWarnings("unchecked") + T result = (T) new EventMessage(convertValue((Map) msgArr[2]), msgArr[1].toString()); + return result; } - private static GenericEvent convertValue(Map map) { + private static GenericEvent convertValue(Map map) { log.info("Converting map to GenericEvent: {}", map); return I_DECODER_MAPPER_BLACKBIRD.convertValue(map, new TypeReference<>() {}); } diff --git a/nostr-java-event/src/main/java/nostr/event/message/GenericMessage.java b/nostr-java-event/src/main/java/nostr/event/message/GenericMessage.java index 28505fc14..eeb07d34a 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/GenericMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/GenericMessage.java @@ -1,12 +1,8 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import java.util.ArrayList; -import java.util.List; import lombok.Getter; import lombok.NonNull; import lombok.Setter; @@ -14,8 +10,12 @@ import nostr.base.IElement; import nostr.base.IGenericElement; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; +import java.util.ArrayList; +import java.util.List; + /** * @author squirrel */ @@ -59,7 +59,6 @@ public String encode() throws EventEncodingException { } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") public static T decode(@NonNull Object[] msgArr) { GenericMessage gm = new GenericMessage(msgArr[0].toString()); for (int i = 1; i < msgArr.length; i++) { @@ -67,6 +66,8 @@ public static T decode(@NonNull Object[] msgArr) { gm.addAttribute(new ElementAttribute(null, msgArr[i])); } } - return (T) gm; + @SuppressWarnings("unchecked") + T result = (T) gm; + return result; } } diff --git a/nostr-java-event/src/main/java/nostr/event/message/NoticeMessage.java b/nostr-java-event/src/main/java/nostr/event/message/NoticeMessage.java index 27a042405..d24285214 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/NoticeMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/NoticeMessage.java @@ -1,7 +1,5 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -10,6 +8,7 @@ import lombok.Setter; import nostr.base.Command; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; /** @@ -37,8 +36,9 @@ public String encode() throws EventEncodingException { } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") public static T decode(@NonNull Object arg) { - return (T) new NoticeMessage(arg.toString()); + @SuppressWarnings("unchecked") + T result = (T) new NoticeMessage(arg.toString()); + return result; } } diff --git a/nostr-java-event/src/main/java/nostr/event/message/OkMessage.java b/nostr-java-event/src/main/java/nostr/event/message/OkMessage.java index 544e6aff1..bc31f423d 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/OkMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/OkMessage.java @@ -1,8 +1,5 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; -import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -11,8 +8,11 @@ import lombok.Setter; import nostr.base.Command; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; +import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; + @Setter @Getter public class OkMessage extends BaseMessage { @@ -46,12 +46,13 @@ public String encode() throws EventEncodingException { } // Generics are erased at runtime; BaseMessage subtype is determined by caller context - @SuppressWarnings("unchecked") public static T decode(@NonNull String jsonString) throws EventEncodingException { try { Object[] msgArr = I_DECODER_MAPPER_BLACKBIRD.readValue(jsonString, Object[].class); - return (T) new OkMessage(msgArr[1].toString(), (Boolean) msgArr[2], msgArr[3].toString()); + @SuppressWarnings("unchecked") + T result = (T) new OkMessage(msgArr[1].toString(), (Boolean) msgArr[2], msgArr[3].toString()); + return result; } catch (JsonProcessingException e) { throw new EventEncodingException("Failed to decode ok message", e); } diff --git a/nostr-java-event/src/main/java/nostr/event/message/RelayAuthenticationMessage.java b/nostr-java-event/src/main/java/nostr/event/message/RelayAuthenticationMessage.java index 9cf4d68c5..155745b90 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/RelayAuthenticationMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/RelayAuthenticationMessage.java @@ -1,7 +1,5 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -10,6 +8,7 @@ import lombok.Setter; import nostr.base.Command; import nostr.event.BaseMessage; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; /** diff --git a/nostr-java-event/src/main/java/nostr/event/message/ReqMessage.java b/nostr-java-event/src/main/java/nostr/event/message/ReqMessage.java index f80006b1e..88c79241e 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/ReqMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/ReqMessage.java @@ -1,15 +1,9 @@ package nostr.event.message; -import nostr.event.json.EventJsonMapper; -import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import java.time.temporal.ValueRange; -import java.util.List; -import java.util.stream.IntStream; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -17,10 +11,17 @@ import nostr.base.Command; import nostr.event.BaseMessage; import nostr.event.filter.Filters; +import nostr.event.json.EventJsonMapper; import nostr.event.json.codec.EventEncodingException; import nostr.event.json.codec.FiltersDecoder; import nostr.event.json.codec.FiltersEncoder; +import java.time.temporal.ValueRange; +import java.util.List; +import java.util.stream.IntStream; + +import static nostr.base.IDecoder.I_DECODER_MAPPER_BLACKBIRD; + /** * @author squirrel */ @@ -63,16 +64,18 @@ public String encode() throws EventEncodingException { } } - @SuppressWarnings("unchecked") public static T decode( @NonNull Object subscriptionId, @NonNull String jsonString) throws EventEncodingException { validateSubscriptionId(subscriptionId.toString()); - return (T) - new ReqMessage( - subscriptionId.toString(), - getJsonFiltersList(jsonString).stream() - .map(filtersList -> new FiltersDecoder().decode(filtersList)) - .toList()); + @SuppressWarnings("unchecked") + T result = + (T) + new ReqMessage( + subscriptionId.toString(), + getJsonFiltersList(jsonString).stream() + .map(filtersList -> new FiltersDecoder().decode(filtersList)) + .toList()); + return result; } private static JsonNode createJsonNode(String jsonNode) throws EventEncodingException { @@ -95,20 +98,12 @@ private static void validateSubscriptionId(String subscriptionId) { private static List getJsonFiltersList(String jsonString) throws EventEncodingException { try { - return IntStream.range( - FILTERS_START_INDEX, I_DECODER_MAPPER_BLACKBIRD.readTree(jsonString).size()) - .mapToObj(idx -> readTree(jsonString, idx)) + JsonNode root = I_DECODER_MAPPER_BLACKBIRD.readTree(jsonString); + return IntStream.range(FILTERS_START_INDEX, root.size()) + .mapToObj(idx -> root.get(idx).toString()) .toList(); } catch (JsonProcessingException e) { throw new EventEncodingException("Invalid ReqMessage filters json", e); } } - - private static String readTree(String jsonString, int idx) throws EventEncodingException { - try { - return I_DECODER_MAPPER_BLACKBIRD.readTree(jsonString).get(idx).toString(); - } catch (JsonProcessingException e) { - throw new EventEncodingException("Failed to read json tree", e); - } - } } diff --git a/nostr-java-event/src/main/java/nostr/event/serializer/EventSerializer.java b/nostr-java-event/src/main/java/nostr/event/serializer/EventSerializer.java index 03e8fb1ab..616970e5c 100644 --- a/nostr-java-event/src/main/java/nostr/event/serializer/EventSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/serializer/EventSerializer.java @@ -3,10 +3,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.List; import lombok.NonNull; import nostr.base.PublicKey; import nostr.event.BaseTag; @@ -14,6 +10,11 @@ import nostr.util.NostrException; import nostr.util.NostrUtil; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.List; + /** * Serializes Nostr events according to NIP-01 canonical format. * diff --git a/nostr-java-event/src/main/java/nostr/event/support/GenericEventConverter.java b/nostr-java-event/src/main/java/nostr/event/support/GenericEventConverter.java index d03e2c108..48e621f25 100644 --- a/nostr-java-event/src/main/java/nostr/event/support/GenericEventConverter.java +++ b/nostr-java-event/src/main/java/nostr/event/support/GenericEventConverter.java @@ -1,10 +1,11 @@ package nostr.event.support; -import java.lang.reflect.InvocationTargetException; import lombok.NonNull; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; +import java.lang.reflect.InvocationTargetException; + /** * Converts {@link GenericEvent} instances to concrete event subtypes. */ diff --git a/nostr-java-event/src/main/java/nostr/event/support/GenericEventUpdater.java b/nostr-java-event/src/main/java/nostr/event/support/GenericEventUpdater.java index 67d054a6c..c613e7efc 100644 --- a/nostr-java-event/src/main/java/nostr/event/support/GenericEventUpdater.java +++ b/nostr-java-event/src/main/java/nostr/event/support/GenericEventUpdater.java @@ -1,14 +1,15 @@ package nostr.event.support; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; import nostr.event.impl.GenericEvent; import nostr.util.NostrException; import nostr.util.NostrUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; + /** * Refreshes derived fields (serialized payload, id, timestamp) for {@link GenericEvent}. */ diff --git a/nostr-java-event/src/main/java/nostr/event/support/GenericEventValidator.java b/nostr-java-event/src/main/java/nostr/event/support/GenericEventValidator.java index 8d3ee16ce..c8af01e8c 100644 --- a/nostr-java-event/src/main/java/nostr/event/support/GenericEventValidator.java +++ b/nostr-java-event/src/main/java/nostr/event/support/GenericEventValidator.java @@ -1,13 +1,14 @@ package nostr.event.support; -import java.util.List; -import java.util.Objects; import lombok.NonNull; import nostr.base.NipConstants; import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; import nostr.util.validator.HexStringValidator; +import java.util.List; +import java.util.Objects; + /** * Performs NIP-01 validation on {@link GenericEvent} instances. */ diff --git a/nostr-java-event/src/main/java/nostr/event/tag/AddressTag.java b/nostr-java-event/src/main/java/nostr/event/tag/AddressTag.java index 561a65c98..158f243e9 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/AddressTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/AddressTag.java @@ -1,14 +1,15 @@ package nostr.event.tag; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; +import java.util.Optional; import nostr.base.ElementAttribute; import nostr.base.PublicKey; import nostr.base.Relay; @@ -16,9 +17,9 @@ import nostr.event.BaseTag; import nostr.event.json.serializer.AddressTagSerializer; -/** - * @author eric - */ +import java.util.List; + +/** Represents an 'a' addressable/parameterized replaceable tag (NIP-33). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -31,10 +32,20 @@ public class AddressTag extends BaseTag { private Integer kind; private PublicKey publicKey; private IdentifierTag identifierTag; + @JsonInclude(JsonInclude.Include.NON_NULL) private Relay relay; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for relay. */ + public Optional getRelayOptional() { + return Optional.ofNullable(relay); + } + + /** Optional accessor for identifierTag. */ + public Optional getIdentifierTagOptional() { + return Optional.ofNullable(identifierTag); + } + + public static AddressTag deserialize(@NonNull JsonNode node) { AddressTag tag = new AddressTag(); String[] parts = node.get(1).asText().split(":"); @@ -47,7 +58,7 @@ public static T deserialize(@NonNull JsonNode node) { if (node.size() == 3) { tag.setRelay(new Relay(node.get(2).asText())); } - return (T) tag; + return tag; } public static AddressTag updateFields(@NonNull GenericTag tag) { @@ -58,9 +69,10 @@ public static AddressTag updateFields(@NonNull GenericTag tag) { AddressTag addressTag = new AddressTag(); List attributes = tag.getAttributes(); String attr0 = attributes.get(0).value().toString(); - Integer kind = Integer.parseInt(attr0.split(":")[0]); - PublicKey publicKey = new PublicKey(attr0.split(":")[1]); - String id = attr0.split(":").length == 3 ? attr0.split(":")[2] : null; + String[] parts = attr0.split(":"); + Integer kind = Integer.parseInt(parts[0]); + PublicKey publicKey = new PublicKey(parts[1]); + String id = parts.length == 3 ? parts[2] : null; addressTag.setKind(kind); addressTag.setPublicKey(publicKey); diff --git a/nostr-java-event/src/main/java/nostr/event/tag/DelegationTag.java b/nostr-java-event/src/main/java/nostr/event/tag/DelegationTag.java index d0cd34ece..6fcb9a9d5 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/DelegationTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/DelegationTag.java @@ -2,11 +2,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import java.beans.Transient; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.function.Consumer; -import java.util.function.Supplier; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -18,6 +13,12 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; +import java.beans.Transient; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.function.Consumer; +import java.util.function.Supplier; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/tag/EmojiTag.java b/nostr-java-event/src/main/java/nostr/event/tag/EmojiTag.java index 4e3bc39df..22a87e8f5 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/EmojiTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/EmojiTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,12 +13,11 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author guilhermegps - */ +/** Represents an 'emoji' custom emoji tag (NIP-30). */ @Builder @Data @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"shortcode", "image-url"}) @Tag(code = "emoji", nip = 30) @AllArgsConstructor @NoArgsConstructor @@ -29,12 +29,11 @@ public class EmojiTag extends BaseTag { @JsonProperty("image-url") private String url; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static EmojiTag deserialize(@NonNull JsonNode node) { EmojiTag tag = new EmojiTag(); setRequiredField(node.get(1), (n, t) -> tag.setShortcode(n.asText()), tag); setRequiredField(node.get(2), (n, t) -> tag.setUrl(n.asText()), tag); - return (T) tag; + return tag; } public static EmojiTag updateFields(@NonNull GenericTag tag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/EventTag.java b/nostr-java-event/src/main/java/nostr/event/tag/EventTag.java index 191178fae..10289d228 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/EventTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/EventTag.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; +import java.util.Optional; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,9 +16,7 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author squirrel - */ +/** Represents an 'e' event reference tag (NIP-01). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -43,14 +42,23 @@ public EventTag(String idEvent) { this.idEvent = idEvent; } - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for recommendedRelayUrl. */ + public Optional getRecommendedRelayUrlOptional() { + return Optional.ofNullable(recommendedRelayUrl); + } + + /** Optional accessor for marker. */ + public Optional getMarkerOptional() { + return Optional.ofNullable(marker); + } + + public static EventTag deserialize(@NonNull JsonNode node) { EventTag tag = new EventTag(); setRequiredField(node.get(1), (n, t) -> tag.setIdEvent(n.asText()), tag); setOptionalField(node.get(2), (n, t) -> tag.setRecommendedRelayUrl(n.asText()), tag); setOptionalField( node.get(3), (n, t) -> tag.setMarker(Marker.valueOf(n.asText().toUpperCase())), tag); - return (T) tag; + return tag; } public static EventTag updateFields(@NonNull GenericTag tag) { @@ -62,7 +70,8 @@ public static EventTag updateFields(@NonNull GenericTag tag) { eventTag.setRecommendedRelayUrl(tag.getAttributes().get(1).value().toString()); } if (tag.getAttributes().size() > 2) { - eventTag.setMarker(Marker.valueOf(tag.getAttributes().get(2).value().toString())); + eventTag.setMarker( + Marker.valueOf(tag.getAttributes().get(2).value().toString().toUpperCase())); } return eventTag; diff --git a/nostr-java-event/src/main/java/nostr/event/tag/ExpirationTag.java b/nostr-java-event/src/main/java/nostr/event/tag/ExpirationTag.java index 6650bb88d..00f678728 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/ExpirationTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/ExpirationTag.java @@ -14,9 +14,7 @@ import nostr.event.BaseTag; import nostr.event.json.serializer.ExpirationTagSerializer; -/** - * @author eric - */ +/** Represents an 'expiration' tag (NIP-40). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -28,11 +26,10 @@ public class ExpirationTag extends BaseTag { @Key @JsonProperty private Integer expiration; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static ExpirationTag deserialize(@NonNull JsonNode node) { ExpirationTag tag = new ExpirationTag(); setRequiredField(node.get(1), (n, t) -> tag.setExpiration(Integer.valueOf(n.asText())), tag); - return (T) tag; + return tag; } public static ExpirationTag updateFields(@NonNull GenericTag tag) { @@ -40,7 +37,6 @@ public static ExpirationTag updateFields(@NonNull GenericTag tag) { throw new IllegalArgumentException("Invalid tag code for ExpirationTag"); } String expiration = tag.getAttributes().get(0).value().toString(); - ExpirationTag expirationTag = new ExpirationTag(Integer.parseInt(expiration)); - return expirationTag; + return new ExpirationTag(Integer.parseInt(expiration)); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/GenericTag.java b/nostr-java-event/src/main/java/nostr/event/tag/GenericTag.java index 9af69f1fa..69ba339f1 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/GenericTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/GenericTag.java @@ -1,8 +1,6 @@ package nostr.event.tag; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.util.ArrayList; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -11,6 +9,9 @@ import nostr.event.BaseTag; import nostr.event.json.serializer.GenericTagSerializer; +import java.util.ArrayList; +import java.util.List; + /** * @author squirrel */ diff --git a/nostr-java-event/src/main/java/nostr/event/tag/GeohashTag.java b/nostr-java-event/src/main/java/nostr/event/tag/GeohashTag.java index 2e8778b79..c724622e6 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/GeohashTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/GeohashTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,12 +13,11 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author eric - */ +/** Represents a 'g' geohash location tag (NIP-12). */ @Builder @Data @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"g"}) @Tag(code = "g", nip = 12) @NoArgsConstructor @AllArgsConstructor @@ -27,11 +27,10 @@ public class GeohashTag extends BaseTag { @JsonProperty("g") private String location; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static GeohashTag deserialize(@NonNull JsonNode node) { GeohashTag tag = new GeohashTag(); setRequiredField(node.get(1), (n, t) -> tag.setLocation(n.asText()), tag); - return (T) tag; + return tag; } public static GeohashTag updateFields(@NonNull GenericTag genericTag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/HashtagTag.java b/nostr-java-event/src/main/java/nostr/event/tag/HashtagTag.java index 6bad48f40..ee94adfe4 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/HashtagTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/HashtagTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,12 +13,11 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author eric - */ +/** Represents a 't' hashtag tag (NIP-12). */ @Builder @Data @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"t"}) @Tag(code = "t", nip = 12) @NoArgsConstructor @AllArgsConstructor @@ -27,11 +27,10 @@ public class HashtagTag extends BaseTag { @JsonProperty("t") private String hashTag; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static HashtagTag deserialize(@NonNull JsonNode node) { HashtagTag tag = new HashtagTag(); setRequiredField(node.get(1), (n, t) -> tag.setHashTag(n.asText()), tag); - return (T) tag; + return tag; } public static HashtagTag updateFields(@NonNull GenericTag genericTag) { @@ -42,9 +41,6 @@ public static HashtagTag updateFields(@NonNull GenericTag genericTag) { if (genericTag.getAttributes().size() != 1) { throw new IllegalArgumentException("Invalid number of attributes for HashtagTag"); } - - HashtagTag tag = new HashtagTag(); - tag.setHashTag(genericTag.getAttributes().get(0).value().toString()); - return tag; + return new HashtagTag(genericTag.getAttributes().get(0).value().toString()); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/IdentifierTag.java b/nostr-java-event/src/main/java/nostr/event/tag/IdentifierTag.java index f0b472890..bbec3a2d3 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/IdentifierTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/IdentifierTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,12 +13,11 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author eric - */ +/** Represents a 'd' identifier tag (NIP-33). */ @Builder @Data @EqualsAndHashCode(callSuper = false) +@JsonPropertyOrder({"uuid"}) @Tag(code = "d", nip = 33) @NoArgsConstructor @AllArgsConstructor @@ -25,11 +25,10 @@ public class IdentifierTag extends BaseTag { @Key @JsonProperty private String uuid; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static IdentifierTag deserialize(@NonNull JsonNode node) { IdentifierTag tag = new IdentifierTag(); setRequiredField(node.get(1), (n, t) -> tag.setUuid(n.asText()), tag); - return (T) tag; + return tag; } public static IdentifierTag updateFields(@NonNull GenericTag tag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/LabelNamespaceTag.java b/nostr-java-event/src/main/java/nostr/event/tag/LabelNamespaceTag.java index bbbada67e..f24a244e1 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/LabelNamespaceTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/LabelNamespaceTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Data; @@ -12,7 +13,9 @@ import nostr.event.BaseTag; @Data +/** Represents an 'L' label namespace tag (NIP-32). */ @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"L"}) @Tag(code = "L", nip = 32) @NoArgsConstructor @AllArgsConstructor @@ -22,11 +25,10 @@ public class LabelNamespaceTag extends BaseTag { @JsonProperty("L") private String nameSpace; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static LabelNamespaceTag deserialize(@NonNull JsonNode node) { LabelNamespaceTag tag = new LabelNamespaceTag(); setRequiredField(node.get(1), (n, t) -> tag.setNameSpace(n.asText()), tag); - return (T) tag; + return tag; } public static LabelNamespaceTag updateFields(@NonNull GenericTag tag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/LabelTag.java b/nostr-java-event/src/main/java/nostr/event/tag/LabelTag.java index c84a1a764..dec74a87e 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/LabelTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/LabelTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Data; @@ -12,7 +13,9 @@ import nostr.event.BaseTag; @Data +/** Represents an 'l' label tag (NIP-32). */ @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"l", "L"}) @Tag(code = "l", nip = 32) @NoArgsConstructor @AllArgsConstructor @@ -30,21 +33,19 @@ public LabelTag(@NonNull String label, @NonNull LabelNamespaceTag labelNamespace this(label, labelNamespaceTag.getNameSpace()); } - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static LabelTag deserialize(@NonNull JsonNode node) { LabelTag tag = new LabelTag(); setRequiredField(node.get(1), (n, t) -> tag.setLabel(n.asText()), tag); setRequiredField(node.get(2), (n, t) -> tag.setNameSpace(n.asText()), tag); - return (T) tag; + return tag; } public static LabelTag updateFields(@NonNull GenericTag tag) { if (!"l".equals(tag.getCode())) { throw new IllegalArgumentException("Invalid tag code for LabelTag"); } - LabelTag labelTag = new LabelTag(); - labelTag.setLabel(tag.getAttributes().get(0).value().toString()); - labelTag.setNameSpace(tag.getAttributes().get(1).value().toString()); - return labelTag; + return new LabelTag( + tag.getAttributes().get(0).value().toString(), + tag.getAttributes().get(1).value().toString()); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/NonceTag.java b/nostr-java-event/src/main/java/nostr/event/tag/NonceTag.java index 1ece009e4..fd27802ec 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/NonceTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/NonceTag.java @@ -12,9 +12,7 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author squirrel - */ +/** Represents a 'nonce' proof-of-work tag (NIP-13). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -36,12 +34,11 @@ public NonceTag(@NonNull Integer nonce, @NonNull Integer difficulty) { this.difficulty = difficulty; } - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static NonceTag deserialize(@NonNull JsonNode node) { NonceTag tag = new NonceTag(); setRequiredField(node.get(1), (n, t) -> tag.setNonce(n.asInt()), tag); setRequiredField(node.get(2), (n, t) -> tag.setDifficulty(n.asInt()), tag); - return (T) tag; + return tag; } public static NonceTag updateFields(@NonNull GenericTag genericTag) { @@ -51,10 +48,8 @@ public static NonceTag updateFields(@NonNull GenericTag genericTag) { if (genericTag.getAttributes().size() != 2) { throw new IllegalArgumentException("Invalid number of attributes for NonceTag"); } - - NonceTag tag = new NonceTag(); - tag.setNonce(Integer.valueOf(genericTag.getAttributes().get(0).value().toString())); - tag.setDifficulty(Integer.valueOf(genericTag.getAttributes().get(1).value().toString())); - return tag; + return new NonceTag( + Integer.valueOf(genericTag.getAttributes().get(0).value().toString()), + Integer.valueOf(genericTag.getAttributes().get(1).value().toString())); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/PriceTag.java b/nostr-java-event/src/main/java/nostr/event/tag/PriceTag.java index 43fb0a6a1..85727be24 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/PriceTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/PriceTag.java @@ -1,11 +1,10 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; -import java.math.BigDecimal; -import java.util.Objects; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,6 +14,11 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; +import java.math.BigDecimal; +import java.util.Objects; +import java.util.Optional; + +/** Represents a 'price' tag (NIP-99). */ @Builder @Data @Tag(code = "price", nip = 99) @@ -30,15 +34,22 @@ public class PriceTag extends BaseTag { @Key @JsonProperty private String currency; - @Key @JsonProperty private String frequency; + @Key + @JsonProperty + @JsonInclude(JsonInclude.Include.NON_NULL) + private String frequency; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for frequency. */ + public Optional getFrequencyOptional() { + return Optional.ofNullable(frequency); + } + + public static PriceTag deserialize(@NonNull JsonNode node) { PriceTag tag = new PriceTag(); setRequiredField(node.get(1), (n, t) -> tag.setNumber(new BigDecimal(n.asText())), tag); setOptionalField(node.get(2), (n, t) -> tag.setCurrency(n.asText()), tag); setOptionalField(node.get(3), (n, t) -> tag.setFrequency(n.asText()), tag); - return (T) tag; + return tag; } @Override @@ -64,14 +75,12 @@ public static PriceTag updateFields(@NonNull GenericTag genericTag) { if (genericTag.getAttributes().size() < 2 || genericTag.getAttributes().size() > 3) { throw new IllegalArgumentException("Invalid number of attributes for PriceTag"); } - - PriceTag tag = new PriceTag(); - tag.setNumber(new BigDecimal(genericTag.getAttributes().get(0).value().toString())); - tag.setCurrency(genericTag.getAttributes().get(1).value().toString()); - - if (genericTag.getAttributes().size() > 2) { - tag.setFrequency(genericTag.getAttributes().get(2).value().toString()); - } - return tag; + BigDecimal number = new BigDecimal(genericTag.getAttributes().get(0).value().toString()); + String currency = genericTag.getAttributes().get(1).value().toString(); + String frequency = + genericTag.getAttributes().size() > 2 + ? genericTag.getAttributes().get(2).value().toString() + : null; + return new PriceTag(number, currency, frequency); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/PubKeyTag.java b/nostr-java-event/src/main/java/nostr/event/tag/PubKeyTag.java index 83149a389..9bde58b54 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/PubKeyTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/PubKeyTag.java @@ -14,14 +14,13 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; +import java.util.Optional; import nostr.base.PublicKey; import nostr.base.annotation.Key; import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author squirrel - */ +/** Represents a 'p' public key reference tag (NIP-01). */ @JsonPropertyOrder({"pubKey", "mainRelayUrl", "petName"}) @Builder @Data @@ -54,13 +53,22 @@ public PubKeyTag(@NonNull PublicKey publicKey, String mainRelayUrl, String petNa this.petName = petName; } - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for mainRelayUrl. */ + public Optional getMainRelayUrlOptional() { + return Optional.ofNullable(mainRelayUrl); + } + + /** Optional accessor for petName. */ + public Optional getPetNameOptional() { + return Optional.ofNullable(petName); + } + + public static PubKeyTag deserialize(@NonNull JsonNode node) { PubKeyTag tag = new PubKeyTag(); setRequiredField(node.get(1), (n, t) -> tag.setPublicKey(new PublicKey(n.asText())), tag); setOptionalField(node.get(2), (n, t) -> tag.setMainRelayUrl(n.asText()), tag); setOptionalField(node.get(3), (n, t) -> tag.setPetName(n.asText()), tag); - return (T) tag; + return tag; } public static PubKeyTag updateFields(@NonNull GenericTag tag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/ReferenceTag.java b/nostr-java-event/src/main/java/nostr/event/tag/ReferenceTag.java index d0fd57854..5b484fdd6 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/ReferenceTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/ReferenceTag.java @@ -1,10 +1,9 @@ package nostr.event.tag; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.net.URI; -import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -17,9 +16,10 @@ import nostr.event.BaseTag; import nostr.event.json.serializer.ReferenceTagSerializer; -/** - * @author eric - */ +import java.net.URI; +import java.util.Optional; + +/** Represents an 'r' reference tag (NIP-12). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -33,7 +33,9 @@ public class ReferenceTag extends BaseTag { @JsonProperty("uri") private URI uri; - @Key private Marker marker; + @Key + @JsonInclude(JsonInclude.Include.NON_NULL) + private Marker marker; public ReferenceTag(@NonNull URI uri) { this.uri = uri; @@ -42,13 +44,17 @@ public Optional getUrl() { return Optional.ofNullable(this.uri); } - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for marker. */ + public Optional getMarkerOptional() { + return Optional.ofNullable(marker); + } + + public static ReferenceTag deserialize(@NonNull JsonNode node) { ReferenceTag tag = new ReferenceTag(); setRequiredField(node.get(1), (n, t) -> tag.setUri(URI.create(n.asText())), tag); setOptionalField( node.get(2), (n, t) -> tag.setMarker(Marker.valueOf(n.asText().toUpperCase())), tag); - return (T) tag; + return tag; } public static ReferenceTag updateFields(@NonNull GenericTag genericTag) { @@ -59,16 +65,10 @@ public static ReferenceTag updateFields(@NonNull GenericTag genericTag) { if (genericTag.getAttributes().size() < 1 || genericTag.getAttributes().size() > 2) { throw new IllegalArgumentException("Invalid number of attributes for ReferenceTag"); } - - ReferenceTag tag = new ReferenceTag(); - tag.setUri(URI.create(genericTag.getAttributes().get(0).value().toString())); - if (genericTag.getAttributes().size() == 2) { - tag.setMarker( - Marker.valueOf(genericTag.getAttributes().get(1).value().toString().toUpperCase())); - } else { - tag.setMarker(null); - } - - return tag; + return new ReferenceTag( + URI.create(genericTag.getAttributes().get(0).value().toString()), + genericTag.getAttributes().size() == 2 + ? Marker.valueOf(genericTag.getAttributes().get(1).value().toString().toUpperCase()) + : null); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/RelaysTag.java b/nostr-java-event/src/main/java/nostr/event/tag/RelaysTag.java index 664f782b7..27601226f 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/RelaysTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/RelaysTag.java @@ -2,9 +2,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,6 +12,11 @@ import nostr.event.BaseTag; import nostr.event.json.serializer.RelaysTagSerializer; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** Represents a 'relays' tag (NIP-57). */ @Builder @Data @EqualsAndHashCode(callSuper = true) @@ -35,13 +37,9 @@ public RelaysTag(@NonNull Relay... relays) { this(List.of(relays)); } - @SuppressWarnings("unchecked") - public static T deserialize(JsonNode node) { - return (T) - new RelaysTag( - Optional.ofNullable(node) - .map(jsonNode -> new Relay(jsonNode.get(1).asText())) - .orElseThrow()); + public static RelaysTag deserialize(JsonNode node) { + return new RelaysTag( + Optional.ofNullable(node).map(jsonNode -> new Relay(jsonNode.get(1).asText())).orElseThrow()); } public static RelaysTag updateFields(@NonNull GenericTag genericTag) { @@ -53,8 +51,6 @@ public static RelaysTag updateFields(@NonNull GenericTag genericTag) { for (ElementAttribute attribute : genericTag.getAttributes()) { relays.add(new Relay(attribute.value().toString())); } - - RelaysTag relaysTag = new RelaysTag(relays); - return relaysTag; + return new RelaysTag(relays); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/SubjectTag.java b/nostr-java-event/src/main/java/nostr/event/tag/SubjectTag.java index 859ef412d..f03d99f8f 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/SubjectTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/SubjectTag.java @@ -1,5 +1,6 @@ package nostr.event.tag; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; @@ -9,13 +10,12 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; +import java.util.Optional; import nostr.base.annotation.Key; import nostr.base.annotation.Tag; import nostr.event.BaseTag; -/** - * @author squirrel - */ +/** Represents a 'subject' tag (NIP-14). */ @Builder @Data @NoArgsConstructor @@ -27,13 +27,18 @@ public final class SubjectTag extends BaseTag { @Key @JsonProperty("subject") + @JsonInclude(JsonInclude.Include.NON_NULL) private String subject; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + /** Optional accessor for subject. */ + public Optional getSubjectOptional() { + return Optional.ofNullable(subject); + } + + public static SubjectTag deserialize(@NonNull JsonNode node) { SubjectTag tag = new SubjectTag(); setOptionalField(node.get(1), (n, t) -> tag.setSubject(n.asText()), tag); - return (T) tag; + return tag; } public static SubjectTag updateFields(@NonNull GenericTag genericTag) { diff --git a/nostr-java-event/src/main/java/nostr/event/tag/TagRegistry.java b/nostr-java-event/src/main/java/nostr/event/tag/TagRegistry.java index 2750f133e..f45cd82bf 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/TagRegistry.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/TagRegistry.java @@ -1,9 +1,10 @@ package nostr.event.tag; +import nostr.event.BaseTag; + import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import nostr.event.BaseTag; /** * Registry of tag factory functions keyed by tag code. Allows new tag types to be registered diff --git a/nostr-java-event/src/main/java/nostr/event/tag/UrlTag.java b/nostr-java-event/src/main/java/nostr/event/tag/UrlTag.java index 7b16e1936..602db00c3 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/UrlTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/UrlTag.java @@ -1,6 +1,7 @@ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Data; @@ -11,7 +12,9 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; +/** Represents a 'u' URL tag (NIP-61). */ @EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"u"}) @Data @NoArgsConstructor @AllArgsConstructor @@ -22,11 +25,10 @@ public class UrlTag extends BaseTag { @JsonProperty("u") private String url; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static UrlTag deserialize(@NonNull JsonNode node) { UrlTag tag = new UrlTag(); setRequiredField(node.get(1), (n, t) -> tag.setUrl(n.asText()), tag); - return (T) tag; + return tag; } public static UrlTag updateFields(@NonNull GenericTag tag) { @@ -37,10 +39,6 @@ public static UrlTag updateFields(@NonNull GenericTag tag) { if (tag.getAttributes().size() != 1) { throw new IllegalArgumentException("Invalid number of attributes for UrlTag"); } - - UrlTag urlTag = new UrlTag(); - urlTag.setUrl(tag.getAttributes().get(0).value().toString()); - - return urlTag; + return new UrlTag(tag.getAttributes().get(0).value().toString()); } } diff --git a/nostr-java-event/src/main/java/nostr/event/tag/VoteTag.java b/nostr-java-event/src/main/java/nostr/event/tag/VoteTag.java index 89c189085..d55e970de 100644 --- a/nostr-java-event/src/main/java/nostr/event/tag/VoteTag.java +++ b/nostr-java-event/src/main/java/nostr/event/tag/VoteTag.java @@ -12,6 +12,7 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; +/** Represents a 'v' vote tag (NIP-2112). */ @Builder @Data @EqualsAndHashCode(callSuper = false) @@ -22,20 +23,16 @@ public class VoteTag extends BaseTag { @Key @JsonProperty private Integer vote; - @SuppressWarnings("unchecked") - public static T deserialize(@NonNull JsonNode node) { + public static VoteTag deserialize(@NonNull JsonNode node) { VoteTag tag = new VoteTag(); setRequiredField(node.get(1), (n, t) -> tag.setVote(n.asInt()), tag); - return (T) tag; + return tag; } public static VoteTag updateFields(@NonNull GenericTag genericTag) { if (!"v".equals(genericTag.getCode())) { throw new IllegalArgumentException("Invalid tag code for VoteTag"); } - - VoteTag voteTag = - new VoteTag(Integer.valueOf(genericTag.getAttributes().get(0).value().toString())); - return voteTag; + return new VoteTag(Integer.valueOf(genericTag.getAttributes().get(0).value().toString())); } } diff --git a/nostr-java-event/src/main/java/nostr/event/validator/EventValidator.java b/nostr-java-event/src/main/java/nostr/event/validator/EventValidator.java index 627116c95..3c3043666 100644 --- a/nostr-java-event/src/main/java/nostr/event/validator/EventValidator.java +++ b/nostr-java-event/src/main/java/nostr/event/validator/EventValidator.java @@ -1,13 +1,14 @@ package nostr.event.validator; -import java.util.List; -import java.util.Objects; import lombok.NonNull; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.util.validator.HexStringValidator; +import java.util.List; +import java.util.Objects; + /** * Validates Nostr events according to NIP-01 specification. * diff --git a/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventTest.java b/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventTest.java new file mode 100644 index 000000000..3c20b87e4 --- /dev/null +++ b/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventTest.java @@ -0,0 +1,67 @@ +package nostr.event.impl; + +import nostr.base.PublicKey; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** Unit tests for AddressableEvent kind validation per NIP-01. */ +public class AddressableEventTest { + + @Test + void validKind_30000_shouldPass() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 30_000, new ArrayList<>(), ""); + assertDoesNotThrow(event::validateKind); + } + + @Test + void validKind_35000_shouldPass() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 35_000, new ArrayList<>(), ""); + assertDoesNotThrow(event::validateKind); + } + + @Test + void validKind_39999_shouldPass() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 39_999, new ArrayList<>(), ""); + assertDoesNotThrow(event::validateKind); + } + + @Test + void invalidKind_29999_shouldFail() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 29_999, new ArrayList<>(), ""); + AssertionError error = assertThrows(AssertionError.class, event::validateKind); + assertTrue(error.getMessage().contains("30000") && error.getMessage().contains("40000")); + } + + @Test + void invalidKind_40000_shouldFail() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 40_000, new ArrayList<>(), ""); + AssertionError error = assertThrows(AssertionError.class, event::validateKind); + assertTrue(error.getMessage().contains("30000") && error.getMessage().contains("40000")); + } + + @Test + void invalidKind_0_shouldFail() { + PublicKey pubKey = createDummyPublicKey(); + AddressableEvent event = new AddressableEvent(pubKey, 0, new ArrayList<>(), ""); + AssertionError error = assertThrows(AssertionError.class, event::validateKind); + assertTrue(error.getMessage().contains("30000") && error.getMessage().contains("40000")); + } + + private PublicKey createDummyPublicKey() { + byte[] keyBytes = new byte[32]; + for (int i = 0; i < 32; i++) { + keyBytes[i] = (byte) i; + } + return new PublicKey(keyBytes); + } +} diff --git a/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventValidateTest.java index ee72fab95..79aa22017 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/AddressableEventValidateTest.java @@ -1,15 +1,16 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class AddressableEventValidateTest { private static final String HEX_64 = "a".repeat(64); private static final String SIG_HEX = "b".repeat(128); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ChannelMessageEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ChannelMessageEventValidateTest.java index b6dfeec5a..0d3224401 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/ChannelMessageEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/ChannelMessageEventValidateTest.java @@ -1,15 +1,16 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ChannelMessageEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ClassifiedListingEventTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ClassifiedListingEventTest.java new file mode 100644 index 000000000..def650b18 --- /dev/null +++ b/nostr-java-event/src/test/java/nostr/event/impl/ClassifiedListingEventTest.java @@ -0,0 +1,37 @@ +package nostr.event.impl; + +import nostr.base.Kind; +import nostr.base.PublicKey; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class ClassifiedListingEventTest { + + // Verifies only allowed kinds (30402, 30403) pass validation. + @Test + void validateKindAllowsOnlyNip99Values() { + PublicKey pk = new PublicKey("e4343c157d026999e106b3bc4245b6c87f52cc8050c4c3b2f34b3567a04ccf95"); + + ClassifiedListingEvent active = + new ClassifiedListingEvent(pk, Kind.CLASSIFIED_LISTING, List.of(), ""); + ClassifiedListingEvent inactive = + new ClassifiedListingEvent(pk, Kind.CLASSIFIED_LISTING_INACTIVE, List.of(), ""); + + assertDoesNotThrow(active::validateKind); + assertDoesNotThrow(inactive::validateKind); + } + + // Ensures other kinds fail validation. + @Test + void validateKindRejectsInvalidValues() { + PublicKey pk = new PublicKey("e4343c157d026999e106b3bc4245b6c87f52cc8050c4c3b2f34b3567a04ccf95"); + ClassifiedListingEvent invalid = + new ClassifiedListingEvent(pk, Kind.TEXT_NOTE, List.of(), ""); + assertThrows(AssertionError.class, invalid::validateKind); + } +} + diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ContactListEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ContactListEventValidateTest.java index 88763e371..5eae1afe9 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/ContactListEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/ContactListEventValidateTest.java @@ -1,17 +1,18 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ContactListEventValidateTest { private static final String HEX_64_A = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; diff --git a/nostr-java-event/src/test/java/nostr/event/impl/DeletionEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/DeletionEventValidateTest.java index 92955e9d9..883d286ae 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/DeletionEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/DeletionEventValidateTest.java @@ -1,17 +1,18 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.EventTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class DeletionEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/DirectMessageEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/DirectMessageEventValidateTest.java index 649c761e4..8ba6804ac 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/DirectMessageEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/DirectMessageEventValidateTest.java @@ -1,15 +1,16 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class DirectMessageEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventTest.java b/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventTest.java new file mode 100644 index 000000000..aa2506982 --- /dev/null +++ b/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventTest.java @@ -0,0 +1,36 @@ +package nostr.event.impl; + +import nostr.base.PublicKey; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class EphemeralEventTest { + + // Validates that kinds in [20000, 30000) are accepted. + @Test + void validateKindAllowsEphemeralRange() { + PublicKey pk = new PublicKey("e4343c157d026999e106b3bc4245b6c87f52cc8050c4c3b2f34b3567a04ccf95"); + + EphemeralEvent k20000 = new EphemeralEvent(pk, 20_000, List.of(), ""); + EphemeralEvent k29999 = new EphemeralEvent(pk, 29_999, List.of(), ""); + + assertDoesNotThrow(k20000::validateKind); + assertDoesNotThrow(k29999::validateKind); + } + + // Ensures values outside the range are rejected. + @Test + void validateKindRejectsOutOfRange() { + PublicKey pk = new PublicKey("e4343c157d026999e106b3bc4245b6c87f52cc8050c4c3b2f34b3567a04ccf95"); + EphemeralEvent below = new EphemeralEvent(pk, 19_999, List.of(), ""); + EphemeralEvent atUpper = new EphemeralEvent(pk, 30_000, List.of(), ""); + + assertThrows(AssertionError.class, below::validateKind); + assertThrows(AssertionError.class, atUpper::validateKind); + } +} + diff --git a/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventValidateTest.java index 57b5272c1..4e2b1ad43 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/EphemeralEventValidateTest.java @@ -1,15 +1,16 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class EphemeralEventValidateTest { private static final String HEX_64 = "a".repeat(64); private static final String SIG_HEX = "b".repeat(128); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/GenericEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/GenericEventValidateTest.java index 51733b1bf..d5f99b661 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/GenericEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/GenericEventValidateTest.java @@ -1,13 +1,14 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; import nostr.base.PublicKey; import nostr.base.Signature; import org.junit.jupiter.api.Test; +import java.time.Instant; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class GenericEventValidateTest { private static final String HEX_64_A = "a".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/HideMessageEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/HideMessageEventValidateTest.java index cd7ae9a22..4072114c7 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/HideMessageEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/HideMessageEventValidateTest.java @@ -1,17 +1,18 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.EventTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class HideMessageEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/MuteUserEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/MuteUserEventValidateTest.java index 0a02a2a90..585f525a2 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/MuteUserEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/MuteUserEventValidateTest.java @@ -1,18 +1,19 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class MuteUserEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ReactionEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ReactionEventValidateTest.java index 404bdf009..1b6e5f98c 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/ReactionEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/ReactionEventValidateTest.java @@ -1,18 +1,19 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.EventTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ReactionEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String HEX_64_B = "b".repeat(64); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ReplaceableEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ReplaceableEventValidateTest.java index d9752afad..dab5b3167 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/ReplaceableEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/ReplaceableEventValidateTest.java @@ -1,16 +1,17 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ReplaceableEventValidateTest { private static final String HEX_64_A = "a".repeat(64); private static final String SIG_HEX = "c".repeat(128); diff --git a/nostr-java-event/src/test/java/nostr/event/impl/TextNoteEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/TextNoteEventValidateTest.java index f39acd4f3..0bb9f2e65 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/TextNoteEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/TextNoteEventValidateTest.java @@ -1,18 +1,19 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.lang.reflect.Field; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.BaseTag; import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.lang.reflect.Field; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class TextNoteEventValidateTest { private static final String HEX_64_A = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; diff --git a/nostr-java-event/src/test/java/nostr/event/impl/ZapRequestEventValidateTest.java b/nostr-java-event/src/test/java/nostr/event/impl/ZapRequestEventValidateTest.java index 17e602944..1a3840bbe 100644 --- a/nostr-java-event/src/test/java/nostr/event/impl/ZapRequestEventValidateTest.java +++ b/nostr-java-event/src/test/java/nostr/event/impl/ZapRequestEventValidateTest.java @@ -1,11 +1,5 @@ package nostr.event.impl; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import nostr.base.ElementAttribute; import nostr.base.PublicKey; import nostr.base.Signature; @@ -14,6 +8,13 @@ import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ZapRequestEventValidateTest { private static final String HEX_64_A = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; diff --git a/nostr-java-event/src/test/java/nostr/event/json/EventJsonMapperTest.java b/nostr-java-event/src/test/java/nostr/event/json/EventJsonMapperTest.java index e9ac2e6eb..4ad1dbc65 100644 --- a/nostr-java-event/src/test/java/nostr/event/json/EventJsonMapperTest.java +++ b/nostr-java-event/src/test/java/nostr/event/json/EventJsonMapperTest.java @@ -1,10 +1,11 @@ package nostr.event.json; -import static org.junit.jupiter.api.Assertions.*; - import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + /** Tests for EventJsonMapper contract. */ public class EventJsonMapperTest { diff --git a/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java b/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java index 2173758f9..9cbab220f 100644 --- a/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java @@ -1,15 +1,16 @@ package nostr.event.json.codec; -import static org.junit.jupiter.api.Assertions.assertThrows; - import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import java.io.IOException; import nostr.event.BaseEvent; import org.junit.jupiter.api.Test; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertThrows; + class BaseEventEncoderTest { static class FailingSerializer extends JsonSerializer { diff --git a/nostr-java-event/src/test/java/nostr/event/serializer/EventSerializerTest.java b/nostr-java-event/src/test/java/nostr/event/serializer/EventSerializerTest.java index 78d86c60d..5109b6f86 100644 --- a/nostr-java-event/src/test/java/nostr/event/serializer/EventSerializerTest.java +++ b/nostr-java-event/src/test/java/nostr/event/serializer/EventSerializerTest.java @@ -1,14 +1,17 @@ package nostr.event.serializer; -import static org.junit.jupiter.api.Assertions.*; - -import java.nio.charset.StandardCharsets; -import java.util.List; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.BaseTag; import org.junit.jupiter.api.Test; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Tests for EventSerializer utility methods. */ public class EventSerializerTest { diff --git a/nostr-java-event/src/test/java/nostr/event/support/GenericEventSupportTest.java b/nostr-java-event/src/test/java/nostr/event/support/GenericEventSupportTest.java index ce0ad49f1..62d3bf3e3 100644 --- a/nostr-java-event/src/test/java/nostr/event/support/GenericEventSupportTest.java +++ b/nostr-java-event/src/test/java/nostr/event/support/GenericEventSupportTest.java @@ -1,19 +1,21 @@ package nostr.event.support; -import static org.junit.jupiter.api.Assertions.*; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; - import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.impl.GenericEvent; -import nostr.event.json.EventJsonMapper; import nostr.util.NostrUtil; import org.junit.jupiter.api.Test; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Tests for GenericEventSerializer, Updater and Validator utility classes. */ public class GenericEventSupportTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java index ad841438c..c1f1154c8 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java @@ -1,26 +1,27 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; -import nostr.base.PublicKey; import lombok.extern.slf4j.Slf4j; +import nostr.base.PublicKey; import nostr.event.BaseMessage; +import nostr.event.BaseTag; +import nostr.event.impl.GenericEvent; import nostr.event.json.codec.BaseMessageDecoder; import nostr.event.message.CloseMessage; import nostr.event.message.EoseMessage; import nostr.event.message.EventMessage; import nostr.event.message.NoticeMessage; import nostr.event.message.OkMessage; -import nostr.event.message.ReqMessage; import nostr.event.message.RelayAuthenticationMessage; -import nostr.event.impl.GenericEvent; -import nostr.event.BaseTag; +import nostr.event.message.ReqMessage; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + @Slf4j public class BaseMessageCommandMapperTest { // TODO: flesh out remaining commands diff --git a/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageDecoderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageDecoderTest.java index bc427dddf..b4c671cd4 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageDecoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageDecoderTest.java @@ -1,26 +1,27 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; - import com.fasterxml.jackson.core.JsonProcessingException; import lombok.extern.slf4j.Slf4j; +import nostr.base.PublicKey; import nostr.event.BaseMessage; +import nostr.event.BaseTag; +import nostr.event.impl.GenericEvent; import nostr.event.json.codec.BaseMessageDecoder; import nostr.event.message.CloseMessage; import nostr.event.message.EoseMessage; import nostr.event.message.EventMessage; import nostr.event.message.NoticeMessage; import nostr.event.message.OkMessage; -import nostr.event.message.ReqMessage; import nostr.event.message.RelayAuthenticationMessage; -import nostr.event.impl.GenericEvent; -import nostr.base.PublicKey; -import nostr.event.BaseTag; -import java.util.ArrayList; +import nostr.event.message.ReqMessage; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + @Slf4j public class BaseMessageDecoderTest { // TODO: flesh out remaining commands diff --git a/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java index de0e82040..2166880d6 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java @@ -1,9 +1,5 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -import java.util.List; import nostr.event.BaseTag; import nostr.event.tag.AddressTag; import nostr.event.tag.EmojiTag; @@ -23,6 +19,11 @@ import nostr.event.tag.SubjectTag; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + class BaseTagTest { BaseTag genericTag = BaseTag.create("id", "value"); diff --git a/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java index 5ea56485d..7d38196a7 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java @@ -1,15 +1,16 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import org.junit.jupiter.api.Test; import nostr.base.PublicKey; import nostr.event.entities.CalendarContent; import nostr.event.tag.HashtagTag; import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class CalendarContentAddTagTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java index 64c04463e..d4ce3e195 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java @@ -1,11 +1,11 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - import nostr.event.impl.CalendarTimeBasedEvent; import nostr.event.json.codec.GenericEventDecoder; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class CalendarContentDecodeTest { String eventFullJson = """ diff --git a/nostr-java-event/src/test/java/nostr/event/unit/CalendarDeserializerTest.java b/nostr-java-event/src/test/java/nostr/event/unit/CalendarDeserializerTest.java index aefe546a4..d00347c8d 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/CalendarDeserializerTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/CalendarDeserializerTest.java @@ -1,10 +1,6 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.Signature; @@ -23,6 +19,11 @@ import nostr.event.tag.SubjectTag; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + class CalendarDeserializerTest { private static final PublicKey AUTHOR = diff --git a/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java index c2c4e9ecb..3bcd58caa 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java @@ -1,11 +1,11 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - import nostr.event.impl.ClassifiedListingEvent; import nostr.event.json.codec.GenericEventDecoder; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class ClassifiedListingDecodeTest { String eventJson = """ diff --git a/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java index cdce59504..4dcf58c10 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java @@ -1,12 +1,6 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.fail; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; -import java.util.List; import nostr.base.Marker; import nostr.base.PublicKey; import nostr.event.BaseMessage; @@ -18,6 +12,13 @@ import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.fail; + public class DecodeTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java index 5acd32433..6f9e32a13 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java @@ -1,5 +1,16 @@ package nostr.event.unit; +import nostr.base.Marker; +import nostr.event.BaseTag; +import nostr.event.json.codec.BaseTagEncoder; +import nostr.event.tag.EventTag; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.UUID; +import java.util.function.Predicate; + import static nostr.base.json.EventJsonMapper.mapper; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -7,16 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.lang.reflect.Field; -import java.util.List; -import java.util.UUID; -import java.util.function.Predicate; -import nostr.base.Marker; -import nostr.event.BaseTag; -import nostr.event.json.codec.BaseTagEncoder; -import nostr.event.tag.EventTag; -import org.junit.jupiter.api.Test; - class EventTagTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/EventWithAddressTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/EventWithAddressTagTest.java index a80776e51..5e0620091 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/EventWithAddressTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/EventWithAddressTagTest.java @@ -1,12 +1,6 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.fail; - import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.ArrayList; -import java.util.List; import nostr.base.PublicKey; import nostr.base.Relay; import nostr.event.BaseMessage; @@ -18,6 +12,13 @@ import nostr.event.tag.IdentifierTag; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.fail; + public class EventWithAddressTagTest { @Test public void decodeTestWithRelay() throws JsonProcessingException { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java index b9a1eed6d..2143f260f 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java @@ -1,10 +1,5 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.Date; import lombok.extern.slf4j.Slf4j; import nostr.base.GenericTagQuery; import nostr.base.Kind; @@ -31,6 +26,12 @@ import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + @Slf4j public class FiltersDecoderTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java index be74919ef..30654903b 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java @@ -1,12 +1,5 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.time.Instant; -import java.util.Date; -import java.util.List; import lombok.extern.slf4j.Slf4j; import nostr.base.GenericTagQuery; import nostr.base.Kind; @@ -35,6 +28,14 @@ import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.time.Instant; +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + @Slf4j public class FiltersEncoderTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/FiltersTest.java b/nostr-java-event/src/test/java/nostr/event/unit/FiltersTest.java index bd4a20a9b..a38f05e24 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/FiltersTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/FiltersTest.java @@ -1,19 +1,20 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import nostr.base.Kind; +import nostr.event.filter.Filterable; +import nostr.event.filter.Filters; +import nostr.event.filter.KindFilter; +import org.junit.jupiter.api.Test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.List; import java.util.Map; -import nostr.base.Kind; -import nostr.event.filter.Filterable; -import nostr.event.filter.Filters; -import nostr.event.filter.KindFilter; -import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class FiltersTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/GenericEventBuilderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/GenericEventBuilderTest.java index 28d0176ee..eedf4e818 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/GenericEventBuilderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/GenericEventBuilderTest.java @@ -1,15 +1,16 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.List; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + class GenericEventBuilderTest { private static final String HEX_ID = "a3f2d7306f8911b588f7c5e2d460ad4f8b5e2c5d7a6b8c9d0e1f2a3b4c5d6e7f"; diff --git a/nostr-java-event/src/test/java/nostr/event/unit/GenericTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/GenericTagTest.java index 1d31c599b..c3f8d062e 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/GenericTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/GenericTagTest.java @@ -1,13 +1,14 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -import java.util.List; import nostr.event.BaseTag; import nostr.event.tag.GenericTag; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + public class GenericTagTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/JsonContentValidationTest.java b/nostr-java-event/src/test/java/nostr/event/unit/JsonContentValidationTest.java index 3fa385944..2359f2dd4 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/JsonContentValidationTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/JsonContentValidationTest.java @@ -1,13 +1,14 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.List; import nostr.base.PublicKey; import nostr.event.impl.ChannelCreateEvent; import nostr.event.impl.CreateOrUpdateProductEvent; import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; + public class JsonContentValidationTest { private static final PublicKey PUBKEY = diff --git a/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java b/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java index cb6f7f688..316bf5c1b 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java @@ -1,11 +1,11 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import nostr.base.Kind; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class KindMappingTest { @Test void testKindValueOf() { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java index 8101f591e..c572abda8 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java @@ -1,14 +1,15 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertTrue; +import nostr.event.tag.PriceTag; +import org.junit.jupiter.api.Test; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.List; import java.util.stream.Stream; -import nostr.event.tag.PriceTag; -import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; class PriceTagTest { private static final BigDecimal aVal = new BigDecimal(10.000); diff --git a/nostr-java-event/src/test/java/nostr/event/unit/ProductSerializationTest.java b/nostr-java-event/src/test/java/nostr/event/unit/ProductSerializationTest.java index 9f7403827..14ce86c30 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/ProductSerializationTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/ProductSerializationTest.java @@ -1,15 +1,16 @@ package nostr.event.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.fasterxml.jackson.databind.JsonNode; -import java.util.List; import nostr.event.entities.Product; import nostr.event.entities.Stall; import org.junit.jupiter.api.Test; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class ProductSerializationTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java index 6aaa418b5..ee4573d65 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java @@ -1,13 +1,14 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.lang.reflect.Field; import nostr.base.PublicKey; import nostr.event.tag.PubKeyTag; import org.junit.jupiter.api.Test; +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + class PubkeyTagTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java index 91b63473b..ae7e8c598 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java @@ -1,17 +1,18 @@ package nostr.event.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; - import com.fasterxml.jackson.databind.JsonNode; -import java.util.List; import nostr.base.Relay; import nostr.event.BaseTag; import nostr.event.json.codec.BaseTagEncoder; import nostr.event.tag.RelaysTag; import org.junit.jupiter.api.Test; +import java.util.List; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + class RelaysTagTest { public static final String RELAYS_KEY = "relays"; diff --git a/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java b/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java index 0c1259f11..efdfb9664 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java @@ -1,12 +1,12 @@ package nostr.event.unit; +import nostr.base.Signature; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import nostr.base.Signature; -import org.junit.jupiter.api.Test; - public class SignatureTest { @Test public void testSignatureStringLength() { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/TagDeserializerTest.java b/nostr-java-event/src/test/java/nostr/event/unit/TagDeserializerTest.java index 9e68acc3c..45a9b8d6c 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/TagDeserializerTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/TagDeserializerTest.java @@ -1,11 +1,5 @@ package nostr.event.unit; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNull; - -import java.math.BigDecimal; import nostr.event.BaseTag; import nostr.event.tag.AddressTag; import nostr.event.tag.EventTag; @@ -14,6 +8,13 @@ import nostr.event.tag.UrlTag; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; + +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; + class TagDeserializerTest { @Test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/TagRegistryTest.java b/nostr-java-event/src/test/java/nostr/event/unit/TagRegistryTest.java index 1579d9ce5..2e781a3d6 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/TagRegistryTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/TagRegistryTest.java @@ -1,8 +1,5 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - import nostr.base.annotation.Key; import nostr.base.annotation.Tag; import nostr.event.BaseTag; @@ -10,6 +7,9 @@ import nostr.event.tag.TagRegistry; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + /** Tests for dynamic tag registration. */ class TagRegistryTest { diff --git a/nostr-java-event/src/test/java/nostr/event/unit/ValidateKindTest.java b/nostr-java-event/src/test/java/nostr/event/unit/ValidateKindTest.java index f79650dac..adcdff4b1 100644 --- a/nostr-java-event/src/test/java/nostr/event/unit/ValidateKindTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/ValidateKindTest.java @@ -1,14 +1,15 @@ package nostr.event.unit; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.ArrayList; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.base.Signature; import nostr.event.impl.TextNoteEvent; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertThrows; + public class ValidateKindTest { @Test public void testTextNoteInvalidKind() { diff --git a/nostr-java-event/src/test/java/nostr/event/util/EventTypeCheckerTest.java b/nostr-java-event/src/test/java/nostr/event/util/EventTypeCheckerTest.java index 50dd48750..d3a96d195 100644 --- a/nostr-java-event/src/test/java/nostr/event/util/EventTypeCheckerTest.java +++ b/nostr-java-event/src/test/java/nostr/event/util/EventTypeCheckerTest.java @@ -1,9 +1,11 @@ package nostr.event.util; -import static org.junit.jupiter.api.Assertions.*; - import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** Tests for EventTypeChecker ranges and naming. */ public class EventTypeCheckerTest { diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 1a66647b6..e76880396 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-examples/src/main/java/nostr/examples/ExpirationEventExample.java b/nostr-java-examples/src/main/java/nostr/examples/ExpirationEventExample.java index 707a24d24..fc4d0edb3 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/ExpirationEventExample.java +++ b/nostr-java-examples/src/main/java/nostr/examples/ExpirationEventExample.java @@ -1,7 +1,5 @@ package nostr.examples; -import java.time.Instant; -import java.util.List; import nostr.base.ElementAttribute; import nostr.base.Kind; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -12,6 +10,9 @@ import nostr.event.tag.GenericTag; import nostr.id.Identity; +import java.time.Instant; +import java.util.List; + /** * Example demonstrating creation of an expiration event (NIP-40) and showing how to send it with * either available WebSocket client. diff --git a/nostr-java-examples/src/main/java/nostr/examples/FilterExample.java b/nostr-java-examples/src/main/java/nostr/examples/FilterExample.java index 4af54b1fd..a69b53a6c 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/FilterExample.java +++ b/nostr-java-examples/src/main/java/nostr/examples/FilterExample.java @@ -1,7 +1,5 @@ package nostr.examples; -import java.util.List; -import java.util.Map; import nostr.api.NIP01; import nostr.base.Kind; import nostr.base.PublicKey; @@ -13,6 +11,9 @@ import nostr.event.message.EventMessage; import nostr.id.Identity; +import java.util.List; +import java.util.Map; + /** Demonstrates requesting events from a relay using filters for author and kind. */ public class FilterExample { diff --git a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java index cd38ca43c..146f7c47e 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java +++ b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java @@ -1,12 +1,5 @@ package nostr.examples; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Map; import nostr.api.NIP01; import nostr.api.NIP04; import nostr.api.NIP05; @@ -29,6 +22,14 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + /** Example demonstrating several nostr-java API calls. */ public class NostrApiExamples { diff --git a/nostr-java-examples/src/main/java/nostr/examples/SpringClientTextEventExample.java b/nostr-java-examples/src/main/java/nostr/examples/SpringClientTextEventExample.java index 323c2f437..59da82e17 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/SpringClientTextEventExample.java +++ b/nostr-java-examples/src/main/java/nostr/examples/SpringClientTextEventExample.java @@ -1,9 +1,10 @@ package nostr.examples; -import java.util.Map; import nostr.api.NIP01; import nostr.id.Identity; +import java.util.Map; + /** * Example showing how to create, sign and send a text note using the NIP01 helper built on top of * NostrSpringWebSocketClient. diff --git a/nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java b/nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java index 870691a24..743dfcd42 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java +++ b/nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java @@ -1,12 +1,13 @@ package nostr.examples; -import java.time.Duration; -import java.util.Map; import nostr.api.NostrSpringWebSocketClient; import nostr.base.Kind; import nostr.event.filter.Filters; import nostr.event.filter.KindFilter; +import java.time.Duration; +import java.util.Map; + /** * Example showing how to open a non-blocking subscription using * {@link nostr.api.NostrSpringWebSocketClient} and close it after a fixed duration. diff --git a/nostr-java-examples/src/main/java/nostr/examples/TextNoteEventExample.java b/nostr-java-examples/src/main/java/nostr/examples/TextNoteEventExample.java index e0b38ad6a..ebd4bad64 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/TextNoteEventExample.java +++ b/nostr-java-examples/src/main/java/nostr/examples/TextNoteEventExample.java @@ -1,12 +1,13 @@ package nostr.examples; -import java.util.List; import nostr.client.springwebsocket.StandardWebSocketClient; import nostr.event.BaseTag; import nostr.event.impl.TextNoteEvent; import nostr.event.message.EventMessage; import nostr.id.Identity; +import java.util.List; + /** * Demonstrates creating, signing, and sending a text note using the * {@link nostr.event.impl.TextNoteEvent} class. diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 3ca6deec5..f2aa64d37 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-id/src/main/java/nostr/id/Identity.java b/nostr-java-id/src/main/java/nostr/id/Identity.java index 04bf9fa1d..88d83f1b8 100644 --- a/nostr-java-id/src/main/java/nostr/id/Identity.java +++ b/nostr-java-id/src/main/java/nostr/id/Identity.java @@ -1,7 +1,5 @@ package nostr.id; -import java.security.NoSuchAlgorithmException; -import java.util.function.Consumer; import lombok.Data; import lombok.NonNull; import lombok.ToString; @@ -14,6 +12,9 @@ import nostr.crypto.schnorr.SchnorrException; import nostr.util.NostrUtil; +import java.security.NoSuchAlgorithmException; +import java.util.function.Consumer; + /** * Represents a Nostr identity backed by a private key. * diff --git a/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java b/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java index 465cfc102..5d3c689b9 100644 --- a/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java @@ -1,10 +1,5 @@ package nostr.id; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; import nostr.base.Kind; import nostr.base.PublicKey; import nostr.event.BaseTag; @@ -19,6 +14,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ClassifiedListingEventTest { public static final PublicKey senderPubkey = diff --git a/nostr-java-id/src/test/java/nostr/id/EntityFactory.java b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java index 81032f617..036c96303 100644 --- a/nostr-java-id/src/test/java/nostr/id/EntityFactory.java +++ b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java @@ -1,11 +1,5 @@ package nostr.id; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; import lombok.extern.slf4j.Slf4j; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; @@ -26,6 +20,13 @@ import nostr.event.tag.GenericTag; import nostr.event.tag.PubKeyTag; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + /** * @author squirrel */ diff --git a/nostr-java-id/src/test/java/nostr/id/EventTest.java b/nostr-java-id/src/test/java/nostr/id/EventTest.java index d569f340d..0ca220875 100644 --- a/nostr-java-id/src/test/java/nostr/id/EventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/EventTest.java @@ -1,13 +1,5 @@ package nostr.id; -import static nostr.base.json.EventJsonMapper.mapper; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import lombok.extern.slf4j.Slf4j; import nostr.base.ElementAttribute; import nostr.base.PublicKey; @@ -24,6 +16,14 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import static nostr.base.json.EventJsonMapper.mapper; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * @author squirrel */ @@ -65,9 +65,9 @@ public void testCreateGenericTag() { @Test public void testCreateUnsupportedGenericTagAttribute() { - /** - * test of this functionality relocated to nostr-java-api {@link - * nostr.api.integration.ApiEventIT#testCreateUnsupportedGenericTagAttribute()} + /* + * Test of this functionality relocated to nostr-java-api: + * see nostr.api.integration.ApiEventIT#testCreateUnsupportedGenericTagAttribute() */ } diff --git a/nostr-java-id/src/test/java/nostr/id/IdentityTest.java b/nostr-java-id/src/test/java/nostr/id/IdentityTest.java index b3e7fc716..b0f7cabe3 100644 --- a/nostr-java-id/src/test/java/nostr/id/IdentityTest.java +++ b/nostr-java-id/src/test/java/nostr/id/IdentityTest.java @@ -1,21 +1,22 @@ package nostr.id; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.util.function.Consumer; -import java.util.function.Supplier; import nostr.base.ISignable; import nostr.base.PublicKey; import nostr.base.Signature; -import nostr.crypto.schnorr.Schnorr; -import nostr.crypto.schnorr.SchnorrException; +import nostr.crypto.schnorr.Schnorr; +import nostr.crypto.schnorr.SchnorrException; import nostr.event.impl.GenericEvent; import nostr.event.tag.DelegationTag; import nostr.util.NostrUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.util.function.Consumer; +import java.util.function.Supplier; + /** * @author squirrel */ @@ -23,9 +24,9 @@ public class IdentityTest { public IdentityTest() {} - @Test - // Ensures signing a text note event attaches a signature - public void testSignEvent() { + @Test + // Ensures signing a text note event attaches a signature + public void testSignEvent() { System.out.println("testSignEvent"); Identity identity = Identity.generateRandomIdentity(); PublicKey publicKey = identity.getPublicKey(); @@ -34,9 +35,9 @@ public void testSignEvent() { Assertions.assertNotNull(instance.getSignature()); } - @Test - // Ensures signing a delegation tag populates its signature - public void testSignDelegationTag() { + @Test + // Ensures signing a delegation tag populates its signature + public void testSignDelegationTag() { System.out.println("testSignDelegationTag"); Identity identity = Identity.generateRandomIdentity(); PublicKey publicKey = identity.getPublicKey(); @@ -45,17 +46,17 @@ public void testSignDelegationTag() { Assertions.assertNotNull(delegationTag.getSignature()); } - @Test - // Verifies that generating random identities yields unique private keys - public void testGenerateRandomIdentityProducesUniqueKeys() { + @Test + // Verifies that generating random identities yields unique private keys + public void testGenerateRandomIdentityProducesUniqueKeys() { Identity id1 = Identity.generateRandomIdentity(); Identity id2 = Identity.generateRandomIdentity(); Assertions.assertNotEquals(id1.getPrivateKey(), id2.getPrivateKey()); } - @Test - // Confirms that deriving the public key from a known private key matches expectations - public void testGetPublicKeyDerivation() { + @Test + // Confirms that deriving the public key from a known private key matches expectations + public void testGetPublicKeyDerivation() { String privHex = "0000000000000000000000000000000000000000000000000000000000000001"; Identity identity = Identity.create(privHex); PublicKey expected = @@ -63,10 +64,10 @@ public void testGetPublicKeyDerivation() { Assertions.assertEquals(expected, identity.getPublicKey()); } - @Test - // Verifies that signing produces a Schnorr signature that validates successfully - public void testSignProducesValidSignature() - throws NoSuchAlgorithmException, SchnorrException { + @Test + // Verifies that signing produces a Schnorr signature that validates successfully + public void testSignProducesValidSignature() + throws NoSuchAlgorithmException, SchnorrException { String privHex = "0000000000000000000000000000000000000000000000000000000000000001"; Identity identity = Identity.create(privHex); final byte[] message = "hello".getBytes(StandardCharsets.UTF_8); @@ -105,26 +106,26 @@ public Supplier getByteArraySupplier() { Assertions.assertTrue(verified); } - @Test - // Confirms public key derivation is cached for subsequent calls - public void testPublicKeyCaching() { + @Test + // Confirms public key derivation is cached for subsequent calls + public void testPublicKeyCaching() { Identity identity = Identity.generateRandomIdentity(); PublicKey first = identity.getPublicKey(); PublicKey second = identity.getPublicKey(); Assertions.assertSame(first, second); } - @Test - // Ensures that invalid private keys trigger a derivation failure - public void testGetPublicKeyFailure() { + @Test + // Ensures that invalid private keys trigger a derivation failure + public void testGetPublicKeyFailure() { String invalidPriv = "0000000000000000000000000000000000000000000000000000000000000000"; Identity identity = Identity.create(invalidPriv); Assertions.assertThrows(IllegalStateException.class, identity::getPublicKey); } - @Test - // Ensures that signing with an invalid private key throws SigningException - public void testSignWithInvalidKeyFails() { + @Test + // Ensures that signing with an invalid private key throws SigningException + public void testSignWithInvalidKeyFails() { String invalidPriv = "0000000000000000000000000000000000000000000000000000000000000000"; Identity identity = Identity.create(invalidPriv); diff --git a/nostr-java-id/src/test/java/nostr/id/ReactionEventTest.java b/nostr-java-id/src/test/java/nostr/id/ReactionEventTest.java index f4dcd6ef9..b9a47c048 100644 --- a/nostr-java-id/src/test/java/nostr/id/ReactionEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ReactionEventTest.java @@ -1,15 +1,16 @@ package nostr.id; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.ArrayList; import nostr.base.PublicKey; import nostr.event.entities.Reaction; import nostr.event.impl.GenericEvent; import nostr.event.impl.ReactionEvent; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + class ReactionEventTest { @Test diff --git a/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java b/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java index 9391891de..05458ef40 100644 --- a/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java @@ -1,8 +1,5 @@ package nostr.id; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; import nostr.base.ElementAttribute; import nostr.base.PublicKey; import nostr.base.Relay; @@ -20,6 +17,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ZapRequestEventTest { public final PublicKey sender = Identity.generateRandomIdentity().getPublicKey(); diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index d8c0319d3..5466a49a0 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT ../pom.xml diff --git a/nostr-java-util/src/main/java/nostr/util/NostrUtil.java b/nostr-java-util/src/main/java/nostr/util/NostrUtil.java index 3b6622c33..b5c3a2bb5 100644 --- a/nostr-java-util/src/main/java/nostr/util/NostrUtil.java +++ b/nostr-java-util/src/main/java/nostr/util/NostrUtil.java @@ -1,5 +1,7 @@ package nostr.util; +import nostr.util.validator.HexStringValidator; + import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -7,7 +9,6 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; -import nostr.util.validator.HexStringValidator; /** * @author squirrel diff --git a/nostr-java-util/src/main/java/nostr/util/validator/HexStringValidator.java b/nostr-java-util/src/main/java/nostr/util/validator/HexStringValidator.java index 41898f169..a3d223725 100644 --- a/nostr-java-util/src/main/java/nostr/util/validator/HexStringValidator.java +++ b/nostr-java-util/src/main/java/nostr/util/validator/HexStringValidator.java @@ -1,10 +1,11 @@ package nostr.util.validator; +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; + import java.util.Objects; import java.util.function.BiPredicate; import java.util.function.Predicate; -import lombok.NonNull; -import org.apache.commons.lang3.StringUtils; public class HexStringValidator { private static final String validHexChars = "0123456789abcdef"; diff --git a/nostr-java-util/src/main/java/nostr/util/validator/Nip05Content.java b/nostr-java-util/src/main/java/nostr/util/validator/Nip05Content.java index 25d234a96..5bf86736d 100644 --- a/nostr-java-util/src/main/java/nostr/util/validator/Nip05Content.java +++ b/nostr-java-util/src/main/java/nostr/util/validator/Nip05Content.java @@ -1,11 +1,12 @@ package nostr.util.validator; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import java.util.Map; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; +import java.util.Map; + /** * @author eric */ diff --git a/nostr-java-util/src/main/java/nostr/util/validator/Nip05Validator.java b/nostr-java-util/src/main/java/nostr/util/validator/Nip05Validator.java index ed1fffcf8..ff0c4cf3f 100644 --- a/nostr-java-util/src/main/java/nostr/util/validator/Nip05Validator.java +++ b/nostr-java-util/src/main/java/nostr/util/validator/Nip05Validator.java @@ -4,6 +4,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.module.blackbird.BlackbirdModule; +import lombok.Builder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import nostr.util.NostrException; +import nostr.util.http.DefaultHttpClientProvider; +import nostr.util.http.HttpClientProvider; + import java.io.IOException; import java.net.IDN; import java.net.URI; @@ -17,12 +24,6 @@ import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; -import lombok.Builder; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import nostr.util.NostrException; -import nostr.util.http.DefaultHttpClientProvider; -import nostr.util.http.HttpClientProvider; /** * Validator for NIP-05 identifiers. diff --git a/nostr-java-util/src/test/java/nostr/util/NostrUtilExtendedTest.java b/nostr-java-util/src/test/java/nostr/util/NostrUtilExtendedTest.java index 89b00f1dd..e7b49ad6d 100644 --- a/nostr-java-util/src/test/java/nostr/util/NostrUtilExtendedTest.java +++ b/nostr-java-util/src/test/java/nostr/util/NostrUtilExtendedTest.java @@ -1,14 +1,15 @@ package nostr.util; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.util.Arrays; -import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class NostrUtilExtendedTest { diff --git a/nostr-java-util/src/test/java/nostr/util/NostrUtilRandomTest.java b/nostr-java-util/src/test/java/nostr/util/NostrUtilRandomTest.java index f4799f193..595da1938 100644 --- a/nostr-java-util/src/test/java/nostr/util/NostrUtilRandomTest.java +++ b/nostr-java-util/src/test/java/nostr/util/NostrUtilRandomTest.java @@ -1,12 +1,13 @@ package nostr.util; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - public class NostrUtilRandomTest { @Test diff --git a/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java b/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java index f9eb36939..c1f1e9660 100644 --- a/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java +++ b/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java @@ -1,10 +1,10 @@ package nostr.util; -import static org.junit.jupiter.api.Assertions.assertEquals; - import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * @author squirrel */ diff --git a/nostr-java-util/src/test/java/nostr/util/validator/HexStringValidatorTest.java b/nostr-java-util/src/test/java/nostr/util/validator/HexStringValidatorTest.java index 16d5a74b1..744bfafb6 100644 --- a/nostr-java-util/src/test/java/nostr/util/validator/HexStringValidatorTest.java +++ b/nostr-java-util/src/test/java/nostr/util/validator/HexStringValidatorTest.java @@ -1,10 +1,10 @@ package nostr.util.validator; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; - public class HexStringValidatorTest { @Test diff --git a/nostr-java-util/src/test/java/nostr/util/validator/Nip05ValidatorTest.java b/nostr-java-util/src/test/java/nostr/util/validator/Nip05ValidatorTest.java index 55d6ed993..df696fd14 100644 --- a/nostr-java-util/src/test/java/nostr/util/validator/Nip05ValidatorTest.java +++ b/nostr-java-util/src/test/java/nostr/util/validator/Nip05ValidatorTest.java @@ -1,6 +1,8 @@ package nostr.util.validator; -import static org.junit.jupiter.api.Assertions.*; +import nostr.util.NostrException; +import nostr.util.http.HttpClientProvider; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.lang.reflect.Method; @@ -13,9 +15,11 @@ import java.util.Collections; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import nostr.util.NostrException; -import nostr.util.http.HttpClientProvider; -import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class Nip05ValidatorTest { diff --git a/pom.xml b/pom.xml index adb5f4a90..4e9fa9934 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xyz.tcheeric nostr-java - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT pom ${project.artifactId} From 42740959bc9b45e4a62b6157b9ce41cfcf971960 Mon Sep 17 00:00:00 2001 From: Eric T Date: Sun, 12 Oct 2025 02:19:16 +0100 Subject: [PATCH 2/2] fix: restore GenericTag fallback for DM decrypt --- .../src/main/java/nostr/api/NIP04.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nostr-java-api/src/main/java/nostr/api/NIP04.java b/nostr-java-api/src/main/java/nostr/api/NIP04.java index 5ccd9d063..6611516bb 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP04.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP04.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; /** * NIP-04: Encrypted Direct Messages. @@ -344,6 +345,7 @@ public static String decrypt(@NonNull Identity rcptId, @NonNull GenericEvent eve PubKeyTag pTag = Filterable.getTypeSpecificTags(PubKeyTag.class, event).stream() .findFirst() + .or(() -> findGenericPubKeyTag(event)) .orElseThrow(() -> new NoSuchElementException("No matching p-tag found.")); boolean rcptFlag = amITheRecipient(rcptId, event); @@ -364,6 +366,26 @@ public static String decrypt(@NonNull Identity rcptId, @NonNull GenericEvent eve return cipher.decrypt(event.getContent()); } + private static Optional findGenericPubKeyTag(GenericEvent event) { + return event.getTags().stream() + .filter(tag -> "p".equalsIgnoreCase(tag.getCode())) + .map(NIP04::toPubKeyTag) + .findFirst(); + } + + private static PubKeyTag toPubKeyTag(BaseTag tag) { + if (tag instanceof PubKeyTag pubKeyTag) { + return pubKeyTag; + } + + if (tag instanceof GenericTag genericTag) { + return PubKeyTag.updateFields(genericTag); + } + + throw new IllegalArgumentException( + "Unsupported tag type for p-tag conversion: " + tag.getClass().getName()); + } + private static boolean amITheRecipient(@NonNull Identity recipient, @NonNull GenericEvent event) { // Use helper to fetch the p-tag without manual casts PubKeyTag pTag =