From b8921b6ddb2d18950649621746289ebe221a580b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 7 Mar 2025 21:45:39 -0800 Subject: [PATCH 01/57] nip44 and nip04 modules merged into encryption module --- nostr-java-api/pom.xml | 10 ------ nostr-java-api/src/main/java/module-info.java | 2 -- .../src/main/java/nostr/api/NIP04.java | 2 +- .../src/main/java/nostr/api/NIP44.java | 2 +- nostr-java-encryption-nip04/pom.xml | 32 ------------------- .../src/main/java/module-info.java | 9 ------ .../services/nostr.encryption.MessageCipher | 1 - nostr-java-encryption-nip44/pom.xml | 32 ------------------- .../src/main/java/module-info.java | 10 ------ .../services/nostr.encryption.MessageCipher | 1 - nostr-java-encryption/pom.xml | 17 ++++++++++ .../src/main/java/module-info.java | 6 ++-- .../nostr/encryption}/MessageCipher04.java | 3 +- .../nostr/encryption}/MessageCipher44.java | 5 ++- pom.xml | 2 -- 15 files changed, 26 insertions(+), 108 deletions(-) delete mode 100644 nostr-java-encryption-nip04/pom.xml delete mode 100644 nostr-java-encryption-nip04/src/main/java/module-info.java delete mode 100644 nostr-java-encryption-nip04/src/main/resources/META-INF/services/nostr.encryption.MessageCipher delete mode 100644 nostr-java-encryption-nip44/pom.xml delete mode 100644 nostr-java-encryption-nip44/src/main/java/module-info.java delete mode 100644 nostr-java-encryption-nip44/src/main/resources/META-INF/services/nostr.encryption.MessageCipher rename {nostr-java-encryption-nip04/src/main/java/nostr/encryption/nip04 => nostr-java-encryption/src/main/java/nostr/encryption}/MessageCipher04.java (95%) rename {nostr-java-encryption-nip44/src/main/java/nostr/encryption/nip44 => nostr-java-encryption/src/main/java/nostr/encryption}/MessageCipher44.java (95%) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 21777ec5e..3d0fe24b1 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -34,16 +34,6 @@ nostr-java-encryption ${project.version} - - ${project.groupId} - nostr-java-encryption-nip04 - ${project.version} - - - ${project.groupId} - nostr-java-encryption-nip44 - ${project.version} - org.apache.commons commons-lang3 diff --git a/nostr-java-api/src/main/java/module-info.java b/nostr-java-api/src/main/java/module-info.java index 5238893c9..be79b0170 100644 --- a/nostr-java-api/src/main/java/module-info.java +++ b/nostr-java-api/src/main/java/module-info.java @@ -5,8 +5,6 @@ requires nostr.id; requires nostr.client; requires nostr.encryption; - requires nostr.encryption.nip04dm; - requires nostr.encryption.nip44dm; requires com.fasterxml.jackson.databind; 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 b9788ca80..b2f4dcd8b 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP04.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP04.java @@ -10,7 +10,7 @@ import nostr.base.ITag; import nostr.base.PublicKey; import nostr.encryption.MessageCipher; -import nostr.encryption.nip04.MessageCipher04; +import nostr.encryption.MessageCipher04; import nostr.event.NIP04Event; import nostr.event.impl.DirectMessageEvent; import nostr.event.impl.GenericEvent; 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 778918268..87aca2f57 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP44.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP44.java @@ -6,7 +6,7 @@ import nostr.base.ITag; import nostr.base.PublicKey; import nostr.encryption.MessageCipher; -import nostr.encryption.nip44.MessageCipher44; +import nostr.encryption.MessageCipher44; import nostr.event.BaseTag; import nostr.event.impl.EncryptedPayloadEvent; import nostr.event.impl.GenericEvent; diff --git a/nostr-java-encryption-nip04/pom.xml b/nostr-java-encryption-nip04/pom.xml deleted file mode 100644 index 5c28eba3c..000000000 --- a/nostr-java-encryption-nip04/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - 4.0.0 - - xyz.tcheeric - nostr-java - 0.6.5-SNAPSHOT - - - nostr-java-encryption-nip04 - jar - - nostr-java-encryption-nip04 - http://maven.apache.org - - - UTF-8 - - - - - ${project.groupId} - nostr-java-encryption - ${project.version} - - - ${project.groupId} - nostr-java-crypto - ${project.version} - - - diff --git a/nostr-java-encryption-nip04/src/main/java/module-info.java b/nostr-java-encryption-nip04/src/main/java/module-info.java deleted file mode 100644 index 8acbf4ca2..000000000 --- a/nostr-java-encryption-nip04/src/main/java/module-info.java +++ /dev/null @@ -1,9 +0,0 @@ -module nostr.encryption.nip04dm { - - requires lombok; - - requires nostr.encryption; - requires nostr.crypto; - - exports nostr.encryption.nip04; -} \ No newline at end of file diff --git a/nostr-java-encryption-nip04/src/main/resources/META-INF/services/nostr.encryption.MessageCipher b/nostr-java-encryption-nip04/src/main/resources/META-INF/services/nostr.encryption.MessageCipher deleted file mode 100644 index e18adc2fa..000000000 --- a/nostr-java-encryption-nip04/src/main/resources/META-INF/services/nostr.encryption.MessageCipher +++ /dev/null @@ -1 +0,0 @@ -nostr.encryption.nip04.MessageCipher04 \ No newline at end of file diff --git a/nostr-java-encryption-nip44/pom.xml b/nostr-java-encryption-nip44/pom.xml deleted file mode 100644 index d50eb5b4c..000000000 --- a/nostr-java-encryption-nip44/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - 4.0.0 - - xyz.tcheeric - nostr-java - 0.6.5-SNAPSHOT - - - nostr-java-encryption-nip44 - jar - - nostr-java-encryption-nip44 - http://maven.apache.org - - - UTF-8 - - - - - ${project.groupId} - nostr-java-crypto - ${project.version} - - - ${project.groupId} - nostr-java-encryption - ${project.version} - - - diff --git a/nostr-java-encryption-nip44/src/main/java/module-info.java b/nostr-java-encryption-nip44/src/main/java/module-info.java deleted file mode 100644 index a0604a1d3..000000000 --- a/nostr-java-encryption-nip44/src/main/java/module-info.java +++ /dev/null @@ -1,10 +0,0 @@ -module nostr.encryption.nip44dm { - - requires lombok; - - requires nostr.encryption; - requires nostr.crypto; - requires nostr.util; - - exports nostr.encryption.nip44; -} \ No newline at end of file diff --git a/nostr-java-encryption-nip44/src/main/resources/META-INF/services/nostr.encryption.MessageCipher b/nostr-java-encryption-nip44/src/main/resources/META-INF/services/nostr.encryption.MessageCipher deleted file mode 100644 index 73d2713cb..000000000 --- a/nostr-java-encryption-nip44/src/main/resources/META-INF/services/nostr.encryption.MessageCipher +++ /dev/null @@ -1 +0,0 @@ -nostr.encryption.nip44.MessageCipher44 \ No newline at end of file diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index bc81e01bc..9b0e745fa 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -16,4 +16,21 @@ UTF-8 + + + + org.projectlombok + lombok + + + ${project.groupId} + nostr-java-crypto + ${project.version} + + + ${project.groupId} + nostr-java-util + ${project.version} + + diff --git a/nostr-java-encryption/src/main/java/module-info.java b/nostr-java-encryption/src/main/java/module-info.java index 94ad056bd..eed9f5823 100644 --- a/nostr-java-encryption/src/main/java/module-info.java +++ b/nostr-java-encryption/src/main/java/module-info.java @@ -1,4 +1,6 @@ module nostr.encryption { - + requires lombok; + requires nostr.util; + requires nostr.crypto; exports nostr.encryption; -} \ No newline at end of file +} diff --git a/nostr-java-encryption-nip04/src/main/java/nostr/encryption/nip04/MessageCipher04.java b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java similarity index 95% rename from nostr-java-encryption-nip04/src/main/java/nostr/encryption/nip04/MessageCipher04.java rename to nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java index f759014e6..7fca8d42b 100644 --- a/nostr-java-encryption-nip04/src/main/java/nostr/encryption/nip04/MessageCipher04.java +++ b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher04.java @@ -1,10 +1,9 @@ -package nostr.encryption.nip04; +package nostr.encryption; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; import nostr.crypto.nip04.EncryptedDirectMessage; -import nostr.encryption.MessageCipher; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; diff --git a/nostr-java-encryption-nip44/src/main/java/nostr/encryption/nip44/MessageCipher44.java b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java similarity index 95% rename from nostr-java-encryption-nip44/src/main/java/nostr/encryption/nip44/MessageCipher44.java rename to nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java index 6de3c232c..9e636d81b 100644 --- a/nostr-java-encryption-nip44/src/main/java/nostr/encryption/nip44/MessageCipher44.java +++ b/nostr-java-encryption/src/main/java/nostr/encryption/MessageCipher44.java @@ -1,10 +1,9 @@ -package nostr.encryption.nip44; +package nostr.encryption; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; import nostr.crypto.nip44.EncryptedPayloads; -import nostr.encryption.MessageCipher; import nostr.util.NostrUtil; import java.security.NoSuchAlgorithmException; @@ -51,4 +50,4 @@ private byte[] getConversationKey() { private byte[] generateNonce() { return NostrUtil.createRandomByteArray(NONCE_LENGTH); } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index df4632823..4294df7c4 100644 --- a/pom.xml +++ b/pom.xml @@ -71,8 +71,6 @@ nostr-java-client nostr-java-api nostr-java-encryption - nostr-java-encryption-nip04 - nostr-java-encryption-nip44 From ece7718299d533920231bb1c57862eb215e6c787 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sun, 9 Mar 2025 19:27:44 -0700 Subject: [PATCH 02/57] strip trailing zeros from bigdecimal --- .../nostr/api/factory/impl/NIP01Impl.java | 2 +- .../main/java/nostr/event/tag/PriceTag.java | 18 ++++ .../java/nostr/test/event/PriceTagTest.java | 99 ++++++++++++++----- 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP01Impl.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP01Impl.java index 98e9a679b..971265ef4 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP01Impl.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP01Impl.java @@ -58,7 +58,7 @@ public TextNoteEventFactory(@NonNull Identity sender, @NonNull List tag @Override public TextNoteEvent create() { var event = new TextNoteEvent(getSender(), getTags(), getContent()); - getTags().forEach(t -> event.addTag(t)); + getTags().forEach(event::addTag); return event; } } 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 54e162922..1b9ce70ec 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 @@ -15,6 +15,7 @@ import nostr.event.BaseTag; import java.math.BigDecimal; +import java.util.Objects; import java.util.Optional; @Builder @@ -49,4 +50,21 @@ public static T deserialize(@NonNull JsonNode node) { return (T) tag; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + PriceTag priceTag = (PriceTag) o; + return Objects.equals( + number.stripTrailingZeros(), + priceTag.number.stripTrailingZeros() + ) + && Objects.equals(currency, priceTag.currency) && Objects.equals(frequency, priceTag.frequency); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), number.stripTrailingZeros(), currency, frequency); + } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java index d242d60f7..5ac05f937 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java @@ -1,25 +1,74 @@ -package nostr.test.event; - -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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class PriceTagTest { - - @Test - void getSupportedFields() { - PriceTag priceTag = new PriceTag(new BigDecimal(11111), "BTC", "NANOSECONDS"); - assertDoesNotThrow(() -> { - List list = priceTag.getSupportedFields().stream().toList(); - assertTrue(List.of("number", "currency", "frequency").containsAll(list.stream().map(Field::getName).toList())); - assertTrue(List.of("java.math.BigDecimal", "java.lang.String").containsAll(list.stream().map(field -> field.getAnnotatedType().toString()).toList())); - }); - } - -} \ No newline at end of file +package nostr.test.event; + +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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PriceTagTest { + private final static BigDecimal aVal = new BigDecimal(10.000); + private final static BigDecimal bVal = new BigDecimal(10.00); + private final static BigDecimal cVal = new BigDecimal(10.0); + private final static BigDecimal dVal = new BigDecimal(10.); + private final static BigDecimal eVal = new BigDecimal(10); + + private final static BigDecimal aString = new BigDecimal("10.000"); + private final static BigDecimal bString = new BigDecimal("10.00"); + private final static BigDecimal cString = new BigDecimal("10.0"); + private final static BigDecimal dString = new BigDecimal("10."); + private final static BigDecimal eString = new BigDecimal("10"); + + private static final String BTC = "BTC"; + private static final String freq = "femptosecond"; + + @Test + void valueParameterCompare() { + List list = Stream.of( + aVal, bVal, cVal, dVal, eVal) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); + assertTrue(list.stream().allMatch(list.getFirst()::equals)); + } + + @Test + void stringParameterCompare() { + List list = Stream.of( + aString, bString, cString, dString, eString) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); + assertTrue(list.stream().allMatch(list.getFirst()::equals)); + } + + @Test + void failure() { + List priceTags = List.of( + new PriceTag(new BigDecimal("1"), BTC, freq), + new PriceTag(new BigDecimal("01"), BTC, freq), + new PriceTag(new BigDecimal("001"), BTC, freq), + new PriceTag(new BigDecimal(1), BTC, freq), + new PriceTag(new BigDecimal(01), BTC, freq), + new PriceTag(new BigDecimal(001), BTC, freq) + ); + List list = Stream.of( + aString, bString, cString, dString, eString) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); + assertTrue(list.stream().noneMatch(priceTags::equals)); + } + + @Test + void getSupportedFields() { + PriceTag priceTag = new PriceTag(new BigDecimal(11111), "BTC", "NANOSECONDS"); + assertDoesNotThrow(() -> { + List list = priceTag.getSupportedFields().stream().toList(); + assertTrue(List.of("number", "currency", "frequency").containsAll(list.stream().map(Field::getName).toList())); + assertTrue(List.of("java.math.BigDecimal", "java.lang.String").containsAll(list.stream().map(field -> field.getAnnotatedType().toString()).toList())); + }); + } +} From 0cf2cbf32282ca53a05fc91a45bd0f65d770ba9d Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 00:24:24 -0700 Subject: [PATCH 03/57] afterburner replace objectmapper --- nostr-java-api/src/main/java/module-info.java | 12 +-- .../src/main/java/nostr/api/NIP46.java | 15 ++-- .../src/main/java/nostr/api/NIP60.java | 6 +- .../nostr/api/factory/impl/NIP32Impl.java | 3 +- nostr-java-base/pom.xml | 6 +- .../src/main/java/module-info.java | 19 +++-- .../main/java/nostr/base/ContentReason.java | 8 +- .../src/main/java/nostr/base/FEncoder.java | 4 +- .../src/main/java/nostr/base/IDecoder.java | 7 +- .../src/main/java/nostr/base/IEncoder.java | 4 +- .../src/main/java/nostr/base/IEvent.java | 6 +- .../src/main/java/nostr/base/Profile.java | 42 +++++----- .../src/main/java/nostr/base/Proof.java | 8 +- .../src/main/java/module-info.java | 35 ++++----- .../nostr/event/AbstractEventContent.java | 23 +++--- .../java/nostr/event/filter/Filterable.java | 9 +-- .../java/nostr/event/filter/KindFilter.java | 4 +- .../java/nostr/event/filter/SinceFilter.java | 4 +- .../java/nostr/event/filter/UntilFilter.java | 4 +- .../nostr/event/impl/CalendarRsvpEvent.java | 6 +- .../event/impl/CalendarTimeBasedEvent.java | 2 +- .../event/impl/ClassifiedListingEvent.java | 4 +- .../java/nostr/event/impl/GenericEvent.java | 4 +- .../java/nostr/event/impl/GenericMessage.java | 4 +- .../impl/InternetIdentifierMetadataEvent.java | 3 +- .../java/nostr/event/impl/MetadataEvent.java | 4 +- .../event/json/codec/BaseEventEncoder.java | 2 +- .../event/json/codec/BaseMessageDecoder.java | 24 +++--- .../event/json/codec/BaseTagDecoder.java | 6 +- .../java/nostr/event/json/codec/FDecoder.java | 1 + .../event/json/codec/FiltersDecoder.java | 21 +---- .../event/json/codec/FiltersEncoder.java | 4 +- .../event/json/codec/GenericTagDecoder.java | 13 ++-- .../json/codec/GenericTagQueryEncoder.java | 2 +- .../event/json/codec/Nip05ContentDecoder.java | 4 +- .../event/json/codec/OstEventEncoder.java | 6 +- .../serializer/CustomBaseListSerializer.java | 15 ++-- .../CanonicalAuthenticationMessage.java | 13 ++-- .../nostr/event/message/CloseMessage.java | 5 +- .../nostr/event/message/ClosedMessage.java | 5 +- .../java/nostr/event/message/EoseMessage.java | 5 +- .../nostr/event/message/EventMessage.java | 7 +- .../nostr/event/message/NoticeMessage.java | 5 +- .../java/nostr/event/message/OkMessage.java | 5 +- .../message/RelayAuthenticationMessage.java | 5 +- .../java/nostr/event/message/ReqMessage.java | 28 +++---- .../test/java/nostr/test/api/NIP60Test.java | 36 ++++----- .../java/nostr/test/event/ApiEventTest.java | 6 +- ...entTestUsingSpringWebSocketClientTest.java | 37 ++++----- .../nostr/test/event/ApiNIP52EventTest.java | 27 +++---- .../nostr/test/event/ApiNIP52RequestTest.java | 20 +++-- .../nostr/test/event/ApiNIP99EventTest.java | 49 ++++-------- .../nostr/test/event/ApiNIP99RequestTest.java | 20 +++-- .../event/CalendarTimeBasedEventTest.java | 78 +++++++++---------- .../test/java/nostr/test/event/EventTest.java | 3 +- .../java/nostr/test/event/RelaysTagTest.java | 6 +- .../java/nostr/test/json/JsonParseTest.java | 19 ++--- pom.xml | 7 +- 58 files changed, 348 insertions(+), 382 deletions(-) diff --git a/nostr-java-api/src/main/java/module-info.java b/nostr-java-api/src/main/java/module-info.java index be79b0170..92f8a0115 100644 --- a/nostr-java-api/src/main/java/module-info.java +++ b/nostr-java-api/src/main/java/module-info.java @@ -6,12 +6,12 @@ requires nostr.client; requires nostr.encryption; - requires com.fasterxml.jackson.databind; - - requires lombok; - requires java.logging; - requires nostr.crypto; + requires lombok; + requires nostr.crypto; requires org.apache.commons.lang3; + requires com.fasterxml.jackson.module.afterburner; + requires com.fasterxml.jackson.databind; + requires java.logging; - exports nostr.api; + exports nostr.api; } 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 c806e1b07..4af9e0584 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP46.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP46.java @@ -1,7 +1,6 @@ package nostr.api; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -17,6 +16,8 @@ import java.util.Set; import java.util.logging.Level; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + public final class NIP46 extends EventNostr { public NIP46(@NonNull Identity sender) { @@ -70,8 +71,7 @@ public void addParam(String param) { public String toString() { try { - ObjectMapper objectMapper = new ObjectMapper(); - return objectMapper.writeValueAsString(this); + return MAPPER_AFTERBURNER.writeValueAsString(this); } catch (JsonProcessingException ex) { // Handle the exception if needed log.log(Level.WARNING, "Error converting to JSON: {0}", ex.getMessage()); @@ -80,9 +80,8 @@ public String toString() { } public static Request fromString(@NonNull String jsonString) { - ObjectMapper objectMapper = new ObjectMapper(); try { - return objectMapper.readValue(jsonString, Request.class); + return MAPPER_AFTERBURNER.readValue(jsonString, Request.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } @@ -100,8 +99,7 @@ public static final class Response implements Serializable { public String toString() { try { - ObjectMapper objectMapper = new ObjectMapper(); - return objectMapper.writeValueAsString(this); + return MAPPER_AFTERBURNER.writeValueAsString(this); } catch (JsonProcessingException ex) { // Handle the exception if needed log.log(Level.WARNING, "Error converting to JSON: {0}", ex.getMessage()); @@ -110,9 +108,8 @@ public String toString() { } public static Response fromString(@NonNull String jsonString) { - ObjectMapper objectMapper = new ObjectMapper(); try { - return objectMapper.readValue(jsonString, Response.class); + return MAPPER_AFTERBURNER.readValue(jsonString, Response.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } 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 e6a3135c3..cb012dc3d 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP60.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP60.java @@ -30,6 +30,8 @@ import nostr.event.tag.EventTag; import nostr.id.Identity; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + public class NIP60 extends EventNostr { private static final String MINT_TAG_NAME = "mint"; @@ -189,12 +191,12 @@ private String getWalletEventContent(@NonNull Wallet wallet) { tags.add(NIP60.createBalanceTag(wallet.getBalance(), wallet.getUnit())); tags.add(NIP60.createPrivKeyTag(wallet.getPrivateKey())); - return NIP44.encrypt(getSender(), new ObjectMapper().writeValueAsString(tags), getSender().getPublicKey()); + return NIP44.encrypt(getSender(), MAPPER_AFTERBURNER.writeValueAsString(tags), getSender().getPublicKey()); } @SneakyThrows private String getTokenEventContent(@NonNull Token token) { - return NIP44.encrypt(getSender(), new ObjectMapper().writeValueAsString(token), getSender().getPublicKey()); + return NIP44.encrypt(getSender(), MAPPER_AFTERBURNER.writeValueAsString(token), getSender().getPublicKey()); } @SneakyThrows diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java index a9cbc5209..1b19e8855 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java @@ -14,6 +14,7 @@ import java.util.Map; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static nostr.util.NostrUtil.escapeJsonString; /** @@ -65,7 +66,7 @@ public String[] toParams() { result = new String[3]; result[0] = value; result[1] = nameSpace.getValue(); - result[2] = escapeJsonString(new ObjectMapper().writeValueAsString(metadata)); + result[2] = escapeJsonString(MAPPER_AFTERBURNER.writeValueAsString(metadata)); } else { result = new String[2]; result[0] = value; diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index acf2f5122..41d0263ce 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -19,8 +19,8 @@ lombok - com.fasterxml.jackson.core - jackson-databind + com.fasterxml.jackson.module + jackson-module-afterburner @@ -35,4 +35,4 @@ ${project.version} - \ No newline at end of file + diff --git a/nostr-java-base/src/main/java/module-info.java b/nostr-java-base/src/main/java/module-info.java index 8e935de14..bcc09ce7c 100644 --- a/nostr-java-base/src/main/java/module-info.java +++ b/nostr-java-base/src/main/java/module-info.java @@ -1,13 +1,12 @@ module nostr.base { - requires static lombok; - requires com.fasterxml.jackson.databind; - requires com.fasterxml.jackson.annotation; - requires com.fasterxml.jackson.core; - requires nostr.util; - requires nostr.crypto; - requires java.logging; - - exports nostr.base; - exports nostr.base.annotation; + requires static lombok; + requires nostr.util; + requires nostr.crypto; + requires com.fasterxml.jackson.module.afterburner; + requires com.fasterxml.jackson.databind; + requires java.logging; + + exports nostr.base; + exports nostr.base.annotation; } diff --git a/nostr-java-base/src/main/java/nostr/base/ContentReason.java b/nostr-java-base/src/main/java/nostr/base/ContentReason.java index fd95d1ac4..f196bbcb5 100644 --- a/nostr-java-base/src/main/java/nostr/base/ContentReason.java +++ b/nostr-java-base/src/main/java/nostr/base/ContentReason.java @@ -1,13 +1,13 @@ package nostr.base; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; - import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + /** * @author guilhermegps * @@ -22,10 +22,8 @@ public class ContentReason { @Override public String toString() { - ObjectMapper mapper = new ObjectMapper(); - try { - return mapper.writeValueAsString(this); + return MAPPER_AFTERBURNER.writeValueAsString(this); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/nostr-java-base/src/main/java/nostr/base/FEncoder.java b/nostr-java-base/src/main/java/nostr/base/FEncoder.java index 1304d0f17..2b71e99f3 100644 --- a/nostr-java-base/src/main/java/nostr/base/FEncoder.java +++ b/nostr-java-base/src/main/java/nostr/base/FEncoder.java @@ -2,9 +2,11 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.module.afterburner.AfterburnerModule; public interface FEncoder { - ObjectMapper MAPPER = new ObjectMapper().setSerializationInclusion(Include.NON_NULL); + ObjectMapper F_ENCODER_MAPPER_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); String encode(); } diff --git a/nostr-java-base/src/main/java/nostr/base/IDecoder.java b/nostr-java-base/src/main/java/nostr/base/IDecoder.java index f94d95120..5eab64600 100644 --- a/nostr-java-base/src/main/java/nostr/base/IDecoder.java +++ b/nostr-java-base/src/main/java/nostr/base/IDecoder.java @@ -1,6 +1,10 @@ package nostr.base; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.module.afterburner.AfterburnerModule; /** * @@ -8,7 +12,8 @@ * @param */ public interface IDecoder { - + ObjectMapper I_DECODER_MAPPER_AFTERBURNER + = JsonMapper.builder().addModule(new AfterburnerModule()).build().configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); T decode(String str) throws JsonProcessingException; } diff --git a/nostr-java-base/src/main/java/nostr/base/IEncoder.java b/nostr-java-base/src/main/java/nostr/base/IEncoder.java index 631fd3fca..b32a72ad6 100644 --- a/nostr-java-base/src/main/java/nostr/base/IEncoder.java +++ b/nostr-java-base/src/main/java/nostr/base/IEncoder.java @@ -3,6 +3,8 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.module.afterburner.AfterburnerModule; /** @@ -11,7 +13,7 @@ * @param */ public interface IEncoder { - ObjectMapper MAPPER = new ObjectMapper().setSerializationInclusion(Include.NON_NULL); + ObjectMapper I_ENCODER_MAPPER_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); String encode(); } diff --git a/nostr-java-base/src/main/java/nostr/base/IEvent.java b/nostr-java-base/src/main/java/nostr/base/IEvent.java index 94d78744b..832293c00 100644 --- a/nostr-java-base/src/main/java/nostr/base/IEvent.java +++ b/nostr-java-base/src/main/java/nostr/base/IEvent.java @@ -1,10 +1,14 @@ package nostr.base; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.module.afterburner.AfterburnerModule; + /** * * @author squirrel */ public interface IEvent extends IElement, IBech32Encodable { - + ObjectMapper MAPPER_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build(); String getId(); } diff --git a/nostr-java-base/src/main/java/nostr/base/Profile.java b/nostr-java-base/src/main/java/nostr/base/Profile.java index 5ecbd0abe..25e16833a 100644 --- a/nostr-java-base/src/main/java/nostr/base/Profile.java +++ b/nostr-java-base/src/main/java/nostr/base/Profile.java @@ -1,11 +1,7 @@ package nostr.base; -import java.net.URL; - import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -13,8 +9,11 @@ import lombok.ToString; import lombok.experimental.SuperBuilder; +import java.net.URL; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + /** - * * @author eric */ @Data @@ -24,27 +23,26 @@ @AllArgsConstructor public abstract class Profile { - private final String name; + private final String name; - @ToString.Exclude - private String about; + @ToString.Exclude + private String about; - @ToString.Exclude - private URL picture; + @ToString.Exclude + private URL picture; - protected Profile() { - this.name = null; - } + protected Profile() { + this.name = null; + } - @JsonValue - @Override - public String toString() { - ObjectMapper objectMapper = new ObjectMapper(); - try { - return objectMapper.writeValueAsString(this); - } catch (JsonProcessingException ex) { - throw new RuntimeException(ex); - } + @JsonValue + @Override + public String toString() { + try { + return MAPPER_AFTERBURNER.writeValueAsString(this); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); } + } } diff --git a/nostr-java-base/src/main/java/nostr/base/Proof.java b/nostr-java-base/src/main/java/nostr/base/Proof.java index 87a1ac356..1cef1b61c 100644 --- a/nostr-java-base/src/main/java/nostr/base/Proof.java +++ b/nostr-java-base/src/main/java/nostr/base/Proof.java @@ -1,16 +1,14 @@ package nostr.base; -import com.fasterxml.jackson.annotation.JsonKey; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.SneakyThrows; -import lombok.ToString; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; @Data @NoArgsConstructor @@ -33,6 +31,6 @@ public class Proof { @SneakyThrows @Override public String toString() { - return new ObjectMapper().writeValueAsString(this); + return MAPPER_AFTERBURNER.writeValueAsString(this); } } diff --git a/nostr-java-event/src/main/java/module-info.java b/nostr-java-event/src/main/java/module-info.java index 60e80d4b3..270c88e55 100644 --- a/nostr-java-event/src/main/java/module-info.java +++ b/nostr-java-event/src/main/java/module-info.java @@ -1,22 +1,21 @@ module nostr.event { - requires static lombok; - requires nostr.base; - requires com.fasterxml.jackson.databind; - requires com.fasterxml.jackson.annotation; - requires com.fasterxml.jackson.core; - requires nostr.crypto; - requires nostr.util; - requires java.logging; - requires java.desktop; + requires static lombok; + requires nostr.base; + requires nostr.crypto; + requires nostr.util; + requires com.fasterxml.jackson.module.afterburner; + requires com.fasterxml.jackson.databind; + requires java.logging; + requires java.desktop; - exports nostr.event; - exports nostr.event.impl; - exports nostr.event.message; - exports nostr.event.json.codec; - exports nostr.event.json.deserializer; - exports nostr.event.json.serializer; - exports nostr.event.tag; - exports nostr.event.util; - exports nostr.event.filter; + exports nostr.event; + exports nostr.event.impl; + exports nostr.event.message; + exports nostr.event.json.codec; + exports nostr.event.json.deserializer; + exports nostr.event.json.serializer; + exports nostr.event.tag; + exports nostr.event.util; + exports nostr.event.filter; } diff --git a/nostr-java-event/src/main/java/nostr/event/AbstractEventContent.java b/nostr-java-event/src/main/java/nostr/event/AbstractEventContent.java index 09bf7f81e..9a7ecb851 100644 --- a/nostr-java-event/src/main/java/nostr/event/AbstractEventContent.java +++ b/nostr-java-event/src/main/java/nostr/event/AbstractEventContent.java @@ -1,23 +1,22 @@ package nostr.event; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.base.IEvent; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + /** - * - * @author eric * @param + * @author eric */ public abstract class AbstractEventContent implements IContent { - - @Override - public String toString() { - try { - ObjectMapper mapper = new ObjectMapper(); - return mapper.writeValueAsString(this); - } catch (JsonProcessingException ex) { - throw new RuntimeException(ex); - } + + @Override + public String toString() { + try { + return MAPPER_AFTERBURNER.writeValueAsString(this); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); } + } } 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 70654ee32..9af6024a2 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,6 +1,5 @@ package nostr.event.filter; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import nostr.event.BaseTag; @@ -10,9 +9,9 @@ import java.util.Optional; import java.util.function.Predicate; -public interface Filterable { - ObjectMapper mapper = new ObjectMapper(); +import static nostr.base.IEvent.MAPPER_AFTERBURNER; +public interface Filterable { Predicate getPredicate(); T getFilterable(); Object getFilterableValue(); @@ -26,7 +25,7 @@ default List getTypeSpecificTags(Class tagClass, Gener } default ObjectNode toObjectNode(ObjectNode objectNode) { - ArrayNode arrayNode = mapper.createArrayNode(); + ArrayNode arrayNode = MAPPER_AFTERBURNER.createArrayNode(); Optional.ofNullable(objectNode.get(getFilterKey())) .ifPresent(jsonNode -> @@ -39,7 +38,7 @@ default ObjectNode toObjectNode(ObjectNode objectNode) { default void addToArrayNode(ArrayNode arrayNode) { arrayNode.addAll( - mapper.createArrayNode().add( + MAPPER_AFTERBURNER.createArrayNode().add( getFilterableValue().toString())); } } 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 4d5b10f63..273e8d1f7 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 @@ -9,6 +9,8 @@ import java.util.function.Function; import java.util.function.Predicate; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + @EqualsAndHashCode(callSuper = true) public class KindFilter extends AbstractFilterable { public final static String FILTER_KEY = "kinds"; @@ -26,7 +28,7 @@ public Predicate getPredicate() { @Override public void addToArrayNode(ArrayNode arrayNode) { arrayNode.addAll( - mapper.createArrayNode().add( + MAPPER_AFTERBURNER.createArrayNode().add( getFilterableValue())); } 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 8c7f6ebcd..edcd31087 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 @@ -9,6 +9,8 @@ import java.util.function.Function; import java.util.function.Predicate; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + @EqualsAndHashCode(callSuper = true) public class SinceFilter extends AbstractFilterable { public final static String FILTER_KEY = "since"; @@ -25,7 +27,7 @@ public Predicate getPredicate() { @Override public ObjectNode toObjectNode(ObjectNode objectNode) { - return mapper.createObjectNode().put(FILTER_KEY, getSince()); + return MAPPER_AFTERBURNER.createObjectNode().put(FILTER_KEY, getSince()); } @Override 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 5876724fe..48e88179e 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 @@ -9,6 +9,8 @@ import java.util.function.Function; import java.util.function.Predicate; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + @EqualsAndHashCode(callSuper = true) public class UntilFilter extends AbstractFilterable { public final static String FILTER_KEY = "until"; @@ -25,7 +27,7 @@ public Predicate getPredicate() { @Override public ObjectNode toObjectNode(ObjectNode objectNode) { - return mapper.createObjectNode().put(FILTER_KEY, getUntil()); + return MAPPER_AFTERBURNER.createObjectNode().put(FILTER_KEY, getUntil()); } @Override 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 6243aa523..722323c84 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 @@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -18,7 +17,6 @@ import nostr.event.Kind; import nostr.event.NIP52Event; import nostr.event.impl.CalendarRsvpEvent.CalendarRsvpEventDeserializer; -import nostr.event.impl.CalendarTimeBasedEvent.CalendarTimeBasedEventDeserializer; import nostr.event.tag.AddressTag; import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; @@ -55,7 +53,7 @@ public CalendarRsvpEventDeserializer() { super(CalendarRsvpEvent.class); } -// TODO: below methods needs comprehensive tags assignment completion + // TODO: below methods needs comprehensive tags assignment completion @Override public CalendarRsvpEvent deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { JsonNode calendarTimeBasedEventNode = jsonParser.getCodec().readTree(jsonParser); @@ -66,7 +64,7 @@ public CalendarRsvpEvent deserialize(JsonParser jsonParser, DeserializationConte .map( JsonNode::elements) .map(element -> - new ObjectMapper().convertValue(element, BaseTag.class)).toList(); + MAPPER_AFTERBURNER.convertValue(element, BaseTag.class)).toList(); List genericTags = baseTags.stream() .filter(GenericTag.class::isInstance) 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 812f73146..29893ed8c 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 @@ -74,7 +74,7 @@ public CalendarTimeBasedEvent deserialize(JsonParser jsonParser, Deserialization .map( JsonNode::elements) .map(element -> - new ObjectMapper().convertValue(element, BaseTag.class)).toList(); + MAPPER_AFTERBURNER.convertValue(element, BaseTag.class)).toList(); List genericTags = baseTags.stream() .filter(GenericTag.class::isInstance) 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 6d392578a..c0520514e 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 @@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; + import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -85,7 +85,7 @@ public ClassifiedListingEvent deserialize(JsonParser jsonParser, Deserialization .map( JsonNode::elements) .map(element -> - new ObjectMapper().convertValue(element, BaseTag.class)).toList(); + MAPPER_AFTERBURNER.convertValue(element, BaseTag.class)).toList(); List genericTags = baseTags.stream() .filter(GenericTag.class::isInstance) 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 e31c423e6..e2536f837 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 @@ -39,6 +39,8 @@ import nostr.util.NostrUtil; import nostr.util.thread.HexStringValidator; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -203,7 +205,7 @@ protected void validate() { } private String serialize() throws NostrException { - var mapper = IEncoder.MAPPER; + var mapper = I_ENCODER_MAPPER_AFTERBURNER; var arrayNode = JsonNodeFactory.instance.arrayNode(); try { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java index ee06ffeaf..f54544e7b 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java @@ -14,6 +14,8 @@ import java.util.ArrayList; import java.util.List; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -52,7 +54,7 @@ public void addAttribute(ElementAttribute attribute) { public String encode() throws JsonProcessingException { getArrayNode().add(getCommand()); getAttributes().stream().map(ElementAttribute::getValue).forEach(v -> getArrayNode().add(v.toString())); - return IEncoder.MAPPER.writeValueAsString(getArrayNode()); + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(getArrayNode()); } public static T decode(@NonNull Object[] msgArr) { 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 179258a19..5ab5b07b3 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 @@ -45,8 +45,7 @@ private void init(UserProfile profile) { private void setContent(UserProfile profile) { try { - ObjectMapper objectMapper = new ObjectMapper(); - String jsonString = objectMapper.writeValueAsString(new Nip05Obj(profile.getName(), profile.getNip05())); + String jsonString = MAPPER_AFTERBURNER.writeValueAsString(new Nip05Obj(profile.getName(), profile.getNip05())); // Escape the JSON string String escapedJsonString = escapeJsonString(jsonString); diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java index 52e41e482..8207f1e96 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java @@ -17,6 +17,8 @@ import nostr.event.Kind; import nostr.event.NIP01Event; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -59,7 +61,7 @@ public void update() { } private void setContent() { - var mapper = IEncoder.MAPPER; + var mapper = I_ENCODER_MAPPER_AFTERBURNER; try { ObjectNode objNode = JsonNodeFactory.instance.objectNode(); objNode.set("name", mapper.valueToTree(this.getProfile().getName())); diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java index 8c47e017f..0afbfe0f8 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java @@ -30,7 +30,7 @@ public String encode() { protected String toJson() throws NostrException { try { - return IEncoder.MAPPER.writeValueAsString(event); + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(event); } catch (JsonProcessingException e) { throw new NostrException(e); } 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 b84c1917d..b688e1193 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 @@ -1,8 +1,7 @@ package nostr.event.json.codec; -import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.SneakyThrows; import nostr.base.IDecoder; @@ -24,32 +23,27 @@ /** * @author eric */ +@NoArgsConstructor public class BaseMessageDecoder implements IDecoder { public static final int COMMAND_INDEX = 0; public static final int ARG_INDEX = 1; public static final int FILTERS_START_INDEX = 2; - private final ObjectMapper mapper = new ObjectMapper(); - - public BaseMessageDecoder() { - mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - } - @Override public T decode(@NonNull String jsonString) throws JsonProcessingException { ValidJsonNodeFirstPair validJsonNodeFirstPair = json_strCmd_arg(jsonString); String command = validJsonNodeFirstPair.formerly_strCmd(); Object subscriptionId = validJsonNodeFirstPair.formerly_arg(); - Object[] msgArr = mapper.readValue(jsonString, Object[].class); // TODO: replace with jsonNode after ReqMessage.decode() is finished + Object[] msgArr = I_DECODER_MAPPER_AFTERBURNER.readValue(jsonString, Object[].class); // TODO: replace with jsonNode after ReqMessage.decode() is finished return switch (command) { case "AUTH" -> subscriptionId instanceof Map map ? - CanonicalAuthenticationMessage.decode(map, mapper) : + CanonicalAuthenticationMessage.decode(map) : RelayAuthenticationMessage.decode(subscriptionId); case "CLOSE" -> CloseMessage.decode(subscriptionId); case "EOSE" -> EoseMessage.decode(subscriptionId); - case "EVENT" -> EventMessage.decode(msgArr, mapper); + case "EVENT" -> EventMessage.decode(msgArr, I_DECODER_MAPPER_AFTERBURNER); case "NOTICE" -> NoticeMessage.decode(subscriptionId); case "OK" -> OkMessage.decode(msgArr); case "REQ" -> ReqMessage.decode(subscriptionId, json_msgArr(jsonString)); @@ -59,18 +53,18 @@ public T decode(@NonNull String jsonString) throws JsonProcessingException { private ValidJsonNodeFirstPair json_strCmd_arg(@NonNull String jsonString) throws JsonProcessingException { return new ValidJsonNodeFirstPair( - mapper.readTree(jsonString).get(COMMAND_INDEX).asText(), - mapper.readTree(jsonString).get(ARG_INDEX).asText()); + I_DECODER_MAPPER_AFTERBURNER.readTree(jsonString).get(COMMAND_INDEX).asText(), + I_DECODER_MAPPER_AFTERBURNER.readTree(jsonString).get(ARG_INDEX).asText()); } private List json_msgArr(@NonNull String jsonString) throws JsonProcessingException { - return IntStream.range(FILTERS_START_INDEX, mapper.readTree(jsonString).size()) + return IntStream.range(FILTERS_START_INDEX, I_DECODER_MAPPER_AFTERBURNER.readTree(jsonString).size()) .mapToObj(idx -> readTree(jsonString, idx)).toList(); } @SneakyThrows private String readTree(String jsonString, int idx) { - return mapper.readTree(jsonString).get(idx).toString(); + return I_DECODER_MAPPER_AFTERBURNER.readTree(jsonString).get(idx).toString(); } private record ValidJsonNodeFirstPair( 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 46e6fe3d6..559852baf 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,11 +1,12 @@ package nostr.event.json.codec; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import nostr.base.IDecoder; import nostr.event.BaseTag; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + /** * * @author eric @@ -22,8 +23,7 @@ public BaseTagDecoder() { @Override public T decode(String jsonString) { try { - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(jsonString, clazz); + return MAPPER_AFTERBURNER.readValue(jsonString, clazz); } catch (JsonProcessingException ex) { throw new RuntimeException(ex); } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/FDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/FDecoder.java index 48160a18b..24a894d78 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/FDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/FDecoder.java @@ -1,5 +1,6 @@ package nostr.event.json.codec; public interface FDecoder { + T decode(String str); } 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 abde5f764..bffc41cb2 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,42 +1,27 @@ package nostr.event.json.codec; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import lombok.NonNull; import lombok.SneakyThrows; -import nostr.event.filter.AddressableTagFilter; -import nostr.event.filter.AuthorFilter; -import nostr.event.filter.EventFilter; import nostr.event.filter.Filterable; import nostr.event.filter.Filters; -import nostr.event.filter.GenericTagQueryFilter; -import nostr.event.filter.GeohashTagFilter; -import nostr.event.filter.HashtagTagFilter; -import nostr.event.filter.IdentifierTagFilter; -import nostr.event.filter.KindFilter; -import nostr.event.filter.ReferencedEventFilter; -import nostr.event.filter.ReferencedPublicKeyFilter; -import nostr.event.filter.SinceFilter; -import nostr.event.filter.UntilFilter; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; -import java.util.stream.StreamSupport; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; /** * @author eric */ @Data public class FiltersDecoder implements FDecoder { - private final static ObjectMapper mapper = new ObjectMapper(); @SneakyThrows public Filters decode(@NonNull String jsonFiltersList) { final List filterables = new ArrayList<>(); - mapper.readTree(jsonFiltersList).fields().forEachRemaining(node -> + MAPPER_AFTERBURNER.readTree(jsonFiltersList).fields().forEachRemaining(node -> filterables.addAll( FilterableProvider.getFilterFunction( node.getValue(), diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java index 5675cd752..5cea19e92 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java @@ -17,10 +17,10 @@ public FiltersEncoder(Filters filters) { @Override public String encode() { - ObjectNode root = MAPPER.createObjectNode(); + ObjectNode root = F_ENCODER_MAPPER_AFTERBURNER.createObjectNode(); filters.getFiltersMap().forEach((key, filterableList) -> { - final ObjectNode objectNode = MAPPER.createObjectNode(); + final ObjectNode objectNode = F_ENCODER_MAPPER_AFTERBURNER.createObjectNode(); root.setAll( filterableList .stream() 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 e8658a779..3f6724408 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,16 +1,16 @@ package nostr.event.json.codec; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.ArrayList; -import java.util.List; - import lombok.Data; import nostr.base.ElementAttribute; import nostr.base.IDecoder; import nostr.event.impl.GenericTag; +import java.util.ArrayList; +import java.util.List; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + @Data public class GenericTagDecoder implements IDecoder { @@ -23,8 +23,7 @@ public GenericTagDecoder() { @Override public T decode(String json) { try { - ObjectMapper objectMapper = new ObjectMapper(); - String[] jsonElements = objectMapper.readValue(json, String[].class); + String[] jsonElements = MAPPER_AFTERBURNER.readValue(json, String[].class); String code = jsonElements[0]; diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java index 006b13c19..fcbf1030b 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java @@ -27,7 +27,7 @@ public GenericTagQueryEncoder(GenericTagQuery tag) { @Override public String encode() { try { - return FEncoder.MAPPER.writeValueAsString(genericTagQuery); + return F_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(genericTagQuery); } catch (JsonProcessingException e) { throw new RuntimeException(e); } 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 44cab726e..1cd4e635d 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 @@ -6,6 +6,8 @@ import nostr.base.IDecoder; import nostr.event.Nip05Content; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; + /** * * @author eric @@ -22,7 +24,7 @@ public Nip05ContentDecoder() { @Override public T decode(String jsonContent) { try { - return new ObjectMapper().readValue(jsonContent, clazz); + return MAPPER_AFTERBURNER.readValue(jsonContent, clazz); } catch (JsonProcessingException ex) { throw new RuntimeException(ex); } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java index 91b3a581c..0e6c7c4dd 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java @@ -39,17 +39,17 @@ public String encode() { private String toJson() throws NostrException { try { - JsonNode node = IEncoder.MAPPER.valueToTree(event); + JsonNode node = I_ENCODER_MAPPER_AFTERBURNER.valueToTree(event); ObjectNode objNode = (ObjectNode) node; event.getAttributes().parallelStream() .map(ElementAttribute::getValue) .forEach(ev -> { var expression = (HashMap) ev; - objNode.set("ots", IEncoder.MAPPER.valueToTree(expression.get("ots"))); + objNode.set("ots", I_ENCODER_MAPPER_AFTERBURNER.valueToTree(expression.get("ots"))); }); - return IEncoder.MAPPER.writeValueAsString(node); + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(node); } catch (JsonProcessingException | IllegalArgumentException e) { throw new NostrException(e); } diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java index 2d3ba9b02..3cde81853 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java +++ b/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java @@ -1,5 +1,11 @@ package nostr.event.json.serializer; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import nostr.event.BaseEvent; + import java.io.IOException; import java.util.Iterator; import java.util.List; @@ -8,12 +14,7 @@ import java.util.Spliterators; import java.util.stream.StreamSupport; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import nostr.base.IEncoder; -import nostr.event.BaseEvent; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; /** * @author guilhermegps @@ -33,7 +34,7 @@ public void serialize(T value, JsonGenerator gen, SerializerProvider serializers } private JsonNode toJson(Object obj) { - var mapper = IEncoder.MAPPER; + var mapper = I_ENCODER_MAPPER_AFTERBURNER; try { JsonNode node = mapper.valueToTree(obj); 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 3599a1a10..26599836f 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 @@ -20,6 +20,9 @@ import java.util.List; import java.util.Map; +import static nostr.base.IDecoder.I_DECODER_MAPPER_AFTERBURNER; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * @author eric */ @@ -36,16 +39,16 @@ public CanonicalAuthenticationMessage(CanonicalAuthenticationEvent event) { } @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) - .add(IEncoder.MAPPER.readTree( + .add(I_ENCODER_MAPPER_AFTERBURNER.readTree( new BaseEventEncoder<>(getEvent()).encode()))); } @SneakyThrows - public static T decode(@NonNull Map map, ObjectMapper mapper) { - var event = mapper.convertValue(map, new TypeReference() {}); + public static T decode(@NonNull Map map) { + var event = I_DECODER_MAPPER_AFTERBURNER.convertValue(map, new TypeReference() {}); List genericTags = event.getTags().stream() .filter(GenericTag.class::isInstance) @@ -65,4 +68,4 @@ private static String getAttributeValue(List genericTags, String att return genericTags.stream() .filter(tag -> tag.getCode().equalsIgnoreCase(attributeName)).map(GenericTag::getAttributes).toList().get(0).get(0).getValue().toString(); } -} \ No newline at end of file +} 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 91d765bca..358113c04 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 @@ -6,9 +6,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -31,7 +32,7 @@ public CloseMessage(String subscriptionId) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getSubscriptionId())); diff --git a/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java b/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java index 628c7adbf..8ff9dfcbe 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java @@ -6,9 +6,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + @Setter @Getter public class ClosedMessage extends BaseMessage { @@ -27,7 +28,7 @@ public ClosedMessage(@NonNull String subId, @NonNull String message) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getSubscriptionId())); 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 d00b57cf9..ff91201d3 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 @@ -7,9 +7,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -31,7 +32,7 @@ public EoseMessage(String subId) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getSubscriptionId())); 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 7caf29d7d..410abee3b 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 @@ -8,7 +8,6 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.base.IEvent; import nostr.event.BaseEvent; import nostr.event.BaseMessage; @@ -18,6 +17,8 @@ import java.util.Map; import java.util.Optional; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + @Setter @Getter public class EventMessage extends BaseMessage { @@ -43,9 +44,9 @@ public String encode() throws JsonProcessingException { var arrayNode = getArrayNode().add(getCommand()); Optional.ofNullable(getSubscriptionId()) .ifPresent(arrayNode::add); - arrayNode.add(IEncoder.MAPPER.readTree( + arrayNode.add(I_ENCODER_MAPPER_AFTERBURNER.readTree( new BaseEventEncoder<>((BaseEvent)getEvent()).encode())); - return IEncoder.MAPPER.writeValueAsString(arrayNode); + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(arrayNode); } public static T decode(@NonNull Object[] msgArr, ObjectMapper mapper) { 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 745e33510..3bcaab2ea 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 @@ -6,9 +6,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -27,7 +28,7 @@ public NoticeMessage(@NonNull String message) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getMessage())); 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 9245ba1e1..e39c2cda4 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 @@ -6,9 +6,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author squirrel @@ -35,7 +36,7 @@ public OkMessage(String eventId, Boolean flag, String message) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getEventId()) 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 bbd894428..8e19d2a12 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 @@ -6,9 +6,10 @@ import lombok.NonNull; import lombok.Setter; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * * @author eric @@ -27,7 +28,7 @@ public RelayAuthenticationMessage(String challenge) { @Override public String encode() throws JsonProcessingException { - return IEncoder.MAPPER.writeValueAsString( + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getChallenge())); 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 f3f2d1491..a1cc89442 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 @@ -8,7 +8,6 @@ import lombok.NonNull; import lombok.ToString; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.event.BaseMessage; import nostr.event.filter.Filters; import nostr.event.json.codec.FiltersDecoder; @@ -17,6 +16,8 @@ import java.time.temporal.ValueRange; import java.util.List; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; + /** * @author squirrel */ @@ -31,7 +32,6 @@ public class ReqMessage extends BaseMessage { private final List filtersList; public ReqMessage(@NonNull String subscriptionId, Filters... filtersList) { -// TODO: complete logic for a list of filters this(subscriptionId, List.of(filtersList)); } @@ -45,25 +45,25 @@ public ReqMessage(@NonNull String subscriptionId, List filtersList) { @Override public String encode() throws JsonProcessingException { getArrayNode() - .add(getCommand()) - .add(getSubscriptionId()); + .add(getCommand()) + .add(getSubscriptionId()); filtersList.stream() - .map(FiltersEncoder::new) - .map(FiltersEncoder::encode) - .map(ReqMessage::createJsonNode) - .forEach(jsonNode -> - getArrayNode().add(jsonNode)); + .map(FiltersEncoder::new) + .map(FiltersEncoder::encode) + .map(ReqMessage::createJsonNode) + .forEach(jsonNode -> + getArrayNode().add(jsonNode)); - return IEncoder.MAPPER.writeValueAsString(getArrayNode()); + return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(getArrayNode()); } public static T decode(@NonNull Object subscriptionId, @NonNull List jsonFiltersList) { validateSubscriptionId(subscriptionId.toString()); ReqMessage reqMessage = new ReqMessage( - subscriptionId.toString(), - jsonFiltersList.stream().map(filtersList -> - new FiltersDecoder().decode(filtersList)).toList()); + subscriptionId.toString(), + jsonFiltersList.stream().map(filtersList -> + new FiltersDecoder().decode(filtersList)).toList()); return (T) reqMessage; } @@ -75,7 +75,7 @@ private static void validateSubscriptionId(String subscriptionId) { private static JsonNode createJsonNode(String jsonNode) { try { - return IEncoder.MAPPER.readTree(jsonNode); + return I_ENCODER_MAPPER_AFTERBURNER.readTree(jsonNode); } catch (JsonProcessingException e) { throw new IllegalArgumentException(String.format("Malformed encoding ReqMessage json: [%s]", jsonNode), e); } diff --git a/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java b/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java index db697af1e..9ed239212 100644 --- a/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java +++ b/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java @@ -1,15 +1,6 @@ package nostr.test.api; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.NonNull; import nostr.api.NIP44; import nostr.api.NIP60; @@ -26,6 +17,14 @@ import nostr.event.tag.AddressTag; import nostr.event.tag.EventTag; import nostr.id.Identity; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; public class NIP60Test { @@ -70,22 +69,21 @@ public void createWalletEvent() throws JsonProcessingException { // Assert relay tags List relayTags = tags.stream() - .filter(tag -> tag.getCode().equals("relay")) - .toList(); + .filter(tag -> tag.getCode().equals("relay")) + .toList(); Assertions.assertEquals(2, relayTags.size()); // Assert mint tags List mintTags = tags.stream() - .filter(tag -> tag.getCode().equals("mint")) - .toList(); + .filter(tag -> tag.getCode().equals("mint")) + .toList(); Assertions.assertEquals(3, mintTags.size()); // Decrypt and verify content String decryptedContent = NIP44.decrypt(sender, event.getContent(), sender.getPublicKey()); - ObjectMapper mapper = new ObjectMapper(); - GenericTag[] contentTags = mapper.readValue(decryptedContent, GenericTag[].class); + GenericTag[] contentTags = MAPPER_AFTERBURNER.readValue(decryptedContent, GenericTag[].class); // First tag should be balance Assertions.assertEquals("balance", contentTags[0].getCode()); @@ -145,8 +143,7 @@ public void createTokenEvent() throws JsonProcessingException { // Decrypt and verify content String decryptedContent = NIP44.decrypt(sender, event.getContent(), sender.getPublicKey()); - ObjectMapper mapper = new ObjectMapper(); - Token contentToken = mapper.readValue(decryptedContent, Token.class); + Token contentToken = MAPPER_AFTERBURNER.readValue(decryptedContent, Token.class); Assertions.assertEquals("https://stablenut.umint.cash", contentToken.getMint().getUrl()); Proof proofContent = contentToken.getProofs().get(0); @@ -198,14 +195,13 @@ public void createSpendingHistoryEvent() throws JsonProcessingException { // Decrypt and verify content String decryptedContent = NIP44.decrypt(sender, event.getContent(), sender.getPublicKey()); - ObjectMapper mapper = new ObjectMapper(); - BaseTag[] contentTags = mapper.readValue(decryptedContent, BaseTag[].class); + BaseTag[] contentTags = MAPPER_AFTERBURNER.readValue(decryptedContent, BaseTag[].class); // Assert direction GenericTag directionTag = (GenericTag) contentTags[0]; Assertions.assertEquals("direction", directionTag.getCode()); Assertions.assertEquals("in", - directionTag.getAttributes().get(0).getValue().toString()); + directionTag.getAttributes().get(0).getValue().toString()); // Assert amount GenericTag amountTag = (GenericTag) contentTags[1]; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java index 76fe053b2..ce29313a2 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java @@ -1,7 +1,6 @@ package nostr.test.event; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.api.EventNostr; import nostr.api.NIP01; import nostr.api.NIP04; @@ -10,6 +9,7 @@ import nostr.api.NIP44; import nostr.api.NIP52; import nostr.api.NIP57; +import nostr.api.NostrIF; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; import nostr.base.PrivateKey; @@ -51,6 +51,7 @@ import java.util.Properties; import java.util.UUID; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -361,8 +362,7 @@ public void testNIP15CreateStallEvent() throws JsonProcessingException { // Fetch the content and compare with the above original var content = instance.getEvent().getContent(); - ObjectMapper mapper = new ObjectMapper(); - var expected = mapper.readValue(content, Stall.class); + var expected = MAPPER_AFTERBURNER.readValue(content, Stall.class); assertEquals(expected, stall); } diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java index a71f2c04c..685c90dc5 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java @@ -1,25 +1,24 @@ package nostr.test.event; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; - import nostr.api.NIP15; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.impl.GenericEvent; import nostr.event.message.EventMessage; import nostr.id.Identity; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static nostr.test.event.ApiEventTest.createProduct; import static nostr.test.event.ApiEventTest.createStall; +import static org.junit.jupiter.api.Assertions.assertTrue; class ApiEventTestUsingSpringWebSocketClientTest { private static Map relays; @@ -51,16 +50,14 @@ void testNIP15SendProductEventUsingSpringWebSocketClient() throws IOException { String eventResponse = springWebSocketClient.send(message).stream().findFirst().get(); - ObjectMapper mapper = new ObjectMapper(); - // Extract and compare only first 3 elements of the JSON array - var expectedArray = mapper.readTree(expectedResponseJson(event.getId())).get(0).asText(); - var expectedSubscriptionId = mapper.readTree(expectedResponseJson(event.getId())).get(1).asText(); - var expectedSuccess = mapper.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); + var expectedArray = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(0).asText(); + var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(1).asText(); + var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); - var actualArray = mapper.readTree(eventResponse).get(0).asText(); - var actualSubscriptionId = mapper.readTree(eventResponse).get(1).asText(); - var actualSuccess = mapper.readTree(eventResponse).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponse).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponse).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponse).get(2).asBoolean(); assertTrue(expectedArray.equals(actualArray), "First element should match"); diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java index fa0e7186b..7b527a2a0 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java @@ -1,14 +1,5 @@ package nostr.test.event; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; - import nostr.api.NIP52; import nostr.base.PrivateKey; import nostr.base.PublicKey; @@ -21,6 +12,14 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import nostr.test.util.JsonComparator; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; +import static org.junit.jupiter.api.Assertions.assertTrue; class ApiNIP52EventTest { private static final String RELAY_URI = "ws://localhost:5555"; @@ -47,19 +46,17 @@ void testNIP52CalendarTimeBasedEventEventUsingSpringWebSocketClient() throws IOE GenericEvent event = nip52.createCalendarTimeBasedEvent(tags, "content", createCalendarContent()).sign().getEvent(); EventMessage message = new EventMessage(event); - ObjectMapper mapper = new ObjectMapper(); + var expectedJson = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())); + var actualJson = MAPPER_AFTERBURNER.readTree(springWebSocketClient.send(message).stream().findFirst().get()); - var expectedJson = mapper.readTree(expectedResponseJson(event.getId())); - var actualJson = mapper.readTree(springWebSocketClient.send(message).stream().findFirst().get()); - // Compare only first 3 elements of the JSON arrays assertTrue( JsonComparator.isEquivalentJson( - mapper.createArrayNode() + MAPPER_AFTERBURNER.createArrayNode() .add(expectedJson.get(0)) // OK Command .add(expectedJson.get(1)) // event id .add(expectedJson.get(2)), // Accepted? - mapper.createArrayNode() + MAPPER_AFTERBURNER.createArrayNode() .add(actualJson.get(0)) .add(actualJson.get(1)) .add(actualJson.get(2)))); diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java index 6baba40fa..ff044ce39 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java @@ -1,6 +1,5 @@ package nostr.test.event; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -24,6 +23,7 @@ import java.util.ArrayList; import java.util.List; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; class ApiNIP52RequestTest { @@ -113,16 +113,14 @@ void testNIP99CalendarContentPreRequest() throws IOException { SpringWebSocketClient springWebSocketEventClient = new SpringWebSocketClient(RELAY_URI); String eventResponse = springWebSocketEventClient.send(eventMessage).stream().findFirst().get(); - ObjectMapper mapper = new ObjectMapper(); - // Extract and compare only first 3 elements of the JSON array - var expectedArray = mapper.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); - var expectedSubscriptionId = mapper.readTree(expectedEventResponseJson(event.getId())).get(1).asText(); - var expectedSuccess = mapper.readTree(expectedEventResponseJson(event.getId())).get(2).asBoolean(); + var expectedArray = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); + var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(1).asText(); + var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(2).asBoolean(); - var actualArray = mapper.readTree(eventResponse).get(0).asText(); - var actualSubscriptionId = mapper.readTree(eventResponse).get(1).asText(); - var actualSuccess = mapper.readTree(eventResponse).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponse).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponse).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponse).get(2).asBoolean(); assertTrue(expectedArray.equals(actualArray), "First element should match"); assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); @@ -139,8 +137,8 @@ void testNIP99CalendarContentPreRequest() throws IOException { assertTrue( JsonComparator.isEquivalentJson( - mapper.readTree(expectedRequestResponseJson()), - mapper.readTree(reqResponse))); + MAPPER_AFTERBURNER.readTree(expectedRequestResponseJson()), + MAPPER_AFTERBURNER.readTree(reqResponse))); springWebSocketRequestClient.closeSocket(); */ diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java index b21fbd3eb..642e9959b 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java @@ -1,14 +1,5 @@ package nostr.test.event; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; - import nostr.api.NIP99; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -19,21 +10,15 @@ import nostr.event.message.EventMessage; import nostr.event.tag.PriceTag; import nostr.id.Identity; -import static nostr.test.event.ClassifiedListingEventTest.CLASSIFIED_LISTING_CONTENT; -import static nostr.test.event.ClassifiedListingEventTest.CLASSIFIED_LISTING_LOCATION; -import static nostr.test.event.ClassifiedListingEventTest.CLASSIFIED_LISTING_PUBLISHED_AT; -import static nostr.test.event.ClassifiedListingEventTest.CURRENCY; -import static nostr.test.event.ClassifiedListingEventTest.E_TAG; -import static nostr.test.event.ClassifiedListingEventTest.FREQUENCY; -import static nostr.test.event.ClassifiedListingEventTest.G_TAG; -import static nostr.test.event.ClassifiedListingEventTest.LOCATION_CODE; -import static nostr.test.event.ClassifiedListingEventTest.NUMBER; -import static nostr.test.event.ClassifiedListingEventTest.PUBLISHED_AT_CODE; -import static nostr.test.event.ClassifiedListingEventTest.P_TAG; -import static nostr.test.event.ClassifiedListingEventTest.SUBJECT_TAG; -import static nostr.test.event.ClassifiedListingEventTest.SUMMARY_CODE; -import static nostr.test.event.ClassifiedListingEventTest.TITLE_CODE; -import static nostr.test.event.ClassifiedListingEventTest.T_TAG; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static nostr.base.IEvent.MAPPER_AFTERBURNER; +import static nostr.test.event.ClassifiedListingEventTest.*; +import static org.junit.jupiter.api.Assertions.assertTrue; class ApiNIP99EventTest { private static final String RELAY_URI = "ws://localhost:5555"; @@ -68,22 +53,20 @@ void testNIP99ClassifiedListingEvent() throws IOException { GenericEvent event = nip99.createClassifiedListingEvent(tags, CLASSIFIED_LISTING_CONTENT, classifiedListing).sign().getEvent(); EventMessage message = new EventMessage(event); - ObjectMapper mapper = new ObjectMapper(); - // Extract and compare only first 3 elements of the JSON array - var expectedArray = mapper.readTree(expectedResponseJson(event.getId())).get(0).asText(); - var expectedSubscriptionId = mapper.readTree(expectedResponseJson(event.getId())).get(1).asText(); - var expectedSuccess = mapper.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); + var expectedArray = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(0).asText(); + var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(1).asText(); + var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); String eventResponse = springWebSocketClient.send(message).stream().findFirst().get(); - var actualArray = mapper.readTree(eventResponse).get(0).asText(); - var actualSubscriptionId = mapper.readTree(eventResponse).get(1).asText(); - var actualSuccess = mapper.readTree(eventResponse).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponse).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponse).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponse).get(2).asBoolean(); assertTrue(expectedArray.equals(actualArray), "First element should match"); assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); - + springWebSocketClient.closeSocket(); } diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java index 10b9017b0..bd9a44cef 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java @@ -1,7 +1,6 @@ package nostr.test.event; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.api.NIP99; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -25,6 +24,7 @@ import java.util.ArrayList; import java.util.List; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static nostr.test.event.ClassifiedListingEventTest.LOCATION_CODE; import static nostr.test.event.ClassifiedListingEventTest.PUBLISHED_AT_CODE; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -99,16 +99,14 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { assertTrue(eventResponses.size() == 1, "Expected 1 event response, but got " + eventResponses.size()); - ObjectMapper mapper = new ObjectMapper(); - // Extract and compare only first 3 elements of the JSON array - var expectedArray = mapper.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); - var expectedSubscriptionId = mapper.readTree(expectedEventResponseJson(event.getId())).get(1).asText(); - var expectedSuccess = mapper.readTree(expectedEventResponseJson(event.getId())).get(2).asBoolean(); + var expectedArray = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); + var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(1).asText(); + var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(2).asBoolean(); - var actualArray = mapper.readTree(eventResponses.get(0)).get(0).asText(); - var actualSubscriptionId = mapper.readTree(eventResponses.get(0)).get(1).asText(); - var actualSuccess = mapper.readTree(eventResponses.get(0)).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(2).asBoolean(); assertTrue(expectedArray.equals(actualArray), "First element should match"); assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); @@ -124,8 +122,8 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { List reqResponses = springWebSocketRequestClient.send(reqJson).stream().toList(); springWebSocketRequestClient.closeSocket(); - var actualJson = mapper.readTree(reqResponses.getFirst()); - var expectedJson = mapper.readTree(expectedRequestResponseJson()); + var actualJson = MAPPER_AFTERBURNER.readTree(reqResponses.getFirst()); + var expectedJson = MAPPER_AFTERBURNER.readTree(expectedRequestResponseJson()); // Verify you receive the event assertTrue(actualJson.get(0).asText().equals("EVENT"), "Event should be received, and not " + actualJson.get(0).asText()); diff --git a/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java b/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java index e35652e07..25e268677 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.base.Signature; @@ -28,6 +27,7 @@ import java.util.List; import java.util.function.BiFunction; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -82,7 +82,7 @@ void setup() throws URISyntaxException { tags.add(GenericTag.create(END_CODE, 52, l.toString())); CalendarContent calendarContent = CalendarContent.builder(identifierTag, CALENDAR_TIME_BASED_EVENT_TITLE, START) - .build(); + .build(); // a random set of calendar tags // calendarContent.setEndTzid(CALENDAR_TIME_BASED_EVENT_END_TZID); calendarContent.setSummary(CALENDAR_TIME_BASED_EVENT_SUMMARY); @@ -90,40 +90,39 @@ void setup() throws URISyntaxException { // calendarContent.setReferenceTags(List.of(new ReferenceTag(uri))); instance = new NIP52<>(identity) - .createCalendarTimeBasedEvent(tags, CALENDAR_TIME_BASED_EVENT_CONTENT, calendarContent).getEvent(); + .createCalendarTimeBasedEvent(tags, CALENDAR_TIME_BASED_EVENT_CONTENT, calendarContent).getEvent(); signature = identity.sign(instance); instance.setSignature(signature); expectedEncodedJson = "{" - + "\"id\":\"" + instance.getId() + "\"," - + "\"kind\":31923," - + "\"content\":\"calendar Time-Based Event content\"," - + "\"pubkey\":\"" + senderPubkey + "\"," - + "\"created_at\":" + instance.getCreatedAt() + "," - + "\"tags\":[" - + "[\"p\",\"2bed79f81439ff794cf5ac5f7bff9121e257f399829e472c7a14d3e86fe76985\",\"http://some.url\",\"ISSUER\"]," - + "[\"p\",\"494001ac0c8af2a10f60f23538e5b35d3cdacb8e1cc956fe7a16dfa5cbfc4347\",\"http://some.url\",\"COUNTERPARTY\"]," - + "[\"location\",\"Calendar Time-Based Event location\"]," - + "[\"subject\",\"Calendar Time-Based Event Test Subject Tag\"]," - + "[\"g\",\"Calendar Time-Based Event Test Geohash Tag\"]," - + "[\"t\",\"Calendar Time-Based Event Test Hashtag Tag\"]," - + "[\"start_tzid\",\"1687765220\"]," - + "[\"end\",\"1716513986368\"]," - + "[\"d\",\"UUID-CalendarTimeBasedEventTest\"]," - + "[\"title\",\"Calendar Time-Based Event title\"]," - + "[\"start\",\"1716513986268\"]," - + "[\"end_tzid\",\"1687765220\"]," - + "[\"summary\",\"Calendar Time-Based Event summary\"]," - + "[\"r\",\"http://some.url\"]]," - + "\"sig\":\"" + signature.toString() + "\"" - + "}"; + + "\"id\":\"" + instance.getId() + "\"," + + "\"kind\":31923," + + "\"content\":\"calendar Time-Based Event content\"," + + "\"pubkey\":\"" + senderPubkey + "\"," + + "\"created_at\":" + instance.getCreatedAt() + "," + + "\"tags\":[" + + "[\"p\",\"2bed79f81439ff794cf5ac5f7bff9121e257f399829e472c7a14d3e86fe76985\",\"http://some.url\",\"ISSUER\"]," + + "[\"p\",\"494001ac0c8af2a10f60f23538e5b35d3cdacb8e1cc956fe7a16dfa5cbfc4347\",\"http://some.url\",\"COUNTERPARTY\"]," + + "[\"location\",\"Calendar Time-Based Event location\"]," + + "[\"subject\",\"Calendar Time-Based Event Test Subject Tag\"]," + + "[\"g\",\"Calendar Time-Based Event Test Geohash Tag\"]," + + "[\"t\",\"Calendar Time-Based Event Test Hashtag Tag\"]," + + "[\"start_tzid\",\"1687765220\"]," + + "[\"end\",\"1716513986368\"]," + + "[\"d\",\"UUID-CalendarTimeBasedEventTest\"]," + + "[\"title\",\"Calendar Time-Based Event title\"]," + + "[\"start\",\"1716513986268\"]," + + "[\"end_tzid\",\"1687765220\"]," + + "[\"summary\",\"Calendar Time-Based Event summary\"]," + + "[\"r\",\"http://some.url\"]]," + + "\"sig\":\"" + signature.toString() + "\"" + + "}"; } @Test void testCalendarTimeBasedEventEncoding() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - var instanceJson = mapper.readTree(new BaseEventEncoder<>(instance).encode()); - var expectedJson = mapper.readTree(expectedEncodedJson); + var instanceJson = MAPPER_AFTERBURNER.readTree(new BaseEventEncoder<>(instance).encode()); + var expectedJson = MAPPER_AFTERBURNER.readTree(expectedEncodedJson); // Helper function to find tag value BiFunction findTagArray = (tags, tagName) -> { @@ -137,21 +136,20 @@ void testCalendarTimeBasedEventEncoding() throws JsonProcessingException { // Verify required fields match assertTrue(findTagArray.apply(instanceJson.get("tags"), "d").get(1).asText() - .equals(findTagArray.apply(expectedJson.get("tags"), "d").get(1).asText())); + .equals(findTagArray.apply(expectedJson.get("tags"), "d").get(1).asText())); assertTrue(findTagArray.apply(instanceJson.get("tags"), "title").get(1).asText() - .equals(findTagArray.apply(expectedJson.get("tags"), "title").get(1).asText())); + .equals(findTagArray.apply(expectedJson.get("tags"), "title").get(1).asText())); assertTrue(findTagArray.apply(instanceJson.get("tags"), "start").get(1).asText() - .equals(findTagArray.apply(expectedJson.get("tags"), "start").get(1).asText())); + .equals(findTagArray.apply(expectedJson.get("tags"), "start").get(1).asText())); } @Test void testCalendarTimeBasedEventDecoding() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - var decodedJson = mapper.readTree( - new BaseEventEncoder<>( - mapper.readValue(expectedEncodedJson, GenericEvent.class)) - .encode()); - var instanceJson = mapper.readTree(new BaseEventEncoder<>(instance).encode()); + var decodedJson = MAPPER_AFTERBURNER.readTree( + new BaseEventEncoder<>( + MAPPER_AFTERBURNER.readValue(expectedEncodedJson, GenericEvent.class)) + .encode()); + var instanceJson = MAPPER_AFTERBURNER.readTree(new BaseEventEncoder<>(instance).encode()); // Helper function to find tag value BiFunction findTagArray = (tags, tagName) -> { @@ -168,10 +166,10 @@ void testCalendarTimeBasedEventDecoding() throws JsonProcessingException { var instanceTags = instanceJson.get("tags"); assertTrue(findTagArray.apply(decodedTags, "d").get(1).asText() - .equals(findTagArray.apply(instanceTags, "d").get(1).asText())); + .equals(findTagArray.apply(instanceTags, "d").get(1).asText())); assertTrue(findTagArray.apply(decodedTags, "title").get(1).asText() - .equals(findTagArray.apply(instanceTags, "title").get(1).asText())); + .equals(findTagArray.apply(instanceTags, "title").get(1).asText())); assertTrue(findTagArray.apply(decodedTags, "start").get(1).asText() - .equals(findTagArray.apply(instanceTags, "start").get(1).asText())); + .equals(findTagArray.apply(instanceTags, "start").get(1).asText())); } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java index a65742a23..261274a82 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java @@ -21,6 +21,7 @@ import nostr.util.NostrException; import nostr.util.NostrUtil; +import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.*; /** @@ -67,7 +68,7 @@ public void testCreateGenericTag() { var strJsonEvent = encoder.encode(); assertDoesNotThrow(() -> { - BaseTag tag = IEncoder.MAPPER.readValue(strJsonEvent, BaseTag.class); + BaseTag tag = I_ENCODER_MAPPER_AFTERBURNER.readValue(strJsonEvent, BaseTag.class); assertEquals(genericTag, tag); }); } diff --git a/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java b/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java index 11878d524..4c331a0e3 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java @@ -1,7 +1,6 @@ package nostr.test.event; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import nostr.base.Relay; import nostr.event.BaseTag; import nostr.event.json.codec.BaseTagEncoder; @@ -10,6 +9,7 @@ import java.util.List; +import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -33,11 +33,11 @@ void testSerialize() { void testDeserialize() { final String EXPECTED = "[\"relays\",\"ws://localhost:5555\"]"; assertDoesNotThrow(() -> { - JsonNode node = new ObjectMapper().readTree(EXPECTED); + JsonNode node = MAPPER_AFTERBURNER.readTree(EXPECTED); BaseTag deserialize = RelaysTag.deserialize(node); assertEquals(RELAYS_KEY, deserialize.getCode()); assertEquals(HOST_VALUE, ((RelaysTag) deserialize).getRelays().get(0).getUri()); }); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java index 1041ac5e1..d30c099d3 100644 --- a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java +++ b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java @@ -1,7 +1,6 @@ package nostr.test.json; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.java.Log; import nostr.api.NIP01; import nostr.base.Command; @@ -50,20 +49,14 @@ import java.math.BigDecimal; 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.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 static nostr.base.IEvent.MAPPER_AFTERBURNER; +import static org.junit.jupiter.api.Assertions.*; /** * @author eric */ @Log public class JsonParseTest { - ObjectMapper mapper = new ObjectMapper(); - @Test public void testBaseMessageDecoderEventFilter() throws JsonProcessingException { log.info("testBaseMessageDecoderEventFilter"); @@ -653,11 +646,11 @@ public void testGenericTagQueryListDecoder() throws JsonProcessingException { new IdentifierTagFilter<>(new IdentifierTag(uuidValue2)))); assertTrue(JsonComparator.isEquivalentJson( - mapper.createArrayNode() - .add(mapper.readTree( + MAPPER_AFTERBURNER.createArrayNode() + .add(MAPPER_AFTERBURNER.readTree( expectedReqMessage.encode())), - mapper.createArrayNode() - .add(mapper.readTree(decodedReqMessage.encode())))); + MAPPER_AFTERBURNER.createArrayNode() + .add(MAPPER_AFTERBURNER.readTree(decodedReqMessage.encode())))); assertEquals(expectedReqMessage, decodedReqMessage); } diff --git a/pom.xml b/pom.xml index 4294df7c4..06df6e6f6 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,7 @@ 3.3.0 1.6.0 0.8.12 + 2.18.3 @@ -113,9 +114,9 @@ ${lombok.version} - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} + com.fasterxml.jackson.module + jackson-module-afterburner + ${jackson-module-afterburner.version} org.bouncycastle From 7fc7ed8bbd83a393fd6ab40deac0a0c39a618df3 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 18:14:46 -0700 Subject: [PATCH 04/57] spring boot conversion, removes need for module-info.java files. add gradle support --- .gitignore | 8 +++ gradle.properties | 5 ++ nostr-java-api/build.gradle | 18 +++++ nostr-java-api/src/main/java/module-info.java | 17 ----- nostr-java-base/build.gradle | 16 +++++ .../src/main/java/module-info.java | 12 ---- nostr-java-client/build.gradle | 21 ++++++ .../src/main/java/module-info.java | 17 ----- nostr-java-crypto/build.gradle | 15 +++++ .../src/main/java/module-info.java | 14 ---- nostr-java-encryption/build.gradle | 15 +++++ .../src/main/java/module-info.java | 6 -- nostr-java-event/build.gradle | 15 +++++ .../src/main/java/module-info.java | 21 ------ nostr-java-examples/build.gradle | 17 +++++ .../src/main/java/module-info.java | 12 ---- nostr-java-id/build.gradle | 17 +++++ nostr-java-id/src/main/java/module-info.java | 11 --- nostr-java-test/build.gradle | 28 ++++++++ nostr-java-test/pom.xml | 3 +- nostr-java-util/build.gradle | 13 ++++ .../src/main/java/module-info.java | 7 -- pom.xml | 67 ++++++++++++++----- settings.gradle | 15 +++++ 24 files changed, 257 insertions(+), 133 deletions(-) create mode 100644 gradle.properties create mode 100644 nostr-java-api/build.gradle delete mode 100644 nostr-java-api/src/main/java/module-info.java create mode 100644 nostr-java-base/build.gradle delete mode 100644 nostr-java-base/src/main/java/module-info.java create mode 100644 nostr-java-client/build.gradle delete mode 100644 nostr-java-client/src/main/java/module-info.java create mode 100644 nostr-java-crypto/build.gradle delete mode 100644 nostr-java-crypto/src/main/java/module-info.java create mode 100644 nostr-java-encryption/build.gradle delete mode 100644 nostr-java-encryption/src/main/java/module-info.java create mode 100644 nostr-java-event/build.gradle delete mode 100644 nostr-java-event/src/main/java/module-info.java create mode 100644 nostr-java-examples/build.gradle delete mode 100644 nostr-java-examples/src/main/java/module-info.java create mode 100644 nostr-java-id/build.gradle delete mode 100644 nostr-java-id/src/main/java/module-info.java create mode 100644 nostr-java-test/build.gradle create mode 100644 nostr-java-util/build.gradle delete mode 100644 nostr-java-util/src/main/java/module-info.java create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index 9298972c8..a7b31a6f2 100644 --- a/.gitignore +++ b/.gitignore @@ -212,6 +212,14 @@ hs_err_pid* ## ignoring target file target/ +# Gradle files +.gradle/ +build/ +gradle/ +gradlew +gradlew.bat +buildSrc/ + ### VisualStudioCode ### .vscode .vscode/* diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..377538c99 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,5 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties + +org.gradle.configuration-cache=true + diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle new file mode 100644 index 000000000..9a0387737 --- /dev/null +++ b/nostr-java-api/build.gradle @@ -0,0 +1,18 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api project(':nostr-java-base') + api project(':nostr-java-event') + api project(':nostr-java-id') + api project(':nostr-java-client') + api project(':nostr-java-encryption') + api libs.org.apache.commons.commons.lang3 +} + +description = 'nostr-java-api' diff --git a/nostr-java-api/src/main/java/module-info.java b/nostr-java-api/src/main/java/module-info.java deleted file mode 100644 index 92f8a0115..000000000 --- a/nostr-java-api/src/main/java/module-info.java +++ /dev/null @@ -1,17 +0,0 @@ -module nostr.api { - requires nostr.base; - requires nostr.util; - requires nostr.event; - requires nostr.id; - requires nostr.client; - requires nostr.encryption; - - requires lombok; - requires nostr.crypto; - requires org.apache.commons.lang3; - requires com.fasterxml.jackson.module.afterburner; - requires com.fasterxml.jackson.databind; - requires java.logging; - - exports nostr.api; -} diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle new file mode 100644 index 000000000..fe98223a3 --- /dev/null +++ b/nostr-java-base/build.gradle @@ -0,0 +1,16 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api libs.com.fasterxml.jackson.module.jackson.module.afterburner + api project(':nostr-java-util') + api project(':nostr-java-crypto') +} + +description = 'nostr-java-base' diff --git a/nostr-java-base/src/main/java/module-info.java b/nostr-java-base/src/main/java/module-info.java deleted file mode 100644 index bcc09ce7c..000000000 --- a/nostr-java-base/src/main/java/module-info.java +++ /dev/null @@ -1,12 +0,0 @@ - -module nostr.base { - requires static lombok; - requires nostr.util; - requires nostr.crypto; - requires com.fasterxml.jackson.module.afterburner; - requires com.fasterxml.jackson.databind; - requires java.logging; - - exports nostr.base; - exports nostr.base.annotation; -} diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle new file mode 100644 index 000000000..d8429f4cb --- /dev/null +++ b/nostr-java-client/build.gradle @@ -0,0 +1,21 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api project(':nostr-java-event') + api project(':nostr-java-base') + api project(':nostr-java-id') + api libs.org.springframework.spring.websocket + api libs.jakarta.websocket.jakarta.websocket.api + api libs.jakarta.websocket.jakarta.websocket.client.api + api libs.org.springframework.spring.webflux + api libs.io.projectreactor.netty.reactor.netty.http + api libs.org.awaitility.awaitility +} + +description = 'nostr-java-client' diff --git a/nostr-java-client/src/main/java/module-info.java b/nostr-java-client/src/main/java/module-info.java deleted file mode 100644 index f897a28f3..000000000 --- a/nostr-java-client/src/main/java/module-info.java +++ /dev/null @@ -1,17 +0,0 @@ -module nostr.client { - requires nostr.event; - requires static lombok; - requires java.logging; - requires nostr.util; - requires nostr.base; - requires com.fasterxml.jackson.core; - requires reactor.core; - requires spring.webflux; - requires spring.context; - requires spring.beans; - requires spring.websocket; - requires jakarta.websocket.client; - requires awaitility; - - exports nostr.client.springwebsocket; -} diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle new file mode 100644 index 000000000..3b92a318b --- /dev/null +++ b/nostr-java-crypto/build.gradle @@ -0,0 +1,15 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api libs.org.bouncycastle.bcprov.jdk18on + api project(':nostr-java-util') +} + +description = 'nostr-java-crypto' diff --git a/nostr-java-crypto/src/main/java/module-info.java b/nostr-java-crypto/src/main/java/module-info.java deleted file mode 100644 index a6047471b..000000000 --- a/nostr-java-crypto/src/main/java/module-info.java +++ /dev/null @@ -1,14 +0,0 @@ - -module nostr.crypto { - requires static lombok; - requires java.logging; - - requires org.bouncycastle.provider; - - requires nostr.util; - - exports nostr.crypto.bech32; - exports nostr.crypto.schnorr; - exports nostr.crypto.nip04; - exports nostr.crypto.nip44; -} diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle new file mode 100644 index 000000000..9b32bfd80 --- /dev/null +++ b/nostr-java-encryption/build.gradle @@ -0,0 +1,15 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api project(':nostr-java-crypto') + api project(':nostr-java-util') +} + +description = 'nostr-java-encryption' diff --git a/nostr-java-encryption/src/main/java/module-info.java b/nostr-java-encryption/src/main/java/module-info.java deleted file mode 100644 index eed9f5823..000000000 --- a/nostr-java-encryption/src/main/java/module-info.java +++ /dev/null @@ -1,6 +0,0 @@ -module nostr.encryption { - requires lombok; - requires nostr.util; - requires nostr.crypto; - exports nostr.encryption; -} diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle new file mode 100644 index 000000000..06e752237 --- /dev/null +++ b/nostr-java-event/build.gradle @@ -0,0 +1,15 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api project(':nostr-java-base') + api project(':nostr-java-util') +} + +description = 'nostr-java-event' diff --git a/nostr-java-event/src/main/java/module-info.java b/nostr-java-event/src/main/java/module-info.java deleted file mode 100644 index 270c88e55..000000000 --- a/nostr-java-event/src/main/java/module-info.java +++ /dev/null @@ -1,21 +0,0 @@ - -module nostr.event { - requires static lombok; - requires nostr.base; - requires nostr.crypto; - requires nostr.util; - requires com.fasterxml.jackson.module.afterburner; - requires com.fasterxml.jackson.databind; - requires java.logging; - requires java.desktop; - - exports nostr.event; - exports nostr.event.impl; - exports nostr.event.message; - exports nostr.event.json.codec; - exports nostr.event.json.deserializer; - exports nostr.event.json.serializer; - exports nostr.event.tag; - exports nostr.event.util; - exports nostr.event.filter; -} diff --git a/nostr-java-examples/build.gradle b/nostr-java-examples/build.gradle new file mode 100644 index 000000000..0bb3535cc --- /dev/null +++ b/nostr-java-examples/build.gradle @@ -0,0 +1,17 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api project(':nostr-java-event') + api project(':nostr-java-base') + api project(':nostr-java-id') + api project(':nostr-java-client') + api project(':nostr-java-api') +} + +description = 'nostr-java-examples' diff --git a/nostr-java-examples/src/main/java/module-info.java b/nostr-java-examples/src/main/java/module-info.java deleted file mode 100644 index bab2a15e0..000000000 --- a/nostr-java-examples/src/main/java/module-info.java +++ /dev/null @@ -1,12 +0,0 @@ - -module nostr.examples { - requires nostr.event; - requires nostr.api; - requires static lombok; - requires nostr.util; - requires nostr.base; - requires nostr.id; - requires java.logging; - - exports nostr.examples; -} diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle new file mode 100644 index 000000000..ee22d2fb3 --- /dev/null +++ b/nostr-java-id/build.gradle @@ -0,0 +1,17 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api project(':nostr-java-base') + api project(':nostr-java-event') + api project(':nostr-java-util') + api project(':nostr-java-crypto') +} + +description = 'nostr-java-id' diff --git a/nostr-java-id/src/main/java/module-info.java b/nostr-java-id/src/main/java/module-info.java deleted file mode 100644 index 59373282f..000000000 --- a/nostr-java-id/src/main/java/module-info.java +++ /dev/null @@ -1,11 +0,0 @@ - -module nostr.id { - requires static lombok; - requires nostr.base; - requires nostr.crypto; - requires nostr.event; - requires nostr.util; - requires java.logging; - - exports nostr.id; -} diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle new file mode 100644 index 000000000..736bbbeed --- /dev/null +++ b/nostr-java-test/build.gradle @@ -0,0 +1,28 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok + api project(':nostr-java-event') + api project(':nostr-java-base') + api project(':nostr-java-util') + api project(':nostr-java-client') + api libs.org.springframework.spring.websocket + api libs.jakarta.websocket.jakarta.websocket.api + api libs.jakarta.websocket.jakarta.websocket.client.api + api libs.org.glassfish.tyrus.bundles.tyrus.standalone.client + api libs.org.springframework.spring.webflux + api libs.io.projectreactor.netty.reactor.netty.http + testImplementation project(':nostr-java-id') + testImplementation libs.org.junit.jupiter.junit.jupiter.engine + testImplementation project(':nostr-java-api') + testImplementation libs.org.awaitility.awaitility + testImplementation libs.com.google.guava.guava +} + +description = 'nostr-java-test' diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml index 0ad8d8305..c04c3af06 100644 --- a/nostr-java-test/pom.xml +++ b/nostr-java-test/pom.xml @@ -45,7 +45,8 @@ org.junit.jupiter - junit-jupiter-engine + junit-jupiter + ${junit-jupiter.version} ${project.groupId} diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle new file mode 100644 index 000000000..cda9bd19d --- /dev/null +++ b/nostr-java-util/build.gradle @@ -0,0 +1,13 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + id 'buildlogic.java-conventions' +} + +dependencies { + api libs.org.projectlombok.lombok +} + +description = 'nostr-java-util' diff --git a/nostr-java-util/src/main/java/module-info.java b/nostr-java-util/src/main/java/module-info.java deleted file mode 100644 index 8658ffc7d..000000000 --- a/nostr-java-util/src/main/java/module-info.java +++ /dev/null @@ -1,7 +0,0 @@ -module nostr.util { - requires static lombok; - requires java.logging; - - exports nostr.util; - exports nostr.util.thread; -} diff --git a/pom.xml b/pom.xml index 06df6e6f6..edb541038 100644 --- a/pom.xml +++ b/pom.xml @@ -74,26 +74,27 @@ - ${version} - UTF-8 21 + 3.3.5 + + ${version} + 3.17.0 + 1.18.34 ${java.version} ${java.version} - - 4.9.3 - 2.8.0 + + UTF-8 - 1.18.34 - 1.70 1.78 2.17.2 + 2.18.3 3.17.0 - 5.10.2 + 5.10.2 3.23.1 @@ -102,12 +103,47 @@ 3.3.0 1.6.0 0.8.12 - 2.18.3 + + org.springframework.boot + spring-boot + ${spring-boot.version} + + + org.springframework.boot + spring-boot-autoconfigure + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter + ${spring-boot.version} + + + org.springframework.boot + spring-boot-devtools + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-websocket + ${spring-boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + org.projectlombok lombok @@ -125,16 +161,17 @@ + org.junit.jupiter - junit-jupiter-engine - ${junit.version} + junit-jupiter + ${junit-jupiter.version} test - org.assertj - assertj-core - ${assertj.version} + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} test @@ -197,7 +234,7 @@ ${gpg.keyname} - ${gpg.keyname} + diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..4f100c851 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,15 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +rootProject.name = 'nostr-java' +include(':nostr-java-crypto') +include(':nostr-java-base') +include(':nostr-java-test') +include(':nostr-java-client') +include(':nostr-java-event') +include(':nostr-java-examples') +include(':nostr-java-util') +include(':nostr-java-api') +include(':nostr-java-id') +include(':nostr-java-encryption') From b2cbf0306543e6e8ba5826efa0eac54d16fcff66 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 20:41:23 -0700 Subject: [PATCH 05/57] pom dependency cleanup and reorg. all unit and integration tests passing against superconductor --- .../nostr/api/NostrSpringWebSocketClient.java | 5 - nostr-java-client/pom.xml | 49 +++++-- .../ReactiveWebSocketClient.java | 52 ------- .../main/java/nostr/crypto/bech32/Bech32.java | 6 +- .../crypto/nip04/EncryptedDirectMessage.java | 38 ++--- nostr-java-test/build.gradle | 1 - nostr-java-test/pom.xml | 137 +++++------------- pom.xml | 33 ++--- 8 files changed, 106 insertions(+), 215 deletions(-) delete mode 100644 nostr-java-client/src/main/java/nostr/client/springwebsocket/ReactiveWebSocketClient.java 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 9cf09d1fc..31ba1a3eb 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java @@ -136,11 +136,6 @@ public boolean verify(@NonNull GenericEvent event) { } } - @Override - public Identity getSender() { - return sender; - } - @Override public Map getRelays() { return clientMap.values().stream() diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index f2911d6ec..3806805fd 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -6,9 +6,25 @@ nostr-java 0.6.5-SNAPSHOT + nostr-java-client jar + + + 4.2.2 + 2.2.0 + 1.1.20 + 6.1.10 + 6.1.10 + + + + org.springframework.boot + spring-boot-starter-websocket + ${spring-boot.version} + + ${project.groupId} nostr-java-event @@ -24,38 +40,39 @@ nostr-java-id ${project.version} + org.springframework spring-websocket - 6.1.10 + ${spring-websocket.version} - - jakarta.websocket - jakarta.websocket-api - 2.2.0 + org.springframework + spring-webflux + ${spring-webflux.version} - - jakarta.websocket - jakarta.websocket-client-api - 2.2.0 + io.projectreactor.netty + reactor-netty-http + ${reactor-netty-http.version} - org.springframework - spring-webflux - 6.1.10 + jakarta.websocket + jakarta.websocket-api + ${jakarta.websocket-api.version} - io.projectreactor.netty - reactor-netty-http - 1.1.20 + jakarta.websocket + jakarta.websocket-client-api + + ${jakarta.websocket-api.version} + org.awaitility awaitility - 4.2.2 + ${awaitility.version} diff --git a/nostr-java-client/src/main/java/nostr/client/springwebsocket/ReactiveWebSocketClient.java b/nostr-java-client/src/main/java/nostr/client/springwebsocket/ReactiveWebSocketClient.java deleted file mode 100644 index 4f9f72647..000000000 --- a/nostr-java-client/src/main/java/nostr/client/springwebsocket/ReactiveWebSocketClient.java +++ /dev/null @@ -1,52 +0,0 @@ -package nostr.client.springwebsocket; - -import com.fasterxml.jackson.core.JsonProcessingException; -import nostr.event.BaseMessage; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.socket.WebSocketMessage; -import org.springframework.web.reactive.socket.WebSocketSession; -import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient; -import reactor.core.publisher.Flux; - -import java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -@Component -@Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class ReactiveWebSocketClient implements WebSocketClientIF { - private final ReactorNettyWebSocketClient client; - private final URI uri; - - public ReactiveWebSocketClient(@Value("${nostr.relay.uri}") String relayUri) { - this.client = new ReactorNettyWebSocketClient(); - this.uri = URI.create(relayUri); - } - - @Override - public List send(T baseMessage) throws JsonProcessingException { - return send(baseMessage.encode()); - } - - @Override - public List send(String json) { - List events = new ArrayList<>(); - client.execute(uri, - session -> - session - .send(Flux.just(session.textMessage(json))) - .thenMany(session.receive().take(1).map(WebSocketMessage::getPayloadAsText)) - .doOnNext(events::add).then()) - .block(); - return events; - } - - @Override - public void closeSocket() throws IOException { - client.execute(uri, WebSocketSession::close).block(); - } -} 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 896ab5b06..b96f8e6fe 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 @@ -62,20 +62,20 @@ private Bech32Data(final Encoding encoding, final String hrp, final byte[] data) } public static String toBech32(Bech32Prefix hrp, byte[] hexKey) throws NostrException { - var data = convertBits(hexKey, 8, 5, true); + byte[] data = convertBits(hexKey, 8, 5, true); return Bech32.encode(Bech32.Encoding.BECH32, hrp.getCode(), data); } public static String toBech32(Bech32Prefix hrp, String hexKey) throws NostrException { - var data = NostrUtil.hexToBytes(hexKey); + byte[] data = NostrUtil.hexToBytes(hexKey); return toBech32(hrp, data); } // Added by squirrel public static String fromBech32(String strBech32) throws NostrException { - var data = Bech32.decode(strBech32).data; + byte[] data = Bech32.decode(strBech32).data; data = convertBits(data, 5, 8, true); 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 92206f73b..feb7b6e7f 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 @@ -26,20 +26,20 @@ public static String encrypt(@NonNull String message, @NonNull byte[] senderPriv } public static String decryptMessage(@NonNull byte[] senderPrivKey, @NonNull String encContent, @NonNull byte[] rcptPubKey) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { - var sharedSecret = getSharedSecretKeySpec(senderPrivKey, rcptPubKey); - return decryptMessage(sharedSecret, encContent); + SecretKeySpec sharedSecret = getSharedSecretKeySpec(senderPrivKey, rcptPubKey); + return decryptMessage(sharedSecret, encContent); } private static String decryptMessage(SecretKeySpec sharedSecretKey, String encodedMessage) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { - final var parts = encodedMessage.split("\\?iv="); + String[] parts = encodedMessage.split("\\?iv="); - final var Base64Decoder = Base64.getDecoder(); - final var encryptedMessage = Base64Decoder.decode(parts[0]); - final var iv = Base64Decoder.decode(parts[1]); + Base64.Decoder Base64Decoder = Base64.getDecoder(); + byte[] encryptedMessage = Base64Decoder.decode(parts[0]); + byte[] iv = Base64Decoder.decode(parts[1]); - var cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - var ivParamSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + IvParameterSpec ivParamSpec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, sharedSecretKey, ivParamSpec); return new String(cipher.doFinal(encryptedMessage), StandardCharsets.UTF_8); @@ -47,21 +47,21 @@ private static String decryptMessage(SecretKeySpec sharedSecretKey, String encod static String encryptMessage(byte[] senderPrivateKey, byte[] rcptPublicKey, String message) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { - var sharedSecretKey = getSharedSecretKeySpec(senderPrivateKey, rcptPublicKey); + SecretKeySpec sharedSecretKey = getSharedSecretKeySpec(senderPrivateKey, rcptPublicKey); - var iv = NostrUtil.createRandomByteArray(16); - var ivParamSpec = new IvParameterSpec(iv); + byte[] iv = NostrUtil.createRandomByteArray(16); + IvParameterSpec ivParamSpec = new IvParameterSpec(iv); - var cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, sharedSecretKey, ivParamSpec); - final var msg = message.getBytes(StandardCharsets.UTF_8); - var encryptedMessage = cipher.doFinal(msg); + byte[] msg = message.getBytes(StandardCharsets.UTF_8); + byte[] encryptedMessage = cipher.doFinal(msg); - final var Base64Encoder = Base64.getEncoder(); - var encryptedMessage64 = Base64Encoder.encode(encryptedMessage); + Base64.Encoder Base64Encoder = Base64.getEncoder(); + byte[] encryptedMessage64 = Base64Encoder.encode(encryptedMessage); - var iv64 = Base64Encoder.encode(ivParamSpec.getIV()); + byte[] iv64 = Base64Encoder.encode(ivParamSpec.getIV()); return new String(encryptedMessage64) + "?iv=" + new String(iv64); } @@ -70,8 +70,8 @@ private static SecretKeySpec getSharedSecretKeySpec(byte[] privateKey, byte[] pu final String secKeyHex = NostrUtil.bytesToHex(privateKey); final String pubKeyHex = NostrUtil.bytesToHex(publicKey); - var sharedPoint = getSharedSecret(secKeyHex, pubKeyHex); - var sharedX = Arrays.copyOfRange(sharedPoint, 1, 33); + byte[] sharedPoint = getSharedSecret(secKeyHex, pubKeyHex); + byte[] sharedX = Arrays.copyOfRange(sharedPoint, 1, 33); return new SecretKeySpec(sharedX, "AES"); } diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle index 736bbbeed..5dcb7d356 100644 --- a/nostr-java-test/build.gradle +++ b/nostr-java-test/build.gradle @@ -15,7 +15,6 @@ dependencies { api libs.org.springframework.spring.websocket api libs.jakarta.websocket.jakarta.websocket.api api libs.jakarta.websocket.jakarta.websocket.client.api - api libs.org.glassfish.tyrus.bundles.tyrus.standalone.client api libs.org.springframework.spring.webflux api libs.io.projectreactor.netty.reactor.netty.http testImplementation project(':nostr-java-id') diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml index c04c3af06..48a181f66 100644 --- a/nostr-java-test/pom.xml +++ b/nostr-java-test/pom.xml @@ -11,103 +11,10 @@ nostr-java-test jar - - - - - org.projectlombok - lombok - - - - - ${project.groupId} - nostr-java-event - ${project.version} - - - ${project.groupId} - nostr-java-base - ${project.version} - - - ${project.groupId} - nostr-java-id - ${project.version} - test - - - ${project.groupId} - nostr-java-util - ${project.version} - - - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - - - ${project.groupId} - nostr-java-client - ${project.version} - - - ${project.groupId} - nostr-java-api - ${project.version} - test - - - - org.springframework - spring-websocket - 6.1.10 - - - - jakarta.websocket - jakarta.websocket-api - 2.2.0 - - - - jakarta.websocket - jakarta.websocket-client-api - 2.2.0 - - - - org.glassfish.tyrus.bundles - tyrus-standalone-client - 2.1.5 - - - - org.springframework - spring-webflux - 6.1.10 - - - io.projectreactor.netty - reactor-netty-http - 1.1.20 - - - - org.awaitility - awaitility - 4.2.2 - test - - - com.google.guava - guava - 33.2.1-jre - test - - + + + 33.2.1-jre + @@ -187,4 +94,40 @@ + + + + + org.projectlombok + lombok + + + + + ${project.groupId} + nostr-java-client + ${project.version} + + + ${project.groupId} + nostr-java-util + ${project.version} + + + ${project.groupId} + nostr-java-api + ${project.version} + + + + + org.junit.jupiter + junit-jupiter-api + + + com.google.guava + guava + ${guava.version} + + diff --git a/pom.xml b/pom.xml index edb541038..fc3616731 100644 --- a/pom.xml +++ b/pom.xml @@ -74,28 +74,23 @@ + 0.6.5-SNAPSHOT 21 3.3.5 - - ${version} - 3.17.0 - 1.18.34 ${java.version} ${java.version} - UTF-8 + 1.18.34 + 3.17.0 1.70 1.78 - 2.17.2 2.18.3 - 3.17.0 5.10.2 - 3.23.1 3.13.0 @@ -128,11 +123,7 @@ spring-boot-devtools ${spring-boot.version} - - org.springframework.boot - spring-boot-starter-websocket - ${spring-boot.version} - + org.springframework.boot spring-boot-configuration-processor @@ -159,22 +150,20 @@ bcprov-jdk18on ${bcprov-jdk18on.version} - - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - + org.springframework.boot spring-boot-starter-test ${spring-boot.version} test - + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + From 8db999e71c12c02127b477761986366093e75e85 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 20:56:35 -0700 Subject: [PATCH 06/57] spring boot version up --- nostr-java-test/pom.xml | 2 +- pom.xml | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml index 48a181f66..5fb60fe86 100644 --- a/nostr-java-test/pom.xml +++ b/nostr-java-test/pom.xml @@ -13,7 +13,7 @@ jar - 33.2.1-jre + 33.4.0-jre diff --git a/pom.xml b/pom.xml index fc3616731..1b89f3461 100644 --- a/pom.xml +++ b/pom.xml @@ -76,19 +76,18 @@ 0.6.5-SNAPSHOT 21 - 3.3.5 + 3.4.3 ${java.version} ${java.version} UTF-8 + 2.18.3 1.18.34 3.17.0 1.70 1.78 - 2.18.3 - 5.10.2 @@ -102,7 +101,6 @@ - org.springframework.boot spring-boot @@ -123,7 +121,6 @@ spring-boot-devtools ${spring-boot.version} - org.springframework.boot spring-boot-configuration-processor From a4124b5f3e06d3bcd56f310a3229a1769765df17 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 21:17:38 -0700 Subject: [PATCH 07/57] old modules pom cruft leaned out --- nostr-java-api/pom.xml | 5 ++--- nostr-java-examples/pom.xml | 6 +----- nostr-java-id/pom.xml | 3 --- nostr-java-util/pom.xml | 17 ++++++++++++++--- pom.xml | 4 ++-- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 3d0fe24b1..cdee97652 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -6,8 +6,10 @@ nostr-java 0.6.5-SNAPSHOT + nostr-java-api jar + ${project.groupId} @@ -40,7 +42,4 @@ ${commons-lang3.version} - - nostr.java.api.NostrJavaApi - diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 5fa7b1fe7..24811cfac 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -12,10 +12,6 @@ nostr-java-examples jar - - nostr.examples.NostrApiExamples - - @@ -44,4 +40,4 @@ ${project.version} - \ No newline at end of file + diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index c3a2e4af5..806b96c32 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -12,9 +12,6 @@ nostr-java-id jar - - - diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 7dc6acd13..9dad03e70 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -12,9 +12,9 @@ nostr-java-util jar - - nostr.util.NostrUtil - + + + @@ -22,5 +22,16 @@ org.projectlombok lombok + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/pom.xml b/pom.xml index 1b89f3461..149930b9a 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.3.1 attach-sources @@ -195,7 +195,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 + 3.10.1 attach-javadocs From 47f2df72b82c5fae4e1ab48d78b9b907f3fc82f6 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 11 Mar 2025 21:37:26 -0700 Subject: [PATCH 08/57] removed duplicate transitive pom dependencies --- nostr-java-api/pom.xml | 15 --------------- nostr-java-client/pom.xml | 10 ---------- nostr-java-encryption/pom.xml | 5 ----- nostr-java-event/pom.xml | 7 +------ nostr-java-examples/pom.xml | 20 -------------------- nostr-java-id/pom.xml | 15 --------------- 6 files changed, 1 insertion(+), 71 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index cdee97652..6c4e0877b 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -11,21 +11,6 @@ jar - - ${project.groupId} - nostr-java-base - ${project.version} - - - ${project.groupId} - nostr-java-event - ${project.version} - - - ${project.groupId} - nostr-java-id - ${project.version} - ${project.groupId} nostr-java-client diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 3806805fd..9791f6715 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -25,16 +25,6 @@ ${spring-boot.version} - - ${project.groupId} - nostr-java-event - ${project.version} - - - ${project.groupId} - nostr-java-base - ${project.version} - ${project.groupId} nostr-java-id diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 9b0e745fa..5e4d8b155 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -27,10 +27,5 @@ nostr-java-crypto ${project.version} - - ${project.groupId} - nostr-java-util - ${project.version} - diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 44581be69..bd55ebdc2 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -25,10 +25,5 @@ nostr-java-base ${project.version} - - ${project.groupId} - nostr-java-util - ${project.version} - - \ No newline at end of file + diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 24811cfac..3ed2cc91e 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -14,26 +14,6 @@ - - ${project.groupId} - nostr-java-event - ${project.version} - - - ${project.groupId} - nostr-java-base - ${project.version} - - - ${project.groupId} - nostr-java-id - ${project.version} - - - ${project.groupId} - nostr-java-client - ${project.version} - ${project.groupId} nostr-java-api diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 806b96c32..d09d26295 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -20,25 +20,10 @@ - - ${project.groupId} - nostr-java-base - ${project.version} - ${project.groupId} nostr-java-event ${project.version} - - ${project.groupId} - nostr-java-util - ${project.version} - - - ${project.groupId} - nostr-java-crypto - ${project.version} - From fbf770d8251e6f8998cd7412a635e554cc7c413a Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 12 Mar 2025 12:01:05 -0700 Subject: [PATCH 09/57] successful groovy compilation --- build.gradle | 79 +++++++++++++++++++ nostr-java-api/build.gradle | 13 ++- nostr-java-base/build.gradle | 10 +-- nostr-java-client/build.gradle | 23 +++--- nostr-java-crypto/build.gradle | 11 ++- nostr-java-encryption/build.gradle | 9 +-- nostr-java-event/build.gradle | 10 +-- nostr-java-examples/build.gradle | 12 +-- nostr-java-id/build.gradle | 12 +-- nostr-java-test/build.gradle | 32 ++++---- .../test/resources/junit-platform.properties | 7 ++ nostr-java-util/build.gradle | 16 ++-- 12 files changed, 152 insertions(+), 82 deletions(-) create mode 100644 build.gradle create mode 100644 nostr-java-test/src/test/resources/junit-platform.properties diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..b2c6a4bd9 --- /dev/null +++ b/build.gradle @@ -0,0 +1,79 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.4.3' + id 'io.spring.dependency-management' version '1.1.7' + + id 'io.freefair.lombok' version '8.12.2.1' + id 'com.adarshr.test-logger' version '4.0.0' + id 'org.gradle.test-retry' version '1.6.2' + + id 'groovy-gradle-plugin' + id 'java-library' +} + +group = 'xyz.tcheeric' +version = '0.6.5-SNAPSHOT' +description = 'nostr-java' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + gradlePluginPortal() + mavenLocal() + mavenCentral() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +dependencies { + developmentOnly 'org.springframework.boot:spring-boot-devtools:3.4.3' + + implementation 'org.springframework.boot:spring-boot-starter:3.4.3' + implementation 'org.springframework.boot:spring-boot-autoconfigure:3.4.3' + implementation 'org.springframework.boot:spring-boot-configuration-processor:3.4.3' + implementation 'org.apache.commons:commons-lang3:3.17.0' + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.80' + + implementation 'org.springframework.boot:spring-boot-starter-validation:3.4.3' + implementation 'org.springframework.boot:spring-boot-starter-websocket:3.4.3' + + implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:2.18.3' + implementation 'com.google.guava:guava:33.2.1-jre' + + testImplementation 'org.awaitility:awaitility:4.2.0' + testImplementation 'org.springframework.boot:spring-boot-starter-test:3.4.3' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + implementation 'org.projectlombok:lombok:1.18.36' + annotationProcessor 'org.projectlombok:lombok:1.18.36' + + testImplementation 'org.projectlombok:lombok:1.18.36' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.36' +} + +tasks.named('test') { + useJUnitPlatform() +} + +test { + retry { +// failOnPassedAfterRetry = true + maxRetries = 2 +// maxFailures = 42 + } +} + +bootJar { + enabled = false +} diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index 9a0387737..fa4422da6 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -1,18 +1,15 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api project(':nostr-java-base') - api project(':nostr-java-event') - api project(':nostr-java-id') + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-client') api project(':nostr-java-encryption') - api libs.org.apache.commons.commons.lang3 + implementation libs.org.apache.commons.commons.lang3 } description = 'nostr-java-api' diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index fe98223a3..25d03e8f8 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -1,14 +1,12 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok - api libs.com.fasterxml.jackson.module.jackson.module.afterburner + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-util') api project(':nostr-java-crypto') } diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index d8429f4cb..02160c245 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -1,21 +1,20 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api project(':nostr-java-event') - api project(':nostr-java-base') + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-id') - api libs.org.springframework.spring.websocket - api libs.jakarta.websocket.jakarta.websocket.api - api libs.jakarta.websocket.jakarta.websocket.client.api - api libs.org.springframework.spring.webflux - api libs.io.projectreactor.netty.reactor.netty.http - api libs.org.awaitility.awaitility + implementation libs.org.springframework.boot.spring.boot.starter.websocket + implementation libs.org.springframework.spring.websocket + implementation libs.org.springframework.spring.webflux + implementation libs.io.projectreactor.netty.reactor.netty.http + implementation libs.jakarta.websocket.jakarta.websocket.api + implementation libs.jakarta.websocket.jakarta.websocket.client.api + implementation libs.org.awaitility.awaitility } description = 'nostr-java-client' diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index 3b92a318b..d95782445 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -1,14 +1,13 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok - api libs.org.bouncycastle.bcprov.jdk18on + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + implementation libs.org.bouncycastle.bcprov.jdk18on api project(':nostr-java-util') } diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 9b32bfd80..008cbd7b0 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -1,13 +1,12 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-crypto') api project(':nostr-java-util') } diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index 06e752237..a40232f88 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -1,15 +1,13 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-base') - api project(':nostr-java-util') } description = 'nostr-java-event' diff --git a/nostr-java-examples/build.gradle b/nostr-java-examples/build.gradle index 0bb3535cc..732cd607f 100644 --- a/nostr-java-examples/build.gradle +++ b/nostr-java-examples/build.gradle @@ -1,16 +1,12 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api project(':nostr-java-event') - api project(':nostr-java-base') - api project(':nostr-java-id') - api project(':nostr-java-client') + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-api') } diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index ee22d2fb3..11a25f7fd 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -1,17 +1,13 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok - api project(':nostr-java-base') + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-event') - api project(':nostr-java-util') - api project(':nostr-java-crypto') } description = 'nostr-java-id' diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle index 5dcb7d356..6a0253fb2 100644 --- a/nostr-java-test/build.gradle +++ b/nostr-java-test/build.gradle @@ -1,27 +1,23 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok - api project(':nostr-java-event') - api project(':nostr-java-base') - api project(':nostr-java-util') + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + testImplementation libs.org.projectlombok.lombok + testAnnotationProcessor libs.org.projectlombok.lombok + + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + api project(':nostr-java-client') - api libs.org.springframework.spring.websocket - api libs.jakarta.websocket.jakarta.websocket.api - api libs.jakarta.websocket.jakarta.websocket.client.api - api libs.org.springframework.spring.webflux - api libs.io.projectreactor.netty.reactor.netty.http - testImplementation project(':nostr-java-id') - testImplementation libs.org.junit.jupiter.junit.jupiter.engine - testImplementation project(':nostr-java-api') - testImplementation libs.org.awaitility.awaitility - testImplementation libs.com.google.guava.guava + api project(':nostr-java-util') + api project(':nostr-java-api') + implementation libs.com.google.guava.guava + testImplementation libs.org.junit.jupiter.junit.jupiter.api } description = 'nostr-java-test' diff --git a/nostr-java-test/src/test/resources/junit-platform.properties b/nostr-java-test/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-test/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index cda9bd19d..564e30461 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -1,13 +1,19 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'buildlogic.java-conventions' } dependencies { - api libs.org.projectlombok.lombok + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + testImplementation libs.org.projectlombok.lombok + testAnnotationProcessor libs.org.projectlombok.lombok + + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + testImplementation libs.org.springframework.boot.spring.boot.starter.test + testImplementation libs.org.junit.jupiter.junit.jupiter.api } description = 'nostr-java-util' From e9e360e4e1012b60a11f21fb7955c41ff344547b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 12 Mar 2025 14:43:09 -0700 Subject: [PATCH 10/57] per module local maven publish --- .gitignore | 2 - buildSrc/build.gradle | 45 +++++++++++++++++++ .../groovy/buildlogic.java-conventions.gradle | 39 ++++++++++++++++ nostr-java-api/build.gradle | 9 ++++ nostr-java-base/build.gradle | 9 ++++ nostr-java-client/build.gradle | 9 ++++ nostr-java-crypto/build.gradle | 9 ++++ nostr-java-encryption/build.gradle | 9 ++++ nostr-java-event/build.gradle | 9 ++++ nostr-java-examples/build.gradle | 9 ++++ nostr-java-id/build.gradle | 9 ++++ nostr-java-test/build.gradle | 9 ++++ nostr-java-util/build.gradle | 9 ++++ 13 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/buildlogic.java-conventions.gradle diff --git a/.gitignore b/.gitignore index a7b31a6f2..267d6bffe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - # Created by https://www.gitignore.io/api/java,eclipse,java-web,code-java,intellij+all,visualstudiocode # Edit at https://www.gitignore.io/?templates=java,eclipse,java-web,code-java,intellij+all,visualstudiocode @@ -218,7 +217,6 @@ build/ gradle/ gradlew gradlew.bat -buildSrc/ ### VisualStudioCode ### .vscode diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 000000000..b11a5e916 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,45 @@ +plugins { +// id 'java' +// id 'io.freefair.lombok' version '8.12.2.1' + id 'groovy-gradle-plugin' +} + +repositories { + gradlePluginPortal() + mavenLocal() + mavenCentral() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +dependencies { + def springBootVersion = '3.4.3' + def apacheCommonsLang3 = '3.17.0' + def jacksonModuleAfterburner = '2.18.3' + def googleGuava = '33.2.1-jre' + def bouncyCastle = '1.80' + def awaitility = '4.2.0' + def lombok = '1.18.36' + + implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion + implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle + + implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion + + implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner + implementation 'com.google.guava:guava:' + googleGuava + + testImplementation 'org.awaitility:awaitility:' + awaitility + testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + implementation 'org.projectlombok:lombok:' + lombok + annotationProcessor 'org.projectlombok:lombok:' + lombok + testImplementation 'org.projectlombok:lombok:' + lombok + testAnnotationProcessor 'org.projectlombok:lombok:' + lombok +} diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle new file mode 100644 index 000000000..53a1dea97 --- /dev/null +++ b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle @@ -0,0 +1,39 @@ +plugins { + id 'java' + id 'java-library' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +group = 'xyz.tcheeric' +version = '0.6.5-SNAPSHOT' +description = 'nostr-java' +java.sourceCompatibility = JavaVersion.VERSION_21 +java.targetCompatibility = JavaVersion.VERSION_21 + +subprojects { + publishing { + publications { + maven(MavenPublication) { +// groupId = 'xyz.tcheeric' + artifactId = description +// version = '0.6.5-SNAPSHOT' + from(components.java) + } + } + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} + +tasks.withType(Javadoc).configureEach { + options.encoding = 'UTF-8' +} diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index fa4422da6..85fff8353 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -13,3 +13,12 @@ dependencies { } description = 'nostr-java-api' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index 25d03e8f8..5d7f94a3c 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -12,3 +12,12 @@ dependencies { } description = 'nostr-java-base' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index 02160c245..f9493cc58 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -18,3 +18,12 @@ dependencies { } description = 'nostr-java-client' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index d95782445..c07b99e89 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -12,3 +12,12 @@ dependencies { } description = 'nostr-java-crypto' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 008cbd7b0..62882ab52 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -12,3 +12,12 @@ dependencies { } description = 'nostr-java-encryption' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index a40232f88..3f0a2d5fd 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -11,3 +11,12 @@ dependencies { } description = 'nostr-java-event' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-examples/build.gradle b/nostr-java-examples/build.gradle index 732cd607f..01f602b16 100644 --- a/nostr-java-examples/build.gradle +++ b/nostr-java-examples/build.gradle @@ -11,3 +11,12 @@ dependencies { } description = 'nostr-java-examples' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index 11a25f7fd..3f3d72c72 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -11,3 +11,12 @@ dependencies { } description = 'nostr-java-id' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle index 6a0253fb2..9215c7d3b 100644 --- a/nostr-java-test/build.gradle +++ b/nostr-java-test/build.gradle @@ -21,3 +21,12 @@ dependencies { } description = 'nostr-java-test' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index 564e30461..8653a7b8e 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -17,3 +17,12 @@ dependencies { } description = 'nostr-java-util' + +publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } +} From dc35b8712b0272d5614cd23f58833bac05ce2388 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 12 Mar 2025 15:41:58 -0700 Subject: [PATCH 11/57] publish local after build. --- buildSrc/src/main/groovy/buildlogic.java-conventions.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle index 53a1dea97..ac500743d 100644 --- a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle +++ b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle @@ -37,3 +37,7 @@ tasks.withType(JavaCompile).configureEach { tasks.withType(Javadoc).configureEach { options.encoding = 'UTF-8' } + +tasks.build.finalizedBy() { + tasks.publishToMavenLocal +} From 89189c5c4b9767a2cac6d7da4032f097722ed2cf Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 12 Mar 2025 17:29:08 -0700 Subject: [PATCH 12/57] test customiations --- .../groovy/buildlogic.java-conventions.gradle | 8 +-- .../src/main/java/nostr/base/Relay.java | 3 - .../main/java/nostr/event/tag/PriceTag.java | 66 +++++++++---------- nostr-java-test/build.gradle | 38 ++++++++--- .../nostr/test/event/APINIP09EventTest.java | 2 + .../java/nostr/test/event/ApiEventTest.java | 2 + .../java/nostr/test/event/PriceTagTest.java | 43 +++++++----- 7 files changed, 95 insertions(+), 67 deletions(-) diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle index ac500743d..5d1f0cceb 100644 --- a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle +++ b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle @@ -21,9 +21,7 @@ subprojects { publishing { publications { maven(MavenPublication) { -// groupId = 'xyz.tcheeric' artifactId = description -// version = '0.6.5-SNAPSHOT' from(components.java) } } @@ -38,6 +36,6 @@ tasks.withType(Javadoc).configureEach { options.encoding = 'UTF-8' } -tasks.build.finalizedBy() { - tasks.publishToMavenLocal -} +//tasks.build.finalizedBy() { +// tasks.publishToMavenLocal +//} 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 20dc5f8fa..e40aa0e77 100644 --- a/nostr-java-base/src/main/java/nostr/base/Relay.java +++ b/nostr-java-base/src/main/java/nostr/base/Relay.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -34,8 +33,6 @@ public class Relay { @ToString.Include private String host; - @ToString.Exclude - @EqualsAndHashCode.Exclude private RelayInformationDocument informationDocument; public Relay(@NonNull String uri) { 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 1b9ce70ec..dac11842f 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 @@ -7,7 +7,6 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.NonNull; import lombok.RequiredArgsConstructor; import nostr.base.annotation.Key; @@ -20,51 +19,48 @@ @Builder @Data -@EqualsAndHashCode(callSuper = true) @Tag(code = "price", nip = 99) @RequiredArgsConstructor @AllArgsConstructor @JsonPropertyOrder({"number", "currency", "frequency"}) public class PriceTag extends BaseTag { - @Key - @JsonProperty - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal number; + @Key + @JsonProperty + @JsonFormat(shape = JsonFormat.Shape.STRING) + private BigDecimal number; - @Key - @JsonProperty - private String currency; + @Key + @JsonProperty + private String currency; - @Key - @JsonProperty - private String frequency; + @Key + @JsonProperty + private String frequency; - public static T deserialize(@NonNull JsonNode node) { - String text = Optional.ofNullable(node.get(1)).orElseThrow().asText(); - final BigDecimal number = new BigDecimal(text); - final String currency = Optional.ofNullable(node.get(2)).orElseThrow().asText(); + public static T deserialize(@NonNull JsonNode node) { + String text = Optional.ofNullable(node.get(1)).orElseThrow().asText(); + final BigDecimal number = new BigDecimal(text); + final String currency = Optional.ofNullable(node.get(2)).orElseThrow().asText(); - PriceTag tag = PriceTag.builder().number(number).currency(currency).build(); - Optional.ofNullable(node.get(3)).ifPresent(jsonNode1 -> tag.setFrequency(jsonNode1.asText())); + PriceTag tag = PriceTag.builder().number(number).currency(currency).build(); + Optional.ofNullable(node.get(3)).ifPresent(jsonNode1 -> tag.setFrequency(jsonNode1.asText())); - return (T) tag; - } + return (T) tag; + } - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - PriceTag priceTag = (PriceTag) o; - return Objects.equals( - number.stripTrailingZeros(), - priceTag.number.stripTrailingZeros() - ) - && Objects.equals(currency, priceTag.currency) && Objects.equals(frequency, priceTag.frequency); - } + @Override + public boolean equals(Object o) { + return super.equals(o) && + Objects.equals( + number.stripTrailingZeros(), + ((PriceTag) o).number.stripTrailingZeros() + ) + && Objects.equals(currency, ((PriceTag) o).currency) && Objects.equals(frequency, ((PriceTag) o).frequency); + } - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), number.stripTrailingZeros(), currency, frequency); - } + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), number.stripTrailingZeros(), currency, frequency); + } } diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle index 9215c7d3b..65555e4ee 100644 --- a/nostr-java-test/build.gradle +++ b/nostr-java-test/build.gradle @@ -12,21 +12,41 @@ dependencies { testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + + implementation libs.com.google.guava.guava + implementation libs.org.springframework.boot.spring.boot.starter.test + implementation libs.org.junit.jupiter.junit.jupiter.api + + testImplementation libs.com.google.guava.guava + testImplementation libs.org.springframework.boot.spring.boot.starter.test + testImplementation libs.org.junit.jupiter.junit.jupiter.api api project(':nostr-java-client') api project(':nostr-java-util') api project(':nostr-java-api') - implementation libs.com.google.guava.guava - testImplementation libs.org.junit.jupiter.junit.jupiter.api } description = 'nostr-java-test' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +// no publishing for test module +//publishing { +// publications { +// maven(MavenPublication) { +// artifactId = description +// from(components.java) +// } +// } +//} + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() } + +//test { +// retry { +// failOnPassedAfterRetry = false +// maxRetries = 2 +//// maxFailures = 42 +// } +//} diff --git a/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java index f44849bbf..3c5ef09a7 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java @@ -18,6 +18,7 @@ import nostr.event.tag.IdentifierTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; import java.io.IOException; import java.util.List; @@ -30,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +@ActiveProfiles("test") public class APINIP09EventTest { private static final String RELAY_URI = "ws://localhost:5555"; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java index ce29313a2..78c8942b8 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java @@ -41,6 +41,7 @@ import nostr.id.Identity; import nostr.util.NostrException; import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; import java.io.IOException; import java.io.InputStream; @@ -62,6 +63,7 @@ /** * @author eric */ +@ActiveProfiles("test") public class ApiEventTest { public static final String NOSTR_JAVA_PUBKEY = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; diff --git a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java index 5ac05f937..81e4c8c03 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java @@ -2,6 +2,7 @@ import nostr.event.tag.PriceTag; import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; import java.lang.reflect.Field; import java.math.BigDecimal; @@ -30,35 +31,35 @@ class PriceTagTest { @Test void valueParameterCompare() { List list = Stream.of( - aVal, bVal, cVal, dVal, eVal) - .map(bigDecimal -> - new PriceTag(bigDecimal, BTC, freq)).toList(); + aVal, bVal, cVal, dVal, eVal) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); assertTrue(list.stream().allMatch(list.getFirst()::equals)); } @Test void stringParameterCompare() { List list = Stream.of( - aString, bString, cString, dString, eString) - .map(bigDecimal -> - new PriceTag(bigDecimal, BTC, freq)).toList(); + aString, bString, cString, dString, eString) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); assertTrue(list.stream().allMatch(list.getFirst()::equals)); } @Test void failure() { List priceTags = List.of( - new PriceTag(new BigDecimal("1"), BTC, freq), - new PriceTag(new BigDecimal("01"), BTC, freq), - new PriceTag(new BigDecimal("001"), BTC, freq), - new PriceTag(new BigDecimal(1), BTC, freq), - new PriceTag(new BigDecimal(01), BTC, freq), - new PriceTag(new BigDecimal(001), BTC, freq) + new PriceTag(new BigDecimal("1"), BTC, freq), + new PriceTag(new BigDecimal("01"), BTC, freq), + new PriceTag(new BigDecimal("001"), BTC, freq), + new PriceTag(new BigDecimal(1), BTC, freq), + new PriceTag(new BigDecimal(01), BTC, freq), + new PriceTag(new BigDecimal(001), BTC, freq) ); List list = Stream.of( - aString, bString, cString, dString, eString) - .map(bigDecimal -> - new PriceTag(bigDecimal, BTC, freq)).toList(); + aString, bString, cString, dString, eString) + .map(bigDecimal -> + new PriceTag(bigDecimal, BTC, freq)).toList(); assertTrue(list.stream().noneMatch(priceTags::equals)); } @@ -71,4 +72,16 @@ void getSupportedFields() { assertTrue(List.of("java.math.BigDecimal", "java.lang.String").containsAll(list.stream().map(field -> field.getAnnotatedType().toString()).toList())); }); } + + @Test + void donothing() { + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + System.out.println("00000000000000000000000000000"); + } } From df4b5ca4ebc6777a06eafaed2d758965d11c819a Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 12 Mar 2025 18:45:23 -0700 Subject: [PATCH 13/57] daemon conf --- gradle.properties | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 377538c99..90caf12dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,3 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties - org.gradle.configuration-cache=true +org.gradle.daemon=true From 75dfa345968fa6c08af2c6e0c7214b70b405afb2 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 13 Mar 2025 11:41:19 -0700 Subject: [PATCH 14/57] tags deserialization cleanup, introduce basttag consumer --- nostr-java-event/build.gradle | 4 +++ .../src/main/java/nostr/event/BaseTag.java | 31 ++++++++++++------- .../event/json/codec/BaseTagEncoder.java | 9 ++---- .../main/java/nostr/event/tag/EventTag.java | 21 +++---------- .../main/java/nostr/event/tag/PubKeyTag.java | 20 ++---------- .../main/java/nostr/event/tag/SubjectTag.java | 8 ++--- 6 files changed, 37 insertions(+), 56 deletions(-) diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index 3f0a2d5fd..f912a8f91 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -7,6 +7,10 @@ dependencies { annotationProcessor libs.org.projectlombok.lombok implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + + implementation libs.org.apache.commons.commons.lang3 + implementation libs.com.google.guava.guava + api project(':nostr-java-base') } 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 c3a50a909..afacf153e 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -1,6 +1,7 @@ package nostr.event; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Data; @@ -13,14 +14,20 @@ import nostr.base.annotation.Tag; import nostr.event.json.deserializer.TagDeserializer; import nostr.event.json.serializer.TagSerializer; +import nostr.event.tag.EventTag; import nostr.util.NostrException; +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.ArrayList; +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; /** * @@ -44,8 +51,7 @@ public void setParent(IEvent event) { @Override public String getCode() { - var tag = this.getClass().getAnnotation(Tag.class); - return tag.code(); + return this.getClass().getAnnotation(Tag.class).code(); } @Override @@ -63,14 +69,15 @@ public String getFieldValue(Field field) throws NostrException { } public List getSupportedFields() throws NostrException { - var fields = this.getClass().getDeclaredFields(); - List fieldList = new ArrayList<>(); - for (Field f : fields) { - if (null != f.getAnnotation(Key.class) && null != getFieldValue(f)) { - fieldList.add(f); - } - } - - return fieldList; + return new Streams.FailableStream<>(Arrays.stream(this.getClass().getDeclaredFields())) + .filter(f -> + Objects.nonNull(f.getAnnotation(Key.class))) + .filter(f -> + Objects.nonNull(getFieldValue(f))) + .collect(Collectors.toList()); + } + + protected static void setTagFields(JsonNode node, BiConsumer con, T tag) { + Optional.ofNullable(node).ifPresent(n -> con.accept(n, tag)); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java index 9dc9dc6f8..403241d7f 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import lombok.AllArgsConstructor; - import lombok.Data; import lombok.NonNull; import nostr.base.IEncoder; @@ -15,7 +14,6 @@ /** * @author guilhermegps - * */ @Data @AllArgsConstructor @@ -31,13 +29,12 @@ public BaseTagEncoder(@NonNull BaseTag tag) { @Override public String encode() { try { +// TODO: revisit below using afterburner alternative SimpleModule module = new SimpleModule(); module.addSerializer(new TagSerializer()); - var mapper = (new ObjectMapper()) + return (new ObjectMapper()) .setSerializationInclusion(Include.NON_NULL) - .registerModule(module); - - return mapper.writeValueAsString(tag); + .registerModule(module).writeValueAsString(tag); } catch (JsonProcessingException e) { throw new RuntimeException(e); } 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 ea42f1094..e6f16068c 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 @@ -21,7 +21,6 @@ import nostr.event.Marker; /** - * * @author squirrel */ @Builder @@ -55,23 +54,13 @@ public EventTag(String idEvent) { //this.marker = this.idEvent == null ? Marker.ROOT : Marker.REPLY; } +// tag.setMarker(Marker.valueOf(nodeMarker.asText().toUpperCase())); + public static T deserialize(@NonNull JsonNode node) { EventTag tag = new EventTag(); - - final JsonNode nodeIdEvent = node.get(1); - if (nodeIdEvent != null) { - tag.setIdEvent(nodeIdEvent.asText()); - } - - final JsonNode nodeRelay = node.get(2); - if (nodeRelay != null) { - tag.setRecommendedRelayUrl(nodeRelay.asText()); - } - - final JsonNode nodeMarker = node.get(3); - if (nodeMarker != null) { - tag.setMarker(Marker.valueOf(nodeMarker.asText().toUpperCase())); - } + setTagFields(node.get(1), (n, t) -> tag.setIdEvent(n.asText()), tag); + setTagFields(node.get(2), (n, t) -> tag.setRecommendedRelayUrl(n.asText()), tag); + setTagFields(node.get(3), (n, t) -> tag.setMarker(Marker.valueOf(n.asText().toUpperCase())), tag); return (T) tag; } } 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 60749556a..3ad9bc5fc 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 @@ -20,7 +20,6 @@ import nostr.event.BaseTag; /** - * * @author squirrel */ @JsonPropertyOrder({"pubKey", "mainRelayUrl", "petName"}) @@ -57,22 +56,9 @@ public PubKeyTag(@NonNull PublicKey publicKey, String mainRelayUrl, String petNa public static T deserialize(@NonNull JsonNode node) { PubKeyTag tag = new PubKeyTag(); - - final JsonNode nodePubKey = node.get(1); - if (nodePubKey != null) { - tag.setPublicKey(new PublicKey(nodePubKey.asText())); - } - - final JsonNode nodeMainUrl = node.get(2); - if (nodeMainUrl != null) { - tag.setMainRelayUrl(nodeMainUrl.asText()); - } - - final JsonNode nodePetName = node.get(3); - if (nodePetName != null) { - tag.setPetName(nodePetName.asText()); - } - + setTagFields(node.get(1), (n, t) -> tag.setPublicKey(new PublicKey(n.asText())), tag); + setTagFields(node.get(2), (n, t) -> tag.setMainRelayUrl(n.asText()), tag); + setTagFields(node.get(3), (n, t) -> tag.setPetName(n.asText()), tag); return (T) tag; } } 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 533493b59..845bcc132 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 @@ -14,6 +14,8 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; +import java.util.Optional; + /** * * @author squirrel @@ -33,11 +35,7 @@ public final class SubjectTag extends BaseTag { public static T deserialize(@NonNull JsonNode node) { SubjectTag tag = new SubjectTag(); - - final JsonNode nodeSubject = node.get(1); - if (nodeSubject != null) { - tag.setSubject(nodeSubject.asText()); - } + setTagFields(node.get(1), (n, t) -> tag.setSubject(n.asText()), tag); return (T) tag; } } From 87db88b01ee06247efff1886270fd9e23ee04246 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 13 Mar 2025 13:43:33 -0700 Subject: [PATCH 15/57] remaining tags serialize() implementation modernization --- .../src/main/java/nostr/event/BaseTag.java | 10 +++++---- .../main/java/nostr/event/tag/EventTag.java | 13 +++-------- .../main/java/nostr/event/tag/GeohashTag.java | 10 ++------- .../main/java/nostr/event/tag/HashtagTag.java | 8 +------ .../java/nostr/event/tag/IdentifierTag.java | 8 +------ .../main/java/nostr/event/tag/NonceTag.java | 17 ++++---------- .../main/java/nostr/event/tag/PriceTag.java | 12 ++++------ .../main/java/nostr/event/tag/PubKeyTag.java | 6 ++--- .../main/java/nostr/event/tag/RelaysTag.java | 22 +++++++++---------- .../main/java/nostr/event/tag/SubjectTag.java | 4 +--- .../resources/application-test.properties | 4 ++++ 11 files changed, 40 insertions(+), 74 deletions(-) create mode 100644 nostr-java-test/src/test/resources/application-test.properties 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 afacf153e..f8a7bd2e2 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -14,7 +14,6 @@ import nostr.base.annotation.Tag; import nostr.event.json.deserializer.TagDeserializer; import nostr.event.json.serializer.TagSerializer; -import nostr.event.tag.EventTag; import nostr.util.NostrException; import org.apache.commons.lang3.stream.Streams; @@ -30,7 +29,6 @@ import java.util.stream.Collectors; /** - * * @author squirrel */ @Data @@ -76,8 +74,12 @@ public List getSupportedFields() throws NostrException { Objects.nonNull(getFieldValue(f))) .collect(Collectors.toList()); } - - protected static void setTagFields(JsonNode node, BiConsumer con, T tag) { + + protected static void setOptionalField(JsonNode node, BiConsumer con, T tag) { Optional.ofNullable(node).ifPresent(n -> con.accept(n, tag)); } + + protected static void setRequiredField(JsonNode node, BiConsumer con, T tag) { + con.accept(Optional.ofNullable(node).orElseThrow(), 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 e6f16068c..bbc55abe0 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 @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package nostr.event.tag; import com.fasterxml.jackson.annotation.JsonInclude; @@ -54,13 +49,11 @@ public EventTag(String idEvent) { //this.marker = this.idEvent == null ? Marker.ROOT : Marker.REPLY; } -// tag.setMarker(Marker.valueOf(nodeMarker.asText().toUpperCase())); - public static T deserialize(@NonNull JsonNode node) { EventTag tag = new EventTag(); - setTagFields(node.get(1), (n, t) -> tag.setIdEvent(n.asText()), tag); - setTagFields(node.get(2), (n, t) -> tag.setRecommendedRelayUrl(n.asText()), tag); - setTagFields(node.get(3), (n, t) -> tag.setMarker(Marker.valueOf(n.asText().toUpperCase())), tag); + 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; } } 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 96302d378..054804a33 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 @@ -13,7 +13,6 @@ import nostr.event.BaseTag; /** - * * @author eric */ @Builder @@ -23,19 +22,14 @@ @NoArgsConstructor @AllArgsConstructor public class GeohashTag extends BaseTag { - + @Key @JsonProperty("g") private String location; public static T deserialize(@NonNull JsonNode node) { GeohashTag tag = new GeohashTag(); - - final JsonNode nodePubKey = node.get(1); - if (nodePubKey != null) { - tag.setLocation(nodePubKey.asText()); - } - + setRequiredField(node.get(1), (n, t) -> tag.setLocation(n.asText()), tag); return (T) tag; } } 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 da33f509b..ea1f35c8d 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 @@ -13,7 +13,6 @@ import nostr.event.BaseTag; /** - * * @author eric */ @Builder @@ -30,12 +29,7 @@ public class HashtagTag extends BaseTag { public static T deserialize(@NonNull JsonNode node) { HashtagTag tag = new HashtagTag(); - - final JsonNode nodePubKey = node.get(1); - if (nodePubKey != null) { - tag.setHashTag(nodePubKey.asText()); - } - + setRequiredField(node.get(1), (n, t) -> tag.setHashTag(n.asText()), tag); return (T) tag; } } 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 93ed02345..8f1d98cf9 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 @@ -13,7 +13,6 @@ import nostr.event.BaseTag; /** - * * @author eric */ @Builder @@ -30,12 +29,7 @@ public class IdentifierTag extends BaseTag { public static T deserialize(@NonNull JsonNode node) { IdentifierTag tag = new IdentifierTag(); - - final JsonNode nodePubKey = node.get(1); - if (nodePubKey != null) { - tag.setId(nodePubKey.asText()); - } - + setRequiredField(node.get(1), (n, t) -> tag.setId(n.asText()), tag); return (T) tag; } } 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 cec19b4dc..370bd8cd7 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 @@ -4,17 +4,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; -import nostr.base.annotation.Key; -import nostr.event.BaseTag; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; +import nostr.base.annotation.Key; import nostr.base.annotation.Tag; +import nostr.event.BaseTag; /** - * * @author squirrel */ @Builder @@ -40,16 +39,8 @@ public NonceTag(@NonNull Integer nonce, @NonNull Integer difficulty) { public static T deserialize(@NonNull JsonNode node) { NonceTag tag = new NonceTag(); - - final JsonNode nodeNonce = node.get(1); - if (nodeNonce != null) { - tag.setNonce(Integer.valueOf(nodeNonce.asText())); - } - - final JsonNode nodeDifficulty = node.get(2); - if (nodeDifficulty != null) { - tag.setDifficulty(Integer.valueOf(nodeDifficulty.asText())); - } + setRequiredField(node.get(1), (n, t) -> tag.setNonce(Integer.valueOf(n.asText())), tag); + setRequiredField(node.get(2), (n, t) -> tag.setDifficulty(Integer.valueOf(n.asText())), tag); return (T) tag; } } 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 dac11842f..60aeabb8d 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 @@ -15,7 +15,6 @@ import java.math.BigDecimal; import java.util.Objects; -import java.util.Optional; @Builder @Data @@ -39,13 +38,10 @@ public class PriceTag extends BaseTag { private String frequency; public static T deserialize(@NonNull JsonNode node) { - String text = Optional.ofNullable(node.get(1)).orElseThrow().asText(); - final BigDecimal number = new BigDecimal(text); - final String currency = Optional.ofNullable(node.get(2)).orElseThrow().asText(); - - PriceTag tag = PriceTag.builder().number(number).currency(currency).build(); - Optional.ofNullable(node.get(3)).ifPresent(jsonNode1 -> tag.setFrequency(jsonNode1.asText())); - + 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; } 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 3ad9bc5fc..2c725de4f 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 @@ -56,9 +56,9 @@ public PubKeyTag(@NonNull PublicKey publicKey, String mainRelayUrl, String petNa public static T deserialize(@NonNull JsonNode node) { PubKeyTag tag = new PubKeyTag(); - setTagFields(node.get(1), (n, t) -> tag.setPublicKey(new PublicKey(n.asText())), tag); - setTagFields(node.get(2), (n, t) -> tag.setMainRelayUrl(n.asText()), tag); - setTagFields(node.get(3), (n, t) -> tag.setPetName(n.asText()), tag); + 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; } } 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 62926f6e6..cec82c762 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 @@ -20,17 +20,17 @@ @Tag(code = "relays", nip = 57) @JsonSerialize(using = RelaysTagSerializer.class) public class RelaysTag extends BaseTag { - private final List relays; + private final List relays; - public RelaysTag(@NonNull List relays) { - this.relays = relays; - } + public RelaysTag(@NonNull List relays) { + this.relays = relays; + } - public RelaysTag(@NonNull Relay... relays) { - this(List.of(relays)); - } + public RelaysTag(@NonNull Relay... relays) { + this(List.of(relays)); + } - public static T deserialize(@NonNull JsonNode node) { - return (T) new RelaysTag(Optional.of(node).stream().map(jsonNode -> new Relay(jsonNode.get(1).asText())).toList()); - } -} \ No newline at end of file + public static T deserialize(JsonNode node) { + return (T) new RelaysTag(Optional.ofNullable(node).map(jsonNode -> new Relay(jsonNode.get(1).asText())).orElseThrow()); + } +} 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 845bcc132..6950cab64 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 @@ -14,8 +14,6 @@ import nostr.base.annotation.Tag; import nostr.event.BaseTag; -import java.util.Optional; - /** * * @author squirrel @@ -35,7 +33,7 @@ public final class SubjectTag extends BaseTag { public static T deserialize(@NonNull JsonNode node) { SubjectTag tag = new SubjectTag(); - setTagFields(node.get(1), (n, t) -> tag.setSubject(n.asText()), tag); + setOptionalField(node.get(1), (n, t) -> tag.setSubject(n.asText()), tag); return (T) tag; } } diff --git a/nostr-java-test/src/test/resources/application-test.properties b/nostr-java-test/src/test/resources/application-test.properties new file mode 100644 index 000000000..c8e8aa339 --- /dev/null +++ b/nostr-java-test/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr=debug +logging.pattern.console=%msg%n From 0ae8b5f52573438151bd980aef4c0bd80f010f3b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 13 Mar 2025 13:56:17 -0700 Subject: [PATCH 16/57] cleanup --- .../test/java/nostr/test/event/PriceTagTest.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java index 81e4c8c03..40bc4dd13 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java @@ -2,7 +2,6 @@ import nostr.event.tag.PriceTag; import org.junit.jupiter.api.Test; -import org.springframework.test.context.ActiveProfiles; import java.lang.reflect.Field; import java.math.BigDecimal; @@ -72,16 +71,4 @@ void getSupportedFields() { assertTrue(List.of("java.math.BigDecimal", "java.lang.String").containsAll(list.stream().map(field -> field.getAnnotatedType().toString()).toList())); }); } - - @Test - void donothing() { - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - System.out.println("00000000000000000000000000000"); - } } From 374d9b20477969b6f10f75f306e494b5351c5af9 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 14 Mar 2025 19:28:57 -0700 Subject: [PATCH 17/57] general refactor & cleanup --- .../groovy/buildlogic.java-conventions.gradle | 41 - ...xyz.tcheeric.nostr-java-conventions.gradle | 71 ++ .../src/main/java/nostr/api/EventNostr.java | 6 +- .../src/main/java/nostr/api/NIP44.java | 71 +- .../src/main/java/nostr/api/NostrIF.java | 2 +- .../nostr/api/NostrSpringWebSocketClient.java | 2 +- .../src/main/java/nostr/base/BaseKey.java | 4 +- .../src/main/java/nostr/base/ISignable.java | 8 +- .../src/main/java/nostr/base/UserProfile.java | 4 +- .../main/java/nostr/crypto/bech32/Bech32.java | 38 +- .../src/main/java/nostr/event/BaseTag.java | 8 +- .../event/filter/AddressableTagFilter.java | 92 +- .../java/nostr/event/filter/Filterable.java | 3 +- .../event/filter/GenericTagQueryFilter.java | 86 +- .../nostr/event/filter/GeohashTagFilter.java | 36 +- .../nostr/event/filter/HashtagTagFilter.java | 36 +- .../event/filter/IdentifierTagFilter.java | 47 +- .../event/filter/ReferencedEventFilter.java | 48 +- .../filter/ReferencedPublicKeyFilter.java | 48 +- .../java/nostr/event/impl/GenericEvent.java | 46 +- .../impl/InternetIdentifierMetadataEvent.java | 5 +- .../event/json/codec/BaseEventEncoder.java | 8 +- .../event/json/codec/OstEventEncoder.java | 8 +- .../event/json/serializer/TagSerializer.java | 6 +- .../java/nostr/event/tag/DelegationTag.java | 28 +- .../java/nostr/event/util/Nip05Validator.java | 14 +- .../java/nostr/examples/NostrApiExamples.java | 4 +- .../src/main/java/nostr/id/Identity.java | 54 +- .../java/nostr/test/base/BaseKeyTest.java | 116 +-- .../java/nostr/test/crypto/CryptoTest.java | 4 +- .../java/nostr/test/event/ApiEventTest.java | 955 +++++++++--------- ...entTestUsingSpringWebSocketClientTest.java | 81 +- .../test/java/nostr/test/event/EventTest.java | 9 +- .../java/nostr/test/event/SignatureTest.java | 20 +- .../java/nostr/test/event/TestConfig.java | 21 + .../java/nostr/test/json/JsonParseTest.java | 6 +- .../main/java/nostr/util/NostrException.java | 12 - .../nostr/util/thread/HexStringValidator.java | 58 +- 38 files changed, 1022 insertions(+), 1084 deletions(-) delete mode 100644 buildSrc/src/main/groovy/buildlogic.java-conventions.gradle create mode 100644 buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle create mode 100644 nostr-java-test/src/test/java/nostr/test/event/TestConfig.java delete mode 100644 nostr-java-util/src/main/java/nostr/util/NostrException.java diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle deleted file mode 100644 index 5d1f0cceb..000000000 --- a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle +++ /dev/null @@ -1,41 +0,0 @@ -plugins { - id 'java' - id 'java-library' - id 'maven-publish' -} - -repositories { - mavenLocal() - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } -} - -group = 'xyz.tcheeric' -version = '0.6.5-SNAPSHOT' -description = 'nostr-java' -java.sourceCompatibility = JavaVersion.VERSION_21 -java.targetCompatibility = JavaVersion.VERSION_21 - -subprojects { - publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' -} - -tasks.withType(Javadoc).configureEach { - options.encoding = 'UTF-8' -} - -//tasks.build.finalizedBy() { -// tasks.publishToMavenLocal -//} diff --git a/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle b/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle new file mode 100644 index 000000000..f571fb8c3 --- /dev/null +++ b/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle @@ -0,0 +1,71 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.4.3' + id 'io.spring.dependency-management' version '1.1.7' + + id 'io.freefair.lombok' version '8.12.2.1' + id 'com.adarshr.test-logger' version '4.0.0' + id 'org.gradle.test-retry' version '1.6.2' + + id 'groovy-gradle-plugin' + id 'java-library' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +group = 'xyz.tcheeric-conventions' +version = '0.6.5-SNAPSHOT' +description = 'nostr-java' +java.sourceCompatibility = JavaVersion.VERSION_21 +java.targetCompatibility = JavaVersion.VERSION_21 + +dependencies { + def springBootVersion = '3.4.3' + def apacheCommonsLang3 = '3.17.0' + def jacksonModuleAfterburner = '2.18.3' + def googleGuava = '33.2.1-jre' + def bouncyCastle = '1.80' + def awaitility = '4.2.0' + def lombok = '1.18.36' + + implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion + implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle + + implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion + + implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner + implementation 'com.google.guava:guava:' + googleGuava + + testImplementation 'org.awaitility:awaitility:' + awaitility + testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + implementation 'org.projectlombok:lombok:' + lombok + annotationProcessor 'org.projectlombok:lombok:' + lombok + testImplementation 'org.projectlombok:lombok:' + lombok + testAnnotationProcessor 'org.projectlombok:lombok:' + lombok +} + +subprojects { + publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } + } +} + +//tasks.build.finalizedBy() { +// tasks.publishToMavenLocal +//} 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 af3310462..462d33a98 100644 --- a/nostr-java-api/src/main/java/nostr/api/EventNostr.java +++ b/nostr-java-api/src/main/java/nostr/api/EventNostr.java @@ -37,9 +37,8 @@ public EventNostr(@NonNull Identity sender) { super(sender); } - public EventNostr sign() { + public EventNostr sign() throws Exception { super.sign(getSender(), event); - return this; } @@ -69,19 +68,16 @@ public U signAndSend(Map relays) { public EventNostr setSender(@NonNull Identity sender) { super.setSender(sender); - return this; } public EventNostr setRelays(@NonNull Map relays) { super.setRelays(relays); - return this; } public EventNostr setRecipient(@NonNull PublicKey recipient) { this.recipient = recipient; - return this; } 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 87aca2f57..ec5c50f66 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP44.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP44.java @@ -8,6 +8,7 @@ import nostr.encryption.MessageCipher; import nostr.encryption.MessageCipher44; import nostr.event.BaseTag; +import nostr.event.filter.Filterable; import nostr.event.impl.EncryptedPayloadEvent; import nostr.event.impl.GenericEvent; import nostr.event.tag.PubKeyTag; @@ -26,12 +27,6 @@ public NIP44(@NonNull Identity sender, @NonNull PublicKey recipient) { setRecipient(recipient); } - /** - * Create a NIP44 Encrypted Payload - * - * @param content the EP content in clear-text - * @return the EP event - */ public NIP44 createDirectMessageEvent(@NonNull String content) { var encryptedContent = encrypt(getSender(), content, getRecipient()); var factory = new NIP44Impl.EncryptedPayloadEventFactory(getSender(), getRecipient(), encryptedContent); @@ -40,14 +35,6 @@ public NIP44 createDirectMessageEvent(@NonNull String content) { return this; } - /** - * Create a NIP44 Encrypted Payload - * - * @param tags additional note's tags - * @param recipient the EP recipient - * @param content the EP content - * @return the EP event - */ public NIP44 createDirectMessageEvent(@NonNull List tags, @NonNull PublicKey recipient, @NonNull String content) { var encryptedContent = encrypt(getSender(), content, recipient); var factory = new NIP44Impl.EncryptedPayloadEventFactory(getSender(), tags, recipient, encryptedContent); @@ -56,14 +43,8 @@ public NIP44 createDirectMessageEvent(@NonNull List tags, @NonNull P return this; } - /** - * Encrypt an Encrypted Payload event - * - * @param senderId - * @param ep the EP event - */ - public static void encrypt(@NonNull Identity senderId, @NonNull EncryptedPayloadEvent ep) { - encryptDirectMessage(senderId, ep); + public static void encrypt(@NonNull Identity sender, @NonNull EncryptedPayloadEvent ep) { + encryptDirectMessage(sender, ep); } public NIP44 encrypt() { @@ -71,63 +52,45 @@ public NIP44 encrypt() { return this; } - public static String encrypt(@NonNull Identity senderId, @NonNull String message, @NonNull PublicKey recipient) { - MessageCipher cipher = new MessageCipher44(senderId.getPrivateKey().getRawData(), recipient.getRawData()); + public static String encrypt(@NonNull Identity sender, @NonNull String message, @NonNull PublicKey recipient) { + MessageCipher cipher = new MessageCipher44(sender.getPrivateKey().getRawData(), recipient.getRawData()); return cipher.encrypt(message); } - /** - * Decrypt an encrypted Payloads - * - * @param rcptId - * @param ep the encrypted Payloads - * @return the ep content in clear-text - */ - public static String decrypt(@NonNull Identity rcptId, @NonNull EncryptedPayloadEvent ep) { - return NIP44.decrypt(rcptId, (GenericEvent) ep); + public static String decrypt(@NonNull Identity recipient, @NonNull EncryptedPayloadEvent ep) { + return NIP44.decrypt(recipient, (GenericEvent) ep); } - /** - * Decrypt an encrypted Payloads - * - * @param identity the sender's identity - * @param encrypteEPessage the encrypted message - * @param recipient the recipient's public key - * @return the ep content in clear-text - */ public static String decrypt(@NonNull Identity identity, @NonNull String encrypteEPessage, @NonNull PublicKey recipient) { MessageCipher cipher = new MessageCipher44(identity.getPrivateKey().getRawData(), recipient.getRawData()); return cipher.decrypt(encrypteEPessage); } - public static String decrypt(@NonNull Identity rcptId, @NonNull GenericEvent event) { - var recipient = event.getTags() - .stream() - .filter(t -> t.getCode().equalsIgnoreCase("p")) - .findFirst() - .orElseThrow(() -> new NoSuchElementException("No matching p-tag found.")); - var pTag = (PubKeyTag) recipient; - - boolean rcptFlag = amITheRecipient(rcptId, event); + public static String decrypt(@NonNull Identity recipient, @NonNull GenericEvent event) { + boolean rcptFlag = amITheRecipient(recipient, event); if (!rcptFlag) { // I am the message sender - MessageCipher cipher = new MessageCipher44(rcptId.getPrivateKey().getRawData(), pTag.getPublicKey().getRawData()); + MessageCipher cipher = new MessageCipher44(recipient.getPrivateKey().getRawData(), + Filterable.getTypeSpecificTags(PubKeyTag.class, event) + .stream() + .findFirst() + .orElseThrow(() -> new NoSuchElementException("No matching p-tag found.")).getPublicKey().getRawData()); return cipher.decrypt(event.getContent()); } // I am the message recipient var sender = event.getPubKey(); log.log(Level.FINE, "The message is being decrypted for {0}", sender); - MessageCipher cipher = new MessageCipher44(rcptId.getPrivateKey().getRawData(), sender.getRawData()); + MessageCipher cipher = new MessageCipher44(recipient.getPrivateKey().getRawData(), sender.getRawData()); return cipher.decrypt(event.getContent()); } - private static void encryptDirectMessage(@NonNull Identity senderId, @NonNull EncryptedPayloadEvent ep) { + private static void encryptDirectMessage(@NonNull Identity sender, @NonNull EncryptedPayloadEvent ep) { ITag pkTag = ep.getTags().get(0); if (pkTag instanceof PubKeyTag pubKeyTag) { var rcptPublicKey = pubKeyTag.getPublicKey(); - MessageCipher cipher = new MessageCipher44(senderId.getPrivateKey().getRawData(), rcptPublicKey.getRawData()); + MessageCipher cipher = new MessageCipher44(sender.getPrivateKey().getRawData(), rcptPublicKey.getRawData()); var encryptedContent = cipher.encrypt(ep.getContent()); ep.setContent(encryptedContent); } 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 f297dfb21..7a28e197b 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrIF.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrIF.java @@ -20,7 +20,7 @@ public interface NostrIF { List sendRequest(@NonNull Filters filters, @NonNull String subscriptionId, Map relays); List sendRequest(@NonNull List filtersList, @NonNull String subscriptionId); List sendRequest(@NonNull List filtersList, @NonNull String subscriptionId, Map relays); - NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable); + NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) throws Exception; boolean verify(@NonNull GenericEvent event); Identity getSender(); Map getRelays(); 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 31ba1a3eb..e0b0171ff 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java @@ -115,7 +115,7 @@ public List sendRequest(@NonNull Filters filters, @NonNull String subscr @Override - public NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) { + public NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) throws Exception { identity.sign(signable); return this; } 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 a8ca1142d..965a33408 100644 --- a/nostr-java-base/src/main/java/nostr/base/BaseKey.java +++ b/nostr-java-base/src/main/java/nostr/base/BaseKey.java @@ -7,7 +7,7 @@ import lombok.NonNull; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; import java.util.Arrays; @@ -32,7 +32,7 @@ public abstract class BaseKey implements IKey { public String toBech32String() { try { return Bech32.toBech32(prefix, rawData); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } } diff --git a/nostr-java-base/src/main/java/nostr/base/ISignable.java b/nostr-java-base/src/main/java/nostr/base/ISignable.java index b0a35f38f..c26c3960e 100644 --- a/nostr-java-base/src/main/java/nostr/base/ISignable.java +++ b/nostr-java-base/src/main/java/nostr/base/ISignable.java @@ -1,13 +1,17 @@ package nostr.base; +import java.nio.ByteBuffer; +import java.util.function.Consumer; +import java.util.function.Supplier; + /** * * @author squirrel */ public interface ISignable { - Signature getSignature(); - void setSignature(Signature signature); + Consumer getSignatureConsumer(); + Supplier getByeArraySupplier(); } diff --git a/nostr-java-base/src/main/java/nostr/base/UserProfile.java b/nostr-java-base/src/main/java/nostr/base/UserProfile.java index 998519766..ae1bc5320 100644 --- a/nostr-java-base/src/main/java/nostr/base/UserProfile.java +++ b/nostr-java-base/src/main/java/nostr/base/UserProfile.java @@ -12,7 +12,7 @@ import lombok.extern.java.Log; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; /** * @@ -39,7 +39,7 @@ public UserProfile(@NonNull PublicKey publicKey, String name, String nip05, Stri public String toBech32() { try { return Bech32.encode(Bech32.Encoding.BECH32, Bech32Prefix.NPROFILE.getCode(), this.publicKey.getRawData()); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { log.log(Level.SEVERE, null, ex); throw new RuntimeException(ex); } 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 b96f8e6fe..125f581c7 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 @@ -5,7 +5,7 @@ import java.util.List; import java.util.Locale; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; /** @@ -61,20 +61,20 @@ private Bech32Data(final Encoding encoding, final String hrp, final byte[] data) } } - public static String toBech32(Bech32Prefix hrp, byte[] hexKey) throws NostrException { + public static String toBech32(Bech32Prefix hrp, byte[] hexKey) throws NostrExceptionFactory { byte[] data = convertBits(hexKey, 8, 5, true); return Bech32.encode(Bech32.Encoding.BECH32, hrp.getCode(), data); } - public static String toBech32(Bech32Prefix hrp, String hexKey) throws NostrException { + public static String toBech32(Bech32Prefix hrp, String hexKey) throws NostrExceptionFactory { byte[] data = NostrUtil.hexToBytes(hexKey); return toBech32(hrp, data); } // Added by squirrel - public static String fromBech32(String strBech32) throws NostrException { + public static String fromBech32(String strBech32) throws NostrExceptionFactory { byte[] data = Bech32.decode(strBech32).data; data = convertBits(data, 5, 8, true); @@ -93,9 +93,9 @@ public static String fromBech32(String strBech32) throws NostrException { * * @param bech32 * @return - * @throws nostr.util.NostrException + * @throws NostrExceptionFactory */ - public static String encode(final Bech32Data bech32) throws NostrException { + public static String encode(final Bech32Data bech32) throws NostrExceptionFactory { return encode(bech32.encoding, bech32.hrp, bech32.data); } @@ -106,12 +106,12 @@ public static String encode(final Bech32Data bech32) throws NostrException { * @param hrp * @param values * @return - * @throws nostr.util.NostrException + * @throws NostrExceptionFactory */ // Modified to throw NostrExceptions - public static String encode(Encoding encoding, String hrp, final byte[] values) throws NostrException { + public static String encode(Encoding encoding, String hrp, final byte[] values) throws NostrExceptionFactory { if (hrp.isEmpty()) { - throw new NostrException("Human-readable part is too short"); + throw new NostrExceptionFactory("Human-readable part is too short"); } hrp = hrp.toLowerCase(Locale.ROOT); @@ -133,53 +133,53 @@ public static String encode(Encoding encoding, String hrp, final byte[] values) * * @param str * @return - * @throws nostr.util.NostrException + * @throws NostrExceptionFactory */ // Modified to throw NostrExceptions - public static Bech32Data decode(final String str) throws NostrException { + public static Bech32Data decode(final String str) throws NostrExceptionFactory { boolean lower = false, upper = false; if (str.length() < 8) { - throw new NostrException("Input too short: " + str.length()); + throw new NostrExceptionFactory("Input too short: " + str.length()); } for (int i = 0; i < str.length(); ++i) { char c = str.charAt(i); if (c < 33 || c > 126) { - throw new NostrException(String.format("Invalid Character %c, %d", c, i)); + throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); } if (c >= 'a' && c <= 'z') { if (upper) { - throw new NostrException(String.format("Invalid Character %c, %d", c, i)); + throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); } lower = true; } if (c >= 'A' && c <= 'Z') { if (lower) { - throw new NostrException(String.format("Invalid Character %c, %d", c, i)); + throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); } upper = true; } } final int pos = str.lastIndexOf('1'); if (pos < 1) { - throw new NostrException("Missing human-readable part"); + throw new NostrExceptionFactory("Missing human-readable part"); } final int dataPartLength = str.length() - 1 - pos; if (dataPartLength < 6) { - throw new NostrException(String.format("Data part too short: %d)", dataPartLength)); + throw new NostrExceptionFactory(String.format("Data part too short: %d)", dataPartLength)); } byte[] values = new byte[dataPartLength]; for (int i = 0; i < dataPartLength; ++i) { char c = str.charAt(i + pos + 1); if (CHARSET_REV[c] == -1) { - throw new NostrException(String.format("Invalid Character %c, %d", c, i + pos + 1)); + throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i + pos + 1)); } values[i] = CHARSET_REV[c]; } String hrp = str.substring(0, pos).toLowerCase(Locale.ROOT); Encoding encoding = verifyChecksum(hrp, values); if (encoding == null) { - throw new NostrException("InvalidChecksum"); + throw new NostrExceptionFactory("InvalidChecksum"); } return new Bech32Data(encoding, hrp, Arrays.copyOfRange(values, 0, values.length - 6)); } 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 f8a7bd2e2..cdcacc56c 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -14,7 +14,7 @@ import nostr.base.annotation.Tag; import nostr.event.json.deserializer.TagDeserializer; import nostr.event.json.serializer.TagSerializer; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import org.apache.commons.lang3.stream.Streams; import java.beans.IntrospectionException; @@ -57,16 +57,16 @@ public Integer getNip() { return 1; } - public String getFieldValue(Field field) throws NostrException { + public String getFieldValue(Field field) throws NostrExceptionFactory { try { Object f = new PropertyDescriptor(field.getName(), this.getClass()).getReadMethod().invoke(this); return f != null ? f.toString() : null; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException ex) { - throw new NostrException(ex); + throw new NostrExceptionFactory(ex); } } - public List getSupportedFields() throws NostrException { + public List getSupportedFields() throws NostrExceptionFactory { return new Streams.FailableStream<>(Arrays.stream(this.getClass().getDeclaredFields())) .filter(f -> Objects.nonNull(f.getAnnotation(Key.class))) diff --git a/nostr-java-event/src/main/java/nostr/event/filter/AddressableTagFilter.java b/nostr-java-event/src/main/java/nostr/event/filter/AddressableTagFilter.java index 50bdbbf56..ae86a6ca3 100644 --- a/nostr-java-event/src/main/java/nostr/event/filter/AddressableTagFilter.java +++ b/nostr-java-event/src/main/java/nostr/event/filter/AddressableTagFilter.java @@ -17,61 +17,61 @@ @EqualsAndHashCode(callSuper = true) public class AddressableTagFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#a"; + public final static String FILTER_KEY = "#a"; - public AddressableTagFilter(T addressableTag) { - super(addressableTag, FILTER_KEY); - } + public AddressableTagFilter(T addressableTag) { + super(addressableTag, FILTER_KEY); + } - @Override - public Predicate getPredicate() { - return this::compare; - } + @Override + public Predicate getPredicate() { + return this::compare; + } - public static AddressTag createAddressTag(@NonNull JsonNode addressableTag) throws IllegalArgumentException { - try { - List list = Arrays.stream(addressableTag.asText().split(":")).toList(); + public static AddressTag createAddressTag(@NonNull JsonNode addressableTag) throws IllegalArgumentException { + try { + List list = Arrays.stream(addressableTag.asText().split(":")).toList(); - AddressTag addressTag = new AddressTag(); - addressTag.setKind(Integer.valueOf(list.getFirst())); - addressTag.setPublicKey(new PublicKey(list.get(1))); - addressTag.setIdentifierTag(new IdentifierTag(list.get(2))); + AddressTag addressTag = new AddressTag(); + addressTag.setKind(Integer.valueOf(list.getFirst())); + addressTag.setPublicKey(new PublicKey(list.get(1))); + addressTag.setIdentifierTag(new IdentifierTag(list.get(2))); - return addressTag; - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - String.format("Malformed JsonNode addressable tag: [%s]", addressableTag.asText()), e); + return addressTag; + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format("Malformed JsonNode addressable tag: [%s]", addressableTag.asText()), e); + } } - } - @Override - public String getFilterableValue() { - T addressableTag = getAddressableTag(); - Integer kind = addressableTag.getKind(); - String hexString = addressableTag.getPublicKey().toHexString(); - String id = addressableTag.getIdentifierTag().getId(); + @Override + public String getFilterableValue() { + T addressableTag = getAddressableTag(); + Integer kind = addressableTag.getKind(); + String hexString = addressableTag.getPublicKey().toHexString(); + String id = addressableTag.getIdentifierTag().getId(); - return Stream.of(kind, hexString, id) - .map(Object::toString) - .collect(Collectors.joining(":")); - } + return Stream.of(kind, hexString, id) + .map(Object::toString) + .collect(Collectors.joining(":")); + } - private boolean compare(@NonNull GenericEvent genericEvent) { - T addressableTag = getAddressableTag(); - return - !genericEvent.getPubKey().toHexString().equals( - addressableTag.getPublicKey().toHexString()) || - !genericEvent.getKind().equals( - addressableTag.getKind()) || - getTypeSpecificTags(IdentifierTag.class, genericEvent).stream() - .anyMatch(identifierTag -> - identifierTag.getId().equals( - addressableTag.getIdentifierTag().getId())); - } + private boolean compare(@NonNull GenericEvent genericEvent) { + T addressableTag = getAddressableTag(); + return + !genericEvent.getPubKey().toHexString().equals( + addressableTag.getPublicKey().toHexString()) || + !genericEvent.getKind().equals( + addressableTag.getKind()) || + Filterable.getTypeSpecificTags(IdentifierTag.class, genericEvent).stream() + .anyMatch(identifierTag -> + identifierTag.getId().equals( + addressableTag.getIdentifierTag().getId())); + } - private T getAddressableTag() { - return super.getFilterable(); - } + private T getAddressableTag() { + return super.getFilterable(); + } - public static Function fxn = node -> new AddressableTagFilter<>(AddressableTagFilter.createAddressTag(node)); + public static Function fxn = node -> new AddressableTagFilter<>(AddressableTagFilter.createAddressTag(node)); } 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 9af6024a2..b0cac310c 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 @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.NonNull; import nostr.event.BaseTag; import nostr.event.impl.GenericEvent; @@ -17,7 +18,7 @@ public interface Filterable { Object getFilterableValue(); String getFilterKey(); - default List getTypeSpecificTags(Class tagClass, GenericEvent event) { + static List getTypeSpecificTags(@NonNull Class tagClass, @NonNull GenericEvent event) { return event.getTags().stream() .filter(tagClass::isInstance) .map(tagClass::cast) 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 b624e396b..c92ffeb98 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 @@ -12,47 +12,47 @@ @EqualsAndHashCode(callSuper = true) public class GenericTagQueryFilter extends AbstractFilterable { - public static final String HASH_PREFIX = "#"; - - public GenericTagQueryFilter(T genericTagQuery) { - super(genericTagQuery, genericTagQuery.getTagName()); - } - - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(GenericTag.class, genericEvent).stream() - .filter(genericTag -> - genericTag.getCode().equals(stripLeadingHashTag())) - .anyMatch(genericTag -> - genericTag - .getAttributes().stream().map( - ElementAttribute::getValue).toList() - .contains( - getFilterableValue())); - } - - @Override - public String getFilterKey() { - return getGenericTagQuery().getTagName(); - } - - @Override - public String getFilterableValue() { - return getGenericTagQuery().getValue(); - } - - private T getGenericTagQuery() { - return super.getFilterable(); - } - - private String stripLeadingHashTag() { - return getFilterKey().startsWith(HASH_PREFIX) ? - getFilterKey().substring(1) : - getFilterKey(); - } - - public static Function fxn(String type) { - return node -> new GenericTagQueryFilter<>(new GenericTagQuery(type, node.asText())); - } + public static final String HASH_PREFIX = "#"; + + public GenericTagQueryFilter(T genericTagQuery) { + super(genericTagQuery, genericTagQuery.getTagName()); + } + + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(GenericTag.class, genericEvent).stream() + .filter(genericTag -> + genericTag.getCode().equals(stripLeadingHashTag())) + .anyMatch(genericTag -> + genericTag + .getAttributes().stream().map( + ElementAttribute::getValue).toList() + .contains( + getFilterableValue())); + } + + @Override + public String getFilterKey() { + return getGenericTagQuery().getTagName(); + } + + @Override + public String getFilterableValue() { + return getGenericTagQuery().getValue(); + } + + private T getGenericTagQuery() { + return super.getFilterable(); + } + + private String stripLeadingHashTag() { + return getFilterKey().startsWith(HASH_PREFIX) ? + getFilterKey().substring(1) : + getFilterKey(); + } + + public static Function fxn(String type) { + return node -> new GenericTagQueryFilter<>(new GenericTagQuery(type, node.asText())); + } } 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 c565ff58d..2cec9cb28 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 @@ -10,27 +10,27 @@ @EqualsAndHashCode(callSuper = true) public class GeohashTagFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#g"; + public final static String FILTER_KEY = "#g"; - public GeohashTagFilter(T geohashTag) { - super(geohashTag, FILTER_KEY); - } + public GeohashTagFilter(T geohashTag) { + super(geohashTag, FILTER_KEY); + } - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(GeohashTag.class, genericEvent).stream().anyMatch(geoHashTag -> - geoHashTag.getLocation().equals(getFilterableValue())); - } + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(GeohashTag.class, genericEvent).stream().anyMatch(geoHashTag -> + geoHashTag.getLocation().equals(getFilterableValue())); + } - @Override - public String getFilterableValue() { - return getGeoHashTag().getLocation(); - } + @Override + public String getFilterableValue() { + return getGeoHashTag().getLocation(); + } - private T getGeoHashTag() { - return super.getFilterable(); - } + private T getGeoHashTag() { + return super.getFilterable(); + } - public static Function fxn = node -> new GeohashTagFilter<>(new GeohashTag(node.asText())); + public static Function fxn = node -> new GeohashTagFilter<>(new GeohashTag(node.asText())); } 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 926359f1e..f4b4bea04 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 @@ -10,27 +10,27 @@ @EqualsAndHashCode(callSuper = true) public class HashtagTagFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#t"; + public final static String FILTER_KEY = "#t"; - public HashtagTagFilter(T hashtagTag) { - super(hashtagTag, FILTER_KEY); - } + public HashtagTagFilter(T hashtagTag) { + super(hashtagTag, FILTER_KEY); + } - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(HashtagTag.class, genericEvent).stream().anyMatch(hashtagTag -> - hashtagTag.getHashTag().equals(getFilterableValue())); - } + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(HashtagTag.class, genericEvent).stream().anyMatch(hashtagTag -> + hashtagTag.getHashTag().equals(getFilterableValue())); + } - @Override - public String getFilterableValue() { - return getHashtagTag().getHashTag(); - } + @Override + public String getFilterableValue() { + return getHashtagTag().getHashTag(); + } - private T getHashtagTag() { - return super.getFilterable(); - } + private T getHashtagTag() { + return super.getFilterable(); + } - public static Function fxn = node -> new HashtagTagFilter<>(new HashtagTag(node.asText())); + public static Function fxn = node -> new HashtagTagFilter<>(new HashtagTag(node.asText())); } 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 9e0253689..8eb7b55b9 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 @@ -10,27 +10,28 @@ @EqualsAndHashCode(callSuper = true) public class IdentifierTagFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#d"; - public IdentifierTagFilter(T identifierTag) { - super(identifierTag, FILTER_KEY); - } - - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(IdentifierTag.class, genericEvent).stream() - .anyMatch(genericEventIdentifierTag -> - genericEventIdentifierTag.getId().equals(getFilterableValue())); - } - - @Override - public String getFilterableValue() { - return getIdentifierTag().getId(); - } - - private T getIdentifierTag() { - return super.getFilterable(); - } - - public static Function fxn = node -> new IdentifierTagFilter<>(new IdentifierTag(node.asText())); + public final static String FILTER_KEY = "#d"; + + public IdentifierTagFilter(T identifierTag) { + super(identifierTag, FILTER_KEY); + } + + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(IdentifierTag.class, genericEvent).stream() + .anyMatch(genericEventIdentifierTag -> + genericEventIdentifierTag.getId().equals(getFilterableValue())); + } + + @Override + public String getFilterableValue() { + return getIdentifierTag().getId(); + } + + private T getIdentifierTag() { + return super.getFilterable(); + } + + public static Function fxn = node -> new IdentifierTagFilter<>(new IdentifierTag(node.asText())); } 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 7db2c97f1..50950847a 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 @@ -10,28 +10,28 @@ @EqualsAndHashCode(callSuper = true) public class ReferencedEventFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#e"; - - public ReferencedEventFilter(T referencedEventTag) { - super(referencedEventTag, FILTER_KEY); - } - - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(EventTag.class, genericEvent).stream() - .anyMatch(eventTag -> - eventTag.getIdEvent().equals(getFilterableValue())); - } - - @Override - public String getFilterableValue() { - return getReferencedEventTag().getIdEvent(); - } - - private T getReferencedEventTag() { - return super.getFilterable(); - } - - public static Function fxn = node -> new ReferencedEventFilter<>(new EventTag(node.asText())); + public final static String FILTER_KEY = "#e"; + + public ReferencedEventFilter(T referencedEventTag) { + super(referencedEventTag, FILTER_KEY); + } + + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(EventTag.class, genericEvent).stream() + .anyMatch(eventTag -> + eventTag.getIdEvent().equals(getFilterableValue())); + } + + @Override + public String getFilterableValue() { + return getReferencedEventTag().getIdEvent(); + } + + private T getReferencedEventTag() { + return super.getFilterable(); + } + + public static Function fxn = node -> new ReferencedEventFilter<>(new EventTag(node.asText())); } 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 11b54a4c9..a22439cad 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 @@ -11,28 +11,28 @@ @EqualsAndHashCode(callSuper = true) public class ReferencedPublicKeyFilter extends AbstractFilterable { - public final static String FILTER_KEY = "#p"; - - public ReferencedPublicKeyFilter(T referencedPubKeyTag) { - super(referencedPubKeyTag, FILTER_KEY); - } - - @Override - public Predicate getPredicate() { - return (genericEvent) -> - getTypeSpecificTags(PubKeyTag.class, genericEvent).stream() - .anyMatch(pubKeyTag -> - pubKeyTag.getPublicKey().toHexString().equals(getFilterableValue())); - } - - @Override - public String getFilterableValue() { - return getReferencedPublicKey().getPublicKey().toHexString(); - } - - private T getReferencedPublicKey() { - return super.getFilterable(); - } - - public static Function fxn = node -> new ReferencedPublicKeyFilter<>(new PubKeyTag(new PublicKey(node.asText()))); + public final static String FILTER_KEY = "#p"; + + public ReferencedPublicKeyFilter(T referencedPubKeyTag) { + super(referencedPubKeyTag, FILTER_KEY); + } + + @Override + public Predicate getPredicate() { + return (genericEvent) -> + Filterable.getTypeSpecificTags(PubKeyTag.class, genericEvent).stream() + .anyMatch(pubKeyTag -> + pubKeyTag.getPublicKey().toHexString().equals(getFilterableValue())); + } + + @Override + public String getFilterableValue() { + return getReferencedPublicKey().getPublicKey().toHexString(); + } + + private T getReferencedPublicKey() { + return super.getFilterable(); + } + + public static Function fxn = node -> new ReferencedPublicKeyFilter<>(new PubKeyTag(new PublicKey(node.asText()))); } 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 e2536f837..0df39092b 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 @@ -1,26 +1,15 @@ package nostr.event.impl; -import java.beans.Transient; -import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.node.JsonNodeFactory; - import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import lombok.extern.java.Log; import nostr.base.ElementAttribute; -import nostr.base.IEncoder; import nostr.base.IGenericElement; import nostr.base.ISignable; import nostr.base.ITag; @@ -35,14 +24,25 @@ import nostr.event.Kind; import nostr.event.json.deserializer.PublicKeyDeserializer; import nostr.event.json.deserializer.SignatureDeserializer; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; import nostr.util.thread.HexStringValidator; +import java.beans.Transient; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.logging.Level; + import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; /** - * * @author squirrel */ @Log @@ -148,7 +148,7 @@ public String toBech32() { try { return Bech32.toBech32(Bech32Prefix.NOTE, this.getId()); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } } @@ -182,7 +182,7 @@ public void update() { this._serializedEvent = this.serialize().getBytes(StandardCharsets.UTF_8); this.id = NostrUtil.bytesToHex(NostrUtil.sha256(_serializedEvent)); - } catch (NostrException | NoSuchAlgorithmException ex) { + } catch (NostrExceptionFactory | NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } catch (AssertionError ex) { log.log(Level.WARNING, ex.getMessage()); @@ -204,7 +204,7 @@ protected void validate() { } - private String serialize() throws NostrException { + private String serialize() throws NostrExceptionFactory { var mapper = I_ENCODER_MAPPER_AFTERBURNER; var arrayNode = JsonNodeFactory.instance.arrayNode(); @@ -218,10 +218,22 @@ private String serialize() throws NostrException { return mapper.writeValueAsString(arrayNode); } catch (JsonProcessingException e) { - throw new NostrException(e); + throw new NostrExceptionFactory(e); } } + @Override + public Consumer getSignatureConsumer() { + return this::setSignature; + } + + @Override + public Supplier getByeArraySupplier() { + this.update(); + log.log(Level.FINER, "Serialized event: {0}", new String(this.get_serializedEvent())); + return () -> ByteBuffer.wrap(this.get_serializedEvent()); + } + protected final void updateTagsParents(List tagList) { if (tagList != null && !tagList.isEmpty()) { for (ITag t : tagList) { 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 5ab5b07b3..0662f9e4b 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 @@ -3,7 +3,6 @@ import static nostr.util.NostrUtil.escapeJsonString; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; @@ -15,7 +14,7 @@ import nostr.event.Kind; import nostr.event.NIP05Event; import nostr.event.util.Nip05Validator; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; /** * @@ -37,7 +36,7 @@ private void init(UserProfile profile) { Nip05Validator.builder().nip05(profile.getNip05()).publicKey(profile.getPublicKey()).build().validate(); setContent(profile); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java index 0afbfe0f8..c93e25d3a 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java @@ -4,7 +4,7 @@ import lombok.Data; import nostr.base.IEncoder; import nostr.event.BaseEvent; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; /** * @author guilhermegps @@ -23,16 +23,16 @@ public BaseEventEncoder(T event) { public String encode() { try { return toJson(); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } } - protected String toJson() throws NostrException { + protected String toJson() throws NostrExceptionFactory { try { return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(event); } catch (JsonProcessingException e) { - throw new NostrException(e); + throw new NostrExceptionFactory(e); } } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java index 0e6c7c4dd..9c0fda925 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java @@ -11,7 +11,7 @@ import nostr.base.IEncoder; import nostr.base.Relay; import nostr.event.impl.OtsEvent; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; /** * @author guilhermegps @@ -32,12 +32,12 @@ public OstEventEncoder(OtsEvent event) { public String encode() { try { return toJson(); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } } - private String toJson() throws NostrException { + private String toJson() throws NostrExceptionFactory { try { JsonNode node = I_ENCODER_MAPPER_AFTERBURNER.valueToTree(event); ObjectNode objNode = (ObjectNode) node; @@ -51,7 +51,7 @@ private String toJson() throws NostrException { return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(node); } catch (JsonProcessingException | IllegalArgumentException e) { - throw new NostrException(e); + throw new NostrExceptionFactory(e); } } 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 9c40e03e4..ec0a425a3 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 @@ -9,7 +9,7 @@ import nostr.base.ElementAttribute; import nostr.event.BaseTag; import nostr.event.impl.GenericTag; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import java.io.IOException; import java.io.Serial; @@ -40,7 +40,7 @@ public void serialize(BaseTag value, JsonGenerator gen, SerializerProvider seria fields.forEach((Field f) -> { try { node.put(f.getName(), value.getFieldValue(f)); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { throw new RuntimeException(ex); } }); @@ -64,7 +64,7 @@ public void serialize(BaseTag value, JsonGenerator gen, SerializerProvider seria throw new AssertionError("node.isObject()", new RuntimeException()); } - } catch (IOException | NostrException e) { + } catch (IOException | NostrExceptionFactory e) { throw new RuntimeException(e); } } 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 3f10518cb..2856bad93 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,20 +2,24 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import nostr.base.ISignable; -import nostr.base.annotation.Key; -import nostr.event.BaseTag; -import nostr.base.PublicKey; -import nostr.base.Signature; -import java.beans.Transient; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import nostr.base.ISignable; +import nostr.base.PublicKey; +import nostr.base.Signature; +import nostr.base.annotation.Key; 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 */ @Data @@ -47,4 +51,14 @@ public DelegationTag(PublicKey delegator, String conditions) { public String getToken() { return "nostr:" + getCode() + ":" + delegator.toString() + ":" + conditions; } + + @Override + public Consumer getSignatureConsumer() { + return this::setSignature; + } + + @Override + public Supplier getByeArraySupplier() { + return () -> ByteBuffer.wrap(this.getToken().getBytes(StandardCharsets.UTF_8)); + } } diff --git a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java index e9589f477..3b913a50f 100644 --- a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java +++ b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java @@ -6,7 +6,7 @@ import nostr.base.PublicKey; import nostr.event.Nip05Content; import nostr.event.json.codec.Nip05ContentDecoder; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import java.io.BufferedReader; import java.io.IOException; @@ -32,14 +32,14 @@ public class Nip05Validator { private static final String LOCAL_PART_PATTERN = "^[a-zA-Z0-9-_\\.]+$"; - public void validate() throws NostrException { + public void validate() throws NostrExceptionFactory { if (this.nip05 != null) { var splited = nip05.split("@"); var localPart = splited[0]; var domain = splited[1]; if (!localPart.matches(LOCAL_PART_PATTERN)) { - throw new NostrException("Invalid syntax in nip05 attribute."); + throw new NostrExceptionFactory("Invalid syntax in nip05 attribute."); } // Verify the public key @@ -48,12 +48,12 @@ public void validate() throws NostrException { validatePublicKey(domain, localPart); } catch (IOException | URISyntaxException ex) { log.log(Level.SEVERE, ex.getMessage()); - throw new NostrException(ex); + throw new NostrExceptionFactory(ex); } } } - private void validatePublicKey(String domain, String localPart) throws NostrException, IOException, URISyntaxException { + private void validatePublicKey(String domain, String localPart) throws NostrExceptionFactory, IOException, URISyntaxException { // Set up and estgetPublicKeyablish the HTTP connection String strUrl = "https:///.well-known/nostr.json?name=".replace("", domain).replace("", localPart); @@ -75,14 +75,14 @@ private void validatePublicKey(String domain, String localPart) throws NostrExce log.log(Level.FINE, "Public key for {0} returned by the server: [{1}]", new Object[]{localPart, pubKey}); if (pubKey != null && !pubKey.equals(publicKey.toString())) { - throw new NostrException(String.format("Public key mismatch. Expected %s - Received: %s", publicKey, pubKey)); + throw new NostrExceptionFactory(String.format("Public key mismatch. Expected %s - Received: %s", publicKey, pubKey)); } // All well! return; } - throw new NostrException(String.format("Failed to connect to %s. Error message: %s", strUrl, connection.getResponseMessage())); + throw new NostrExceptionFactory(String.format("Failed to connect to %s. Error message: %s", strUrl, connection.getResponseMessage())); } private String getPublicKey(StringBuilder content, String localPart) { 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 b2316ca45..89104e124 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java +++ b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java @@ -35,7 +35,7 @@ import nostr.event.tag.EventTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import java.io.IOException; import java.io.InputStream; @@ -182,7 +182,7 @@ public static void main(String[] args) throws Exception { } catch (IllegalArgumentException ex) { log.log(Level.SEVERE, null, ex); - throw new NostrException(ex); + throw new NostrExceptionFactory(ex); } } 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 2bc427d3c..3e0d610c2 100644 --- a/nostr-java-id/src/main/java/nostr/id/Identity.java +++ b/nostr-java-id/src/main/java/nostr/id/Identity.java @@ -10,13 +10,9 @@ import nostr.base.PublicKey; import nostr.base.Signature; import nostr.crypto.schnorr.Schnorr; -import nostr.event.impl.GenericEvent; -import nostr.event.tag.DelegationTag; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; -import java.nio.charset.StandardCharsets; -import java.util.logging.Level; - /** * @author squirrel */ @@ -57,53 +53,27 @@ public static Identity generateRandomIdentity() { return new Identity(PrivateKey.generateRandomPrivKey()); } - public PublicKey getPublicKey() { + public PublicKey getPublicKey() throws NostrExceptionFactory { try { return new PublicKey(Schnorr.genPubKey(this.getPrivateKey().getRawData())); - } catch (Exception e) { - throw new RuntimeException(e); + } catch (Exception ex) { + throw new NostrExceptionFactory(ex); } } - public Signature sign(@NonNull ISignable signable) { - if (signable instanceof GenericEvent genericEvent) { - try { - return signEvent(genericEvent); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } else if (signable instanceof DelegationTag delegationTag) { - try { - return signDelegationTag(delegationTag); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - throw new RuntimeException(); - } - - private Signature signEvent(@NonNull GenericEvent event) throws Exception { - event.update(); - log.log(Level.FINER, "Serialized event: {0}", new String(event.get_serializedEvent())); - final var signedHashedSerializedEvent = Schnorr.sign(NostrUtil.sha256(event.get_serializedEvent()), this.getPrivateKey().getRawData(), generateAuxRand()); - final Signature signature = new Signature(); - signature.setRawData(signedHashedSerializedEvent); - signature.setPubKey(getPublicKey()); - event.setSignature(signature); - return signature; - } - - private Signature signDelegationTag(@NonNull DelegationTag delegationTag) throws Exception { - final var signedHashedToken = Schnorr.sign(NostrUtil.sha256(delegationTag.getToken().getBytes(StandardCharsets.UTF_8)), this.getPrivateKey().getRawData(), generateAuxRand()); + public Signature sign(@NonNull ISignable signable) { final Signature signature = new Signature(); - signature.setRawData(signedHashedToken); + signature.setRawData( + Schnorr.sign( + NostrUtil.sha256(signable.getByeArraySupplier().get().array()), + this.getPrivateKey().getRawData(), + generateAuxRand())); signature.setPubKey(getPublicKey()); - delegationTag.setSignature(signature); + signable.getSignatureConsumer().accept(signature); return signature; } private byte[] generateAuxRand() { return NostrUtil.createRandomByteArray(32); } - -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java b/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java index 599e6f300..32021a401 100644 --- a/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java +++ b/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java @@ -9,72 +9,72 @@ import static org.junit.jupiter.api.Assertions.assertThrows; class BaseKeyTest { - public static final String VALID_HEXPUBKEY = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; - public static final String INVALID_HEXPUBKEY_NON_HEX_DIGITS = "XYZdf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; - public static final String INVALID_HEXPUBKEY_LENGTH_TOO_SHORT = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6"; - public static final String INVALID_HEXPUBKEY_LENGTH_TOO_LONG = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f666"; - public static final String VALID_HEXPUBKEY_ALL_ZEROS = "0000000000000000000000000000000000000000000000000000000000000000"; - public static final String VALID_HEXPUBKEY_ALL_FF = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - public static final String INVALID_HEXPUBKEY_HAS_MULTIPLE_UPPERCASE = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; - public static final String INVALID_HEXPUBKEY_HAS_SINGLE_UPPERCASE = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6F"; + public static final String VALID_HEXPUBKEY = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; + public static final String INVALID_HEXPUBKEY_NON_HEX_DIGITS = "XYZdf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; + public static final String INVALID_HEXPUBKEY_LENGTH_TOO_SHORT = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6"; + public static final String INVALID_HEXPUBKEY_LENGTH_TOO_LONG = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f666"; + public static final String VALID_HEXPUBKEY_ALL_ZEROS = "0000000000000000000000000000000000000000000000000000000000000000"; + public static final String VALID_HEXPUBKEY_ALL_FF = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + public static final String INVALID_HEXPUBKEY_HAS_MULTIPLE_UPPERCASE = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; + public static final String INVALID_HEXPUBKEY_HAS_SINGLE_UPPERCASE = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6F"; - @Test - public void testValidPublicKeyString() { - System.out.println("testValidPublicKeyString"); - assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY)); - } + @Test + public void testValidPublicKeyString() { + System.out.println("testValidPublicKeyString"); + assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY)); + } - @Test - public void testValidPublicKeyByteArray() { - System.out.println("testValidPublicKeyByteArray"); - assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY.getBytes(StandardCharsets.UTF_8))); - } + @Test + public void testValidPublicKeyByteArray() { + System.out.println("testValidPublicKeyByteArray"); + assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY.getBytes(StandardCharsets.UTF_8))); + } - @Test - public void testInValidNullPublicKeyString() { - System.out.println("testInValidNullPublicKeyString"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey("")); - } + @Test + public void testInValidNullPublicKeyString() { + System.out.println("testInValidNullPublicKeyString"); + assertThrows(AssertionError.class, () -> new PublicKey("")); + } - @Test - public void testInValidPublicKeyNonHexDigits() { - System.out.println("testInValidPublicKeyNonHexDigits"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey(INVALID_HEXPUBKEY_NON_HEX_DIGITS)); - } + @Test + public void testInValidPublicKeyNonHexDigits() { + System.out.println("testInValidPublicKeyNonHexDigits"); + assertThrows(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_NON_HEX_DIGITS)); + } - @Test - public void testInValidPublicKeyLengthTooShort() { - System.out.println("testInValidPublicKeyLengthTooShort"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey(INVALID_HEXPUBKEY_LENGTH_TOO_SHORT)); - } + @Test + public void testInValidPublicKeyLengthTooShort() { + System.out.println("testInValidPublicKeyLengthTooShort"); + assertThrows(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_LENGTH_TOO_SHORT)); + } - @Test - public void testInValidPublicKeyLengthTooLong() { - System.out.println("testInValidPublicKeyLengthTooShort"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey(INVALID_HEXPUBKEY_LENGTH_TOO_LONG)); - } + @Test + public void testInValidPublicKeyLengthTooLong() { + System.out.println("testInValidPublicKeyLengthTooShort"); + assertThrows(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_LENGTH_TOO_LONG)); + } - @Test - public void testValidPublicKeyAllZeros() { - System.out.println("testValidPublicKeyAllZeros"); - assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY_ALL_ZEROS)); - } + @Test + public void testValidPublicKeyAllZeros() { + System.out.println("testValidPublicKeyAllZeros"); + assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY_ALL_ZEROS)); + } - @Test - public void testValidPublicKeyAllFF() { - System.out.println("testValidPublicKeyAllFF"); - assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY_ALL_FF)); - } + @Test + public void testValidPublicKeyAllFF() { + System.out.println("testValidPublicKeyAllFF"); + assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY_ALL_FF)); + } - @Test - public void testInvalidPublicKeyMultipleUppercase() { - System.out.println("testInvalidPublicKeyMultipleUppercase"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey(INVALID_HEXPUBKEY_HAS_MULTIPLE_UPPERCASE)); - } + @Test + public void testInvalidPublicKeyMultipleUppercase() { + System.out.println("testInvalidPublicKeyMultipleUppercase"); + assertThrows(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_HAS_MULTIPLE_UPPERCASE)); + } - @Test - public void testInvalidPublicKeySingleUppercase() { - System.out.println("testInvalidPublicKeySingleUppercase"); - assertThrows(IllegalArgumentException.class, () -> new PublicKey(INVALID_HEXPUBKEY_HAS_SINGLE_UPPERCASE)); - } + @Test + public void testInvalidPublicKeySingleUppercase() { + System.out.println("testInvalidPublicKeySingleUppercase"); + assertThrows(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_HAS_SINGLE_UPPERCASE)); + } } diff --git a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java b/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java index 58c193211..f703d6472 100644 --- a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java +++ b/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java @@ -6,7 +6,7 @@ import nostr.crypto.schnorr.Schnorr; import nostr.event.impl.GenericEvent; import nostr.id.Identity; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; import org.junit.jupiter.api.Test; @@ -33,7 +33,7 @@ public void testBech32() { assertEquals(npub, Bech32.toBech32(Bech32Prefix.NPUB, hexPub)); assertEquals("56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f", Bech32.fromBech32(npub)); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { fail(ex); } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java index 78c8942b8..531be55db 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java @@ -9,11 +9,9 @@ import nostr.api.NIP44; import nostr.api.NIP52; import nostr.api.NIP57; -import nostr.api.NostrIF; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; import nostr.base.PrivateKey; -import nostr.base.PublicKey; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; import nostr.event.BaseTag; @@ -39,628 +37,591 @@ import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; -import java.io.InputStream; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.UUID; import static nostr.base.IEvent.MAPPER_AFTERBURNER; -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.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.*; + /** * @author eric */ +@ExtendWith(SpringExtension.class) +@SpringJUnitConfig(TestConfig.class) @ActiveProfiles("test") -public class ApiEventTest { +class ApiEventTest { + @Autowired + private Map relays; + + @Test + public void testNIP01CreateTextNoteEvent() throws NostrExceptionFactory { + System.out.println("testNIP01CreateTextNoteEvent"); + + var nip01 = new NIP01(Identity.generateRandomIdentity()); + var instance = nip01.createTextNoteEvent( + List.of(NIP01.createPubKeyTag(Identity.generateRandomIdentity().getPublicKey())), + "Hello simplified nostr-java!") + .getEvent(); + instance.update(); + + assertNotNull(instance.getId()); + assertNotNull(instance.getCreatedAt()); + assertNull(instance.getSignature()); + + final String bech32 = instance.toBech32(); + assertNotNull(bech32); + assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); + + await().atMost(Duration.ofSeconds(3)); + } - public static final String NOSTR_JAVA_PUBKEY = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; - - private static final Map RELAYS = getRelays(); + @Test + public void testNIP01SendTextNoteEvent() throws IOException { + System.out.println("testNIP01SendTextNoteEvent"); - @Test - public void testNIP01CreateTextNoteEvent() throws NostrException { - System.out.println("testNIP01CreateTextNoteEvent"); + var nip01 = new NIP01(Identity.generateRandomIdentity()); + var instance = nip01.createTextNoteEvent("Hello simplified nostr-java!").sign(); - PublicKey publicKey = new PublicKey(NOSTR_JAVA_PUBKEY); - var recipient = NIP01.createPubKeyTag(publicKey); - List tags = new ArrayList<>(); - tags.add(recipient); - Identity identity = Identity.generateRandomIdentity(); - var nip01 = new NIP01(identity); - var instance = nip01.createTextNoteEvent(tags, "Hello simplified nostr-java!") - .getEvent(); - instance.update(); + var response = instance.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip01.getEvent().getId(), ((OkMessage) response).getEventId()); - assertNotNull(instance.getId()); - assertNotNull(instance.getCreatedAt()); - assertNull(instance.getSignature()); + nip01.close(); + } - final String bech32 = instance.toBech32(); - assertNotNull(bech32); - assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); - } + @Test + public void testNIP04SendDirectMessage() throws IOException { + System.out.println("testNIP04SendDirectMessage"); - @Test - public void testNIP01SendTextNoteEvent() throws IOException { - System.out.println("testNIP01SendTextNoteEvent"); + var nip04 = new NIP04( + Identity.generateRandomIdentity(), + Identity.generateRandomIdentity().getPublicKey()); - Identity identity = Identity.generateRandomIdentity(); - var nip01 = new NIP01(identity); - var instance = nip01.createTextNoteEvent("Hello simplified nostr-java!").sign(); + var instance = nip04 + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") + .sign(); - var response = instance.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip01.getEvent().getId(), ((OkMessage) response).getEventId()); + var signature = instance.getEvent().getSignature(); + assertNotNull(signature); + var response = instance.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip04.getEvent().getId(), ((OkMessage) response).getEventId()); + nip04.close(); + } - nip01.close(); - } + @Test + public void testNIP44SendDirectMessage() throws IOException { + System.out.println("testNIP44SendDirectMessage"); + + var nip44 = new NIP44( + Identity.generateRandomIdentity(), + Identity.generateRandomIdentity().getPublicKey()); + + var instance = nip44 + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); + assertNotNull(instance.getEvent().getSignature()); + var response = instance.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip44.getEvent().getId(), ((OkMessage) response).getEventId()); + nip44.close(); + } - @Test - public void testNIP04SendDirectMessage() throws IOException { - System.out.println("testNIP04SendDirectMessage"); + @Test + public void testNIP01SendTextNoteEventGeoHashTag() throws IOException { + System.out.println("testNIP01SendTextNoteEventGeoHashTag"); - PublicKey nostr_java = new PublicKey(NOSTR_JAVA_PUBKEY); - Identity identity = Identity.generateRandomIdentity(); - var nip04 = new NIP04(identity, nostr_java); - var instance = nip04 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") - .sign(); + String targetString = "geohash_tag-location-testNIP01SendTextNoteEventGeoHashTag"; + GeohashTag geohashTag = new GeohashTag(targetString); - var signature = instance.getEvent().getSignature(); - assertNotNull(signature); - var response = instance.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip04.getEvent().getId(), ((OkMessage) response).getEventId()); - nip04.close(); - } + NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); + nip01.createTextNoteEvent(List.of(geohashTag), "GeohashTag Test location testNIP01SendTextNoteEventGeoHashTag").signAndSend(relays); - @Test - public void testNIP44SendDirectMessage() throws IOException { - System.out.println("testNIP44SendDirectMessage"); + Filters filters = new Filters( + new GeohashTagFilter<>(new GeohashTag(targetString))); - PublicKey nostr_java = new PublicKey(NOSTR_JAVA_PUBKEY); + List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); - Identity identity = Identity.generateRandomIdentity(); - var nip44 = new NIP44(identity, nostr_java); + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); + assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); - var instance = nip44 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); - assertNotNull(instance.getEvent().getSignature()); - var response = instance.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip44.getEvent().getId(), ((OkMessage) response).getEventId()); - nip44.close(); - } + nip01.close(); + } - @Test - public void testNIP01SendTextNoteEventGeoHashTag() throws IOException { - System.out.println("testNIP01SendTextNoteEventGeoHashTag"); + @Test + public void testNIP01SendTextNoteEventHashtagTag() throws IOException { + System.out.println("testNIP01SendTextNoteEventHashtagTag"); - Identity identity = Identity.generateRandomIdentity(); + String targetString = "hashtag-tag-value-testNIP01SendTextNoteEventHashtagTag"; + HashtagTag hashtagTag = new HashtagTag(targetString); - String targetString = "geohash_tag-location"; - GeohashTag geohashTag = new GeohashTag(targetString); - NIP01 nip01 = new NIP01<>(identity); + NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); + nip01.createTextNoteEvent(List.of(hashtagTag), "Hashtag Tag Test value testNIP01SendTextNoteEventHashtagTag").signAndSend(relays); - nip01.createTextNoteEvent(List.of(geohashTag), "GeohashTag Test location").signAndSend(Map.of("local", "ws://localhost:5555")); + Filters filters = new Filters( + new HashtagTagFilter<>(new HashtagTag(targetString))); - Filters filters = new Filters( - new GeohashTagFilter<>(new GeohashTag(targetString))); + List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); - List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); + assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); - assertFalse(result.isEmpty()); - assertEquals(2, result.size()); - assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); + nip01.close(); + } - nip01.close(); - } + @Test + public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException { + System.out.println("testNIP01SendTextNoteEventCustomGenericTag"); - @Test - public void testNIP01SendTextNoteEventHashtagTag() throws IOException { - System.out.println("testNIP01SendTextNoteEventHashtagTag"); + String targetString = "custom-generic-tag-testNIP01SendTextNoteEventCustomGenericTag"; + GenericTag genericTag = GenericTag.create("m", 1, targetString); - Identity identity = Identity.generateRandomIdentity(); + NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); + nip01.createTextNoteEvent(List.of(genericTag), "Custom Generic Tag Test testNIP01SendTextNoteEventCustomGenericTag").signAndSend(relays); - String targetString = "hashtag-tag-value"; - HashtagTag hashtagTag = new HashtagTag(targetString); - NIP01 nip01 = new NIP01<>(identity); + Filters filters = new Filters( + new GenericTagQueryFilter<>(new GenericTagQuery("#m", targetString))); - nip01.createTextNoteEvent(List.of(hashtagTag), "Hashtag Tag Test value").signAndSend(Map.of("local", "ws://localhost:5555")); + List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); - Filters filters = new Filters( - new HashtagTagFilter<>(new HashtagTag(targetString))); + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); - List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); + String matcher = """ + ["m","custom-generic-tag-testNIP01SendTextNoteEventCustomGenericTag"]"""; - assertFalse(result.isEmpty()); - assertEquals(2, result.size()); - assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); + assertTrue(result.stream().anyMatch(s -> s.contains(matcher))); - nip01.close(); - } + nip01.close(); + } - @Test - public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException { - System.out.println("testNIP01SendTextNoteEventCustomGenericTag"); + @Test + public void testFiltersListReturnSameSingularEvent() throws IOException { + System.out.println("testFiltersListReturnSameSingularEvent"); - Identity identity = Identity.generateRandomIdentity(); + String geoHashTagTarget = "geohash_tag-location_SameSingularEvent"; + GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); - String targetString = "custom-generic-tag"; - GenericTag genericTag = GenericTag.create("m", 1, targetString); - NIP01 nip01 = new NIP01<>(identity); - nip01.createTextNoteEvent(List.of(genericTag), "Custom Generic Tag Test").signAndSend(Map.of("local", "ws://localhost:5555")); + String genericTagTarget = "generic-tag-value_SameSingularEvent"; + GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); - Filters filters = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", targetString))); + NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); - List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); + nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays); - assertFalse(result.isEmpty()); - assertEquals(2, result.size()); + Filters filters1 = new Filters( + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget))); + Filters filters2 = new Filters( + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); - String matcher = """ - ["m","custom-generic-tag"]"""; + List result = nip01.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); - assertTrue(result.stream().anyMatch(s -> s.contains(matcher))); + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); + assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); - nip01.close(); - } + nip01.close(); + } - @Test - public void testFiltersListReturnSameSingularEvent() throws IOException { - System.out.println("testFiltersListReturnSameSingularEvent"); + @Test + public void testFiltersListReturnTwoDifferentEvents() throws IOException { + System.out.println("testFiltersListReturnTwoDifferentEvents"); - Identity identity = Identity.generateRandomIdentity(); +// first event + String geoHashTagTarget1 = "geohash_tag-location-1"; + GeohashTag geohashTag1 = new GeohashTag(geoHashTagTarget1); + String genericTagTarget1 = "generic-tag-value-1"; + GenericTag genericTag1 = GenericTag.create("m", 1, genericTagTarget1); + NIP01 nip01_1 = new NIP01<>(Identity.generateRandomIdentity()); + nip01_1.createTextNoteEvent(List.of(geohashTag1, genericTag1), "Multiple Filters 1").signAndSend(relays); - String geoHashTagTarget = "geohash_tag-location_SameSingularEvent"; - GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); +// second event + String geoHashTagTarget2 = "geohash_tag-location-2"; + GeohashTag geohashTag2 = new GeohashTag(geoHashTagTarget2); + String genericTagTarget2 = "generic-tag-value-2"; + GenericTag genericTag2 = GenericTag.create("m", 1, genericTagTarget2); + NIP01 nip01_2 = new NIP01<>(Identity.generateRandomIdentity()); + nip01_2.createTextNoteEvent(List.of(geohashTag2, genericTag2), "Multiple Filters 2").signAndSend(relays); - String genericTagTarget = "generic-tag-value_SameSingularEvent"; - GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); + Filters filters1 = new Filters( + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget1))); // 1st filter should find match in 1st event - NIP01 nip01 = new NIP01<>(identity); + Filters filters2 = new Filters( + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget2))); // 2nd filter should find match in 2nd event - nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(Map.of("local", "ws://localhost:5555")); + List result = nip01_1.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); - Filters filters1 = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget))); - Filters filters2 = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); + assertFalse(result.isEmpty()); + assertEquals(3, result.size()); + assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget1))); + assertTrue(result.stream().anyMatch(s -> s.contains(genericTagTarget2))); - List result = nip01.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); + nip01_1.close(); + nip01_2.close(); + } - assertFalse(result.isEmpty()); - assertEquals(2, result.size()); - assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); + @Test + public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOException { + System.out.println("testMultipleFilters"); - nip01.close(); - } + String geoHashTagTarget = "geohash_tag-location-DifferentTypesReturnSameEvent"; + GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); - @Test - public void testFiltersListReturnTwoDifferentEvents() throws IOException { - System.out.println("testFiltersListReturnTwoDifferentEvents"); + String genericTagTarget = "generic-tag-value-DifferentTypesReturnSameEvent"; + GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); -// first event - Identity identity1 = Identity.generateRandomIdentity(); - String geoHashTagTarget1 = "geohash_tag-location-1"; - GeohashTag geohashTag1 = new GeohashTag(geoHashTagTarget1); - String genericTagTarget1 = "generic-tag-value-1"; - GenericTag genericTag1 = GenericTag.create("m", 1, genericTagTarget1); - NIP01 nip01_1 = new NIP01<>(identity1); - nip01_1.createTextNoteEvent(List.of(geohashTag1, genericTag1), "Multiple Filters 1").signAndSend(Map.of("local", "ws://localhost:5555")); + NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); + nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays); -// second event - Identity identity2 = Identity.generateRandomIdentity(); - String geoHashTagTarget2 = "geohash_tag-location-2"; - GeohashTag geohashTag2 = new GeohashTag(geoHashTagTarget2); - String genericTagTarget2 = "generic-tag-value-2"; - GenericTag genericTag2 = GenericTag.create("m", 1, genericTagTarget2); - NIP01 nip01_2 = new NIP01<>(identity2); - nip01_2.createTextNoteEvent(List.of(geohashTag2, genericTag2), "Multiple Filters 2").signAndSend(Map.of("local", "ws://localhost:5555")); + Filters filters = new Filters( + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget)), + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); + + List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); + + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); + assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); + + nip01.close(); + } + + @Test + public void testNIP04EncryptDecrypt() { + System.out.println("testNIP04EncryptDecrypt"); - Filters filters1 = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget1))); // 1st filter should find match in 1st event + Identity identity = Identity.generateRandomIdentity(); + var nip04 = new NIP04(identity, Identity.generateRandomIdentity().getPublicKey()); + var instance = nip04 + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") + .sign(); - Filters filters2 = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget2))); // 2nd filter should find match in 2nd event + var message = NIP04.decrypt(identity, instance.getEvent()); - List result = nip01_1.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); + assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message); + } - assertFalse(result.isEmpty()); - assertEquals(3, result.size()); - assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget1))); - assertTrue(result.stream().anyMatch(s -> s.contains(genericTagTarget2))); + @Test + public void testNIP44EncryptDecrypt() { + System.out.println("testNIP44EncryptDecrypt"); - nip01_1.close(); - nip01_2.close(); - } + Identity identity = Identity.generateRandomIdentity(); + var nip44 = new NIP44(identity, Identity.generateRandomIdentity().getPublicKey()); - @Test - public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOException { - System.out.println("testMultipleFilters"); + var instance = nip44 + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); + var message = NIP44.decrypt(identity, instance.getEvent()); - Identity identity = Identity.generateRandomIdentity(); + assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message); + } - String geoHashTagTarget = "geohash_tag-location-DifferentTypesReturnSameEvent"; - GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); + @Test + public void testNIP15CreateStallEvent() throws JsonProcessingException { + System.out.println("testNIP15CreateStallEvent"); - String genericTagTarget = "generic-tag-value-DifferentTypesReturnSameEvent"; - GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); + Stall stall = createStall(); + var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); - NIP01 nip01 = new NIP01<>(identity); + // Create and send the nostr event + var instance = nip15.createCreateOrUpdateStallEvent(stall).sign(); + var signature = instance.getEvent().getSignature(); + assertNotNull(signature); - nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(Map.of("local", "ws://localhost:5555")); + // Fetch the content and compare with the above original + var content = instance.getEvent().getContent(); + var expected = MAPPER_AFTERBURNER.readValue(content, Stall.class); - Filters filters = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget)), - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); + assertEquals(expected, stall); + } - List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); + @Test + public void testNIP15UpdateStallEvent() throws IOException { + System.out.println("testNIP15UpdateStallEvent"); - assertFalse(result.isEmpty()); - assertEquals(2, result.size()); - assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); + var stall = createStall(); + var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); - nip01.close(); - } + // Create and send the nostr event + var instance = nip15.createCreateOrUpdateStallEvent(stall).sign(); + var signature = instance.getEvent().getSignature(); + assertNotNull(signature); - @Test - public void testNIP04EncryptDecrypt() { - System.out.println("testNIP04EncryptDecrypt"); + var response = instance.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - var nostr_java = new PublicKey(NOSTR_JAVA_PUBKEY); - Identity identity = Identity.generateRandomIdentity(); - var nip04 = new NIP04(identity, nostr_java); - var instance = nip04 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") - .sign(); + // Update the shipping + var shipping = stall.getShipping(); + shipping.setCost(20.00f); - var message = NIP04.decrypt(identity, instance.getEvent()); + EventNostr event = nip15.createCreateOrUpdateStallEvent(stall).sign(); + response = event.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message); - } + nip15.close(); + } - @Test - public void testNIP44EncryptDecrypt() { - System.out.println("testNIP44EncryptDecrypt"); + @Test + public void testNIP15CreateProductEvent() throws IOException { - var nostr_java = new PublicKey(NOSTR_JAVA_PUBKEY); + System.out.println("testNIP15CreateProductEvent"); - Identity identity = Identity.generateRandomIdentity(); - var nip44 = new NIP44(identity, nostr_java); + // Create the stall object + var stall = createStall(); + var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); - var instance = nip44 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); - var message = NIP44.decrypt(identity, instance.getEvent()); + // Create the product + var product = createProduct(stall); - assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message); - } + List categories = new ArrayList<>(); + categories.add("bijoux"); + categories.add("Hommes"); - @Test - public void testNIP15CreateStallEvent() throws JsonProcessingException { - System.out.println("testNIP15CreateStallEvent"); + EventNostr event = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); + var response = event.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - Stall stall = createStall(); - var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); + nip15.close(); + } - // Create and send the nostr event - var instance = nip15.createCreateOrUpdateStallEvent(stall).sign(); - var signature = instance.getEvent().getSignature(); - assertNotNull(signature); + @Test + public void testNIP15UpdateProductEvent() throws IOException { - // Fetch the content and compare with the above original - var content = instance.getEvent().getContent(); - var expected = MAPPER_AFTERBURNER.readValue(content, Stall.class); + System.out.println("testNIP15UpdateProductEvent"); - assertEquals(expected, stall); - } + // Create the stall object + var stall = createStall(); + var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); - @Test - public void testNIP15UpdateStallEvent() throws IOException { - System.out.println("testNIP15UpdateStallEvent"); + // Create the product + var product = createProduct(stall); - var stall = createStall(); - var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); + List categories = new ArrayList<>(); + categories.add("bijoux"); + categories.add("Hommes"); - // Create and send the nostr event - var instance = nip15.createCreateOrUpdateStallEvent(stall).sign(); - var signature = instance.getEvent().getSignature(); - assertNotNull(signature); + EventNostr event1 = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); + var response = event1.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - var response = instance.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); + product.setDescription("Un nouveau bijou en or"); + categories.add("bagues"); - // Update the shipping - var shipping = stall.getShipping(); - shipping.setCost(20.00f); + EventNostr event2 = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); + response = event2.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - EventNostr event = nip15.createCreateOrUpdateStallEvent(stall).sign(); - response = event.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); + nip15.close(); + } - nip15.close(); - } + @Test + public void testNIP32CreateNameSpace() { - @Test - public void testNIP15CreateProductEvent() throws IOException { + System.out.println("testNIP32CreateNameSpace"); - System.out.println("testNIP15CreateProductEvent"); + var langNS = NIP32.createNameSpaceTag("Languages"); - // Create the stall object - var stall = createStall(); - var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); + assertEquals("L", langNS.getCode()); + assertEquals(1, langNS.getAttributes().size()); + assertEquals("Languages", langNS.getAttributes().iterator().next().getValue()); + } - // Create the product - var product = createProduct(stall); + @Test + public void testNIP32CreateLabel1() { - List categories = new ArrayList<>(); - categories.add("bijoux"); - categories.add("Hommes"); + System.out.println("testNIP32CreateLabel1"); - EventNostr event = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); - var response = event.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); + var label = NIP32.createLabelTag("Languages", "english"); - nip15.close(); - } + assertEquals("l", label.getCode()); + assertEquals(2, label.getAttributes().size()); + assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); + } - @Test - public void testNIP15UpdateProductEvent() throws IOException { + @Test + public void testNIP32CreateLabel2() { - System.out.println("testNIP15UpdateProductEvent"); + System.out.println("testNIP32CreateLabel2"); - // Create the stall object - var stall = createStall(); - var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); + var metadata = new HashMap(); + metadata.put("article", "the"); + var label = NIP32.createLabelTag("Languages", "english", metadata); - // Create the product - var product = createProduct(stall); + assertEquals("l", label.getCode()); + assertEquals(3, label.getAttributes().size()); + assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}", 32)), + "{\\\"article\\\":\\\"the\\\"}"); + } - List categories = new ArrayList<>(); - categories.add("bijoux"); - categories.add("Hommes"); + @Test + public void testNIP52CalendarTimeBasedEventEvent() throws IOException { + System.out.println("testNIP52CalendarTimeBasedEventEvent"); - EventNostr event1 = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); - var response = event1.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); + CalendarContent calendarContent = CalendarContent.builder( + new IdentifierTag("UUID-CalendarTimeBasedEventTest"), + "Calendar Time-Based Event title", + 1716513986268L).build(); - product.setDescription("Un nouveau bijou en or"); - categories.add("bagues"); + calendarContent.setStartTzid("1687765220"); + calendarContent.setEndTzid("1687765230"); - EventNostr event2 = nip15.createCreateOrUpdateProductEvent(product, categories).sign(); - response = event2.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); + calendarContent.setLabels(List.of("english", "mycenaean greek")); - nip15.close(); - } + List tags = new ArrayList<>(); + tags.add(new PubKeyTag(Identity.generateRandomIdentity().getPublicKey(), + "ws://localhost:5555", + "ISSUER")); + tags.add(new PubKeyTag(Identity.generateRandomIdentity().getPublicKey(), + "", + "COUNTERPARTY")); - @Test - public void testNIP32CreateNameSpace() { + var nip52 = new NIP52<>(Identity.create(PrivateKey.generateRandomPrivKey())); + EventNostr event = nip52.createCalendarTimeBasedEvent(tags, "content", calendarContent).sign(); + var response = event.setRelays(relays).send(); + assertTrue(response instanceof OkMessage); + assertEquals(nip52.getEvent().getId(), ((OkMessage) response).getEventId()); - System.out.println("testNIP32CreateNameSpace"); + nip52.close(); + } - var langNS = NIP32.createNameSpaceTag("Languages"); + @Test + void testNIP57CreateZapRequestEvent() throws NostrExceptionFactory { + System.out.println("testNIP57CreateZapRequestEvent"); + + var nip57 = new NIP57(Identity.generateRandomIdentity()); + final String ZAP_REQUEST_CONTENT = "zap request content"; + final Long AMOUNT = 1232456L; + final String LNURL = "lnUrl"; + final String RELAYS_TAG = "ws://localhost:5555"; + ZapRequestEvent instance = nip57 + .createZapRequestEvent(Identity.generateRandomIdentity().getPublicKey(), new ArrayList(), ZAP_REQUEST_CONTENT, AMOUNT, LNURL, RELAYS_TAG).getEvent(); + instance.update(); + + assertNotNull(instance.getId()); + assertNotNull(instance.getCreatedAt()); + assertNotNull(instance.getContent()); + assertNull(instance.getSignature()); + + assertNotNull(instance.getZapRequest()); + assertNotNull(instance.getZapRequest().getRelaysTag()); + assertNotNull(instance.getZapRequest().getAmount()); + assertNotNull(instance.getZapRequest().getLnUrl()); + + assertEquals(ZAP_REQUEST_CONTENT, instance.getContent()); + assertTrue(instance.getZapRequest().getRelaysTag().getRelays().stream() + .anyMatch(relay -> relay.getUri().equals(RELAYS_TAG))); + assertEquals(AMOUNT, instance.getZapRequest().getAmount()); + assertEquals(LNURL, instance.getZapRequest().getLnUrl()); + + final String bech32 = instance.toBech32(); + assertNotNull(bech32); + assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); + } + + @Test + void testNIP57CreateZapReceiptEvent() throws NostrExceptionFactory { + System.out.println("testNIP57CreateZapReceiptEvent"); + + String zapRequestPubKeyTag = Identity.generateRandomIdentity().getPublicKey().toString(); + String zapRequestEventTag = Identity.generateRandomIdentity().getPublicKey().toString(); + String zapRequestAddressTag = Identity.generateRandomIdentity().getPublicKey().toString(); + final String ZAP_RECEIPT_IDENTIFIER = "ipsum"; + final String ZAP_RECEIPT_RELAY_URI = "ws://localhost:5555"; + final String BOLT_11 = "bolt11"; + final String DESCRIPTION_SHA256 = "descriptionSha256"; + final String PRE_IMAGE = "preimage"; + var nip57 = new NIP57(Identity.generateRandomIdentity()); + + ZapReceiptEvent instance = nip57.createZapReceiptEvent(zapRequestPubKeyTag, getBaseTags(), zapRequestEventTag, + zapRequestAddressTag, ZAP_RECEIPT_IDENTIFIER, ZAP_RECEIPT_RELAY_URI, BOLT_11, DESCRIPTION_SHA256, PRE_IMAGE) + .getEvent(); + instance.update(); + + assertNotNull(instance.getId()); + assertNotNull(instance.getCreatedAt()); + assertNull(instance.getSignature()); + + assertNotNull(instance.getZapReceipt()); + assertNotNull(instance.getZapReceipt().getBolt11()); + assertNotNull(instance.getZapReceipt().getDescriptionSha256()); + assertNotNull(instance.getZapReceipt().getPreimage()); + + assertEquals(BOLT_11, instance.getZapReceipt().getBolt11()); + assertEquals(DESCRIPTION_SHA256, instance.getZapReceipt().getDescriptionSha256()); + assertEquals(PRE_IMAGE, instance.getZapReceipt().getPreimage()); + + final String bech32 = instance.toBech32(); + assertNotNull(bech32); + assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); + } + + private static List getBaseTags() { + return new ArrayList(); + } - assertEquals("L", langNS.getCode()); - assertEquals(1, langNS.getAttributes().size()); - assertEquals("Languages", langNS.getAttributes().iterator().next().getValue()); - } + public static Stall createStall() { - @Test - public void testNIP32CreateLabel1() { + // Create the county list + List countries = new ArrayList<>(); + countries.add("France"); + countries.add("Canada"); + countries.add("Cameroun"); + + // Create the shipping object + var shipping = new CreateOrUpdateStallEvent.Stall.Shipping(); + shipping.setCost(12.00f); + shipping.setCountries(countries); + shipping.setName("French Countries"); + + // Create the stall object + var stall = new CreateOrUpdateStallEvent.Stall(); + stall.setCurrency("USD"); + stall.setDescription("This is a test stall"); + stall.setName("Maximus Primus"); + stall.setShipping(shipping); + + return stall; + } - System.out.println("testNIP32CreateLabel1"); - - var label = NIP32.createLabelTag("Languages", "english"); - - assertEquals("l", label.getCode()); - assertEquals(2, label.getAttributes().size()); - assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); - } - - @Test - public void testNIP32CreateLabel2() { - - System.out.println("testNIP32CreateLabel2"); - - var metadata = new HashMap(); - metadata.put("article", "the"); - var label = NIP32.createLabelTag("Languages", "english", metadata); - - assertEquals("l", label.getCode()); - assertEquals(3, label.getAttributes().size()); - assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}", 32)), - "{\\\"article\\\":\\\"the\\\"}"); - } - - @Test - public void testNIP52CalendarTimeBasedEventEvent() throws IOException { - System.out.println("testNIP52CalendarTimeBasedEventEvent"); - - CalendarContent calendarContent = CalendarContent.builder( - new IdentifierTag("UUID-CalendarTimeBasedEventTest"), - "Calendar Time-Based Event title", - 1716513986268L).build(); - - calendarContent.setStartTzid("1687765220"); - calendarContent.setEndTzid("1687765230"); - - calendarContent.setLabels(List.of("english", "mycenaean greek")); - - List tags = new ArrayList<>(); - tags.add(new PubKeyTag(new PublicKey("2bed79f81439ff794cf5ac5f7bff9121e257f399829e472c7a14d3e86fe76985"), - "ws://localhost:5555", - "ISSUER")); - tags.add(new PubKeyTag(new PublicKey("494001ac0c8af2a10f60f23538e5b35d3cdacb8e1cc956fe7a16dfa5cbfc4347"), - "", - "COUNTERPARTY")); - - var nip52 = new NIP52<>(Identity.create(PrivateKey.generateRandomPrivKey())); - EventNostr event = nip52.createCalendarTimeBasedEvent(tags, "content", calendarContent).sign(); - var response = event.setRelays(RELAYS).send(); - assertTrue(response instanceof OkMessage); - assertEquals(nip52.getEvent().getId(), ((OkMessage) response).getEventId()); - - nip52.close(); - } - - @Test - void testNIP57CreateZapRequestEvent() throws NostrException { - System.out.println("testNIP57CreateZapRequestEvent"); - - Identity sender = Identity.generateRandomIdentity(); - List baseTags = new ArrayList(); - PublicKey recipient = Identity.generateRandomIdentity().getPublicKey(); - var nip57 = new NIP57(sender); - final String ZAP_REQUEST_CONTENT = "zap request content"; - final Long AMOUNT = 1232456L; - final String LNURL = "lnUrl"; - final String RELAYS_TAG = "ws://localhost:5555"; - ZapRequestEvent instance = nip57 - .createZapRequestEvent(recipient, baseTags, ZAP_REQUEST_CONTENT, AMOUNT, LNURL, RELAYS_TAG).getEvent(); - instance.update(); - - assertNotNull(instance.getId()); - assertNotNull(instance.getCreatedAt()); - assertNotNull(instance.getContent()); - assertNull(instance.getSignature()); - - assertNotNull(instance.getZapRequest()); - assertNotNull(instance.getZapRequest().getRelaysTag()); - assertNotNull(instance.getZapRequest().getAmount()); - assertNotNull(instance.getZapRequest().getLnUrl()); - - assertEquals(ZAP_REQUEST_CONTENT, instance.getContent()); - assertTrue(instance.getZapRequest().getRelaysTag().getRelays().stream() - .anyMatch(relay -> relay.getUri().equals(RELAYS_TAG))); - assertEquals(AMOUNT, instance.getZapRequest().getAmount()); - assertEquals(LNURL, instance.getZapRequest().getLnUrl()); - - final String bech32 = instance.toBech32(); - assertNotNull(bech32); - assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); - } - - @Test - void testNIP57CreateZapReceiptEvent() throws NostrException { - System.out.println("testNIP57CreateZapReceiptEvent"); - - Identity sender = Identity.generateRandomIdentity(); - List baseTags = new ArrayList(); - String zapRequestPubKeyTag = Identity.generateRandomIdentity().getPublicKey().toString(); - String zapRequestEventTag = Identity.generateRandomIdentity().getPublicKey().toString(); - String zapRequestAddressTag = Identity.generateRandomIdentity().getPublicKey().toString(); - final String ZAP_RECEIPT_IDENTIFIER = "ipsum"; - final String ZAP_RECEIPT_RELAY_URI = "ws://localhost:5555"; - final String BOLT_11 = "bolt11"; - final String DESCRIPTION_SHA256 = "descriptionSha256"; - final String PRE_IMAGE = "preimage"; - var nip57 = new NIP57(sender); - - ZapReceiptEvent instance = nip57.createZapReceiptEvent(zapRequestPubKeyTag, baseTags, zapRequestEventTag, - zapRequestAddressTag, ZAP_RECEIPT_IDENTIFIER, ZAP_RECEIPT_RELAY_URI, BOLT_11, DESCRIPTION_SHA256, PRE_IMAGE) - .getEvent(); - instance.update(); - - assertNotNull(instance.getId()); - assertNotNull(instance.getCreatedAt()); - assertNull(instance.getSignature()); - - assertNotNull(instance.getZapReceipt()); - assertNotNull(instance.getZapReceipt().getBolt11()); - assertNotNull(instance.getZapReceipt().getDescriptionSha256()); - assertNotNull(instance.getZapReceipt().getPreimage()); - - assertEquals(BOLT_11, instance.getZapReceipt().getBolt11()); - assertEquals(DESCRIPTION_SHA256, instance.getZapReceipt().getDescriptionSha256()); - assertEquals(PRE_IMAGE, instance.getZapReceipt().getPreimage()); - - final String bech32 = instance.toBech32(); - assertNotNull(bech32); - assertEquals(Bech32Prefix.NOTE.getCode(), Bech32.decode(bech32).hrp); - } - - public static Stall createStall() { - - // Create the county list - List countries = new ArrayList<>(); - countries.add("France"); - countries.add("Canada"); - countries.add("Cameroun"); - - // Create the shipping object - var shipping = new CreateOrUpdateStallEvent.Stall.Shipping(); - shipping.setCost(12.00f); - shipping.setCountries(countries); - shipping.setName("French Countries"); - - // Create the stall object - var stall = new CreateOrUpdateStallEvent.Stall(); - stall.setCurrency("USD"); - stall.setDescription("This is a test stall"); - stall.setName("Maximus Primus"); - stall.setShipping(shipping); - - return stall; - } - - public static NostrMarketplaceEvent.Product createProduct(Stall stall) { - - // Create the product - var product = new NostrMarketplaceEvent.Product(); - product.setCurrency("USD"); - product.setDescription("Un bijou en or"); - product.setImages(new ArrayList<>()); - product.setName("Bague"); - product.setPrice(450.00f); - product.setQuantity(4); - List specs = new ArrayList<>(); - specs.add(new Spec("couleur", "or")); - specs.add(new Spec("poids", "150g")); - product.setSpecs(specs); - product.setStall(stall); - - return product; - } - - public static Map getRelays() { - Map relays = new HashMap<>(); - Properties properties = new Properties(); - try { - InputStream is = ApiEventTest.class.getClassLoader().getResourceAsStream("relays.properties"); - if (is != null) { - properties.load(is); - for (String key : properties.stringPropertyNames()) { - relays.put(key, properties.getProperty(key)); - } - } else { - throw new RuntimeException("Unable to find 'relays.properties' in the classpath"); - } - } catch (IOException e) { - e.printStackTrace(); + public static NostrMarketplaceEvent.Product createProduct(Stall stall) { + + // Create the product + var product = new NostrMarketplaceEvent.Product(); + product.setCurrency("USD"); + product.setDescription("Un bijou en or"); + product.setImages(new ArrayList<>()); + product.setName("Bague"); + product.setPrice(450.00f); + product.setQuantity(4); + List specs = new ArrayList<>(); + specs.add(new Spec("couleur", "or")); + specs.add(new Spec("poids", "150g")); + product.setSpecs(specs); + product.setStall(stall); + + return product; } - return relays; - } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java index 685c90dc5..f8b05fa68 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java @@ -6,9 +6,13 @@ import nostr.event.impl.GenericEvent; import nostr.event.message.EventMessage; import nostr.id.Identity; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; import java.util.ArrayList; @@ -18,56 +22,55 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static nostr.test.event.ApiEventTest.createProduct; import static nostr.test.event.ApiEventTest.createStall; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +@ExtendWith(SpringExtension.class) +@SpringJUnitConfig(TestConfig.class) +@ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientTest { - private static Map relays; - private SpringWebSocketClient springWebSocketClient; + private SpringWebSocketClient springWebSocketClient; - @BeforeAll - static void setupBeforeAll() { - relays = ApiEventTest.getRelays(); - } + @Autowired + Map relays; - @BeforeEach - void setupBeforeEach() { - relays.forEach((key, value) -> springWebSocketClient = new SpringWebSocketClient(value)); - } + @BeforeEach + void setupBeforeEach() { + relays.forEach((key, value) -> springWebSocketClient = new SpringWebSocketClient(value)); + } - @Test - void testNIP15SendProductEventUsingSpringWebSocketClient() throws IOException { - System.out.println("testNIP15CreateProductEventUsingSpringWebSocketClient"); - var product = createProduct(createStall()); + @Test + void testNIP15SendProductEventUsingSpringWebSocketClient() throws IOException { + System.out.println("testNIP15CreateProductEventUsingSpringWebSocketClient"); + var product = createProduct(createStall()); - List categories = new ArrayList<>(); - categories.add("bijoux"); - categories.add("Hommes"); + List categories = new ArrayList<>(); + categories.add("bijoux"); + categories.add("Hommes"); - var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); + var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey())); - GenericEvent event = nip15.createCreateOrUpdateProductEvent(product, categories).sign().getEvent(); - EventMessage message = new EventMessage(event); + GenericEvent event = nip15.createCreateOrUpdateProductEvent(product, categories).sign().getEvent(); + EventMessage message = new EventMessage(event); - String eventResponse = springWebSocketClient.send(message).stream().findFirst().get(); + String eventResponse = springWebSocketClient.send(message).stream().findFirst().orElseThrow(); - // Extract and compare only first 3 elements of the JSON array - var expectedArray = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(0).asText(); - var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(1).asText(); - var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); + // Extract and compare only first 3 elements of the JSON array + var expectedArray = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(0).asText(); + var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(1).asText(); + var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())).get(2).asBoolean(); - var actualArray = MAPPER_AFTERBURNER.readTree(eventResponse).get(0).asText(); - var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponse).get(1).asText(); - var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponse).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponse).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponse).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponse).get(2).asBoolean(); + assertEquals(expectedArray, actualArray, "First element should match"); + assertEquals(expectedSubscriptionId, actualSubscriptionId, "Subscription ID should match"); + assertEquals(expectedSuccess, actualSuccess, "Success flag should match"); - assertTrue(expectedArray.equals(actualArray), "First element should match"); - assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); - assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); + springWebSocketClient.closeSocket(); + } - springWebSocketClient.closeSocket(); - } - - private String expectedResponseJson(String sha256) { - return "[\"OK\",\"" + sha256 + "\",true,\"success: request processed\"]"; - } + private String expectedResponseJson(String sha256) { + return "[\"OK\",\"" + sha256 + "\",true,\"success: request processed\"]"; + } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java index 261274a82..95fc6d585 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test; -import nostr.base.IEncoder; import nostr.base.PublicKey; import nostr.base.Relay; import nostr.crypto.bech32.Bech32; @@ -18,7 +17,7 @@ import nostr.event.util.Nip05Validator; import nostr.id.Identity; import nostr.test.EntityFactory; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; @@ -145,7 +144,7 @@ public void testNip05Validator() { var nip05Validator = Nip05Validator.builder().nip05(nip05).publicKey(publicKey).build(); nip05Validator.validate(); - } catch (NostrException ex) { + } catch (NostrExceptionFactory ex) { fail(ex); } assertTrue(true); @@ -173,12 +172,12 @@ public void testEventIdConstraints() { String id63chars = "fc7f200c5bed175702bd06c7ca5dba90d3497e827350b42fc99c3a4fa276a71"; assertTrue( - assertThrows(IllegalArgumentException.class, () -> genericEvent.setId(id63chars)) + assertThrows(AssertionError.class, () -> genericEvent.setId(id63chars)) .getMessage().contains("[fc7f200c5bed175702bd06c7ca5dba90d3497e827350b42fc99c3a4fa276a71], length: [63], target length: [64]")); String id65chars = "fc7f200c5bed175702bd06c7ca5dba90d3497e827350b42fc99c3a4fa276a7123"; assertTrue( - assertThrows(IllegalArgumentException.class, () -> genericEvent.setId(id65chars)) + assertThrows(AssertionError.class, () -> genericEvent.setId(id65chars)) .getMessage().contains("[fc7f200c5bed175702bd06c7ca5dba90d3497e827350b42fc99c3a4fa276a7123], length: [65], target length: [64]")); } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java b/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java index 18b016199..3011df574 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java @@ -3,18 +3,16 @@ 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 static org.junit.jupiter.api.Assertions.*; public class SignatureTest { - @Test - public void testSignatureStringLength() { - assertDoesNotThrow(() -> - Signature.fromString("86f25c161fec51b9e441bdb2c09095d5f8b92fdce66cb80d9ef09fad6ce53eaa14c5e16787c42f5404905536e43ebec0e463aee819378a4acbe412c533e60546")); + @Test + public void testSignatureStringLength() { + assertDoesNotThrow(() -> + Signature.fromString("86f25c161fec51b9e441bdb2c09095d5f8b92fdce66cb80d9ef09fad6ce53eaa14c5e16787c42f5404905536e43ebec0e463aee819378a4acbe412c533e60546")); - assertTrue( - assertThrows(IllegalArgumentException.class, () -> Signature.fromString("86f25c161fec51b9e441bdb2c09095d5f8b92fdce66cb80d9ef09fad6ce53eaa14c5e16787c42f5404905536e43ebec0e463aee819378a4acbe412c533e60546a")) - .getMessage().contains("[129], target length: [128]")); - } + assertTrue( + assertThrows(AssertionError.class, () -> Signature.fromString("86f25c161fec51b9e441bdb2c09095d5f8b92fdce66cb80d9ef09fad6ce53eaa14c5e16787c42f5404905536e43ebec0e463aee819378a4acbe412c533e60546a")) + .getMessage().contains("[129], target length: [128]")); + } } diff --git a/nostr-java-test/src/test/java/nostr/test/event/TestConfig.java b/nostr-java-test/src/test/java/nostr/test/event/TestConfig.java new file mode 100644 index 000000000..6629f4b9f --- /dev/null +++ b/nostr-java-test/src/test/java/nostr/test/event/TestConfig.java @@ -0,0 +1,21 @@ +package nostr.test.event; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.TestPropertySource; + +import java.util.Map; +import java.util.ResourceBundle; +import java.util.stream.Collectors; + +@TestConfiguration +@TestPropertySource("classpath:relays.properties") +public class TestConfig { + + @Bean + public Map relays() { + ResourceBundle relaysBundle = ResourceBundle.getBundle("relays"); + return relaysBundle.keySet().stream() + .collect(Collectors.toMap(key -> key, relaysBundle::getString)); + } +} diff --git a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java index d30c099d3..554b40b4d 100644 --- a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java +++ b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java @@ -43,7 +43,7 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import nostr.test.util.JsonComparator; -import nostr.util.NostrException; +import nostr.util.NostrExceptionFactory; import org.junit.jupiter.api.Test; import java.math.BigDecimal; @@ -327,7 +327,7 @@ public void testClassifiedListingTagSerializer() throws JsonProcessingException } @Test - public void testDeserializeTag() throws NostrException { + public void testDeserializeTag() throws NostrExceptionFactory { log.info("testDeserializeTag"); String npubHex = new PublicKey(Bech32.fromBech32("npub1clk6vc9xhjp8q5cws262wuf2eh4zuvwupft03hy4ttqqnm7e0jrq3upup9")).toString(); @@ -343,7 +343,7 @@ public void testDeserializeTag() throws NostrException { } @Test - public void testDeserializeGenericTag() throws NostrException { + public void testDeserializeGenericTag() throws NostrExceptionFactory { log.info("testDeserializeGenericTag"); String npubHex = new PublicKey(Bech32.fromBech32("npub1clk6vc9xhjp8q5cws262wuf2eh4zuvwupft03hy4ttqqnm7e0jrq3upup9")).toString(); final String jsonString = "[\"gt\", \"" + npubHex + "\", \"wss://nostr.java\", \"alice\"]"; diff --git a/nostr-java-util/src/main/java/nostr/util/NostrException.java b/nostr-java-util/src/main/java/nostr/util/NostrException.java deleted file mode 100644 index 9c405b27d..000000000 --- a/nostr-java-util/src/main/java/nostr/util/NostrException.java +++ /dev/null @@ -1,12 +0,0 @@ -package nostr.util; - -import lombok.experimental.StandardException; - -/** - * - * @author squirrel - */ -@StandardException -public class NostrException extends Exception { - -} diff --git a/nostr-java-util/src/main/java/nostr/util/thread/HexStringValidator.java b/nostr-java-util/src/main/java/nostr/util/thread/HexStringValidator.java index e7da244be..6411b4ef0 100644 --- a/nostr-java-util/src/main/java/nostr/util/thread/HexStringValidator.java +++ b/nostr-java-util/src/main/java/nostr/util/thread/HexStringValidator.java @@ -1,52 +1,30 @@ package nostr.util.thread; import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.BiFunction; -import java.util.function.Function; +import java.util.Objects; +import java.util.function.BiPredicate; +import java.util.function.Predicate; public class HexStringValidator { - private static final String validHexChars = "0123456789abcdef"; + private static final String validHexChars = "0123456789abcdef"; - private static final BiFunction lengthCheck = (s, targetLength) -> s.length() == targetLength; - private static final Function hexCharsCheck = HexStringValidator::checkValidHexChars; - private static final Function upperCaseCheck = s -> s.toLowerCase().equals(s); + private static final BiPredicate lengthCheck = (s, l) -> Objects.equals(s.length(), l); + private static final Predicate hexCharsCheck = HexStringValidator::validHex; + private static final Predicate upperCaseCheck = s -> s.toLowerCase().equals(s); - public static void validateHex(@NonNull String hexString, int targetLength) { - List exceptions = new ArrayList<>(); - Optional.of(hexString) // non-null enforcement - .filter(s -> { - if (!lengthCheck.apply(s, targetLength)) { - return exceptions.add(String.format("Invalid hex string: [%s], length: [%d], target length: [%d]", hexString, hexString.length(), targetLength)); - } - return true; - }) - .filter(s -> { - if (!hexCharsCheck.apply(s)) { - exceptions.add(String.format("Invalid hex string: [%s] has non-hex characters", hexString)); - } - return true; - }) - .filter(s -> { - if (!upperCaseCheck.apply(s)) { - exceptions.add(String.format("Invalid hex string: [%s] has uppcase characters", hexString)); - } - return true; - }); - - if (!exceptions.isEmpty()) { - throw new IllegalArgumentException(exceptions.getFirst()); + public static void validateHex(@NonNull String hexString, int targetLength) { + // split into distinct checks per unique/specific error message + assert lengthCheck.test(hexString, targetLength) : + String.format("Invalid hex string: [%s], length: [%d], target length: [%d]", hexString, hexString.length(), targetLength); + assert hexCharsCheck.test(hexString) : + String.format("Invalid hex string: [%s] has non-hex characters", hexString); + assert upperCaseCheck.test(hexString) : + String.format("Invalid hex string: [%s] has upper-case characters", hexString); } - } - private static Boolean checkValidHexChars(String aHexString) { - for (char a : aHexString.toLowerCase().toCharArray()) { - if (validHexChars.indexOf(a) < 0) - return false; + private static Boolean validHex(String aHexString) { + return StringUtils.containsOnly(aHexString.toLowerCase(), validHexChars); } - return true; - } } From a84696cd20a869604278625730b861ea5225a3fc Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 14 Mar 2025 21:07:08 -0700 Subject: [PATCH 18/57] exceptions update --- build.gradle | 4 +- buildSrc/build.gradle | 4 +- .../groovy/buildlogic.java-conventions.gradle | 41 ++++++ ...xyz.tcheeric.nostr-java-conventions.gradle | 71 ---------- .../src/main/java/nostr/api/EventNostr.java | 2 +- .../nostr/api/NostrSpringWebSocketClient.java | 2 +- .../src/main/java/nostr/base/BaseKey.java | 3 +- .../src/main/java/nostr/base/UserProfile.java | 3 +- .../main/java/nostr/crypto/bech32/Bech32.java | 41 +++--- .../src/main/java/nostr/event/BaseTag.java | 8 +- .../java/nostr/event/impl/GenericEvent.java | 14 +- .../impl/InternetIdentifierMetadataEvent.java | 5 +- .../event/json/codec/BaseEventEncoder.java | 8 +- .../event/json/codec/OstEventEncoder.java | 116 ++++++++-------- .../event/json/serializer/TagSerializer.java | 6 +- .../java/nostr/event/util/Nip05Validator.java | 14 +- .../java/nostr/examples/NostrApiExamples.java | 4 +- .../src/main/java/nostr/id/Identity.java | 12 +- .../java/nostr/test/crypto/CryptoTest.java | 125 +++++++++--------- .../java/nostr/test/event/ApiEventTest.java | 7 +- .../test/java/nostr/test/event/EventTest.java | 4 +- .../java/nostr/test/json/JsonParseTest.java | 5 +- nostr-java-util/build.gradle | 2 + .../main/java/nostr/util/NostrException.java | 14 ++ .../nostr/util/config/ExceptionConfig.java | 5 + 25 files changed, 255 insertions(+), 265 deletions(-) create mode 100644 buildSrc/src/main/groovy/buildlogic.java-conventions.gradle delete mode 100644 buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle create mode 100644 nostr-java-util/src/main/java/nostr/util/NostrException.java create mode 100644 nostr-java-util/src/main/java/nostr/util/config/ExceptionConfig.java diff --git a/build.gradle b/build.gradle index b2c6a4bd9..55fe9620c 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id 'org.gradle.test-retry' version '1.6.2' id 'groovy-gradle-plugin' - id 'java-library' + id 'java-library' } group = 'xyz.tcheeric' @@ -75,5 +75,5 @@ test { } bootJar { - enabled = false + enabled = false } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index b11a5e916..e66ea8027 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,6 +1,6 @@ plugins { -// id 'java' -// id 'io.freefair.lombok' version '8.12.2.1' + id 'java' + id 'io.freefair.lombok' version '8.12.2.1' id 'groovy-gradle-plugin' } diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle new file mode 100644 index 000000000..5d1f0cceb --- /dev/null +++ b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle @@ -0,0 +1,41 @@ +plugins { + id 'java' + id 'java-library' + id 'maven-publish' +} + +repositories { + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +group = 'xyz.tcheeric' +version = '0.6.5-SNAPSHOT' +description = 'nostr-java' +java.sourceCompatibility = JavaVersion.VERSION_21 +java.targetCompatibility = JavaVersion.VERSION_21 + +subprojects { + publishing { + publications { + maven(MavenPublication) { + artifactId = description + from(components.java) + } + } + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} + +tasks.withType(Javadoc).configureEach { + options.encoding = 'UTF-8' +} + +//tasks.build.finalizedBy() { +// tasks.publishToMavenLocal +//} diff --git a/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle b/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle deleted file mode 100644 index f571fb8c3..000000000 --- a/buildSrc/src/main/groovy/xyz.tcheeric.nostr-java-conventions.gradle +++ /dev/null @@ -1,71 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '3.4.3' - id 'io.spring.dependency-management' version '1.1.7' - - id 'io.freefair.lombok' version '8.12.2.1' - id 'com.adarshr.test-logger' version '4.0.0' - id 'org.gradle.test-retry' version '1.6.2' - - id 'groovy-gradle-plugin' - id 'java-library' -} - -repositories { - mavenLocal() - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } -} - -group = 'xyz.tcheeric-conventions' -version = '0.6.5-SNAPSHOT' -description = 'nostr-java' -java.sourceCompatibility = JavaVersion.VERSION_21 -java.targetCompatibility = JavaVersion.VERSION_21 - -dependencies { - def springBootVersion = '3.4.3' - def apacheCommonsLang3 = '3.17.0' - def jacksonModuleAfterburner = '2.18.3' - def googleGuava = '33.2.1-jre' - def bouncyCastle = '1.80' - def awaitility = '4.2.0' - def lombok = '1.18.36' - - implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion - implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 - implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle - - implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion - - implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner - implementation 'com.google.guava:guava:' + googleGuava - - testImplementation 'org.awaitility:awaitility:' + awaitility - testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - - implementation 'org.projectlombok:lombok:' + lombok - annotationProcessor 'org.projectlombok:lombok:' + lombok - testImplementation 'org.projectlombok:lombok:' + lombok - testAnnotationProcessor 'org.projectlombok:lombok:' + lombok -} - -subprojects { - publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } - } -} - -//tasks.build.finalizedBy() { -// tasks.publishToMavenLocal -//} 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 462d33a98..564839acb 100644 --- a/nostr-java-api/src/main/java/nostr/api/EventNostr.java +++ b/nostr-java-api/src/main/java/nostr/api/EventNostr.java @@ -37,7 +37,7 @@ public EventNostr(@NonNull Identity sender) { super(sender); } - public EventNostr sign() throws Exception { + public EventNostr sign() { super.sign(getSender(), event); return this; } 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 e0b0171ff..31ba1a3eb 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java @@ -115,7 +115,7 @@ public List sendRequest(@NonNull Filters filters, @NonNull String subscr @Override - public NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) throws Exception { + public NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) { identity.sign(signable); return this; } 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 965a33408..bd13d13b6 100644 --- a/nostr-java-base/src/main/java/nostr/base/BaseKey.java +++ b/nostr-java-base/src/main/java/nostr/base/BaseKey.java @@ -7,7 +7,6 @@ import lombok.NonNull; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; -import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; import java.util.Arrays; @@ -32,7 +31,7 @@ public abstract class BaseKey implements IKey { public String toBech32String() { try { return Bech32.toBech32(prefix, rawData); - } catch (NostrExceptionFactory ex) { + } catch (Exception ex) { throw new RuntimeException(ex); } } diff --git a/nostr-java-base/src/main/java/nostr/base/UserProfile.java b/nostr-java-base/src/main/java/nostr/base/UserProfile.java index ae1bc5320..0f0f50f46 100644 --- a/nostr-java-base/src/main/java/nostr/base/UserProfile.java +++ b/nostr-java-base/src/main/java/nostr/base/UserProfile.java @@ -12,7 +12,6 @@ import lombok.extern.java.Log; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; -import nostr.util.NostrExceptionFactory; /** * @@ -39,7 +38,7 @@ public UserProfile(@NonNull PublicKey publicKey, String name, String nip05, Stri public String toBech32() { try { return Bech32.encode(Bech32.Encoding.BECH32, Bech32Prefix.NPROFILE.getCode(), this.publicKey.getRawData()); - } catch (NostrExceptionFactory ex) { + } catch (Exception ex) { log.log(Level.SEVERE, null, ex); throw new RuntimeException(ex); } 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 125f581c7..9b8efd790 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 @@ -5,7 +5,6 @@ import java.util.List; import java.util.Locale; -import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; /** @@ -61,20 +60,20 @@ private Bech32Data(final Encoding encoding, final String hrp, final byte[] data) } } - public static String toBech32(Bech32Prefix hrp, byte[] hexKey) throws NostrExceptionFactory { + public static String toBech32(Bech32Prefix hrp, byte[] hexKey) throws Exception { byte[] data = convertBits(hexKey, 8, 5, true); return Bech32.encode(Bech32.Encoding.BECH32, hrp.getCode(), data); } - public static String toBech32(Bech32Prefix hrp, String hexKey) throws NostrExceptionFactory { + public static String toBech32(Bech32Prefix hrp, String hexKey) throws Exception { byte[] data = NostrUtil.hexToBytes(hexKey); return toBech32(hrp, data); } // Added by squirrel - public static String fromBech32(String strBech32) throws NostrExceptionFactory { + public static String fromBech32(String strBech32) throws Exception { byte[] data = Bech32.decode(strBech32).data; data = convertBits(data, 5, 8, true); @@ -93,9 +92,9 @@ public static String fromBech32(String strBech32) throws NostrExceptionFactory { * * @param bech32 * @return - * @throws NostrExceptionFactory + * @throws nostr.util.Exception */ - public static String encode(final Bech32Data bech32) throws NostrExceptionFactory { + public static String encode(final Bech32Data bech32) throws Exception { return encode(bech32.encoding, bech32.hrp, bech32.data); } @@ -106,12 +105,12 @@ public static String encode(final Bech32Data bech32) throws NostrExceptionFactor * @param hrp * @param values * @return - * @throws NostrExceptionFactory + * @throws nostr.util.Exception */ - // Modified to throw NostrExceptions - public static String encode(Encoding encoding, String hrp, final byte[] values) throws NostrExceptionFactory { + // Modified to throw Exceptions + public static String encode(Encoding encoding, String hrp, final byte[] values) throws Exception { if (hrp.isEmpty()) { - throw new NostrExceptionFactory("Human-readable part is too short"); + throw new Exception("Human-readable part is too short"); } hrp = hrp.toLowerCase(Locale.ROOT); @@ -133,53 +132,53 @@ public static String encode(Encoding encoding, String hrp, final byte[] values) * * @param str * @return - * @throws NostrExceptionFactory + * @throws nostr.util.Exception */ - // Modified to throw NostrExceptions - public static Bech32Data decode(final String str) throws NostrExceptionFactory { + // Modified to throw Exceptions + public static Bech32Data decode(final String str) throws Exception { boolean lower = false, upper = false; if (str.length() < 8) { - throw new NostrExceptionFactory("Input too short: " + str.length()); + throw new Exception("Input too short: " + str.length()); } for (int i = 0; i < str.length(); ++i) { char c = str.charAt(i); if (c < 33 || c > 126) { - throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); + throw new Exception(String.format("Invalid Character %c, %d", c, i)); } if (c >= 'a' && c <= 'z') { if (upper) { - throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); + throw new Exception(String.format("Invalid Character %c, %d", c, i)); } lower = true; } if (c >= 'A' && c <= 'Z') { if (lower) { - throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i)); + throw new Exception(String.format("Invalid Character %c, %d", c, i)); } upper = true; } } final int pos = str.lastIndexOf('1'); if (pos < 1) { - throw new NostrExceptionFactory("Missing human-readable part"); + throw new Exception("Missing human-readable part"); } final int dataPartLength = str.length() - 1 - pos; if (dataPartLength < 6) { - throw new NostrExceptionFactory(String.format("Data part too short: %d)", dataPartLength)); + throw new Exception(String.format("Data part too short: %d)", dataPartLength)); } byte[] values = new byte[dataPartLength]; for (int i = 0; i < dataPartLength; ++i) { char c = str.charAt(i + pos + 1); if (CHARSET_REV[c] == -1) { - throw new NostrExceptionFactory(String.format("Invalid Character %c, %d", c, i + pos + 1)); + throw new Exception(String.format("Invalid Character %c, %d", c, i + pos + 1)); } values[i] = CHARSET_REV[c]; } String hrp = str.substring(0, pos).toLowerCase(Locale.ROOT); Encoding encoding = verifyChecksum(hrp, values); if (encoding == null) { - throw new NostrExceptionFactory("InvalidChecksum"); + throw new Exception("InvalidChecksum"); } return new Bech32Data(encoding, hrp, Arrays.copyOfRange(values, 0, values.length - 6)); } 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 cdcacc56c..f8a7bd2e2 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -14,7 +14,7 @@ import nostr.base.annotation.Tag; import nostr.event.json.deserializer.TagDeserializer; import nostr.event.json.serializer.TagSerializer; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import org.apache.commons.lang3.stream.Streams; import java.beans.IntrospectionException; @@ -57,16 +57,16 @@ public Integer getNip() { return 1; } - public String getFieldValue(Field field) throws NostrExceptionFactory { + public String getFieldValue(Field field) throws NostrException { try { Object f = new PropertyDescriptor(field.getName(), this.getClass()).getReadMethod().invoke(this); return f != null ? f.toString() : null; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException ex) { - throw new NostrExceptionFactory(ex); + throw new NostrException(ex); } } - public List getSupportedFields() throws NostrExceptionFactory { + public List getSupportedFields() throws NostrException { return new Streams.FailableStream<>(Arrays.stream(this.getClass().getDeclaredFields())) .filter(f -> Objects.nonNull(f.getAnnotation(Key.class))) 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 0df39092b..74109dcf6 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 @@ -24,7 +24,7 @@ import nostr.event.Kind; import nostr.event.json.deserializer.PublicKeyDeserializer; import nostr.event.json.deserializer.SignatureDeserializer; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import nostr.util.NostrUtil; import nostr.util.thread.HexStringValidator; @@ -148,8 +148,8 @@ public String toBech32() { try { return Bech32.toBech32(Bech32Prefix.NOTE, this.getId()); - } catch (NostrExceptionFactory ex) { - throw new RuntimeException(ex); + } catch (Exception e) { + throw new RuntimeException(e); } } @@ -182,7 +182,7 @@ public void update() { this._serializedEvent = this.serialize().getBytes(StandardCharsets.UTF_8); this.id = NostrUtil.bytesToHex(NostrUtil.sha256(_serializedEvent)); - } catch (NostrExceptionFactory | NoSuchAlgorithmException ex) { + } catch (NostrException | NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } catch (AssertionError ex) { log.log(Level.WARNING, ex.getMessage()); @@ -204,7 +204,7 @@ protected void validate() { } - private String serialize() throws NostrExceptionFactory { + private String serialize() throws NostrException { var mapper = I_ENCODER_MAPPER_AFTERBURNER; var arrayNode = JsonNodeFactory.instance.arrayNode(); @@ -218,15 +218,17 @@ private String serialize() throws NostrExceptionFactory { return mapper.writeValueAsString(arrayNode); } catch (JsonProcessingException e) { - throw new NostrExceptionFactory(e); + throw new NostrException(e); } } + @Transient @Override public Consumer getSignatureConsumer() { return this::setSignature; } + @Transient @Override public Supplier getByeArraySupplier() { this.update(); 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 0662f9e4b..5ab5b07b3 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 @@ -3,6 +3,7 @@ import static nostr.util.NostrUtil.escapeJsonString; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; @@ -14,7 +15,7 @@ import nostr.event.Kind; import nostr.event.NIP05Event; import nostr.event.util.Nip05Validator; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; /** * @@ -36,7 +37,7 @@ private void init(UserProfile profile) { Nip05Validator.builder().nip05(profile.getNip05()).publicKey(profile.getPublicKey()).build().validate(); setContent(profile); - } catch (NostrExceptionFactory ex) { + } catch (NostrException ex) { throw new RuntimeException(ex); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java index c93e25d3a..0afbfe0f8 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java @@ -4,7 +4,7 @@ import lombok.Data; import nostr.base.IEncoder; import nostr.event.BaseEvent; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; /** * @author guilhermegps @@ -23,16 +23,16 @@ public BaseEventEncoder(T event) { public String encode() { try { return toJson(); - } catch (NostrExceptionFactory ex) { + } catch (NostrException ex) { throw new RuntimeException(ex); } } - protected String toJson() throws NostrExceptionFactory { + protected String toJson() throws NostrException { try { return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(event); } catch (JsonProcessingException e) { - throw new NostrExceptionFactory(e); + throw new NostrException(e); } } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java index 9c0fda925..0cd4edbdf 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java @@ -1,58 +1,58 @@ -package nostr.event.json.codec; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import java.util.HashMap; -import lombok.AllArgsConstructor; - -import lombok.Data; -import nostr.base.ElementAttribute; -import nostr.base.IEncoder; -import nostr.base.Relay; -import nostr.event.impl.OtsEvent; -import nostr.util.NostrExceptionFactory; - -/** - * @author guilhermegps - * - */ -@Data -@AllArgsConstructor -public class OstEventEncoder implements IEncoder { - - private final OtsEvent event; - private final Relay relay; - - public OstEventEncoder(OtsEvent event) { - this(event, null); - } - - @Override - public String encode() { - try { - return toJson(); - } catch (NostrExceptionFactory ex) { - throw new RuntimeException(ex); - } - } - - private String toJson() throws NostrExceptionFactory { - try { - JsonNode node = I_ENCODER_MAPPER_AFTERBURNER.valueToTree(event); - ObjectNode objNode = (ObjectNode) node; - event.getAttributes().parallelStream() - .map(ElementAttribute::getValue) - .forEach(ev -> { - var expression = (HashMap) ev; - - objNode.set("ots", I_ENCODER_MAPPER_AFTERBURNER.valueToTree(expression.get("ots"))); - }); - - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(node); - } catch (JsonProcessingException | IllegalArgumentException e) { - throw new NostrExceptionFactory(e); - } - } - -} +//package nostr.event.json.codec; +// +//import com.fasterxml.jackson.core.JsonProcessingException; +//import com.fasterxml.jackson.databind.JsonNode; +//import com.fasterxml.jackson.databind.node.ObjectNode; +//import java.util.HashMap; +//import lombok.AllArgsConstructor; +// +//import lombok.Data; +//import nostr.base.ElementAttribute; +//import nostr.base.IEncoder; +//import nostr.base.Relay; +//import nostr.event.impl.OtsEvent; +//import nostr.util.NostrException; +// +///** +// * @author guilhermegps +// * +// */ +//@Data +//@AllArgsConstructor +//public class OstEventEncoder implements IEncoder { +// +// private final OtsEvent event; +// private final Relay relay; +// +// public OstEventEncoder(OtsEvent event) { +// this(event, null); +// } +// +// @Override +// public String encode() { +// try { +// return toJson(); +// } catch (NostrException ex) { +// throw new RuntimeException(ex); +// } +// } +// +// private String toJson() throws NostrException { +// try { +// JsonNode node = I_ENCODER_MAPPER_AFTERBURNER.valueToTree(event); +// ObjectNode objNode = (ObjectNode) node; +// event.getAttributes().parallelStream() +// .map(ElementAttribute::getValue) +// .forEach(ev -> { +// var expression = (HashMap) ev; +// +// objNode.set("ots", I_ENCODER_MAPPER_AFTERBURNER.valueToTree(expression.get("ots"))); +// }); +// +// return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(node); +// } catch (JsonProcessingException | IllegalArgumentException e) { +// throw new NostrException(e); +// } +// } +// +//} 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 ec0a425a3..9c40e03e4 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 @@ -9,7 +9,7 @@ import nostr.base.ElementAttribute; import nostr.event.BaseTag; import nostr.event.impl.GenericTag; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import java.io.IOException; import java.io.Serial; @@ -40,7 +40,7 @@ public void serialize(BaseTag value, JsonGenerator gen, SerializerProvider seria fields.forEach((Field f) -> { try { node.put(f.getName(), value.getFieldValue(f)); - } catch (NostrExceptionFactory ex) { + } catch (NostrException ex) { throw new RuntimeException(ex); } }); @@ -64,7 +64,7 @@ public void serialize(BaseTag value, JsonGenerator gen, SerializerProvider seria throw new AssertionError("node.isObject()", new RuntimeException()); } - } catch (IOException | NostrExceptionFactory e) { + } catch (IOException | NostrException e) { throw new RuntimeException(e); } } diff --git a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java index 3b913a50f..e9589f477 100644 --- a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java +++ b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java @@ -6,7 +6,7 @@ import nostr.base.PublicKey; import nostr.event.Nip05Content; import nostr.event.json.codec.Nip05ContentDecoder; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import java.io.BufferedReader; import java.io.IOException; @@ -32,14 +32,14 @@ public class Nip05Validator { private static final String LOCAL_PART_PATTERN = "^[a-zA-Z0-9-_\\.]+$"; - public void validate() throws NostrExceptionFactory { + public void validate() throws NostrException { if (this.nip05 != null) { var splited = nip05.split("@"); var localPart = splited[0]; var domain = splited[1]; if (!localPart.matches(LOCAL_PART_PATTERN)) { - throw new NostrExceptionFactory("Invalid syntax in nip05 attribute."); + throw new NostrException("Invalid syntax in nip05 attribute."); } // Verify the public key @@ -48,12 +48,12 @@ public void validate() throws NostrExceptionFactory { validatePublicKey(domain, localPart); } catch (IOException | URISyntaxException ex) { log.log(Level.SEVERE, ex.getMessage()); - throw new NostrExceptionFactory(ex); + throw new NostrException(ex); } } } - private void validatePublicKey(String domain, String localPart) throws NostrExceptionFactory, IOException, URISyntaxException { + private void validatePublicKey(String domain, String localPart) throws NostrException, IOException, URISyntaxException { // Set up and estgetPublicKeyablish the HTTP connection String strUrl = "https:///.well-known/nostr.json?name=".replace("", domain).replace("", localPart); @@ -75,14 +75,14 @@ private void validatePublicKey(String domain, String localPart) throws NostrExce log.log(Level.FINE, "Public key for {0} returned by the server: [{1}]", new Object[]{localPart, pubKey}); if (pubKey != null && !pubKey.equals(publicKey.toString())) { - throw new NostrExceptionFactory(String.format("Public key mismatch. Expected %s - Received: %s", publicKey, pubKey)); + throw new NostrException(String.format("Public key mismatch. Expected %s - Received: %s", publicKey, pubKey)); } // All well! return; } - throw new NostrExceptionFactory(String.format("Failed to connect to %s. Error message: %s", strUrl, connection.getResponseMessage())); + throw new NostrException(String.format("Failed to connect to %s. Error message: %s", strUrl, connection.getResponseMessage())); } private String getPublicKey(StringBuilder content, String localPart) { 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 89104e124..b2316ca45 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java +++ b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java @@ -35,7 +35,7 @@ import nostr.event.tag.EventTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import java.io.IOException; import java.io.InputStream; @@ -182,7 +182,7 @@ public static void main(String[] args) throws Exception { } catch (IllegalArgumentException ex) { log.log(Level.SEVERE, null, ex); - throw new NostrExceptionFactory(ex); + throw new NostrException(ex); } } 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 3e0d610c2..aa29f0911 100644 --- a/nostr-java-id/src/main/java/nostr/id/Identity.java +++ b/nostr-java-id/src/main/java/nostr/id/Identity.java @@ -3,6 +3,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; +import lombok.SneakyThrows; import lombok.ToString; import lombok.extern.java.Log; import nostr.base.ISignable; @@ -10,7 +11,6 @@ import nostr.base.PublicKey; import nostr.base.Signature; import nostr.crypto.schnorr.Schnorr; -import nostr.util.NostrExceptionFactory; import nostr.util.NostrUtil; /** @@ -53,20 +53,22 @@ public static Identity generateRandomIdentity() { return new Identity(PrivateKey.generateRandomPrivKey()); } - public PublicKey getPublicKey() throws NostrExceptionFactory { + public PublicKey getPublicKey() { try { return new PublicKey(Schnorr.genPubKey(this.getPrivateKey().getRawData())); } catch (Exception ex) { - throw new NostrExceptionFactory(ex); + throw new RuntimeException(ex); } } +// TODO: exceptions refactor + @SneakyThrows public Signature sign(@NonNull ISignable signable) { final Signature signature = new Signature(); signature.setRawData( Schnorr.sign( - NostrUtil.sha256(signable.getByeArraySupplier().get().array()), - this.getPrivateKey().getRawData(), + NostrUtil.sha256(signable.getByeArraySupplier().get().array()), + this.getPrivateKey().getRawData(), generateAuxRand())); signature.setPubKey(getPublicKey()); signable.getSignatureConsumer().accept(signature); diff --git a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java b/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java index f703d6472..b36bb89f6 100644 --- a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java +++ b/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java @@ -1,63 +1,62 @@ -package nostr.test.crypto; - -import nostr.base.Signature; -import nostr.crypto.bech32.Bech32; -import nostr.crypto.bech32.Bech32Prefix; -import nostr.crypto.schnorr.Schnorr; -import nostr.event.impl.GenericEvent; -import nostr.id.Identity; -import nostr.util.NostrExceptionFactory; -import nostr.util.NostrUtil; -import org.junit.jupiter.api.Test; - -import static nostr.test.EntityFactory.Events.createTextNoteEvent; -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.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * - * @author squirrel - */ -public class CryptoTest { - - @Test - public void testBech32() { - try { - System.out.println("testBech32"); - - final String hexPub = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; - final String npub = "npub126klq89p42wk78p4j5ur8wlxmxdqepdh8tez9e4axpd4run5nahsmff27j"; - - assertEquals(npub, Bech32.toBech32(Bech32Prefix.NPUB, hexPub)); - assertEquals("56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f", Bech32.fromBech32(npub)); - } catch (NostrExceptionFactory ex) { - fail(ex); - } - } - - @Test - public void testVerifySignature() { - System.out.println("testVerifySignature"); - - Identity identity = Identity.generateRandomIdentity(); - final GenericEvent[] event = {createTextNoteEvent(identity.getPublicKey(), "Hello World")}; - event[0].update(); - assertDoesNotThrow(() -> { - byte[] message = NostrUtil.sha256(event[0].get_serializedEvent()); - Signature signature = identity.sign(event[0]); - boolean verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); - assertTrue(verification, "Schnorr must have a true verify result."); - - event[0] = createTextNoteEvent(identity.getPublicKey(), "Guten Tag"); - event[0].update(); - message = NostrUtil.sha256(event[0].get_serializedEvent()); - verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); - - assertFalse(verification); - }); - } - -} +package nostr.test.crypto; + +import nostr.base.Signature; +import nostr.crypto.bech32.Bech32; +import nostr.crypto.bech32.Bech32Prefix; +import nostr.crypto.schnorr.Schnorr; +import nostr.event.impl.GenericEvent; +import nostr.id.Identity; +import nostr.util.NostrUtil; +import org.junit.jupiter.api.Test; + +import static nostr.test.EntityFactory.Events.createTextNoteEvent; +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.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * + * @author squirrel + */ +public class CryptoTest { + + @Test + public void testBech32() { + try { + System.out.println("testBech32"); + + final String hexPub = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; + final String npub = "npub126klq89p42wk78p4j5ur8wlxmxdqepdh8tez9e4axpd4run5nahsmff27j"; + + assertEquals(npub, Bech32.toBech32(Bech32Prefix.NPUB, hexPub)); + assertEquals("56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f", Bech32.fromBech32(npub)); + } catch (Exception ex) { + fail(ex); + } + } + + @Test + public void testVerifySignature() { + System.out.println("testVerifySignature"); + + Identity identity = Identity.generateRandomIdentity(); + final GenericEvent[] event = {createTextNoteEvent(identity.getPublicKey(), "Hello World")}; + event[0].update(); + assertDoesNotThrow(() -> { + byte[] message = NostrUtil.sha256(event[0].get_serializedEvent()); + Signature signature = identity.sign(event[0]); + boolean verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); + assertTrue(verification, "Schnorr must have a true verify result."); + + event[0] = createTextNoteEvent(identity.getPublicKey(), "Guten Tag"); + event[0].update(); + message = NostrUtil.sha256(event[0].get_serializedEvent()); + verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); + + assertFalse(verification); + }); + } + +} diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java index 531be55db..96b6e297d 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java @@ -37,7 +37,6 @@ import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.util.NostrExceptionFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -69,7 +68,7 @@ class ApiEventTest { private Map relays; @Test - public void testNIP01CreateTextNoteEvent() throws NostrExceptionFactory { + public void testNIP01CreateTextNoteEvent() throws Exception { System.out.println("testNIP01CreateTextNoteEvent"); var nip01 = new NIP01(Identity.generateRandomIdentity()); @@ -508,7 +507,7 @@ public void testNIP52CalendarTimeBasedEventEvent() throws IOException { } @Test - void testNIP57CreateZapRequestEvent() throws NostrExceptionFactory { + void testNIP57CreateZapRequestEvent() throws Exception { System.out.println("testNIP57CreateZapRequestEvent"); var nip57 = new NIP57(Identity.generateRandomIdentity()); @@ -542,7 +541,7 @@ void testNIP57CreateZapRequestEvent() throws NostrExceptionFactory { } @Test - void testNIP57CreateZapReceiptEvent() throws NostrExceptionFactory { + void testNIP57CreateZapReceiptEvent() throws Exception { System.out.println("testNIP57CreateZapReceiptEvent"); String zapRequestPubKeyTag = Identity.generateRandomIdentity().getPublicKey().toString(); diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java index 95fc6d585..4172faa0c 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java @@ -17,7 +17,7 @@ import nostr.event.util.Nip05Validator; import nostr.id.Identity; import nostr.test.EntityFactory; -import nostr.util.NostrExceptionFactory; +import nostr.util.NostrException; import nostr.util.NostrUtil; import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; @@ -144,7 +144,7 @@ public void testNip05Validator() { var nip05Validator = Nip05Validator.builder().nip05(nip05).publicKey(publicKey).build(); nip05Validator.validate(); - } catch (NostrExceptionFactory ex) { + } catch (Exception ex) { fail(ex); } assertTrue(true); diff --git a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java index 554b40b4d..9e4c24b02 100644 --- a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java +++ b/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java @@ -43,7 +43,6 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import nostr.test.util.JsonComparator; -import nostr.util.NostrExceptionFactory; import org.junit.jupiter.api.Test; import java.math.BigDecimal; @@ -327,7 +326,7 @@ public void testClassifiedListingTagSerializer() throws JsonProcessingException } @Test - public void testDeserializeTag() throws NostrExceptionFactory { + public void testDeserializeTag() throws Exception { log.info("testDeserializeTag"); String npubHex = new PublicKey(Bech32.fromBech32("npub1clk6vc9xhjp8q5cws262wuf2eh4zuvwupft03hy4ttqqnm7e0jrq3upup9")).toString(); @@ -343,7 +342,7 @@ public void testDeserializeTag() throws NostrExceptionFactory { } @Test - public void testDeserializeGenericTag() throws NostrExceptionFactory { + public void testDeserializeGenericTag() throws Exception { log.info("testDeserializeGenericTag"); String npubHex = new PublicKey(Bech32.fromBech32("npub1clk6vc9xhjp8q5cws262wuf2eh4zuvwupft03hy4ttqqnm7e0jrq3upup9")).toString(); final String jsonString = "[\"gt\", \"" + npubHex + "\", \"wss://nostr.java\", \"alice\"]"; diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index 8653a7b8e..2ff3e006a 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -3,6 +3,8 @@ plugins { } dependencies { + implementation libs.org.apache.commons.commons.lang3 + implementation libs.org.projectlombok.lombok annotationProcessor libs.org.projectlombok.lombok testImplementation libs.org.projectlombok.lombok diff --git a/nostr-java-util/src/main/java/nostr/util/NostrException.java b/nostr-java-util/src/main/java/nostr/util/NostrException.java new file mode 100644 index 000000000..1210fdbe4 --- /dev/null +++ b/nostr-java-util/src/main/java/nostr/util/NostrException.java @@ -0,0 +1,14 @@ +package nostr.util; + +import lombok.experimental.StandardException; + +/** + * + * @author squirrel + */ +@StandardException +public class NostrException extends Exception { + public NostrException(String message) { + super(message); + } +} diff --git a/nostr-java-util/src/main/java/nostr/util/config/ExceptionConfig.java b/nostr-java-util/src/main/java/nostr/util/config/ExceptionConfig.java new file mode 100644 index 000000000..14612a46d --- /dev/null +++ b/nostr-java-util/src/main/java/nostr/util/config/ExceptionConfig.java @@ -0,0 +1,5 @@ +//package nostr.util.config; + +//@Configuration +//public class ExceptionConfig { +//} From 534f49adb76a0f83dd4556df197df232765ddb36 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 14 Mar 2025 21:35:51 -0700 Subject: [PATCH 19/57] cleanup, note files for fix/refactor --- .../main/java/nostr/base/IUnmarshaller.java | 13 - .../src/main/java/nostr/base/Relay.java | 447 +++++++++--------- .../nostr/base/annotation/CustomHandler.java | 14 - .../nostr/base/annotation/DefaultHandler.java | 18 - .../event/json/codec/GenericEventDecoder.java | 6 +- .../event/json/codec/GenericTagEncoder.java | 30 -- .../json/codec/GenericTagQueryEncoder.java | 35 -- .../event/json/codec/OstEventEncoder.java | 58 --- .../CustomEventListDeserializer.java | 29 -- .../CustomKindListDeserializer.java | 26 - .../CustomPublicKeyListDeserializer.java | 30 -- .../json/serializer/ContactSerializer.java | 24 - .../serializer/CustomBaseListSerializer.java | 57 --- .../CustomIdEventListSerializer.java | 29 -- .../CanonicalAuthenticationMessage.java | 1 + .../nostr/event/message/ClosedMessage.java | 36 -- .../event/message/ContactListMessage.java | 21 - .../nostr/event/message/EventMessage.java | 1 + .../java/nostr/event/message/OkMessage.java | 1 + .../java/nostr/event/util/Nip05Validator.java | 2 + 20 files changed, 221 insertions(+), 657 deletions(-) delete mode 100644 nostr-java-base/src/main/java/nostr/base/IUnmarshaller.java delete mode 100644 nostr-java-base/src/main/java/nostr/base/annotation/CustomHandler.java delete mode 100644 nostr-java-base/src/main/java/nostr/base/annotation/DefaultHandler.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagEncoder.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomEventListDeserializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomKindListDeserializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomPublicKeyListDeserializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/serializer/ContactSerializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/json/serializer/CustomIdEventListSerializer.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java delete mode 100644 nostr-java-event/src/main/java/nostr/event/message/ContactListMessage.java diff --git a/nostr-java-base/src/main/java/nostr/base/IUnmarshaller.java b/nostr-java-base/src/main/java/nostr/base/IUnmarshaller.java deleted file mode 100644 index 2c1f78c89..000000000 --- a/nostr-java-base/src/main/java/nostr/base/IUnmarshaller.java +++ /dev/null @@ -1,13 +0,0 @@ - -package nostr.base; - -/** - * - * @author squirrel - * @param - */ -public interface IUnmarshaller { - - T unmarshall(); - -} 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 e40aa0e77..525f6fb60 100644 --- a/nostr-java-base/src/main/java/nostr/base/Relay.java +++ b/nostr-java-base/src/main/java/nostr/base/Relay.java @@ -1,233 +1,214 @@ -package nostr.base; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; -import lombok.extern.java.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author squirrel - */ -// @Builder -@Data -@ToString(onlyExplicitlyIncluded = true) -@EqualsAndHashCode(onlyExplicitlyIncluded = true) -@AllArgsConstructor -@Log -public class Relay { - - @EqualsAndHashCode.Include - @ToString.Include - private String scheme; - - @EqualsAndHashCode.Include - @ToString.Include - private String host; - - private RelayInformationDocument informationDocument; - - public Relay(@NonNull String uri) { - this(uri, new RelayInformationDocument()); - } - - public Relay(@NonNull String uri, RelayInformationDocument doc) { - this.informationDocument = doc; - String[] s = uri.split("://", 2); - if (s.length != 2) { - throw new RuntimeException("uri must contain scheme and host, passed in uri: \"" + uri + "\""); - } - this.scheme = s[0]; - this.host = s[1]; - } - - // Helper method - public List getSupportedNips() { - return this.getInformationDocument().getSupportedNips(); - } - - // Helper method - public void addNipSupport(int nip) { - this.getSupportedNips().add(nip); - } - - // Helper method - public String printSupportedNips() { - return convertToJsonArray(this.getInformationDocument().getSupportedNips()); - } - - private static String convertToJsonArray(List list) { - StringBuilder jsonBuilder = new StringBuilder(); - jsonBuilder.append("["); - for (int i = 0; i < list.size(); i++) { - jsonBuilder.append("\"").append(list.get(i)).append("\""); - if (i != list.size() - 1) { - jsonBuilder.append(","); - } - } - jsonBuilder.append("]"); - - return jsonBuilder.toString(); - } - - // Helper method - public String getName() { - return this.getInformationDocument().getName(); - } - - // Helper method - public String getUri() { - return this.scheme + "://" + this.host; - } - - // Helper method - public String getHttpUri() { - return this.scheme.replaceFirst("ws", "http") + "://" + this.host; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class RelayInformationDocument { - - @JsonProperty - private String name; - - @JsonProperty - private String description; - - @JsonProperty - private String pubkey; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String id; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String contact; - - @Builder.Default - @JsonProperty("supported_nips") - @JsonIgnoreProperties(ignoreUnknown = true) - private List supportedNips = new ArrayList<>(); - - @Builder.Default - @JsonProperty("supported_nip_extensions") - @JsonIgnoreProperties(ignoreUnknown = true) - private List supportedNipExtensions = new ArrayList<>(); - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String software; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String version; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private Limitation limitation; - - @JsonProperty("payments_url") - private String paymentsUrl; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private Fees fees; - - @Data - public static class Limitation { - - @JsonProperty("max_message_length") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxMessageLength; - - @JsonProperty("max_subscriptions") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxSubscriptions; - - @JsonProperty("max_filters") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxFilters; - - @JsonProperty("max_limit") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxLimit; - - @JsonProperty("max_subid_length") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxSubIdLength; - - @JsonProperty("min_prefix") - @JsonIgnoreProperties(ignoreUnknown = true) - private int minPrefix; - - @JsonProperty("max_event_tags") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxEventTags; - - @JsonProperty("max_content_length") - @JsonIgnoreProperties(ignoreUnknown = true) - private int maxContentLength; - - @JsonProperty("min_pow_difficulty") - @JsonIgnoreProperties(ignoreUnknown = true) - private int minPowDifficulty; - - @JsonProperty("auth_required") - @JsonIgnoreProperties(ignoreUnknown = true) - private boolean authRequired; - - @JsonProperty("payment_required") - @JsonIgnoreProperties(ignoreUnknown = true) - private boolean paymentRequired; - - } - - @Data - public static class Fees { - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private List admission; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private List publication; - - @Data - public static class AdmissionFee { - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private int amount; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String unit; - } - - @Data - public static class PublicationFee { - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private int amount; - - @JsonProperty - @JsonIgnoreProperties(ignoreUnknown = true) - private String unit; - } - } - } -} +package nostr.base; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.ToString; +import lombok.extern.java.Log; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author squirrel + */ +// @Builder +@Data +@ToString(onlyExplicitlyIncluded = true) +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@AllArgsConstructor +@Log +public class Relay { + + @EqualsAndHashCode.Include + @ToString.Include + private String scheme; + + @EqualsAndHashCode.Include + @ToString.Include + private String host; + + private RelayInformationDocument informationDocument; + + public Relay(@NonNull String uri) { + this(uri, new RelayInformationDocument()); + } + + public Relay(@NonNull String uri, RelayInformationDocument doc) { + this.informationDocument = doc; + String[] s = uri.split("://", 2); + if (s.length != 2) { + throw new RuntimeException("uri must contain scheme and host, passed in uri: \"" + uri + "\""); + } + this.scheme = s[0]; + this.host = s[1]; + } + + // Helper method + public List getSupportedNips() { + return this.getInformationDocument().getSupportedNips(); + } + + // Helper method + public void addNipSupport(int nip) { + this.getSupportedNips().add(nip); + } + + // Helper method + public String getName() { + return this.getInformationDocument().getName(); + } + + // Helper method + public String getUri() { + return this.scheme + "://" + this.host; + } + + // Helper method + public String getHttpUri() { + return this.scheme.replaceFirst("ws", "http") + "://" + this.host; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class RelayInformationDocument { + + @JsonProperty + private String name; + + @JsonProperty + private String description; + + @JsonProperty + private String pubkey; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String id; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String contact; + + @Builder.Default + @JsonProperty("supported_nips") + @JsonIgnoreProperties(ignoreUnknown = true) + private List supportedNips = new ArrayList<>(); + + @Builder.Default + @JsonProperty("supported_nip_extensions") + @JsonIgnoreProperties(ignoreUnknown = true) + private List supportedNipExtensions = new ArrayList<>(); + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String software; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String version; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private Limitation limitation; + + @JsonProperty("payments_url") + private String paymentsUrl; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private Fees fees; + + @Data + public static class Limitation { + + @JsonProperty("max_message_length") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxMessageLength; + + @JsonProperty("max_subscriptions") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxSubscriptions; + + @JsonProperty("max_filters") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxFilters; + + @JsonProperty("max_limit") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxLimit; + + @JsonProperty("max_subid_length") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxSubIdLength; + + @JsonProperty("min_prefix") + @JsonIgnoreProperties(ignoreUnknown = true) + private int minPrefix; + + @JsonProperty("max_event_tags") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxEventTags; + + @JsonProperty("max_content_length") + @JsonIgnoreProperties(ignoreUnknown = true) + private int maxContentLength; + + @JsonProperty("min_pow_difficulty") + @JsonIgnoreProperties(ignoreUnknown = true) + private int minPowDifficulty; + + @JsonProperty("auth_required") + @JsonIgnoreProperties(ignoreUnknown = true) + private boolean authRequired; + + @JsonProperty("payment_required") + @JsonIgnoreProperties(ignoreUnknown = true) + private boolean paymentRequired; + + } + + @Data + public static class Fees { + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private List admission; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private List publication; + + @Data + public static class AdmissionFee { + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private int amount; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String unit; + } + + @Data + public static class PublicationFee { + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private int amount; + + @JsonProperty + @JsonIgnoreProperties(ignoreUnknown = true) + private String unit; + } + } + } +} diff --git a/nostr-java-base/src/main/java/nostr/base/annotation/CustomHandler.java b/nostr-java-base/src/main/java/nostr/base/annotation/CustomHandler.java deleted file mode 100644 index b06db1ecf..000000000 --- a/nostr-java-base/src/main/java/nostr/base/annotation/CustomHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package nostr.base.annotation; - -import nostr.base.Command; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface CustomHandler { - Command command(); -} diff --git a/nostr-java-base/src/main/java/nostr/base/annotation/DefaultHandler.java b/nostr-java-base/src/main/java/nostr/base/annotation/DefaultHandler.java deleted file mode 100644 index d3da28b24..000000000 --- a/nostr-java-base/src/main/java/nostr/base/annotation/DefaultHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package nostr.base.annotation; - -import nostr.base.Command; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * - * @author squirrel - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface DefaultHandler { - Command command(); -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericEventDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericEventDecoder.java index 533d61e19..d78e98332 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericEventDecoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericEventDecoder.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import nostr.base.IDecoder; import nostr.event.impl.GenericEvent; @@ -26,8 +25,7 @@ public GenericEventDecoder(Class clazz) { @Override public T decode(String jsonEvent) throws JsonProcessingException { - var mapper = new ObjectMapper(); - mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - return mapper.readValue(jsonEvent, clazz); + I_DECODER_MAPPER_AFTERBURNER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + return I_DECODER_MAPPER_AFTERBURNER.readValue(jsonEvent, clazz); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagEncoder.java deleted file mode 100644 index 5eb8c3205..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagEncoder.java +++ /dev/null @@ -1,30 +0,0 @@ -package nostr.event.json.codec; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; -import nostr.base.IEncoder; -import nostr.base.Relay; -import nostr.event.impl.GenericTag; - -/** - * - * @author eric - */ -@Data -@AllArgsConstructor -public class GenericTagEncoder implements IEncoder { - - private final GenericTag tag; - private final Relay relay; - - public GenericTagEncoder(@NonNull GenericTag tag) { - this(tag, null); - } - - @Override - public String encode() { - var encoder = new BaseTagEncoder(tag, relay); - return encoder.encode(); - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java deleted file mode 100644 index fcbf1030b..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagQueryEncoder.java +++ /dev/null @@ -1,35 +0,0 @@ -package nostr.event.json.codec; - -import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import nostr.base.FEncoder; -import nostr.base.GenericTagQuery; -import nostr.base.Relay; - -/** - * @author guilhermegps - * - */ -@Data -@EqualsAndHashCode(callSuper = false) -@AllArgsConstructor -public class GenericTagQueryEncoder implements FEncoder { - - private final GenericTagQuery genericTagQuery; - private final Relay relay; - - public GenericTagQueryEncoder(GenericTagQuery tag) { - this(tag, null); - } - - @Override - public String encode() { - try { - return F_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(genericTagQuery); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java deleted file mode 100644 index 0cd4edbdf..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/OstEventEncoder.java +++ /dev/null @@ -1,58 +0,0 @@ -//package nostr.event.json.codec; -// -//import com.fasterxml.jackson.core.JsonProcessingException; -//import com.fasterxml.jackson.databind.JsonNode; -//import com.fasterxml.jackson.databind.node.ObjectNode; -//import java.util.HashMap; -//import lombok.AllArgsConstructor; -// -//import lombok.Data; -//import nostr.base.ElementAttribute; -//import nostr.base.IEncoder; -//import nostr.base.Relay; -//import nostr.event.impl.OtsEvent; -//import nostr.util.NostrException; -// -///** -// * @author guilhermegps -// * -// */ -//@Data -//@AllArgsConstructor -//public class OstEventEncoder implements IEncoder { -// -// private final OtsEvent event; -// private final Relay relay; -// -// public OstEventEncoder(OtsEvent event) { -// this(event, null); -// } -// -// @Override -// public String encode() { -// try { -// return toJson(); -// } catch (NostrException ex) { -// throw new RuntimeException(ex); -// } -// } -// -// private String toJson() throws NostrException { -// try { -// JsonNode node = I_ENCODER_MAPPER_AFTERBURNER.valueToTree(event); -// ObjectNode objNode = (ObjectNode) node; -// event.getAttributes().parallelStream() -// .map(ElementAttribute::getValue) -// .forEach(ev -> { -// var expression = (HashMap) ev; -// -// objNode.set("ots", I_ENCODER_MAPPER_AFTERBURNER.valueToTree(expression.get("ots"))); -// }); -// -// return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(node); -// } catch (JsonProcessingException | IllegalArgumentException e) { -// throw new NostrException(e); -// } -// } -// -//} diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomEventListDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomEventListDeserializer.java deleted file mode 100644 index ab163dacd..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomEventListDeserializer.java +++ /dev/null @@ -1,29 +0,0 @@ -package nostr.event.json.deserializer; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import lombok.NoArgsConstructor; -import nostr.event.impl.GenericEvent; -import nostr.event.json.codec.GenericEventDecoder; - -import java.util.ArrayList; -import java.util.List; -import java.io.IOException; - -@NoArgsConstructor -public class CustomEventListDeserializer, U extends GenericEvent> extends JsonDeserializer { - - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { - List eventList = new ArrayList<>(); - JsonNode node = jsonParser.readValueAsTree(); - if (node.isArray()) { - for (JsonNode n : node) { - eventList.add(new GenericEventDecoder().decode(n.toString())); - } - } - return (T) eventList; - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomKindListDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomKindListDeserializer.java deleted file mode 100644 index 47aeea1e3..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomKindListDeserializer.java +++ /dev/null @@ -1,26 +0,0 @@ -package nostr.event.json.deserializer; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import nostr.event.Kind; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class CustomKindListDeserializer extends JsonDeserializer> { - - @Override - public List deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { - List kindList = new ArrayList<>(); - JsonNode node = jsonParser.readValueAsTree(); - if (node.isArray()) { - for (JsonNode n : node) { - kindList.add(Kind.valueOf(Integer.decode(n.asText()))); - } - } - return kindList; - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomPublicKeyListDeserializer.java b/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomPublicKeyListDeserializer.java deleted file mode 100644 index 0c46be4c7..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/deserializer/CustomPublicKeyListDeserializer.java +++ /dev/null @@ -1,30 +0,0 @@ -package nostr.event.json.deserializer; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import lombok.NoArgsConstructor; -import nostr.base.PublicKey; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@NoArgsConstructor -public class CustomPublicKeyListDeserializer extends JsonDeserializer> { - - @Override - // TODO: check ctxt use - public List deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - List publicKeyList = new ArrayList<>(); - JsonNode node = p.readValueAsTree(); - if (node.isArray()) { - for (JsonNode n : node) { - String hex = n.asText(); - publicKeyList.add(new PublicKey(hex)); - } - } - return publicKeyList; - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/ContactSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/ContactSerializer.java deleted file mode 100644 index aad2b2f31..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/ContactSerializer.java +++ /dev/null @@ -1,24 +0,0 @@ -package nostr.event.json.serializer; - -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.impl.CustomerOrderEvent.Customer.Contact; - -/** - * - * @author eric - */ -public class ContactSerializer extends JsonSerializer { - - @Override - public void serialize(Contact contact, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { - jsonGenerator.writeStartObject(); - jsonGenerator.writeStringField("nostr", contact.getPublicKey().toString()); - jsonGenerator.writeStringField("phone", contact.getPhone()); - jsonGenerator.writeStringField("email", contact.getEmail()); - jsonGenerator.writeEndObject(); - } - -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java deleted file mode 100644 index 3cde81853..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java +++ /dev/null @@ -1,57 +0,0 @@ -package nostr.event.json.serializer; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import nostr.event.BaseEvent; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.stream.StreamSupport; - -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; - -/** - * @author guilhermegps - * - */ -public class CustomBaseListSerializer, U extends BaseEvent> extends JsonSerializer { - - @Override - public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) { - try { - var list = value.parallelStream().map(this::toJson).toList(); - - gen.writePOJO(list); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private JsonNode toJson(Object obj) { - var mapper = I_ENCODER_MAPPER_AFTERBURNER; - try { - JsonNode node = mapper.valueToTree(obj); - - if (node.isObject()) { - Iterator> fields = node.fields(); - - var list = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(fields, Spliterator.ORDERED), false) - .map(f -> f.getValue().asText().toLowerCase()).toList(); - - return mapper.valueToTree(list); - } - - return node; - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomIdEventListSerializer.java b/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomIdEventListSerializer.java deleted file mode 100644 index 63f507ef5..000000000 --- a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomIdEventListSerializer.java +++ /dev/null @@ -1,29 +0,0 @@ -package nostr.event.json.serializer; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import nostr.event.impl.GenericEvent; - -import java.io.IOException; -import java.util.List; -import java.util.Objects; - -/** - * @author guilhermegps - */ -public class CustomIdEventListSerializer, U extends GenericEvent> extends JsonSerializer { - - @Override - public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) { - try { - - var list = value.stream().filter(Objects::nonNull).map(U::getId).toList(); - - gen.writePOJO(list); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} 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 26599836f..04d350a2b 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 @@ -65,6 +65,7 @@ public static T decode(@NonNull Map map) { } private static String getAttributeValue(List genericTags, String attributeName) { +// TODO: stream optional return genericTags.stream() .filter(tag -> tag.getCode().equalsIgnoreCase(attributeName)).map(GenericTag::getAttributes).toList().get(0).get(0).getValue().toString(); } diff --git a/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java b/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java deleted file mode 100644 index 8ff9dfcbe..000000000 --- a/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -package nostr.event.message; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.Getter; -import lombok.NonNull; -import lombok.Setter; -import nostr.base.Command; -import nostr.event.BaseMessage; - -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; - -@Setter -@Getter -public class ClosedMessage extends BaseMessage { - - @JsonProperty - private final String subscriptionId; - - @JsonProperty - private final String message; - - public ClosedMessage(@NonNull String subId, @NonNull String message) { - super(Command.CLOSED.name()); - this.subscriptionId = subId; - this.message = message; - } - - @Override - public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( - getArrayNode() - .add(getCommand()) - .add(getSubscriptionId())); - } -} diff --git a/nostr-java-event/src/main/java/nostr/event/message/ContactListMessage.java b/nostr-java-event/src/main/java/nostr/event/message/ContactListMessage.java deleted file mode 100644 index 9b5b70621..000000000 --- a/nostr-java-event/src/main/java/nostr/event/message/ContactListMessage.java +++ /dev/null @@ -1,21 +0,0 @@ -package nostr.event.message; - -import java.util.List; -import lombok.ToString; -import nostr.event.Kind; -import nostr.base.PublicKey; -import nostr.event.BaseTag; -import nostr.event.impl.GenericEvent; - -/** - * - * @author squirrel - */ -@ToString -public class ContactListMessage extends EventMessage { - - public ContactListMessage(List contactList, PublicKey publicKey) { - super(new GenericEvent(publicKey, Kind.CONTACT_LIST, contactList)); - } - -} 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 410abee3b..b506fc9e8 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 @@ -49,6 +49,7 @@ public String encode() throws JsonProcessingException { return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(arrayNode); } +// TODO: refactor into stream returning optional public static T decode(@NonNull Object[] msgArr, ObjectMapper mapper) { var arg = msgArr[1]; if (msgArr.length == 2 && arg instanceof Map map) { 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 e39c2cda4..f481a6459 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 @@ -44,6 +44,7 @@ public String encode() throws JsonProcessingException { .add(getMessage())); } + // TODO: refactor into stream returning optional public static T decode(@NonNull Object[] msgArr) { if (msgArr.length == 4 && msgArr[2] instanceof Boolean duplicate) { String msgArg = msgArr[3].toString(); diff --git a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java index e9589f477..c3deb2b4e 100644 --- a/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java +++ b/nostr-java-event/src/main/java/nostr/event/util/Nip05Validator.java @@ -32,6 +32,7 @@ public class Nip05Validator { private static final String LOCAL_PART_PATTERN = "^[a-zA-Z0-9-_\\.]+$"; +// TODO: refactor public void validate() throws NostrException { if (this.nip05 != null) { var splited = nip05.split("@"); @@ -53,6 +54,7 @@ public void validate() throws NostrException { } } +// TODO: refactor private void validatePublicKey(String domain, String localPart) throws NostrException, IOException, URISyntaxException { // Set up and estgetPublicKeyablish the HTTP connection From f0b3f89685c6a29ac1bf2878a394a178b826af26 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 14 Mar 2025 23:14:46 -0700 Subject: [PATCH 20/57] cleanup --- .../src/main/java/nostr/event/tag/PriceTag.java | 3 +-- nostr-java-util/pom.xml | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) 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 60aeabb8d..8d9c99a26 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 @@ -47,8 +47,7 @@ public static T deserialize(@NonNull JsonNode node) { @Override public boolean equals(Object o) { - return super.equals(o) && - Objects.equals( + return Objects.equals( number.stripTrailingZeros(), ((PriceTag) o).number.stripTrailingZeros() ) diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 9dad03e70..0017f9140 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -12,12 +12,11 @@ nostr-java-util jar - - - - - + + org.apache.commons + commons-lang3 + org.projectlombok lombok From f8c257213b4c41462c3e1ff848310b2a463ebf07 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Fri, 14 Mar 2025 23:22:39 -0700 Subject: [PATCH 21/57] equals fix --- .../src/main/java/nostr/event/tag/PriceTag.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 8d9c99a26..cb4d199ef 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 @@ -47,11 +47,14 @@ public static T deserialize(@NonNull JsonNode node) { @Override public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + PriceTag priceTag = (PriceTag) o; return Objects.equals( number.stripTrailingZeros(), - ((PriceTag) o).number.stripTrailingZeros() + priceTag.number.stripTrailingZeros() ) - && Objects.equals(currency, ((PriceTag) o).currency) && Objects.equals(frequency, ((PriceTag) o).frequency); + && Objects.equals(currency, priceTag.currency) && Objects.equals(frequency, priceTag.frequency); } @Override From b4fdf7a5997253093e1bb499005647e629bbab2e Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sat, 15 Mar 2025 14:11:10 -0700 Subject: [PATCH 22/57] refactored IEncoder & FEncoder into single Encoder (as they both use same mapper) --- .../base/{FEncoder.java => Encoder.java} | 6 ++--- .../src/main/java/nostr/base/IEncoder.java | 19 ------------- .../java/nostr/event/impl/GenericEvent.java | 4 +-- .../java/nostr/event/impl/GenericMessage.java | 5 ++-- .../java/nostr/event/impl/MetadataEvent.java | 5 ++-- .../event/json/codec/BaseEventEncoder.java | 27 +++++-------------- .../event/json/codec/BaseTagEncoder.java | 7 ++--- .../event/json/codec/FiltersEncoder.java | 20 +++++++------- .../CanonicalAuthenticationMessage.java | 8 +++--- .../nostr/event/message/CloseMessage.java | 4 +-- .../java/nostr/event/message/EoseMessage.java | 4 +-- .../nostr/event/message/EventMessage.java | 6 ++--- .../nostr/event/message/NoticeMessage.java | 4 +-- .../java/nostr/event/message/OkMessage.java | 4 +-- .../message/RelayAuthenticationMessage.java | 4 +-- .../java/nostr/event/message/ReqMessage.java | 6 ++--- .../test/java/nostr/test/event/EventTest.java | 5 ++-- 17 files changed, 48 insertions(+), 90 deletions(-) rename nostr-java-base/src/main/java/nostr/base/{FEncoder.java => Encoder.java} (59%) delete mode 100644 nostr-java-base/src/main/java/nostr/base/IEncoder.java diff --git a/nostr-java-base/src/main/java/nostr/base/FEncoder.java b/nostr-java-base/src/main/java/nostr/base/Encoder.java similarity index 59% rename from nostr-java-base/src/main/java/nostr/base/FEncoder.java rename to nostr-java-base/src/main/java/nostr/base/Encoder.java index 2b71e99f3..ea845e586 100644 --- a/nostr-java-base/src/main/java/nostr/base/FEncoder.java +++ b/nostr-java-base/src/main/java/nostr/base/Encoder.java @@ -5,8 +5,8 @@ import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.module.afterburner.AfterburnerModule; -public interface FEncoder { - ObjectMapper F_ENCODER_MAPPER_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); - +public interface Encoder { + ObjectMapper ENCODER_MAPPED_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); + String encode(); } diff --git a/nostr-java-base/src/main/java/nostr/base/IEncoder.java b/nostr-java-base/src/main/java/nostr/base/IEncoder.java deleted file mode 100644 index b32a72ad6..000000000 --- a/nostr-java-base/src/main/java/nostr/base/IEncoder.java +++ /dev/null @@ -1,19 +0,0 @@ - -package nostr.base; - -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; -import com.fasterxml.jackson.module.afterburner.AfterburnerModule; - - -/** - * - * @author squirrel - * @param - */ -public interface IEncoder { - ObjectMapper I_ENCODER_MAPPER_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); - - String encode(); -} 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 74109dcf6..060cb685e 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 @@ -40,7 +40,7 @@ import java.util.function.Supplier; import java.util.logging.Level; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @author squirrel @@ -205,7 +205,7 @@ protected void validate() { } private String serialize() throws NostrException { - var mapper = I_ENCODER_MAPPER_AFTERBURNER; + var mapper = ENCODER_MAPPED_AFTERBURNER; var arrayNode = JsonNodeFactory.instance.arrayNode(); try { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java index f54544e7b..c71a81b2a 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java @@ -7,14 +7,13 @@ import lombok.Setter; import nostr.base.ElementAttribute; import nostr.base.IElement; -import nostr.base.IEncoder; import nostr.base.IGenericElement; import nostr.event.BaseMessage; import java.util.ArrayList; import java.util.List; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -54,7 +53,7 @@ public void addAttribute(ElementAttribute attribute) { public String encode() throws JsonProcessingException { getArrayNode().add(getCommand()); getAttributes().stream().map(ElementAttribute::getValue).forEach(v -> getArrayNode().add(v.toString())); - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(getArrayNode()); + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString(getArrayNode()); } public static T decode(@NonNull Object[] msgArr) { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java b/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java index 8207f1e96..2d1340957 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/MetadataEvent.java @@ -9,7 +9,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; -import nostr.base.IEncoder; import nostr.base.PublicKey; import nostr.base.UserProfile; import nostr.base.annotation.Event; @@ -17,7 +16,7 @@ import nostr.event.Kind; import nostr.event.NIP01Event; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -61,7 +60,7 @@ public void update() { } private void setContent() { - var mapper = I_ENCODER_MAPPER_AFTERBURNER; + var mapper = ENCODER_MAPPED_AFTERBURNER; try { ObjectNode objNode = JsonNodeFactory.instance.objectNode(); objNode.set("name", mapper.valueToTree(this.getProfile().getName())); diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java index 0afbfe0f8..daf18b5b4 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java @@ -1,17 +1,12 @@ package nostr.event.json.codec; -import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; -import nostr.base.IEncoder; +import lombok.SneakyThrows; +import nostr.base.Encoder; import nostr.event.BaseEvent; -import nostr.util.NostrException; -/** - * @author guilhermegps - * - */ @Data -public class BaseEventEncoder implements IEncoder { +public class BaseEventEncoder implements Encoder { private final T event; @@ -20,19 +15,9 @@ public BaseEventEncoder(T event) { } @Override +// TODO: refactor all methods calling this to properly handle invalid json exception + @SneakyThrows public String encode() { - try { - return toJson(); - } catch (NostrException ex) { - throw new RuntimeException(ex); - } - } - - protected String toJson() throws NostrException { - try { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(event); - } catch (JsonProcessingException e) { - throw new NostrException(e); - } + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString(event); } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java index 403241d7f..d25a62e85 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java @@ -7,17 +7,14 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; -import nostr.base.IEncoder; +import nostr.base.Encoder; import nostr.base.Relay; import nostr.event.BaseTag; import nostr.event.json.serializer.TagSerializer; -/** - * @author guilhermegps - */ @Data @AllArgsConstructor -public class BaseTagEncoder implements IEncoder { +public class BaseTagEncoder implements Encoder { private final BaseTag tag; private final Relay relay; diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java index 5cea19e92..2325bd924 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/FiltersEncoder.java @@ -3,12 +3,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Data; import lombok.EqualsAndHashCode; -import nostr.base.FEncoder; +import nostr.base.Encoder; import nostr.event.filter.Filters; @Data @EqualsAndHashCode(callSuper = false) -public class FiltersEncoder implements FEncoder { +public class FiltersEncoder implements Encoder { private final Filters filters; public FiltersEncoder(Filters filters) { @@ -17,17 +17,17 @@ public FiltersEncoder(Filters filters) { @Override public String encode() { - ObjectNode root = F_ENCODER_MAPPER_AFTERBURNER.createObjectNode(); + ObjectNode root = ENCODER_MAPPED_AFTERBURNER.createObjectNode(); filters.getFiltersMap().forEach((key, filterableList) -> { - final ObjectNode objectNode = F_ENCODER_MAPPER_AFTERBURNER.createObjectNode(); + final ObjectNode objectNode = ENCODER_MAPPED_AFTERBURNER.createObjectNode(); root.setAll( - filterableList - .stream() - .map(filterable -> - filterable.toObjectNode(objectNode)) - .toList() - .getFirst()); + filterableList + .stream() + .map(filterable -> + filterable.toObjectNode(objectNode)) + .toList() + .getFirst()); }); return root.toString(); 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 04d350a2b..c7ea876b5 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 @@ -3,13 +3,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.NonNull; import lombok.Setter; import lombok.SneakyThrows; import nostr.base.Command; -import nostr.base.IEncoder; import nostr.base.Relay; import nostr.event.BaseMessage; import nostr.event.impl.CanonicalAuthenticationEvent; @@ -21,7 +19,7 @@ import java.util.Map; import static nostr.base.IDecoder.I_DECODER_MAPPER_AFTERBURNER; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @author eric @@ -39,10 +37,10 @@ public CanonicalAuthenticationMessage(CanonicalAuthenticationEvent event) { } @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) - .add(I_ENCODER_MAPPER_AFTERBURNER.readTree( + .add(ENCODER_MAPPED_AFTERBURNER.readTree( new BaseEventEncoder<>(getEvent()).encode()))); } 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 358113c04..2bfbc38c0 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 @@ -8,7 +8,7 @@ import nostr.base.Command; import nostr.event.BaseMessage; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -32,7 +32,7 @@ public CloseMessage(String subscriptionId) { @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getSubscriptionId())); 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 ff91201d3..204f09623 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 @@ -9,7 +9,7 @@ import nostr.base.Command; import nostr.event.BaseMessage; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -32,7 +32,7 @@ public EoseMessage(String subId) { @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getSubscriptionId())); 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 b506fc9e8..0897e9684 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 @@ -17,7 +17,7 @@ import java.util.Map; import java.util.Optional; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; @Setter @Getter @@ -44,9 +44,9 @@ public String encode() throws JsonProcessingException { var arrayNode = getArrayNode().add(getCommand()); Optional.ofNullable(getSubscriptionId()) .ifPresent(arrayNode::add); - arrayNode.add(I_ENCODER_MAPPER_AFTERBURNER.readTree( + arrayNode.add(ENCODER_MAPPED_AFTERBURNER.readTree( new BaseEventEncoder<>((BaseEvent)getEvent()).encode())); - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(arrayNode); + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString(arrayNode); } // TODO: refactor into stream returning optional 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 3bcaab2ea..8207c4c4a 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 @@ -8,7 +8,7 @@ import nostr.base.Command; import nostr.event.BaseMessage; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -28,7 +28,7 @@ public NoticeMessage(@NonNull String message) { @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getMessage())); 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 f481a6459..4c8375b12 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 @@ -8,7 +8,7 @@ import nostr.base.Command; import nostr.event.BaseMessage; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -36,7 +36,7 @@ public OkMessage(String eventId, Boolean flag, String message) { @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getEventId()) 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 8e19d2a12..841ecd71c 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 @@ -8,7 +8,7 @@ import nostr.base.Command; import nostr.event.BaseMessage; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @@ -28,7 +28,7 @@ public RelayAuthenticationMessage(String challenge) { @Override public String encode() throws JsonProcessingException { - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString( + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString( getArrayNode() .add(getCommand()) .add(getChallenge())); 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 a1cc89442..18e520ae1 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 @@ -16,7 +16,7 @@ import java.time.temporal.ValueRange; import java.util.List; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; /** * @author squirrel @@ -55,7 +55,7 @@ public String encode() throws JsonProcessingException { .forEach(jsonNode -> getArrayNode().add(jsonNode)); - return I_ENCODER_MAPPER_AFTERBURNER.writeValueAsString(getArrayNode()); + return ENCODER_MAPPED_AFTERBURNER.writeValueAsString(getArrayNode()); } public static T decode(@NonNull Object subscriptionId, @NonNull List jsonFiltersList) { @@ -75,7 +75,7 @@ private static void validateSubscriptionId(String subscriptionId) { private static JsonNode createJsonNode(String jsonNode) { try { - return I_ENCODER_MAPPER_AFTERBURNER.readTree(jsonNode); + return ENCODER_MAPPED_AFTERBURNER.readTree(jsonNode); } catch (JsonProcessingException e) { throw new IllegalArgumentException(String.format("Malformed encoding ReqMessage json: [%s]", jsonNode), e); } diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java index 4172faa0c..675379026 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java +++ b/nostr-java-test/src/test/java/nostr/test/event/EventTest.java @@ -17,10 +17,9 @@ import nostr.event.util.Nip05Validator; import nostr.id.Identity; import nostr.test.EntityFactory; -import nostr.util.NostrException; import nostr.util.NostrUtil; -import static nostr.base.IEncoder.I_ENCODER_MAPPER_AFTERBURNER; +import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; import static org.junit.jupiter.api.Assertions.*; /** @@ -67,7 +66,7 @@ public void testCreateGenericTag() { var strJsonEvent = encoder.encode(); assertDoesNotThrow(() -> { - BaseTag tag = I_ENCODER_MAPPER_AFTERBURNER.readValue(strJsonEvent, BaseTag.class); + BaseTag tag = ENCODER_MAPPED_AFTERBURNER.readValue(strJsonEvent, BaseTag.class); assertEquals(genericTag, tag); }); } From 79d3f521e177ebd5e741490e1cdc0f1001e07c49 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sat, 15 Mar 2025 16:22:01 -0700 Subject: [PATCH 23/57] metrics md --- metrics.md | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 metrics.md diff --git a/metrics.md b/metrics.md new file mode 100644 index 000000000..82ca3ce10 --- /dev/null +++ b/metrics.md @@ -0,0 +1,228 @@ +### nostr-java & superconductor: gradle -vs- maven metrics + +---- +##### nostr-java clean build + +###### maven: ~19 seconds + +```java +$ time mvn clean install -Dmaven.test.skip=true + + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 17.592 s + [INFO] Finished at: 2025-03-14T22:31:52-07:00 + [INFO] ------------------------------------------------------------------------ + + real 0m19.156s <----------------------------------------------------------- ~19 sec + user 0m58.042s + sys 0m1.616s +``` + +###### gradle: ~9 seconds +``` java +$ time gradle clean build -x test + +BUILD SUCCESSFUL in 9s +38 actionable tasks: 38 executed +Configuration cache entry reused. + + real 0m9.618s <------------------------------------------------------------- ~9 sec + user 0m2.383s + sys 0m0.116s +``` +---- + +#### nostr-java, subsequent build + +###### maven: ~21 seconds + +```java +$ time mvn install -Dmaven.test.skip=true + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 19.680 s + [INFO] Finished at: 2025-03-14T22:39:35-07:00 + [INFO] ------------------------------------------------------------------------ + + real 0m21.324s <------------------------------------------------------------- ~21sec + user 1m3.300s + sys 0m1.771s +``` + +###### gradle: ~1 second + +```java +$ time gradle build -x test + Reusing configuration cache. + + BUILD SUCCESSFUL in 1s + 27 actionable tasks: 27 up-to-date + Configuration cache entry reused. + + real 0m1.178s <------------------------------------------------------------- ~1sec + user 0m2.082s + sys 0m0.176s +``` + +---- +#### superconductor clean build: + +###### maven: ~11 seconds + +```java +$ time mvn clean install -Dmaven.test.skip=true + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 10.437 s + [INFO] Finished at: 2025-03-14T22:46:58-07:00 + [INFO] ------------------------------------------------------------------------ + + real 0m11.989s <------------------------------------------------------------- ~11sec + user 0m36.291s + sys 0m1.351s +``` + +###### gradle: ~7 seconds + +```java +$ time gradle clean build -x test + + BUILD SUCCESSFUL in 7s + 7 actionable tasks: 4 executed, 2 from cache, 1 up-to-date + + real 0m7.655s <------------------------------------------------------------ ~7sec + user 0m2.800s + sys 0m0.164s +``` + +---- +#### superconductor clean build integration- test: + +###### maven: ~1 minute, 15 seconds +``` java +$ mvn clean install + + [INFO] Results: + [INFO] + [INFO] Tests run: 52, Failures: 0, Errors: 0, Skipped: 0 + [INFO] ------------------------------------------------------------------------ + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 01:15 min <--------------------------------------------------- ~1min 15sec* + [INFO] Finished at: 2025-03-14T23:26:59-07:00 + [INFO] ------------------------------------------------------------------------ + + real 1m16.800s <----------------------------------------------------------------- ~1min 16sec* + user 2m58.945s + sys 0m4.427s +``` +_*one-second time diff re: maven publish to local repo (`~/.m2/xyz/tcheeric/...`)_ + +###### gradle: ~49 seconds +``` java +$ time gradle build + + SUCCESS: Executed 61 tests in 41.1s + + BUILD SUCCESSFUL in 49s + 10 actionable tasks: 6 executed, 4 from cache + + real 0m49.269s <------------------------------------------------------------- ~49sec + user 0m2.854s + sys 0m0.201s +``` + +---- + +#### superconductor subsequent build test +_historical note: significant down/wait-time using maven occurs here, thus motivating gradle build/test option for superconductor, initially, with nostr-java subsequently profiting from same feature/option. **from** **~1 minute** **down to** **~4 seconds** significantly improves workflow continuity. furthermore, multiple iterative test builds occurring as per typical development results in significant cumulative time saved._ + +###### maven: ~1 minute, 3 seconds + +```java +$ time mvn install + + [INFO] Results: + [INFO] + [INFO] Tests run: 52, Failures: 0, Errors: 0, Skipped: 0 + [INFO] ------------------------------------------------------------------------ + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 01:03 min <--------------------------------------------------------- ~1min 3sec** + [INFO] Finished at: 2025-03-14T23:35:18-07:00 + [INFO] ------------------------------------------------------------------------ + + real 1m6.132s <------------------------------------------------------------------------ ~1min 6sec** + user 2m32.305s + sys 0m3.797s +``` +_** three-second time diff re: maven publish to local repo (`~/.m2/xyz/tcheeric/...`)_ + +###### gradle: ~4 seconds +```java +$ time gradle build + +BUILD SUCCESSFUL in 3s +10 actionable tasks: 10 up-to-date + +real 0m4.020s <------------------------------------------------------------------------ ~4sec +user 0m2.913s +``` + +---- + +#### nostr-java integration tests against running SC + +###### maven: ~29 seconds + +```java +$ time mvn test + + [INFO] Results: + [INFO] + [INFO] Tests run: 159, Failures: 0, Errors: 0, Skipped: 0 + [INFO] + [INFO] ------------------------------------------------------------------------ + [INFO] Reactor Summary for nostr-java 0.6.5-SNAPSHOT: + [INFO] + [INFO] nostr-java ......................................... SUCCESS [ 0.012 s] + [INFO] nostr-java-util .................................... SUCCESS [ 0.900 s] + [INFO] nostr-java-crypto .................................. SUCCESS [ 0.353 s] + [INFO] nostr-java-base .................................... SUCCESS [ 0.246 s] + [INFO] nostr-java-event ................................... SUCCESS [ 0.142 s] + [INFO] nostr-java-id ...................................... SUCCESS [ 0.164 s] + [INFO] nostr-java-client .................................. SUCCESS [ 0.438 s] + [INFO] nostr-java-encryption .............................. SUCCESS [ 0.050 s] + [INFO] nostr-java-encryption-nip04 ........................ SUCCESS [ 0.107 s] + [INFO] nostr-java-encryption-nip44 ........................ SUCCESS [ 0.114 s] + [INFO] nostr-java-api ..................................... SUCCESS [ 0.190 s] + [INFO] nostr-java-examples ................................ SUCCESS [ 0.212 s] + [INFO] nostr-java-test .................................... SUCCESS [ 25.933 s] + [INFO] ------------------------------------------------------------------------ + [INFO] BUILD SUCCESS + [INFO] ------------------------------------------------------------------------ + [INFO] Total time: 29.084 s <------------------------------------------------------------------------ ~29sec*** + [INFO] Finished at: 2025-03-15T12:41:13-07:00 + [INFO] ------------------------------------------------------------------------ + + real 0m30.669s <-------------------------------------------------------------------------------------- ~30sec*** + user 1m2.185s + sys 0m1.698s +``` +_*** one-second time diff re: maven publish to local repo (`~/.m2/xyz/tcheeric/...`)_ + +---- + +##### useful gradle commands (w/ maven equivalents) + +```java +alias gc='gradle clean' // 'maven clean' +alias gb='gradle build' // 'maven build' +alias gcb='gradle clean build' // 'maven clean build' + +alias gbnotest='gradle build -x test' // 'maven build -Dmaven.test.skip=true' +alias gcbnotest='gradle clean build -x test' // 'maven clean build -Dmaven.test.skip=true' + +alias gpub='gradle publishToMavenLocal' // 'maven install' +``` From 71f74b705153f92dc864ffafb4f0a42caf08a0f7 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sat, 15 Mar 2025 22:05:16 -0700 Subject: [PATCH 24/57] link test --- metrics.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/metrics.md b/metrics.md index 82ca3ce10..49ccce034 100644 --- a/metrics.md +++ b/metrics.md @@ -1,5 +1,9 @@ ### nostr-java & superconductor: gradle -vs- maven metrics + +[useful gradle commands (w/ maven equivalents) @ bottom of page](https://github.com/avlo/nostr-java-avlo-fork/blob/79d3f521e177ebd5e741490e1cdc0f1001e07c49/metrics.md#useful-gradle-commands-w-maven-equivalents) + + ---- ##### nostr-java clean build From 1ebf33194238b5921f9f8594c880edc3e9dac8ba Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sat, 15 Mar 2025 22:50:54 -0700 Subject: [PATCH 25/57] removed unused imports --- nostr-java-api/src/main/java/nostr/api/NIP60.java | 1 - .../src/main/java/nostr/api/factory/impl/NIP32Impl.java | 1 - nostr-java-base/src/main/java/nostr/base/Encoder.java | 4 +++- .../main/java/nostr/event/impl/CalendarTimeBasedEvent.java | 1 - .../nostr/event/impl/InternetIdentifierMetadataEvent.java | 2 -- .../main/java/nostr/event/json/codec/Nip05ContentDecoder.java | 1 - 6 files changed, 3 insertions(+), 7 deletions(-) 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 cb012dc3d..bc5b0d367 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP60.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP60.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java index 1b19e8855..577e8239e 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP32Impl.java @@ -5,7 +5,6 @@ package nostr.api.factory.impl; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/nostr-java-base/src/main/java/nostr/base/Encoder.java b/nostr-java-base/src/main/java/nostr/base/Encoder.java index ea845e586..326177d98 100644 --- a/nostr-java-base/src/main/java/nostr/base/Encoder.java +++ b/nostr-java-base/src/main/java/nostr/base/Encoder.java @@ -6,7 +6,9 @@ import com.fasterxml.jackson.module.afterburner.AfterburnerModule; public interface Encoder { - ObjectMapper ENCODER_MAPPED_AFTERBURNER = JsonMapper.builder().addModule(new AfterburnerModule()).build().setSerializationInclusion(Include.NON_NULL); + ObjectMapper ENCODER_MAPPED_AFTERBURNER = JsonMapper.builder().addModule( + new AfterburnerModule()).build() + .setSerializationInclusion(Include.NON_NULL); String encode(); } 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 29893ed8c..11b5647a7 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 @@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; 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 5ab5b07b3..12ec416c7 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 @@ -3,8 +3,6 @@ import static nostr.util.NostrUtil.escapeJsonString; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; 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 1cd4e635d..bf3bb681b 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,7 +1,6 @@ package nostr.event.json.codec; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import nostr.base.IDecoder; import nostr.event.Nip05Content; From 0b08674b7c5a9b43862075a8853a4c1795cb6d58 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 11:03:59 -0700 Subject: [PATCH 26/57] gradle updates --- buildSrc/build.gradle | 5 +++-- settings.gradle | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index e66ea8027..e801017c1 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -25,12 +25,13 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion implementation 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion implementation 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion - implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 - implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle + implementation 'org.springframework.boot:spring-boot-starter-security:' + springBootVersion implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion + implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner implementation 'com.google.guava:guava:' + googleGuava diff --git a/settings.gradle b/settings.gradle index 4f100c851..6a2af0c99 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,3 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - rootProject.name = 'nostr-java' include(':nostr-java-crypto') include(':nostr-java-base') From a872b8c17baa73041d5a0d9fc8c19a0efb098f7b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 12:01:00 -0700 Subject: [PATCH 27/57] gradle multi module config --- build.gradle | 79 --------------- buildSrc/build.gradle | 42 +++----- .../groovy/buildlogic.java-conventions.gradle | 41 -------- .../groovy/nostr-java.java-conventions.gradle | 98 +++++++++++++++++++ nostr-java-api/build.gradle | 20 +--- nostr-java-base/build.gradle | 19 +--- nostr-java-client/build.gradle | 26 +---- nostr-java-crypto/build.gradle | 20 +--- nostr-java-encryption/build.gradle | 19 +--- nostr-java-event/build.gradle | 23 +---- nostr-java-examples/build.gradle | 19 +--- .../java/nostr/examples/NostrApiExamples.java | 9 +- nostr-java-id/build.gradle | 19 +--- nostr-java-test/build.gradle | 2 +- nostr-java-util/build.gradle | 27 +---- settings.gradle | 2 +- 16 files changed, 146 insertions(+), 319 deletions(-) delete mode 100644 build.gradle delete mode 100644 buildSrc/src/main/groovy/buildlogic.java-conventions.gradle create mode 100644 buildSrc/src/main/groovy/nostr-java.java-conventions.gradle diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 55fe9620c..000000000 --- a/build.gradle +++ /dev/null @@ -1,79 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '3.4.3' - id 'io.spring.dependency-management' version '1.1.7' - - id 'io.freefair.lombok' version '8.12.2.1' - id 'com.adarshr.test-logger' version '4.0.0' - id 'org.gradle.test-retry' version '1.6.2' - - id 'groovy-gradle-plugin' - id 'java-library' -} - -group = 'xyz.tcheeric' -version = '0.6.5-SNAPSHOT' -description = 'nostr-java' - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(21) - } -} - -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} - -repositories { - gradlePluginPortal() - mavenLocal() - mavenCentral() - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } -} - -dependencies { - developmentOnly 'org.springframework.boot:spring-boot-devtools:3.4.3' - - implementation 'org.springframework.boot:spring-boot-starter:3.4.3' - implementation 'org.springframework.boot:spring-boot-autoconfigure:3.4.3' - implementation 'org.springframework.boot:spring-boot-configuration-processor:3.4.3' - implementation 'org.apache.commons:commons-lang3:3.17.0' - implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.80' - - implementation 'org.springframework.boot:spring-boot-starter-validation:3.4.3' - implementation 'org.springframework.boot:spring-boot-starter-websocket:3.4.3' - - implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:2.18.3' - implementation 'com.google.guava:guava:33.2.1-jre' - - testImplementation 'org.awaitility:awaitility:4.2.0' - testImplementation 'org.springframework.boot:spring-boot-starter-test:3.4.3' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - - implementation 'org.projectlombok:lombok:1.18.36' - annotationProcessor 'org.projectlombok:lombok:1.18.36' - - testImplementation 'org.projectlombok:lombok:1.18.36' - testAnnotationProcessor 'org.projectlombok:lombok:1.18.36' -} - -tasks.named('test') { - useJUnitPlatform() -} - -test { - retry { -// failOnPassedAfterRetry = true - maxRetries = 2 -// maxFailures = 42 - } -} - -bootJar { - enabled = false -} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index e801017c1..904884b8f 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,46 +1,32 @@ plugins { id 'java' - id 'io.freefair.lombok' version '8.12.2.1' id 'groovy-gradle-plugin' } +group = 'xyz.tcheeric' +version = '0.6.5-SNAPSHOT' + repositories { gradlePluginPortal() - mavenLocal() mavenCentral() maven { url = uri('https://repo.maven.apache.org/maven2/') - } + } } dependencies { def springBootVersion = '3.4.3' - def apacheCommonsLang3 = '3.17.0' - def jacksonModuleAfterburner = '2.18.3' - def googleGuava = '33.2.1-jre' - def bouncyCastle = '1.80' - def awaitility = '4.2.0' - def lombok = '1.18.36' - - implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-starter-security:' + springBootVersion - - implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion - implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion - implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 - implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: bouncyCastle - implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner - implementation 'com.google.guava:guava:' + googleGuava + implementation 'org.springframework.boot:spring-boot:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-gradle-plugin:' + springBootVersion +} - testImplementation 'org.awaitility:awaitility:' + awaitility - testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +test { + useJUnitPlatform() +} - implementation 'org.projectlombok:lombok:' + lombok - annotationProcessor 'org.projectlombok:lombok:' + lombok - testImplementation 'org.projectlombok:lombok:' + lombok - testAnnotationProcessor 'org.projectlombok:lombok:' + lombok +configurations { + compileOnly { + extendsFrom annotationProcessor + } } diff --git a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle b/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle deleted file mode 100644 index 5d1f0cceb..000000000 --- a/buildSrc/src/main/groovy/buildlogic.java-conventions.gradle +++ /dev/null @@ -1,41 +0,0 @@ -plugins { - id 'java' - id 'java-library' - id 'maven-publish' -} - -repositories { - mavenLocal() - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } -} - -group = 'xyz.tcheeric' -version = '0.6.5-SNAPSHOT' -description = 'nostr-java' -java.sourceCompatibility = JavaVersion.VERSION_21 -java.targetCompatibility = JavaVersion.VERSION_21 - -subprojects { - publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' -} - -tasks.withType(Javadoc).configureEach { - options.encoding = 'UTF-8' -} - -//tasks.build.finalizedBy() { -// tasks.publishToMavenLocal -//} diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle new file mode 100644 index 000000000..fe6eda204 --- /dev/null +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -0,0 +1,98 @@ +plugins { + id 'java' + id 'java-library' + id 'maven-publish' + id 'groovy-gradle-plugin' + id 'org.springframework.boot' +} + +group = 'xyz.tcheeric' +version = '0.6.5-SNAPSHOT' +description = 'nostr-java' + +java.sourceCompatibility = JavaVersion.VERSION_21 +java.targetCompatibility = JavaVersion.VERSION_21 + +repositories { + gradlePluginPortal() + mavenLocal() + mavenCentral() + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } + // TODO: add eric's remo +} + +publishing { + publications { +// TODO: check gradle vs maven publishing diffs + presto(MavenPublication) { + from components.java + } + } + + repositories { + mavenLocal() + } +} + +dependencies { + def springBootVersion = '3.4.3' + def apacheCommonsLang3 = '3.17.0' + def jacksonModuleAfterburner = '2.18.3' + def googleGuava = '33.2.1-jre' + def bouncyCastle = '1.80' + def awaitility = '4.2.0' + def lombok = '1.18.36' + + implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-devtools:' + springBootVersion +// implementation 'org.springframework.boot:spring-boot-starter-security:' + springBootVersion + annotationProcessor 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion + + implementation 'org.springframework.boot:spring-boot-starter-validation:' + springBootVersion + implementation 'org.springframework.boot:spring-boot-starter-websocket:' + springBootVersion + + implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner + implementation 'org.bouncycastle:bcprov-jdk18on:' + bouncyCastle + + implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 + implementation 'com.google.guava:guava:' + googleGuava + + annotationProcessor 'org.awaitility:awaitility:' + awaitility + implementation 'org.awaitility:awaitility:' + awaitility + + implementation 'org.projectlombok:lombok:' + lombok + annotationProcessor 'org.projectlombok:lombok:' + lombok + + testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion + testImplementation 'org.projectlombok:lombok:' + lombok + testImplementation 'org.awaitility:awaitility:' + awaitility + testAnnotationProcessor 'org.projectlombok:lombok:' + lombok + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' +} + +tasks.bootJar { + enabled = false +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} + +tasks.withType(Javadoc).configureEach { + options.encoding = 'UTF-8' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index 85fff8353..d4fadd3ca 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -1,24 +1,10 @@ plugins { - id 'buildlogic.java-conventions' + id 'nostr-java.java-conventions' } +description = 'nostr-java-api' + dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-client') api project(':nostr-java-encryption') - implementation libs.org.apache.commons.commons.lang3 -} - -description = 'nostr-java-api' - -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } } diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index 5d7f94a3c..290d94b47 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -1,23 +1,10 @@ plugins { - id 'buildlogic.java-conventions' + id 'nostr-java.java-conventions' } +description = 'nostr-java-base' + dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-util') api project(':nostr-java-crypto') } - -description = 'nostr-java-base' - -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } -} diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index f9493cc58..df98b3b45 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -1,29 +1,9 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - api project(':nostr-java-id') - implementation libs.org.springframework.boot.spring.boot.starter.websocket - implementation libs.org.springframework.spring.websocket - implementation libs.org.springframework.spring.webflux - implementation libs.io.projectreactor.netty.reactor.netty.http - implementation libs.jakarta.websocket.jakarta.websocket.api - implementation libs.jakarta.websocket.jakarta.websocket.client.api - implementation libs.org.awaitility.awaitility + id 'nostr-java.java-conventions' } description = 'nostr-java-client' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +dependencies { + api project(':nostr-java-id') } diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index c07b99e89..6b475a650 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -1,23 +1,9 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - implementation libs.org.bouncycastle.bcprov.jdk18on - api project(':nostr-java-util') + id 'nostr-java.java-conventions' } description = 'nostr-java-crypto' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +dependencies { + api project(':nostr-java-util') } diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 62882ab52..6917bde48 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -1,23 +1,10 @@ plugins { - id 'buildlogic.java-conventions' + id 'nostr-java.java-conventions' } +description = 'nostr-java-encryption' + dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner api project(':nostr-java-crypto') api project(':nostr-java-util') } - -description = 'nostr-java-encryption' - -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } -} diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index f912a8f91..c3f4574d4 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -1,26 +1,9 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - - implementation libs.org.apache.commons.commons.lang3 - implementation libs.com.google.guava.guava - - api project(':nostr-java-base') + id 'nostr-java.java-conventions' } description = 'nostr-java-event' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +dependencies { + api project(':nostr-java-base') } diff --git a/nostr-java-examples/build.gradle b/nostr-java-examples/build.gradle index 01f602b16..5d0ab1650 100644 --- a/nostr-java-examples/build.gradle +++ b/nostr-java-examples/build.gradle @@ -1,22 +1,9 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - api project(':nostr-java-api') + id 'nostr-java.java-conventions' } description = 'nostr-java-examples' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +dependencies { + api project(':nostr-java-api') } 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 b2316ca45..ffb6bf3d5 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java +++ b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java @@ -36,6 +36,9 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import nostr.util.NostrException; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.autoconfigure.SpringBootApplication; import java.io.IOException; import java.io.InputStream; @@ -57,7 +60,8 @@ * @author eric */ @Log -public class NostrApiExamples { +@SpringBootApplication +public class NostrApiExamples implements ApplicationRunner { private static final Identity RECIPIENT = Identity.generateRandomIdentity(); private static final Identity SENDER = Identity.generateRandomIdentity(); @@ -82,7 +86,8 @@ public class NostrApiExamples { } } - public static void main(String[] args) throws Exception { + @Override + public void run(ApplicationArguments args) throws Exception { try { log.log(Level.FINE, "================= The Beginning"); logAccountsData(); diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index 3f3d72c72..dd8c7d173 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -1,22 +1,9 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - api project(':nostr-java-event') + id 'nostr-java.java-conventions' } description = 'nostr-java-id' -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } +dependencies { + api project(':nostr-java-event') } diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle index 65555e4ee..c1248a4da 100644 --- a/nostr-java-test/build.gradle +++ b/nostr-java-test/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'buildlogic.java-conventions' + id 'nostr-java.java-conventions' } dependencies { diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index 2ff3e006a..bfeee3db5 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -1,30 +1,5 @@ plugins { - id 'buildlogic.java-conventions' -} - -dependencies { - implementation libs.org.apache.commons.commons.lang3 - - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - testImplementation libs.org.projectlombok.lombok - testAnnotationProcessor libs.org.projectlombok.lombok - - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - testImplementation libs.org.springframework.boot.spring.boot.starter.test - testImplementation libs.org.junit.jupiter.junit.jupiter.api + id 'nostr-java.java-conventions' } description = 'nostr-java-util' - -publishing { - publications { - maven(MavenPublication) { - artifactId = description - from(components.java) - } - } -} diff --git a/settings.gradle b/settings.gradle index 6a2af0c99..9ada6f1dc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ rootProject.name = 'nostr-java' + include(':nostr-java-crypto') include(':nostr-java-base') -include(':nostr-java-test') include(':nostr-java-client') include(':nostr-java-event') include(':nostr-java-examples') From 89a5daef42f0e92844f65cd1cef8995fbccc7408 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 12:52:13 -0700 Subject: [PATCH 28/57] gitignores --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 267d6bffe..b32ca7f82 100644 --- a/.gitignore +++ b/.gitignore @@ -217,6 +217,7 @@ build/ gradle/ gradlew gradlew.bat +buildSrc/build ### VisualStudioCode ### .vscode From accea2b1c1d5a25c6ca1f2da19df25e3bfc50574 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 13:16:15 -0700 Subject: [PATCH 29/57] plain jar classifier --- buildSrc/src/main/groovy/nostr-java.java-conventions.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index fe6eda204..6eb564345 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -79,6 +79,10 @@ tasks.bootJar { enabled = false } +tasks.named("jar") { + archiveClassifier = '' +} + java { toolchain { languageVersion = JavaLanguageVersion.of(21) From e94433f9aab2cbb744b47d9341e05948e2f6dd6b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 13:25:01 -0700 Subject: [PATCH 30/57] placeholder for remote repo publish --- .../groovy/nostr-java.java-conventions.gradle | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index 6eb564345..9133c77ca 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -23,18 +23,17 @@ repositories { // TODO: add eric's remo } -publishing { - publications { -// TODO: check gradle vs maven publishing diffs - presto(MavenPublication) { - from components.java - } - } - - repositories { - mavenLocal() - } -} +//publishing { +// publications { +// nostrjava(MavenPublication) { +// from components.java +// } +// } +//// TODO: eric may want to provide his publishing specs +// repositories { +// someRemoteRepo() +// } +//} dependencies { def springBootVersion = '3.4.3' From 72b1fc31c078450db47ce7ce7da11ae73aa771ea Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 19:59:35 -0700 Subject: [PATCH 31/57] gradle test logger plugin --- buildSrc/build.gradle | 4 -- .../groovy/nostr-java.java-conventions.gradle | 39 ++++++++++++------- gradle.properties | 4 +- nostr-java-base/build.gradle | 12 ++++++ .../test/java/nostr}/base/BaseKeyTest.java | 3 +- .../resources/application-test.properties | 4 ++ .../test/resources/junit-platform.properties | 7 ++++ settings.gradle | 13 +++++++ 8 files changed, 65 insertions(+), 21 deletions(-) rename {nostr-java-test/src/test/java/nostr/test => nostr-java-base/src/test/java/nostr}/base/BaseKeyTest.java (98%) create mode 100644 nostr-java-base/src/test/resources/application-test.properties create mode 100644 nostr-java-base/src/test/resources/junit-platform.properties diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 904884b8f..b4a6d711e 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -21,10 +21,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-gradle-plugin:' + springBootVersion } -test { - useJUnitPlatform() -} - configurations { compileOnly { extendsFrom annotationProcessor diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index 9133c77ca..ede61f736 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -4,6 +4,8 @@ plugins { id 'maven-publish' id 'groovy-gradle-plugin' id 'org.springframework.boot' + id 'com.adarshr.test-logger' + id 'io.spring.dependency-management' } group = 'xyz.tcheeric' @@ -18,9 +20,10 @@ repositories { mavenLocal() mavenCentral() maven { - url = uri('https://repo.maven.apache.org/maven2/') + uri('https://repo.maven.apache.org/maven2/') + url 'https://plugins.gradle.org/m2/' } - // TODO: add eric's remo +//// TODO: eric may want to provide his publishing specs } //publishing { @@ -42,11 +45,12 @@ dependencies { def googleGuava = '33.2.1-jre' def bouncyCastle = '1.80' def awaitility = '4.2.0' +// TODO: save below/Modulith for multi-module integration testing + def springModulithVersion = '1.3.3' def lombok = '1.18.36' implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion implementation 'org.springframework.boot:spring-boot-devtools:' + springBootVersion -// implementation 'org.springframework.boot:spring-boot-starter-security:' + springBootVersion annotationProcessor 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springBootVersion @@ -58,27 +62,38 @@ dependencies { implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 implementation 'com.google.guava:guava:' + googleGuava - - annotationProcessor 'org.awaitility:awaitility:' + awaitility implementation 'org.awaitility:awaitility:' + awaitility - + annotationProcessor 'org.awaitility:awaitility:' + awaitility implementation 'org.projectlombok:lombok:' + lombok annotationProcessor 'org.projectlombok:lombok:' + lombok - testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion testImplementation 'org.projectlombok:lombok:' + lombok testImplementation 'org.awaitility:awaitility:' + awaitility + + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation 'com.adarshr:gradle-test-logger-plugin:4.0.0' + testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion testAnnotationProcessor 'org.projectlombok:lombok:' + lombok +} - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' +subprojects { apply plugin: 'com.adarshr.test-logger' } + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +tasks.test { +// systemProperty("spring.profiles.active", "test") + useJUnitPlatform() } tasks.bootJar { enabled = false } -tasks.named("jar") { +tasks.jar { archiveClassifier = '' } @@ -95,7 +110,3 @@ tasks.withType(JavaCompile).configureEach { tasks.withType(Javadoc).configureEach { options.encoding = 'UTF-8' } - -tasks.named('test') { - useJUnitPlatform() -} diff --git a/gradle.properties b/gradle.properties index 90caf12dc..11faf477f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,5 @@ org.gradle.configuration-cache=true org.gradle.daemon=true - +org.gradle.caching=true +org.gradle.parallel=true +#createReports=true diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index 290d94b47..e8d8e105f 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -1,5 +1,6 @@ plugins { id 'nostr-java.java-conventions' + id 'com.adarshr.test-logger' } description = 'nostr-java-base' @@ -7,4 +8,15 @@ description = 'nostr-java-base' dependencies { api project(':nostr-java-util') api project(':nostr-java-crypto') + +// TODO: save below/Modulith for multi-module integration testing +// testRuntimeOnly 'org.springframework.modulith:spring-modulith-core:1.3.3' +// testCompileOnly 'org.springframework.modulith:spring-modulith-api:1.3.3' +// testCompileOnly 'org.springframework.modulith:spring-modulith-apt:1.3.3' +// testCompileOnly 'org.springframework.modulith:spring-modulith-moments:1.3.3' +} + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() } diff --git a/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java rename to nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java index 32021a401..bfd85e403 100644 --- a/nostr-java-test/src/test/java/nostr/test/base/BaseKeyTest.java +++ b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java @@ -1,6 +1,5 @@ -package nostr.test.base; +package nostr.base; -import nostr.base.PublicKey; import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; diff --git a/nostr-java-base/src/test/resources/application-test.properties b/nostr-java-base/src/test/resources/application-test.properties new file mode 100644 index 000000000..c4bd7b5c1 --- /dev/null +++ b/nostr-java-base/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr.base=INFO +logging.pattern.console=%msg%n diff --git a/nostr-java-base/src/test/resources/junit-platform.properties b/nostr-java-base/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-base/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent diff --git a/settings.gradle b/settings.gradle index 9ada6f1dc..062666aa7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,14 @@ +buildscript { + repositories { + maven { + url 'https://plugins.gradle.org/m2/' + } + } + dependencies { + classpath 'com.adarshr:gradle-test-logger-plugin:4.0.0' + } +} + rootProject.name = 'nostr-java' include(':nostr-java-crypto') @@ -9,3 +20,5 @@ include(':nostr-java-util') include(':nostr-java-api') include(':nostr-java-id') include(':nostr-java-encryption') + +//id 'org.gradle.test-retry' version '1.6.2' From 654c4dee831eff159ab43b7e79cf72b48aeb776d Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 21:31:39 -0700 Subject: [PATCH 32/57] config cleanups --- buildSrc/build.gradle | 2 +- .../groovy/nostr-java.java-conventions.gradle | 9 ++-- gradle.properties | 2 +- nostr-java-test/build.gradle | 52 ------------------- settings.gradle | 2 +- 5 files changed, 8 insertions(+), 59 deletions(-) delete mode 100644 nostr-java-test/build.gradle diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index b4a6d711e..be30e2850 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -10,7 +10,7 @@ repositories { gradlePluginPortal() mavenCentral() maven { - url = uri('https://repo.maven.apache.org/maven2/') + url = 'https://repo.maven.apache.org/maven2/' } } diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index ede61f736..095804125 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -20,19 +20,20 @@ repositories { mavenLocal() mavenCentral() maven { - uri('https://repo.maven.apache.org/maven2/') - url 'https://plugins.gradle.org/m2/' + url = 'https://plugins.gradle.org/m2/' + } + maven { + url = 'https://plugins.gradle.org/m2/' } -//// TODO: eric may want to provide his publishing specs } +//// TODO: commented placeholder as eric may want to provide custom publishing specs //publishing { // publications { // nostrjava(MavenPublication) { // from components.java // } // } -//// TODO: eric may want to provide his publishing specs // repositories { // someRemoteRepo() // } diff --git a/gradle.properties b/gradle.properties index 11faf477f..cd889ee94 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.configuration-cache=true +org.gradle.configuration-cache=false org.gradle.daemon=true org.gradle.caching=true org.gradle.parallel=true diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle deleted file mode 100644 index c1248a4da..000000000 --- a/nostr-java-test/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -plugins { - id 'nostr-java.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - testImplementation libs.org.projectlombok.lombok - testAnnotationProcessor libs.org.projectlombok.lombok - - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - - implementation libs.com.google.guava.guava - implementation libs.org.springframework.boot.spring.boot.starter.test - implementation libs.org.junit.jupiter.junit.jupiter.api - - testImplementation libs.com.google.guava.guava - testImplementation libs.org.springframework.boot.spring.boot.starter.test - testImplementation libs.org.junit.jupiter.junit.jupiter.api - - api project(':nostr-java-client') - api project(':nostr-java-util') - api project(':nostr-java-api') -} - -description = 'nostr-java-test' - -// no publishing for test module -//publishing { -// publications { -// maven(MavenPublication) { -// artifactId = description -// from(components.java) -// } -// } -//} - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} - -//test { -// retry { -// failOnPassedAfterRetry = false -// maxRetries = 2 -//// maxFailures = 42 -// } -//} diff --git a/settings.gradle b/settings.gradle index 062666aa7..8fe1e2175 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ buildscript { repositories { maven { - url 'https://plugins.gradle.org/m2/' + url = 'https://plugins.gradle.org/m2/' } } dependencies { From 6dd39c12f50efc5eb8e2b94a8eb8957698dcca0a Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 21:56:07 -0700 Subject: [PATCH 33/57] event package class tests moved to proper location --- nostr-java-base/pom.xml | 5 ++ nostr-java-event/build.gradle | 5 ++ nostr-java-event/pom.xml | 5 ++ .../test/java/nostr}/event/BaseTagTest.java | 57 +++++++++---------- .../resources/application-test.properties | 4 ++ .../test/resources/junit-platform.properties | 7 +++ nostr-java-test/build.gradle | 52 +++++++++++++++++ 7 files changed, 106 insertions(+), 29 deletions(-) rename {nostr-java-test/src/test/java/nostr/test => nostr-java-event/src/test/java/nostr}/event/BaseTagTest.java (88%) create mode 100644 nostr-java-event/src/test/resources/application-test.properties create mode 100644 nostr-java-event/src/test/resources/junit-platform.properties create mode 100644 nostr-java-test/build.gradle diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 41d0263ce..ee469b2df 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -34,5 +34,10 @@ nostr-java-crypto ${project.version} + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index c3f4574d4..2259e2ea3 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -7,3 +7,8 @@ description = 'nostr-java-event' dependencies { api project(':nostr-java-base') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index bd55ebdc2..1766bd514 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -25,5 +25,10 @@ nostr-java-base ${project.version} + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/nostr-java-test/src/test/java/nostr/test/event/BaseTagTest.java b/nostr-java-event/src/test/java/nostr/event/BaseTagTest.java similarity index 88% rename from nostr-java-test/src/test/java/nostr/test/event/BaseTagTest.java rename to nostr-java-event/src/test/java/nostr/event/BaseTagTest.java index 06c1d9fc2..03baca20e 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/BaseTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/BaseTagTest.java @@ -1,29 +1,28 @@ -package nostr.test.event; - -import nostr.event.BaseTag; -import nostr.event.impl.GenericTag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class BaseTagTest { - - BaseTag genericTag = GenericTag.create("id", 1, "value"); - - @Test - void getNip() { - assertEquals(1, genericTag.getNip()); - } - - @Test - void testHashCode() { - assertEquals(112174237, genericTag.hashCode()); - } - - @Test - void testToString() { - String result = "GenericTag(code=id, nip=1, attributes=[ElementAttribute(name=param0, value=value, nip=null)])"; - assertEquals(result, genericTag.toString()); - } - -} \ No newline at end of file +package nostr.event; + +import nostr.event.impl.GenericTag; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BaseTagTest { + + BaseTag genericTag = GenericTag.create("id", 1, "value"); + + @Test + void getNip() { + assertEquals(1, genericTag.getNip()); + } + + @Test + void testHashCode() { + assertEquals(112174237, genericTag.hashCode()); + } + + @Test + void testToString() { + String result = "GenericTag(code=id, nip=1, attributes=[ElementAttribute(name=param0, value=value, nip=null)])"; + assertEquals(result, genericTag.toString()); + } + +} diff --git a/nostr-java-event/src/test/resources/application-test.properties b/nostr-java-event/src/test/resources/application-test.properties new file mode 100644 index 000000000..c4bd7b5c1 --- /dev/null +++ b/nostr-java-event/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr.base=INFO +logging.pattern.console=%msg%n diff --git a/nostr-java-event/src/test/resources/junit-platform.properties b/nostr-java-event/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-event/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle new file mode 100644 index 000000000..c1248a4da --- /dev/null +++ b/nostr-java-test/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'nostr-java.java-conventions' +} + +dependencies { + implementation libs.org.projectlombok.lombok + annotationProcessor libs.org.projectlombok.lombok + testImplementation libs.org.projectlombok.lombok + testAnnotationProcessor libs.org.projectlombok.lombok + + implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner + annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner + + implementation libs.com.google.guava.guava + implementation libs.org.springframework.boot.spring.boot.starter.test + implementation libs.org.junit.jupiter.junit.jupiter.api + + testImplementation libs.com.google.guava.guava + testImplementation libs.org.springframework.boot.spring.boot.starter.test + testImplementation libs.org.junit.jupiter.junit.jupiter.api + + api project(':nostr-java-client') + api project(':nostr-java-util') + api project(':nostr-java-api') +} + +description = 'nostr-java-test' + +// no publishing for test module +//publishing { +// publications { +// maven(MavenPublication) { +// artifactId = description +// from(components.java) +// } +// } +//} + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} + +//test { +// retry { +// failOnPassedAfterRetry = false +// maxRetries = 2 +//// maxFailures = 42 +// } +//} From 3603bcdb0af56516c09072ec913bdbb2a20b6b91 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Mon, 17 Mar 2025 23:10:47 -0700 Subject: [PATCH 34/57] tests moved to proper modules --- nostr-java-api/build.gradle | 5 + nostr-java-api/pom.xml | 12 ++ .../java/nostr/api/config}/TestConfig.java | 2 +- .../api/integration}/APINIP09EventTest.java | 28 ++-- .../nostr/api/integration}/ApiEventTest.java | 3 +- ...entTestUsingSpringWebSocketClientTest.java | 7 +- .../api/integration}/ApiNIP52EventTest.java | 4 +- .../api/integration}/ApiNIP52RequestTest.java | 2 +- .../api/integration}/ApiNIP99EventTest.java | 33 ++++- .../api/integration}/ApiNIP99RequestTest.java | 7 +- .../nostr/api/integration}/NIP52ImplTest.java | 2 +- .../nostr/api/integration}/NIP60Test.java | 2 +- .../nostr/api/integration}/NIP61Test.java | 2 +- .../api/unit}/CalendarTimeBasedEventTest.java | 2 +- .../java/nostr/api/unit}/JsonParseTest.java | 4 +- .../java/nostr/api/unit}/NIP57ImplTest.java | 4 +- .../java/nostr/api/unit}/NIP99ImplTest.java | 2 +- .../java/nostr/api}/util/JsonComparator.java | 2 +- .../resources/application-test.properties | 4 + .../test/resources/junit-platform.properties | 0 .../src/test/resources/relays.properties | 0 nostr-java-base/pom.xml | 6 + nostr-java-crypto/build.gradle | 5 + nostr-java-crypto/pom.xml | 11 ++ .../test/java/nostr/crypto/CryptoTest.java | 62 ++++++++ .../resources/application-test.properties | 4 + .../test/resources/junit-platform.properties | 7 + nostr-java-event/pom.xml | 7 + .../unit}/BaseMessageCommandMapperTest.java | 2 +- .../nostr/event/{ => unit}/BaseTagTest.java | 3 +- .../unit}/CalendarContentDecodeTest.java | 2 +- .../unit}/ClassifiedListingDecodeTest.java | 2 +- .../java/nostr/event/unit}/DecodeTest.java | 2 +- .../java/nostr/event/unit}/EventTagTest.java | 4 +- .../nostr/event/unit}/FiltersDecoderTest.java | 2 +- .../nostr/event/unit}/FiltersEncoderTest.java | 2 +- .../nostr/event/unit}/KindMappingTest.java | 2 +- .../java/nostr/event/unit}/PriceTagTest.java | 2 +- .../java/nostr/event/unit}/PubkeyTagTest.java | 4 +- .../java/nostr/event/unit}/RelaysTagTest.java | 2 +- .../java/nostr/event/unit}/SignatureTest.java | 2 +- .../resources/application-test.properties | 2 +- nostr-java-id/build.gradle | 5 + nostr-java-id/pom.xml | 12 ++ .../nostr/id}/ClassifiedListingEventTest.java | 5 +- .../test/java/nostr/id}/EntityFactory.java | 3 +- .../src/test/java/nostr/id}/EventTest.java | 4 +- .../src/test/java/nostr}/id/IdentityTest.java | 4 +- .../java/nostr/id}/ZapReceiptEventTest.java | 5 +- .../java/nostr/id}/ZapRequestEventTest.java | 5 +- .../resources/application-test.properties | 2 +- .../test/resources/junit-platform.properties | 7 + nostr-java-test/README.md | 0 nostr-java-test/build.gradle | 52 ------- nostr-java-test/pom.xml | 133 ------------------ .../java/nostr/test/crypto/CryptoTest.java | 62 -------- .../src/test/resources/app.properties | 3 - .../src/test/resources/profile.properties | 3 - nostr-java-util/build.gradle | 5 + nostr-java-util/pom.xml | 4 +- .../test/java/nostr/util}/NostrUtilTest.java | 3 +- .../resources/application-test.properties | 4 + .../test/resources/junit-platform.properties | 7 + 63 files changed, 266 insertions(+), 324 deletions(-) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/config}/TestConfig.java (96%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/APINIP09EventTest.java (84%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiEventTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiEventTestUsingSpringWebSocketClientTest.java (94%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiNIP52EventTest.java (97%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiNIP52RequestTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiNIP99EventTest.java (64%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/ApiNIP99RequestTest.java (96%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/integration}/NIP52ImplTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/api => nostr-java-api/src/test/java/nostr/api/integration}/NIP60Test.java (99%) rename {nostr-java-test/src/test/java/nostr/test/api => nostr-java-api/src/test/java/nostr/api/integration}/NIP61Test.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/unit}/CalendarTimeBasedEventTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/json => nostr-java-api/src/test/java/nostr/api/unit}/JsonParseTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/unit}/NIP57ImplTest.java (96%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-api/src/test/java/nostr/api/unit}/NIP99ImplTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test => nostr-java-api/src/test/java/nostr/api}/util/JsonComparator.java (99%) create mode 100644 nostr-java-api/src/test/resources/application-test.properties rename {nostr-java-test => nostr-java-api}/src/test/resources/junit-platform.properties (100%) rename {nostr-java-test => nostr-java-api}/src/test/resources/relays.properties (100%) create mode 100644 nostr-java-crypto/src/test/java/nostr/crypto/CryptoTest.java create mode 100644 nostr-java-crypto/src/test/resources/application-test.properties create mode 100644 nostr-java-crypto/src/test/resources/junit-platform.properties rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/BaseMessageCommandMapperTest.java (98%) rename nostr-java-event/src/test/java/nostr/event/{ => unit}/BaseTagTest.java (91%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/CalendarContentDecodeTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/ClassifiedListingDecodeTest.java (98%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/DecodeTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/EventTagTest.java (96%) rename {nostr-java-test/src/test/java/nostr/test/filters => nostr-java-event/src/test/java/nostr/event/unit}/FiltersDecoderTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/filters => nostr-java-event/src/test/java/nostr/event/unit}/FiltersEncoderTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/KindMappingTest.java (95%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/PriceTagTest.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/PubkeyTagTest.java (93%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/RelaysTagTest.java (95%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-event/src/test/java/nostr/event/unit}/SignatureTest.java (96%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-id/src/test/java/nostr/id}/ClassifiedListingEventTest.java (98%) rename {nostr-java-test/src/main/java/nostr/test => nostr-java-id/src/test/java/nostr/id}/EntityFactory.java (99%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-id/src/test/java/nostr/id}/EventTest.java (98%) rename {nostr-java-test/src/test/java/nostr/test => nostr-java-id/src/test/java/nostr}/id/IdentityTest.java (93%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-id/src/test/java/nostr/id}/ZapReceiptEventTest.java (97%) rename {nostr-java-test/src/test/java/nostr/test/event => nostr-java-id/src/test/java/nostr/id}/ZapRequestEventTest.java (98%) rename {nostr-java-test => nostr-java-id}/src/test/resources/application-test.properties (70%) create mode 100644 nostr-java-id/src/test/resources/junit-platform.properties delete mode 100644 nostr-java-test/README.md delete mode 100644 nostr-java-test/build.gradle delete mode 100644 nostr-java-test/pom.xml delete mode 100644 nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java delete mode 100644 nostr-java-test/src/test/resources/app.properties delete mode 100644 nostr-java-test/src/test/resources/profile.properties rename {nostr-java-test/src/test/java/nostr/test/base => nostr-java-util/src/test/java/nostr/util}/NostrUtilTest.java (92%) create mode 100644 nostr-java-util/src/test/resources/application-test.properties create mode 100644 nostr-java-util/src/test/resources/junit-platform.properties diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index d4fadd3ca..9b9095426 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -8,3 +8,8 @@ dependencies { api project(':nostr-java-client') api project(':nostr-java-encryption') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 6c4e0877b..125ba66d1 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -26,5 +26,17 @@ commons-lang3 ${commons-lang3.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/nostr-java-test/src/test/java/nostr/test/event/TestConfig.java b/nostr-java-api/src/test/java/nostr/api/config/TestConfig.java similarity index 96% rename from nostr-java-test/src/test/java/nostr/test/event/TestConfig.java rename to nostr-java-api/src/test/java/nostr/api/config/TestConfig.java index 6629f4b9f..6ed88761b 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/TestConfig.java +++ b/nostr-java-api/src/test/java/nostr/api/config/TestConfig.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.config; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; diff --git a/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java similarity index 84% rename from nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java index 3c5ef09a7..784932fa0 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java @@ -1,7 +1,8 @@ -package nostr.test.event; +package nostr.api.integration; import nostr.api.NIP01; import nostr.api.NIP09; +import nostr.api.config.TestConfig; import nostr.base.Relay; import nostr.event.BaseMessage; import nostr.event.BaseTag; @@ -18,7 +19,11 @@ import nostr.event.tag.IdentifierTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; import java.util.List; @@ -31,11 +36,13 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(SpringExtension.class) +@SpringJUnitConfig(TestConfig.class) @ActiveProfiles("test") public class APINIP09EventTest { - - private static final String RELAY_URI = "ws://localhost:5555"; - + @Autowired + private Map relays; + @Test public void deleteEvent() throws IOException { @@ -43,7 +50,7 @@ public void deleteEvent() throws IOException { NIP09 nip09 = new NIP09<>(identity); NIP01 nip01 = new NIP01<>(identity); - nip01.createTextNoteEvent("Delete me!").signAndSend(Map.of("local", RELAY_URI)); + nip01.createTextNoteEvent("Delete me!").signAndSend(relays); Filters filters = new Filters( new KindFilter<>(Kind.TEXT_NOTE), @@ -54,7 +61,7 @@ public void deleteEvent() throws IOException { assertFalse(result.isEmpty()); assertEquals(2, result.size()); - nip09.createDeletionEvent(nip01.getEvent()).signAndSend(Map.of("local", RELAY_URI)); + nip09.createDeletionEvent(nip01.getEvent()).signAndSend(relays); result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -68,10 +75,11 @@ public void deleteEvent() throws IOException { @Test public void deleteEventWithRef() throws IOException { + final String RELAY_URI = "ws://localhost:5555"; Identity identity = Identity.generateRandomIdentity(); NIP01 nip011 = new NIP01<>(identity); - BaseMessage replaceableMessage = nip011.createReplaceableEvent(10_001, "replaceable event").signAndSend(Map.of("local", RELAY_URI)); + BaseMessage replaceableMessage = nip011.createReplaceableEvent(10_001, "replaceable event").signAndSend(relays); assertNotNull(replaceableMessage); assertTrue(replaceableMessage instanceof OkMessage); @@ -84,8 +92,8 @@ public void deleteEventWithRef() throws IOException { .createTextNoteEvent("Reference me!") .getEvent() .addTag(nip01.createAddressTag(10_001, identity.getPublicKey(), identifierTag, new Relay(RELAY_URI))); - - BaseMessage message = nip01.signAndSend(Map.of("local", RELAY_URI)); + + BaseMessage message = nip01.signAndSend(relays); assertNotNull(message); assertTrue(message instanceof OkMessage); @@ -126,7 +134,7 @@ public void deleteEventWithRef() throws IOException { assertEquals(2, kindTags.size()); - nip09.signAndSend(Map.of("local", RELAY_URI)); + nip09.signAndSend(relays); nip01.close(); nip011.close(); diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java index 96b6e297d..11ec1c1fb 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.integration; import com.fasterxml.jackson.core.JsonProcessingException; import nostr.api.EventNostr; @@ -16,6 +16,7 @@ import nostr.crypto.bech32.Bech32Prefix; import nostr.event.BaseTag; import nostr.event.NIP01Event; +import nostr.api.config.TestConfig; import nostr.event.filter.Filters; import nostr.event.filter.GenericTagQueryFilter; import nostr.event.filter.GeohashTagFilter; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java similarity index 94% rename from nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java index f8b05fa68..d91dbbf25 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java @@ -1,6 +1,7 @@ -package nostr.test.event; +package nostr.api.integration; import nostr.api.NIP15; +import nostr.api.config.TestConfig; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.impl.GenericEvent; @@ -19,9 +20,9 @@ import java.util.List; import java.util.Map; +import static nostr.api.integration.ApiEventTest.createProduct; +import static nostr.api.integration.ApiEventTest.createStall; import static nostr.base.IEvent.MAPPER_AFTERBURNER; -import static nostr.test.event.ApiEventTest.createProduct; -import static nostr.test.event.ApiEventTest.createStall; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java similarity index 97% rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java index 7b527a2a0..3b9db8e87 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java @@ -1,6 +1,7 @@ -package nostr.test.event; +package nostr.api.integration; import nostr.api.NIP52; +import nostr.api.util.JsonComparator; import nostr.base.PrivateKey; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; @@ -11,7 +12,6 @@ import nostr.event.tag.IdentifierTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.test.util.JsonComparator; import org.junit.jupiter.api.Test; import java.io.IOException; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java index ff044ce39..4c70ee2f2 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.integration; import nostr.api.NIP52; import nostr.base.PublicKey; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java similarity index 64% rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java index 642e9959b..560bb22be 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java @@ -1,27 +1,56 @@ -package nostr.test.event; +package nostr.api.integration; import nostr.api.NIP99; import nostr.base.PrivateKey; +import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.BaseTag; import nostr.event.impl.ClassifiedListing; import nostr.event.impl.GenericEvent; import nostr.event.impl.GenericTag; import nostr.event.message.EventMessage; +import nostr.event.tag.EventTag; +import nostr.event.tag.GeohashTag; +import nostr.event.tag.HashtagTag; import nostr.event.tag.PriceTag; +import nostr.event.tag.PubKeyTag; +import nostr.event.tag.SubjectTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; import java.io.IOException; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import static nostr.base.IEvent.MAPPER_AFTERBURNER; -import static nostr.test.event.ClassifiedListingEventTest.*; import static org.junit.jupiter.api.Assertions.assertTrue; class ApiNIP99EventTest { private static final String RELAY_URI = "ws://localhost:5555"; + public static final String CLASSIFIED_LISTING_CONTENT = "classified listing content"; + + public static final String PTAG_HEX = "2bed79f81439ff794cf5ac5f7bff9121e257f399829e472c7a14d3e86fe76985"; + public static final String ETAG_HEX = "494001ac0c8af2a10f60f23538e5b35d3cdacb8e1cc956fe7a16dfa5cbfc4347"; + + public static final PubKeyTag P_TAG = new PubKeyTag(new PublicKey(PTAG_HEX)); + public static final EventTag E_TAG = new EventTag(ETAG_HEX); + + public static final String SUBJECT = "Classified Listing Test Subject Tag"; + public static final SubjectTag SUBJECT_TAG = new SubjectTag(SUBJECT); + public static final GeohashTag G_TAG = new GeohashTag("Classified Listing Test Geohash Tag"); + public static final HashtagTag T_TAG = new HashtagTag("Classified Listing Test Hashtag Tag"); + + public static final BigDecimal NUMBER = new BigDecimal("2.71"); + public static final String FREQUENCY = "NANOSECOND"; + public static final String CURRENCY = "BTC"; + + public static final String CLASSIFIED_LISTING_PUBLISHED_AT = "1687765220"; + public static final String CLASSIFIED_LISTING_LOCATION = "classified listing location"; + public static final String TITLE_CODE = "title"; + public static final String SUMMARY_CODE = "summary"; + public static final String PUBLISHED_AT_CODE = "published_at"; + public static final String LOCATION_CODE = "location"; private final SpringWebSocketClient springWebSocketClient; public ApiNIP99EventTest() { diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java similarity index 96% rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java index bd9a44cef..78d759f63 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.integration; import com.fasterxml.jackson.databind.JsonNode; import nostr.api.NIP99; @@ -25,14 +25,13 @@ import java.util.List; import static nostr.base.IEvent.MAPPER_AFTERBURNER; -import static nostr.test.event.ClassifiedListingEventTest.LOCATION_CODE; -import static nostr.test.event.ClassifiedListingEventTest.PUBLISHED_AT_CODE; import static org.junit.jupiter.api.Assertions.assertTrue; class ApiNIP99RequestTest { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; - private static final String SUBSCRIBER_ID = "ApiNIP99RequestTest-subscriber_001"; + public static final String PUBLISHED_AT_CODE = "published_at"; + public static final String LOCATION_CODE = "location"; public static final String ID = "299ab85049a7923e9cd82329c0fa489ca6fd6d21feeeac33543b1237e14a9e07"; public static final String KIND = "30402"; diff --git a/nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java b/nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java index e4400f76f..44c433d33 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.integration; import java.util.ArrayList; import java.util.List; diff --git a/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java b/nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java rename to nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java index 9ed239212..3235061a2 100644 --- a/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java @@ -1,4 +1,4 @@ -package nostr.test.api; +package nostr.api.integration; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.NonNull; diff --git a/nostr-java-test/src/test/java/nostr/test/api/NIP61Test.java b/nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/api/NIP61Test.java rename to nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java index 79ddabf46..1fe3f73cf 100644 --- a/nostr-java-test/src/test/java/nostr/test/api/NIP61Test.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java @@ -1,4 +1,4 @@ -package nostr.test.api; +package nostr.api.integration; import java.util.Arrays; import java.util.List; diff --git a/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java b/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java rename to nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java index 25e268677..86b7adc2f 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/CalendarTimeBasedEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/CalendarTimeBasedEventTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.unit; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; diff --git a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java b/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java rename to nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java index 9e4c24b02..ccfff117e 100644 --- a/nostr-java-test/src/test/java/nostr/test/json/JsonParseTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java @@ -1,8 +1,9 @@ -package nostr.test.json; +package nostr.api.unit; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.extern.java.Log; import nostr.api.NIP01; +import nostr.api.util.JsonComparator; import nostr.base.Command; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; @@ -42,7 +43,6 @@ import nostr.event.tag.PriceTag; import nostr.event.tag.PubKeyTag; import nostr.id.Identity; -import nostr.test.util.JsonComparator; import org.junit.jupiter.api.Test; import java.math.BigDecimal; diff --git a/nostr-java-test/src/test/java/nostr/test/event/NIP57ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java similarity index 96% rename from nostr-java-test/src/test/java/nostr/test/event/NIP57ImplTest.java rename to nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java index a69874a69..af0dd2eb8 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/NIP57ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP57ImplTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.unit; import lombok.extern.java.Log; import nostr.api.factory.impl.NIP57Impl.ZapRequestEventFactory; @@ -43,4 +43,4 @@ void testNIP57CreateZapRequestEventFactory() { assertEquals(AMOUNT, instance.getZapRequest().getAmount()); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/event/NIP99ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/NIP99ImplTest.java rename to nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java index 017c97b54..d9ae63031 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/NIP99ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP99ImplTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.api.unit; import nostr.api.NIP99; import nostr.event.BaseTag; diff --git a/nostr-java-test/src/test/java/nostr/test/util/JsonComparator.java b/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/util/JsonComparator.java rename to nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java index 7758fee66..01d33435b 100644 --- a/nostr-java-test/src/test/java/nostr/test/util/JsonComparator.java +++ b/nostr-java-api/src/test/java/nostr/api/util/JsonComparator.java @@ -1,4 +1,4 @@ -package nostr.test.util; +package nostr.api.util; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeType; diff --git a/nostr-java-api/src/test/resources/application-test.properties b/nostr-java-api/src/test/resources/application-test.properties new file mode 100644 index 000000000..5c1a515fb --- /dev/null +++ b/nostr-java-api/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr.api=INFO +logging.pattern.console=%msg%n diff --git a/nostr-java-test/src/test/resources/junit-platform.properties b/nostr-java-api/src/test/resources/junit-platform.properties similarity index 100% rename from nostr-java-test/src/test/resources/junit-platform.properties rename to nostr-java-api/src/test/resources/junit-platform.properties diff --git a/nostr-java-test/src/test/resources/relays.properties b/nostr-java-api/src/test/resources/relays.properties similarity index 100% rename from nostr-java-test/src/test/resources/relays.properties rename to nostr-java-api/src/test/resources/relays.properties diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index ee469b2df..2df56919b 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -34,6 +34,12 @@ nostr-java-crypto ${project.version} + + + org.springframework.boot + spring-boot-starter-test + test + org.junit.jupiter junit-jupiter-api diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index 6b475a650..14c3029a8 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -7,3 +7,8 @@ description = 'nostr-java-crypto' dependencies { api project(':nostr-java-util') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index b0022724f..0836a64c9 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -36,5 +36,16 @@ nostr-java-util ${project.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/CryptoTest.java b/nostr-java-crypto/src/test/java/nostr/crypto/CryptoTest.java new file mode 100644 index 000000000..28d682ee1 --- /dev/null +++ b/nostr-java-crypto/src/test/java/nostr/crypto/CryptoTest.java @@ -0,0 +1,62 @@ +//package nostr.crypto; +// +//import nostr.base.Signature; +//import nostr.crypto.bech32.Bech32; +//import nostr.crypto.bech32.Bech32Prefix; +//import nostr.crypto.schnorr.Schnorr; +//import nostr.event.impl.GenericEvent; +//import nostr.id.Identity; +//import nostr.util.NostrUtil; +//import org.junit.jupiter.api.Test; +// +//import static nostr.crypto.EntityFactory.Events.createTextNoteEvent; +//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.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; +// +///** +// * +// * @author squirrel +// */ +//public class CryptoTest { +// +// @Test +// public void testBech32() { +// try { +// System.out.println("testBech32"); +// +// final String hexPub = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; +// final String npub = "npub126klq89p42wk78p4j5ur8wlxmxdqepdh8tez9e4axpd4run5nahsmff27j"; +// +// assertEquals(npub, Bech32.toBech32(Bech32Prefix.NPUB, hexPub)); +// assertEquals("56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f", Bech32.fromBech32(npub)); +// } catch (Exception ex) { +// fail(ex); +// } +// } +// +// @Test +// public void testVerifySignature() { +// System.out.println("testVerifySignature"); +// +// Identity identity = Identity.generateRandomIdentity(); +// final GenericEvent[] event = {createTextNoteEvent(identity.getPublicKey(), "Hello World")}; +// event[0].update(); +// assertDoesNotThrow(() -> { +// byte[] message = NostrUtil.sha256(event[0].get_serializedEvent()); +// Signature signature = identity.sign(event[0]); +// boolean verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); +// assertTrue(verification, "Schnorr must have a true verify result."); +// +// event[0] = createTextNoteEvent(identity.getPublicKey(), "Guten Tag"); +// event[0].update(); +// message = NostrUtil.sha256(event[0].get_serializedEvent()); +// verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); +// +// assertFalse(verification); +// }); +// } +// +//} diff --git a/nostr-java-crypto/src/test/resources/application-test.properties b/nostr-java-crypto/src/test/resources/application-test.properties new file mode 100644 index 000000000..887cd2666 --- /dev/null +++ b/nostr-java-crypto/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr.crypto=INFO +logging.pattern.console=%msg%n diff --git a/nostr-java-crypto/src/test/resources/junit-platform.properties b/nostr-java-crypto/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-crypto/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 1766bd514..de916545d 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -25,6 +25,13 @@ nostr-java-base ${project.version} + + + + org.springframework.boot + spring-boot-starter-test + test + org.junit.jupiter junit-jupiter-api diff --git a/nostr-java-test/src/test/java/nostr/test/event/BaseMessageCommandMapperTest.java b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/event/BaseMessageCommandMapperTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java index 94000b102..b2c2621f5 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/BaseMessageCommandMapperTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/BaseMessageCommandMapperTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.extern.java.Log; diff --git a/nostr-java-event/src/test/java/nostr/event/BaseTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java similarity index 91% rename from nostr-java-event/src/test/java/nostr/event/BaseTagTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java index 03baca20e..c6d8bb8d8 100644 --- a/nostr-java-event/src/test/java/nostr/event/BaseTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/BaseTagTest.java @@ -1,5 +1,6 @@ -package nostr.event; +package nostr.event.unit; +import nostr.event.BaseTag; import nostr.event.impl.GenericTag; import org.junit.jupiter.api.Test; diff --git a/nostr-java-test/src/test/java/nostr/test/event/CalendarContentDecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/CalendarContentDecodeTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java index 7e2dae22b..2ec8eee88 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/CalendarContentDecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentDecodeTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.event.impl.CalendarTimeBasedEvent; import nostr.event.json.codec.GenericEventDecoder; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingDecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingDecodeTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java index 9a57e0baf..055dbad84 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingDecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/ClassifiedListingDecodeTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.event.impl.ClassifiedListingEvent; import nostr.event.json.codec.GenericEventDecoder; diff --git a/nostr-java-test/src/test/java/nostr/test/event/DecodeTest.java b/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/DecodeTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java index 1850e4d01..c08c4d159 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/DecodeTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/DecodeTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import com.fasterxml.jackson.core.JsonProcessingException; import nostr.base.PublicKey; diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java similarity index 96% rename from nostr-java-test/src/test/java/nostr/test/event/EventTagTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java index a9bdef8e9..3ba32d8b9 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/EventTagTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.event.Marker; import nostr.event.tag.EventTag; @@ -45,4 +45,4 @@ private String getFieldValue(Field field, EventTag eventTag) { return returnVal[0]; } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/filters/FiltersDecoderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/filters/FiltersDecoderTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java index 6eaec461c..ba46f522c 100644 --- a/nostr-java-test/src/test/java/nostr/test/filters/FiltersDecoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/FiltersDecoderTest.java @@ -1,4 +1,4 @@ -package nostr.test.filters; +package nostr.event.unit; import lombok.extern.java.Log; import nostr.base.GenericTagQuery; diff --git a/nostr-java-test/src/test/java/nostr/test/filters/FiltersEncoderTest.java b/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/filters/FiltersEncoderTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java index 5d0937011..6d5822d72 100644 --- a/nostr-java-test/src/test/java/nostr/test/filters/FiltersEncoderTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/FiltersEncoderTest.java @@ -1,4 +1,4 @@ -package nostr.test.filters; +package nostr.event.unit; import lombok.extern.java.Log; import nostr.base.GenericTagQuery; diff --git a/nostr-java-test/src/test/java/nostr/test/event/KindMappingTest.java b/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java similarity index 95% rename from nostr-java-test/src/test/java/nostr/test/event/KindMappingTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java index cbb4b44b4..5ab05bd16 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/KindMappingTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/KindMappingTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.event.Kind; import org.junit.jupiter.api.Test; diff --git a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java similarity index 99% rename from nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java index 40bc4dd13..3f42d74e5 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/PriceTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/PriceTagTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.event.tag.PriceTag; import org.junit.jupiter.api.Test; diff --git a/nostr-java-test/src/test/java/nostr/test/event/PubkeyTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java similarity index 93% rename from nostr-java-test/src/test/java/nostr/test/event/PubkeyTagTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java index 986d5e93c..6536e4320 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/PubkeyTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/PubkeyTagTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.base.PublicKey; import nostr.event.tag.PubKeyTag; @@ -23,4 +23,4 @@ void getSupportedFields() { }); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java similarity index 95% rename from nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java index 4c331a0e3..afb681970 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/RelaysTagTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/RelaysTagTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import com.fasterxml.jackson.databind.JsonNode; import nostr.base.Relay; diff --git a/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java b/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java similarity index 96% rename from nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java rename to nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java index 3011df574..7bb0b11cd 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/SignatureTest.java +++ b/nostr-java-event/src/test/java/nostr/event/unit/SignatureTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.event.unit; import nostr.base.Signature; import org.junit.jupiter.api.Test; diff --git a/nostr-java-event/src/test/resources/application-test.properties b/nostr-java-event/src/test/resources/application-test.properties index c4bd7b5c1..a4ce64138 100644 --- a/nostr-java-event/src/test/resources/application-test.properties +++ b/nostr-java-event/src/test/resources/application-test.properties @@ -1,4 +1,4 @@ spring.threads.virtual.enabled=true -logging.level.nostr.base=INFO +logging.level.nostr.event=INFO logging.pattern.console=%msg%n diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index dd8c7d173..c9b4be127 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -7,3 +7,8 @@ description = 'nostr-java-id' dependencies { api project(':nostr-java-event') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index d09d26295..1812b83d2 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -25,5 +25,17 @@ nostr-java-event ${project.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingEventTest.java b/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingEventTest.java rename to nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java index b7eb8861a..f8d65670e 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ClassifiedListingEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.id; import nostr.base.PublicKey; import nostr.event.BaseTag; @@ -11,7 +11,6 @@ import nostr.event.tag.PriceTag; import nostr.event.tag.PubKeyTag; import nostr.event.tag.SubjectTag; -import nostr.id.Identity; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -83,4 +82,4 @@ void testConstructClassifiedListingEvent() { assertEquals(senderPubkey.toHexString(), instance.getPubKey().toHexString()); assertEquals(CLASSIFIED_LISTING_CONTENT, instance.getContent()); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/main/java/nostr/test/EntityFactory.java b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java similarity index 99% rename from nostr-java-test/src/main/java/nostr/test/EntityFactory.java rename to nostr-java-id/src/test/java/nostr/id/EntityFactory.java index 6afb38149..4d1a2f95b 100644 --- a/nostr-java-test/src/main/java/nostr/test/EntityFactory.java +++ b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java @@ -1,4 +1,4 @@ -package nostr.test; +package nostr.id; import lombok.extern.java.Log; import nostr.base.ElementAttribute; @@ -9,7 +9,6 @@ import nostr.event.BaseTag; import nostr.event.Kind; import nostr.event.Reaction; -import nostr.event.filter.Filters; import nostr.event.impl.DirectMessageEvent; import nostr.event.impl.EphemeralEvent; import nostr.event.impl.GenericEvent; diff --git a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java b/nostr-java-id/src/test/java/nostr/id/EventTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/event/EventTest.java rename to nostr-java-id/src/test/java/nostr/id/EventTest.java index 675379026..6bfd93da3 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/EventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/EventTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.id; import lombok.extern.java.Log; import nostr.base.ElementAttribute; @@ -15,8 +15,6 @@ import nostr.event.impl.GenericTag; import nostr.event.json.codec.BaseTagEncoder; import nostr.event.util.Nip05Validator; -import nostr.id.Identity; -import nostr.test.EntityFactory; import nostr.util.NostrUtil; import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER; diff --git a/nostr-java-test/src/test/java/nostr/test/id/IdentityTest.java b/nostr-java-id/src/test/java/nostr/id/IdentityTest.java similarity index 93% rename from nostr-java-test/src/test/java/nostr/test/id/IdentityTest.java rename to nostr-java-id/src/test/java/nostr/id/IdentityTest.java index 04f8183e5..64318f925 100644 --- a/nostr-java-test/src/test/java/nostr/test/id/IdentityTest.java +++ b/nostr-java-id/src/test/java/nostr/id/IdentityTest.java @@ -1,10 +1,8 @@ -package nostr.test.id; +package nostr.id; import nostr.base.PublicKey; import nostr.event.tag.DelegationTag; import nostr.event.impl.GenericEvent; -import nostr.id.Identity; -import nostr.test.EntityFactory; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/nostr-java-test/src/test/java/nostr/test/event/ZapReceiptEventTest.java b/nostr-java-id/src/test/java/nostr/id/ZapReceiptEventTest.java similarity index 97% rename from nostr-java-test/src/test/java/nostr/test/event/ZapReceiptEventTest.java rename to nostr-java-id/src/test/java/nostr/id/ZapReceiptEventTest.java index 106cf565d..dd1d94da0 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ZapReceiptEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ZapReceiptEventTest.java @@ -1,10 +1,9 @@ -package nostr.test.event; +package nostr.id; import lombok.extern.java.Log; import nostr.base.PublicKey; import nostr.event.impl.ZapReceiptEvent; import nostr.event.tag.AddressTag; -import nostr.id.Identity; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -47,4 +46,4 @@ void testConstructZapReceiptEvent() { assertEquals(PRE_IMAGE, instance.getZapReceipt().getPreimage()); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/java/nostr/test/event/ZapRequestEventTest.java b/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java similarity index 98% rename from nostr-java-test/src/test/java/nostr/test/event/ZapRequestEventTest.java rename to nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java index 0250cfd6d..9f1fa1f60 100644 --- a/nostr-java-test/src/test/java/nostr/test/event/ZapRequestEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ZapRequestEventTest.java @@ -1,4 +1,4 @@ -package nostr.test.event; +package nostr.id; import nostr.base.PublicKey; import nostr.base.Relay; @@ -11,7 +11,6 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.RelaysTag; import nostr.event.tag.SubjectTag; -import nostr.id.Identity; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -69,4 +68,4 @@ void testConstructZapRequestEvent() { Assertions.assertEquals(LNURL, instance.getZapRequest().getLnUrl()); Assertions.assertEquals(AMOUNT, instance.getZapRequest().getAmount()); } -} \ No newline at end of file +} diff --git a/nostr-java-test/src/test/resources/application-test.properties b/nostr-java-id/src/test/resources/application-test.properties similarity index 70% rename from nostr-java-test/src/test/resources/application-test.properties rename to nostr-java-id/src/test/resources/application-test.properties index c8e8aa339..f375f1180 100644 --- a/nostr-java-test/src/test/resources/application-test.properties +++ b/nostr-java-id/src/test/resources/application-test.properties @@ -1,4 +1,4 @@ spring.threads.virtual.enabled=true -logging.level.nostr=debug +logging.level.nostr.id=INFO logging.pattern.console=%msg%n diff --git a/nostr-java-id/src/test/resources/junit-platform.properties b/nostr-java-id/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-id/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent diff --git a/nostr-java-test/README.md b/nostr-java-test/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/nostr-java-test/build.gradle b/nostr-java-test/build.gradle deleted file mode 100644 index c1248a4da..000000000 --- a/nostr-java-test/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -plugins { - id 'nostr-java.java-conventions' -} - -dependencies { - implementation libs.org.projectlombok.lombok - annotationProcessor libs.org.projectlombok.lombok - testImplementation libs.org.projectlombok.lombok - testAnnotationProcessor libs.org.projectlombok.lombok - - implementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - testImplementation libs.com.fasterxml.jackson.module.jackson.module.afterburner - annotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - testAnnotationProcessor libs.com.fasterxml.jackson.module.jackson.module.afterburner - - implementation libs.com.google.guava.guava - implementation libs.org.springframework.boot.spring.boot.starter.test - implementation libs.org.junit.jupiter.junit.jupiter.api - - testImplementation libs.com.google.guava.guava - testImplementation libs.org.springframework.boot.spring.boot.starter.test - testImplementation libs.org.junit.jupiter.junit.jupiter.api - - api project(':nostr-java-client') - api project(':nostr-java-util') - api project(':nostr-java-api') -} - -description = 'nostr-java-test' - -// no publishing for test module -//publishing { -// publications { -// maven(MavenPublication) { -// artifactId = description -// from(components.java) -// } -// } -//} - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} - -//test { -// retry { -// failOnPassedAfterRetry = false -// maxRetries = 2 -//// maxFailures = 42 -// } -//} diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml deleted file mode 100644 index 5fb60fe86..000000000 --- a/nostr-java-test/pom.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - 4.0.0 - - - xyz.tcheeric - nostr-java - 0.6.5-SNAPSHOT - - - nostr-java-test - jar - - - 33.4.0-jre - - - - - - src/main/java - - **/*.java - - - - - src/main/resources - - - - - - src/test/java - - **/*.java - - - - - src/test/resources - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*Test.java - - - - - org.jacoco - jacoco-maven-plugin - - - one - - prepare-agent - - - - two - verify - - report-aggregate - - - - **/jacoco.exec - - ${project.reporting.outputDirectory}/jacoco-aggregate - - - - - - - - - - integration-tests - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - - - - - - - org.projectlombok - lombok - - - - - ${project.groupId} - nostr-java-client - ${project.version} - - - ${project.groupId} - nostr-java-util - ${project.version} - - - ${project.groupId} - nostr-java-api - ${project.version} - - - - - org.junit.jupiter - junit-jupiter-api - - - com.google.guava - guava - ${guava.version} - - - diff --git a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java b/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java deleted file mode 100644 index b36bb89f6..000000000 --- a/nostr-java-test/src/test/java/nostr/test/crypto/CryptoTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package nostr.test.crypto; - -import nostr.base.Signature; -import nostr.crypto.bech32.Bech32; -import nostr.crypto.bech32.Bech32Prefix; -import nostr.crypto.schnorr.Schnorr; -import nostr.event.impl.GenericEvent; -import nostr.id.Identity; -import nostr.util.NostrUtil; -import org.junit.jupiter.api.Test; - -import static nostr.test.EntityFactory.Events.createTextNoteEvent; -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.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * - * @author squirrel - */ -public class CryptoTest { - - @Test - public void testBech32() { - try { - System.out.println("testBech32"); - - final String hexPub = "56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f"; - final String npub = "npub126klq89p42wk78p4j5ur8wlxmxdqepdh8tez9e4axpd4run5nahsmff27j"; - - assertEquals(npub, Bech32.toBech32(Bech32Prefix.NPUB, hexPub)); - assertEquals("56adf01ca1aa9d6f1c35953833bbe6d99a0c85b73af222e6bd305b51f2749f6f", Bech32.fromBech32(npub)); - } catch (Exception ex) { - fail(ex); - } - } - - @Test - public void testVerifySignature() { - System.out.println("testVerifySignature"); - - Identity identity = Identity.generateRandomIdentity(); - final GenericEvent[] event = {createTextNoteEvent(identity.getPublicKey(), "Hello World")}; - event[0].update(); - assertDoesNotThrow(() -> { - byte[] message = NostrUtil.sha256(event[0].get_serializedEvent()); - Signature signature = identity.sign(event[0]); - boolean verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); - assertTrue(verification, "Schnorr must have a true verify result."); - - event[0] = createTextNoteEvent(identity.getPublicKey(), "Guten Tag"); - event[0].update(); - message = NostrUtil.sha256(event[0].get_serializedEvent()); - verification = Schnorr.verify(message, identity.getPublicKey().getRawData(), signature.getRawData()); - - assertFalse(verification); - }); - } - -} diff --git a/nostr-java-test/src/test/resources/app.properties b/nostr-java-test/src/test/resources/app.properties deleted file mode 100644 index 4ff8e632d..000000000 --- a/nostr-java-test/src/test/resources/app.properties +++ /dev/null @@ -1,3 +0,0 @@ -profile=profile.properties -client=client.properties -relays=relays.properties \ No newline at end of file diff --git a/nostr-java-test/src/test/resources/profile.properties b/nostr-java-test/src/test/resources/profile.properties deleted file mode 100644 index 44f2c68c9..000000000 --- a/nostr-java-test/src/test/resources/profile.properties +++ /dev/null @@ -1,3 +0,0 @@ - -privateKey=519672a628310117110bfa93798eb03566f99b47d75b3998a1d65366aff97988 -publicKey= \ No newline at end of file diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index bfeee3db5..9592ce67b 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -3,3 +3,8 @@ plugins { } description = 'nostr-java-util' + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 0017f9140..4848dfcce 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -13,6 +13,7 @@ jar + org.apache.commons commons-lang3 @@ -21,7 +22,8 @@ org.projectlombok lombok - + + org.springframework.boot spring-boot-starter-test diff --git a/nostr-java-test/src/test/java/nostr/test/base/NostrUtilTest.java b/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java similarity index 92% rename from nostr-java-test/src/test/java/nostr/test/base/NostrUtilTest.java rename to nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java index 677a3a90f..01c7bb85d 100644 --- a/nostr-java-test/src/test/java/nostr/test/base/NostrUtilTest.java +++ b/nostr-java-util/src/test/java/nostr/util/NostrUtilTest.java @@ -1,7 +1,6 @@ -package nostr.test.base; +package nostr.util; import lombok.extern.java.Log; -import nostr.util.NostrUtil; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/nostr-java-util/src/test/resources/application-test.properties b/nostr-java-util/src/test/resources/application-test.properties new file mode 100644 index 000000000..1d2fa226b --- /dev/null +++ b/nostr-java-util/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.threads.virtual.enabled=true + +logging.level.nostr.util=INFO +logging.pattern.console=%msg%n diff --git a/nostr-java-util/src/test/resources/junit-platform.properties b/nostr-java-util/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..a413a5904 --- /dev/null +++ b/nostr-java-util/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# junit-platform.properties + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +#junit.jupiter.execution.parallel.mode.default=concurrent +#junit.jupiter.execution.parallel.mode.classes.default=concurrent From 58aaf737047e4d36c349bb0b2be9c28ba1fff46e Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 01:09:14 -0700 Subject: [PATCH 35/57] maven dependency consolidation --- .../groovy/nostr-java.java-conventions.gradle | 5 +- nostr-java-api/pom.xml | 22 ++- nostr-java-base/pom.xml | 21 --- nostr-java-client/pom.xml | 15 +- nostr-java-crypto/pom.xml | 21 +-- .../java/nostr/crypto/CryptoFailTest.java | 12 ++ nostr-java-encryption/pom.xml | 4 - nostr-java-event/pom.xml | 18 --- nostr-java-id/pom.xml | 18 --- nostr-java-util/pom.xml | 24 ---- pom.xml | 130 +++++++++--------- 11 files changed, 103 insertions(+), 187 deletions(-) create mode 100644 nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index 095804125..1e0901069 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -68,13 +68,12 @@ dependencies { implementation 'org.projectlombok:lombok:' + lombok annotationProcessor 'org.projectlombok:lombok:' + lombok + testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion testImplementation 'org.projectlombok:lombok:' + lombok testImplementation 'org.awaitility:awaitility:' + awaitility - - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'com.adarshr:gradle-test-logger-plugin:4.0.0' - testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion testAnnotationProcessor 'org.projectlombok:lombok:' + lombok + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } subprojects { apply plugin: 'com.adarshr.test-logger' } diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 125ba66d1..158b4044d 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -9,7 +9,7 @@ nostr-java-api jar - + ${project.groupId} @@ -21,21 +21,29 @@ nostr-java-encryption ${project.version} - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - org.springframework.boot spring-boot-starter-test + ${spring-boot.version} test org.junit.jupiter junit-jupiter-api + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter + ${junit-jupiter.version} + test + + + com.google.guava + guava + ${guava.version} test diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 2df56919b..116d899c5 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -13,16 +13,6 @@ jar - - - org.projectlombok - lombok - - - com.fasterxml.jackson.module - jackson-module-afterburner - - ${project.groupId} @@ -34,16 +24,5 @@ nostr-java-crypto ${project.version} - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 9791f6715..18f727972 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -19,18 +19,17 @@ - - org.springframework.boot - spring-boot-starter-websocket - ${spring-boot.version} - - ${project.groupId} nostr-java-id ${project.version} - + + + org.springframework.boot + spring-boot-starter-websocket + ${spring-boot.version} + org.springframework spring-websocket @@ -46,7 +45,6 @@ reactor-netty-http ${reactor-netty-http.version} - jakarta.websocket jakarta.websocket-api @@ -58,7 +56,6 @@ ${jakarta.websocket-api.version} - org.awaitility awaitility diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index 0836a64c9..a28a5fbe2 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -20,32 +20,21 @@ https://github.com/unclebob/more-speech/tree/bdd2f32b37264f20bf6abb4887489e70d2b0fdf1 + + 1.78 + + - - - org.projectlombok - lombok - org.bouncycastle bcprov-jdk18on + ${bcprov-jdk18on.version} ${project.groupId} nostr-java-util ${project.version} - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java b/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java new file mode 100644 index 000000000..078df8c3f --- /dev/null +++ b/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java @@ -0,0 +1,12 @@ +package nostr.crypto; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Fail.fail; + +public class CryptoFailTest { + @Test + public void testEntityFactory() { + fail(); + } +} diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 5e4d8b155..d19ce2f10 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -18,10 +18,6 @@ - - org.projectlombok - lombok - ${project.groupId} nostr-java-crypto diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index de916545d..f4b2feea3 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -13,29 +13,11 @@ jar - - - org.projectlombok - lombok - - ${project.groupId} nostr-java-base ${project.version} - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 1812b83d2..6ab623adf 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -13,29 +13,11 @@ jar - - - org.projectlombok - lombok - - ${project.groupId} nostr-java-event ${project.version} - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 4848dfcce..7792f63d4 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -11,28 +11,4 @@ nostr-java-util jar - - - - - org.apache.commons - commons-lang3 - - - org.projectlombok - lombok - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - - diff --git a/pom.xml b/pom.xml index 149930b9a..1e54d4241 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,6 @@ nostr-java-event nostr-java-examples nostr-java-id - nostr-java-test nostr-java-util nostr-java-client nostr-java-api @@ -85,10 +84,9 @@ 2.18.3 1.18.34 3.17.0 - 1.70 - 1.78 + 33.4.0-jre 5.10.2 @@ -99,71 +97,69 @@ 0.8.12 - - - - org.springframework.boot - spring-boot - ${spring-boot.version} - - - org.springframework.boot - spring-boot-autoconfigure - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter - ${spring-boot.version} - - - org.springframework.boot - spring-boot-devtools - ${spring-boot.version} - - - org.springframework.boot - spring-boot-configuration-processor - ${spring-boot.version} - + + + org.springframework.boot + spring-boot-starter + ${spring-boot.version} + + + org.springframework.boot + spring-boot-devtools + ${spring-boot.version} + + + org.springframework.boot + spring-boot-autoconfigure + ${spring-boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - org.projectlombok - lombok - ${lombok.version} - - - com.fasterxml.jackson.module - jackson-module-afterburner - ${jackson-module-afterburner.version} - - - org.bouncycastle - bcprov-jdk18on - ${bcprov-jdk18on.version} - - - - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.projectlombok + lombok + ${lombok.version} + + + com.fasterxml.jackson.module + jackson-module-afterburner + ${jackson-module-afterburner.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter + ${junit-jupiter.version} + test + + + com.google.guava + guava + ${guava.version} + test + + @@ -220,7 +216,7 @@ ${gpg.keyname} - + From fa5579a2985d8b57ac8e67f5751a70610239b9bf Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 14:40:25 -0700 Subject: [PATCH 36/57] pom parrent updates --- nostr-java-api/pom.xml | 29 +------ .../nostr/api/integration/ApiEventTest.java | 83 +++++++++---------- ...entTestUsingSpringWebSocketClientTest.java | 3 - nostr-java-base/pom.xml | 9 +- nostr-java-client/pom.xml | 4 +- nostr-java-crypto/pom.xml | 5 +- nostr-java-encryption/pom.xml | 6 +- nostr-java-event/pom.xml | 5 +- nostr-java-examples/pom.xml | 7 +- nostr-java-id/pom.xml | 5 +- nostr-java-util/pom.xml | 7 +- 11 files changed, 72 insertions(+), 91 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 158b4044d..0149e35b9 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -1,10 +1,12 @@ 4.0.0 + xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml nostr-java-api @@ -21,30 +23,5 @@ nostr-java-encryption ${project.version} - - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - com.google.guava - guava - ${guava.version} - test - diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java index 11ec1c1fb..0074e5d91 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java @@ -9,6 +9,7 @@ import nostr.api.NIP44; import nostr.api.NIP52; import nostr.api.NIP57; +import nostr.api.config.TestConfig; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; import nostr.base.PrivateKey; @@ -16,7 +17,6 @@ import nostr.crypto.bech32.Bech32Prefix; import nostr.event.BaseTag; import nostr.event.NIP01Event; -import nostr.api.config.TestConfig; import nostr.event.filter.Filters; import nostr.event.filter.GenericTagQueryFilter; import nostr.event.filter.GeohashTagFilter; @@ -39,10 +39,7 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -61,12 +58,14 @@ /** * @author eric */ -@ExtendWith(SpringExtension.class) @SpringJUnitConfig(TestConfig.class) -@ActiveProfiles("test") -class ApiEventTest { +public class ApiEventTest { + private final Map relays; + @Autowired - private Map relays; + public ApiEventTest(Map relaysType) { + this.relays = relaysType; + } @Test public void testNIP01CreateTextNoteEvent() throws Exception { @@ -74,9 +73,9 @@ public void testNIP01CreateTextNoteEvent() throws Exception { var nip01 = new NIP01(Identity.generateRandomIdentity()); var instance = nip01.createTextNoteEvent( - List.of(NIP01.createPubKeyTag(Identity.generateRandomIdentity().getPublicKey())), - "Hello simplified nostr-java!") - .getEvent(); + List.of(NIP01.createPubKeyTag(Identity.generateRandomIdentity().getPublicKey())), + "Hello simplified nostr-java!") + .getEvent(); instance.update(); assertNotNull(instance.getId()); @@ -109,12 +108,12 @@ public void testNIP04SendDirectMessage() throws IOException { System.out.println("testNIP04SendDirectMessage"); var nip04 = new NIP04( - Identity.generateRandomIdentity(), - Identity.generateRandomIdentity().getPublicKey()); + Identity.generateRandomIdentity(), + Identity.generateRandomIdentity().getPublicKey()); var instance = nip04 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") - .sign(); + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") + .sign(); var signature = instance.getEvent().getSignature(); assertNotNull(signature); @@ -129,11 +128,11 @@ public void testNIP44SendDirectMessage() throws IOException { System.out.println("testNIP44SendDirectMessage"); var nip44 = new NIP44( - Identity.generateRandomIdentity(), - Identity.generateRandomIdentity().getPublicKey()); + Identity.generateRandomIdentity(), + Identity.generateRandomIdentity().getPublicKey()); var instance = nip44 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); assertNotNull(instance.getEvent().getSignature()); var response = instance.setRelays(relays).send(); assertTrue(response instanceof OkMessage); @@ -152,7 +151,7 @@ public void testNIP01SendTextNoteEventGeoHashTag() throws IOException { nip01.createTextNoteEvent(List.of(geohashTag), "GeohashTag Test location testNIP01SendTextNoteEventGeoHashTag").signAndSend(relays); Filters filters = new Filters( - new GeohashTagFilter<>(new GeohashTag(targetString))); + new GeohashTagFilter<>(new GeohashTag(targetString))); List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -174,7 +173,7 @@ public void testNIP01SendTextNoteEventHashtagTag() throws IOException { nip01.createTextNoteEvent(List.of(hashtagTag), "Hashtag Tag Test value testNIP01SendTextNoteEventHashtagTag").signAndSend(relays); Filters filters = new Filters( - new HashtagTagFilter<>(new HashtagTag(targetString))); + new HashtagTagFilter<>(new HashtagTag(targetString))); List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -196,7 +195,7 @@ public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException { nip01.createTextNoteEvent(List.of(genericTag), "Custom Generic Tag Test testNIP01SendTextNoteEventCustomGenericTag").signAndSend(relays); Filters filters = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", targetString))); + new GenericTagQueryFilter<>(new GenericTagQuery("#m", targetString))); List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -226,9 +225,9 @@ public void testFiltersListReturnSameSingularEvent() throws IOException { nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays); Filters filters1 = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget))); + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget))); Filters filters2 = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); List result = nip01.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); @@ -260,10 +259,10 @@ public void testFiltersListReturnTwoDifferentEvents() throws IOException { nip01_2.createTextNoteEvent(List.of(geohashTag2, genericTag2), "Multiple Filters 2").signAndSend(relays); Filters filters1 = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget1))); // 1st filter should find match in 1st event + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget1))); // 1st filter should find match in 1st event Filters filters2 = new Filters( - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget2))); // 2nd filter should find match in 2nd event + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget2))); // 2nd filter should find match in 2nd event List result = nip01_1.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString()); @@ -290,8 +289,8 @@ public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOExceptio nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays); Filters filters = new Filters( - new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget)), - new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); + new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget)), + new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget))); List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -309,8 +308,8 @@ public void testNIP04EncryptDecrypt() { Identity identity = Identity.generateRandomIdentity(); var nip04 = new NIP04(identity, Identity.generateRandomIdentity().getPublicKey()); var instance = nip04 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") - .sign(); + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...") + .sign(); var message = NIP04.decrypt(identity, instance.getEvent()); @@ -325,7 +324,7 @@ public void testNIP44EncryptDecrypt() { var nip44 = new NIP44(identity, Identity.generateRandomIdentity().getPublicKey()); var instance = nip44 - .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); + .createDirectMessageEvent("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...").sign(); var message = NIP44.decrypt(identity, instance.getEvent()); assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message); @@ -473,7 +472,7 @@ public void testNIP32CreateLabel2() { assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}", 32)), - "{\\\"article\\\":\\\"the\\\"}"); + "{\\\"article\\\":\\\"the\\\"}"); } @Test @@ -481,9 +480,9 @@ public void testNIP52CalendarTimeBasedEventEvent() throws IOException { System.out.println("testNIP52CalendarTimeBasedEventEvent"); CalendarContent calendarContent = CalendarContent.builder( - new IdentifierTag("UUID-CalendarTimeBasedEventTest"), - "Calendar Time-Based Event title", - 1716513986268L).build(); + new IdentifierTag("UUID-CalendarTimeBasedEventTest"), + "Calendar Time-Based Event title", + 1716513986268L).build(); calendarContent.setStartTzid("1687765220"); calendarContent.setEndTzid("1687765230"); @@ -492,11 +491,11 @@ public void testNIP52CalendarTimeBasedEventEvent() throws IOException { List tags = new ArrayList<>(); tags.add(new PubKeyTag(Identity.generateRandomIdentity().getPublicKey(), - "ws://localhost:5555", - "ISSUER")); + "ws://localhost:5555", + "ISSUER")); tags.add(new PubKeyTag(Identity.generateRandomIdentity().getPublicKey(), - "", - "COUNTERPARTY")); + "", + "COUNTERPARTY")); var nip52 = new NIP52<>(Identity.create(PrivateKey.generateRandomPrivKey())); EventNostr event = nip52.createCalendarTimeBasedEvent(tags, "content", calendarContent).sign(); @@ -517,7 +516,7 @@ void testNIP57CreateZapRequestEvent() throws Exception { final String LNURL = "lnUrl"; final String RELAYS_TAG = "ws://localhost:5555"; ZapRequestEvent instance = nip57 - .createZapRequestEvent(Identity.generateRandomIdentity().getPublicKey(), new ArrayList(), ZAP_REQUEST_CONTENT, AMOUNT, LNURL, RELAYS_TAG).getEvent(); + .createZapRequestEvent(Identity.generateRandomIdentity().getPublicKey(), new ArrayList(), ZAP_REQUEST_CONTENT, AMOUNT, LNURL, RELAYS_TAG).getEvent(); instance.update(); assertNotNull(instance.getId()); @@ -532,7 +531,7 @@ void testNIP57CreateZapRequestEvent() throws Exception { assertEquals(ZAP_REQUEST_CONTENT, instance.getContent()); assertTrue(instance.getZapRequest().getRelaysTag().getRelays().stream() - .anyMatch(relay -> relay.getUri().equals(RELAYS_TAG))); + .anyMatch(relay -> relay.getUri().equals(RELAYS_TAG))); assertEquals(AMOUNT, instance.getZapRequest().getAmount()); assertEquals(LNURL, instance.getZapRequest().getLnUrl()); @@ -556,8 +555,8 @@ void testNIP57CreateZapReceiptEvent() throws Exception { var nip57 = new NIP57(Identity.generateRandomIdentity()); ZapReceiptEvent instance = nip57.createZapReceiptEvent(zapRequestPubKeyTag, getBaseTags(), zapRequestEventTag, - zapRequestAddressTag, ZAP_RECEIPT_IDENTIFIER, ZAP_RECEIPT_RELAY_URI, BOLT_11, DESCRIPTION_SHA256, PRE_IMAGE) - .getEvent(); + zapRequestAddressTag, ZAP_RECEIPT_IDENTIFIER, ZAP_RECEIPT_RELAY_URI, BOLT_11, DESCRIPTION_SHA256, PRE_IMAGE) + .getEvent(); instance.update(); assertNotNull(instance.getId()); diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java index d91dbbf25..b75d6dc1d 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java @@ -9,10 +9,8 @@ import nostr.id.Identity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -25,7 +23,6 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; -@ExtendWith(SpringExtension.class) @SpringJUnitConfig(TestConfig.class) @ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientTest { diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 116d899c5..d32c8ee21 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -1,19 +1,18 @@ - + 4.0.0 xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml - + nostr-java-base jar - ${project.groupId} nostr-java-util diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 18f727972..1d73903b6 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -1,10 +1,12 @@ 4.0.0 + xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml nostr-java-client diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index a28a5fbe2..e868004b6 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -5,10 +5,11 @@ xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml - + nostr-java-crypto jar diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index d19ce2f10..9ccd93095 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -1,12 +1,14 @@ 4.0.0 + xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml - + nostr-java-encryption jar diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index f4b2feea3..e91b2ec3c 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -5,10 +5,11 @@ xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml - + nostr-java-event jar diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 3ed2cc91e..5cec44678 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -5,10 +5,11 @@ xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT - - + ../pom.xml + + nostr-java-examples jar diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 6ab623adf..40641a8be 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -5,10 +5,11 @@ xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT + ../pom.xml - + nostr-java-id jar diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 7792f63d4..21f9d59ae 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -5,10 +5,11 @@ xyz.tcheeric - nostr-java + nostr-java-parent 0.6.5-SNAPSHOT - - + ../pom.xml + + nostr-java-util jar From 5b072260a8a9bd3c4d7722d3dded039da0d81977 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 16:36:38 -0700 Subject: [PATCH 37/57] boot tests running --- nostr-java-api/pom.xml | 9 ++++----- .../java/nostr/config/RelayProperties.java} | 14 +++++++------- .../{test => main}/resources/relays.properties | 0 .../nostr/api/integration/APINIP09EventTest.java | 4 ++-- .../java/nostr/api/integration/ApiEventTest.java | 15 ++++++++------- ...piEventTestUsingSpringWebSocketClientTest.java | 4 ++-- nostr-java-base/pom.xml | 7 +++---- nostr-java-client/pom.xml | 5 ++--- .../src/main/resources/relays.properties | 1 - nostr-java-crypto/pom.xml | 8 +++----- .../test/java/nostr/crypto/CryptoFailTest.java | 12 ------------ nostr-java-encryption/pom.xml | 7 +++---- nostr-java-event/pom.xml | 8 +++----- nostr-java-examples/pom.xml | 8 +++----- nostr-java-id/pom.xml | 8 +++----- nostr-java-util/pom.xml | 6 ++---- 16 files changed, 45 insertions(+), 71 deletions(-) rename nostr-java-api/src/{test/java/nostr/api/config/TestConfig.java => main/java/nostr/config/RelayProperties.java} (50%) rename nostr-java-api/src/{test => main}/resources/relays.properties (100%) delete mode 100644 nostr-java-client/src/main/resources/relays.properties delete mode 100644 nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 0149e35b9..cbc59597f 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -1,27 +1,26 @@ - 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml nostr-java-api jar - + ${project.groupId} nostr-java-client - ${project.version} + ${nostr-project.version} ${project.groupId} nostr-java-encryption - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-api/src/test/java/nostr/api/config/TestConfig.java b/nostr-java-api/src/main/java/nostr/config/RelayProperties.java similarity index 50% rename from nostr-java-api/src/test/java/nostr/api/config/TestConfig.java rename to nostr-java-api/src/main/java/nostr/config/RelayProperties.java index 6ed88761b..ae8d4f066 100644 --- a/nostr-java-api/src/test/java/nostr/api/config/TestConfig.java +++ b/nostr-java-api/src/main/java/nostr/config/RelayProperties.java @@ -1,21 +1,21 @@ -package nostr.api.config; +package nostr.config; -import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.test.context.TestPropertySource; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import java.util.Map; import java.util.ResourceBundle; import java.util.stream.Collectors; -@TestConfiguration -@TestPropertySource("classpath:relays.properties") -public class TestConfig { +@Configuration +@PropertySource("classpath:relays.properties") +public class RelayProperties { @Bean public Map relays() { ResourceBundle relaysBundle = ResourceBundle.getBundle("relays"); return relaysBundle.keySet().stream() - .collect(Collectors.toMap(key -> key, relaysBundle::getString)); + .collect(Collectors.toMap(key -> key, relaysBundle::getString)); } } diff --git a/nostr-java-api/src/test/resources/relays.properties b/nostr-java-api/src/main/resources/relays.properties similarity index 100% rename from nostr-java-api/src/test/resources/relays.properties rename to nostr-java-api/src/main/resources/relays.properties diff --git a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java index 784932fa0..b29cb90fd 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java @@ -2,7 +2,7 @@ import nostr.api.NIP01; import nostr.api.NIP09; -import nostr.api.config.TestConfig; +import nostr.config.RelayProperties; import nostr.base.Relay; import nostr.event.BaseMessage; import nostr.event.BaseTag; @@ -37,7 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith(SpringExtension.class) -@SpringJUnitConfig(TestConfig.class) +@SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") public class APINIP09EventTest { @Autowired diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java index 0074e5d91..5e5840dd7 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java @@ -9,10 +9,10 @@ import nostr.api.NIP44; import nostr.api.NIP52; import nostr.api.NIP57; -import nostr.api.config.TestConfig; import nostr.base.ElementAttribute; import nostr.base.GenericTagQuery; import nostr.base.PrivateKey; +import nostr.config.RelayProperties; import nostr.crypto.bech32.Bech32; import nostr.crypto.bech32.Bech32Prefix; import nostr.event.BaseTag; @@ -39,7 +39,10 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -58,14 +61,12 @@ /** * @author eric */ -@SpringJUnitConfig(TestConfig.class) +@ExtendWith(SpringExtension.class) +@SpringJUnitConfig(RelayProperties.class) +@ActiveProfiles("test") public class ApiEventTest { - private final Map relays; - @Autowired - public ApiEventTest(Map relaysType) { - this.relays = relaysType; - } + private Map relays; @Test public void testNIP01CreateTextNoteEvent() throws Exception { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java index b75d6dc1d..008b008d6 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java @@ -1,7 +1,7 @@ package nostr.api.integration; import nostr.api.NIP15; -import nostr.api.config.TestConfig; +import nostr.config.RelayProperties; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.impl.GenericEvent; @@ -23,7 +23,7 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; -@SpringJUnitConfig(TestConfig.class) +@SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientTest { private SpringWebSocketClient springWebSocketClient; diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index d32c8ee21..8ae49fc92 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -1,10 +1,9 @@ - 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -16,12 +15,12 @@ ${project.groupId} nostr-java-util - ${project.version} + ${nostr-project.version} ${project.groupId} nostr-java-crypto - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 1d73903b6..d7f2c90d1 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -1,10 +1,9 @@ - 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -24,7 +23,7 @@ ${project.groupId} nostr-java-id - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-client/src/main/resources/relays.properties b/nostr-java-client/src/main/resources/relays.properties deleted file mode 100644 index ced21d9de..000000000 --- a/nostr-java-client/src/main/resources/relays.properties +++ /dev/null @@ -1 +0,0 @@ -nostr_rs_relay=localhost:5555 \ No newline at end of file diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index e868004b6..84b0696ae 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -1,11 +1,9 @@ - - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -35,7 +33,7 @@ ${project.groupId} nostr-java-util - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java b/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java deleted file mode 100644 index 078df8c3f..000000000 --- a/nostr-java-crypto/src/test/java/nostr/crypto/CryptoFailTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package nostr.crypto; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Fail.fail; - -public class CryptoFailTest { - @Test - public void testEntityFactory() { - fail(); - } -} diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 9ccd93095..b6ccacdec 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -23,7 +22,7 @@ ${project.groupId} nostr-java-crypto - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index e91b2ec3c..ff2950485 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -1,11 +1,9 @@ - - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -18,7 +16,7 @@ ${project.groupId} nostr-java-base - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 5cec44678..be3c9ebc5 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -1,11 +1,9 @@ - - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -18,7 +16,7 @@ ${project.groupId} nostr-java-api - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 40641a8be..e2ac20675 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -1,11 +1,9 @@ - - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml @@ -18,7 +16,7 @@ ${project.groupId} nostr-java-event - ${project.version} + ${nostr-project.version} diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 21f9d59ae..2a63680da 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -1,11 +1,9 @@ - - + 4.0.0 xyz.tcheeric - nostr-java-parent + nostr-java 0.6.5-SNAPSHOT ../pom.xml From b3dc2bec51c1188b3f13da661aa905a4a2f6ca55 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 17:47:59 -0700 Subject: [PATCH 38/57] finalized tests --- nostr-java-api/pom.xml | 4 +- nostr-java-base/pom.xml | 4 +- nostr-java-client/pom.xml | 2 +- nostr-java-crypto/pom.xml | 2 +- nostr-java-encryption/pom.xml | 2 +- nostr-java-event/pom.xml | 2 +- nostr-java-examples/pom.xml | 2 +- nostr-java-id/pom.xml | 2 +- pom.xml | 173 ++++++++++++---------------------- 9 files changed, 71 insertions(+), 122 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index cbc59597f..b60f18204 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -15,12 +15,12 @@ ${project.groupId} nostr-java-client - ${nostr-project.version} + ${nostr-java.version} ${project.groupId} nostr-java-encryption - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 8ae49fc92..103219fe7 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -15,12 +15,12 @@ ${project.groupId} nostr-java-util - ${nostr-project.version} + ${nostr-java.version} ${project.groupId} nostr-java-crypto - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index d7f2c90d1..405a337fe 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -23,7 +23,7 @@ ${project.groupId} nostr-java-id - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index 84b0696ae..b60d82e4e 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -33,7 +33,7 @@ ${project.groupId} nostr-java-util - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index b6ccacdec..5a7734cf5 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -22,7 +22,7 @@ ${project.groupId} nostr-java-crypto - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index ff2950485..00c84a67c 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -16,7 +16,7 @@ ${project.groupId} nostr-java-base - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index be3c9ebc5..6ebdb695c 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -16,7 +16,7 @@ ${project.groupId} nostr-java-api - ${nostr-project.version} + ${nostr-java.version} diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index e2ac20675..884eade2e 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -16,7 +16,7 @@ ${project.groupId} nostr-java-event - ${nostr-project.version} + ${nostr-java.version} diff --git a/pom.xml b/pom.xml index 1e54d4241..5abe5ed91 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,4 @@ - - + 4.0.0 xyz.tcheeric @@ -8,6 +6,12 @@ 0.6.5-SNAPSHOT pom + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + ${project.artifactId} Java SDK for Nostr, for generating, signing and publishing events to relays https://github.com/tcheeric/nostr-java @@ -73,8 +77,9 @@ - 0.6.5-SNAPSHOT + 0.6.5-SNAPSHOT 21 + 3.4.3 ${java.version} ${java.version} @@ -82,12 +87,12 @@ 2.18.3 - 1.18.34 3.17.0 + 1.18.34 - 33.4.0-jre 5.10.2 + 33.4.0-jre 3.13.0 @@ -108,16 +113,6 @@ spring-boot-devtools ${spring-boot.version} - - org.springframework.boot - spring-boot-autoconfigure - ${spring-boot.version} - - - org.springframework.boot - spring-boot-configuration-processor - ${spring-boot.version} - org.apache.commons @@ -141,12 +136,6 @@ ${spring-boot.version} test - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter @@ -164,101 +153,13 @@ - - org.sonatype.central - central-publishing-maven-plugin - 0.6.0 - true - - central - true - published - - - - org.apache.maven.plugins - maven-source-plugin - 3.3.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.10.1 - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - ${gpg.keyname} - - - - - - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - true - resolveCiFriendliesOnly - - - - flatten - process-resources - - flatten - - - - flatten.clean - clean - - clean - - - - org.apache.maven.plugins maven-compiler-plugin ${maven-compiler-plugin.version} - true - - - org.projectlombok - lombok - ${lombok.version} - - + ${maven.compiler.source} + ${maven.compiler.target} @@ -286,5 +187,53 @@ + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + test + + + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + + integration-test + verify + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + + prepare-agent + report + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source} + ${maven.compiler.target} + + + + From b6c8c2aac29ef8e33cb6946acb9f15efcd47f405 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 18:00:36 -0700 Subject: [PATCH 39/57] publications --- pom.xml | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/pom.xml b/pom.xml index 5abe5ed91..59ab17bd1 100644 --- a/pom.xml +++ b/pom.xml @@ -153,6 +153,88 @@ + + org.sonatype.central + central-publishing-maven-plugin + 0.6.0 + true + + central + true + published + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + ${gpg.keyname} + + ${gpg.keyname} + + + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + org.apache.maven.plugins maven-compiler-plugin From f5136e70c4a5f599be27a4912b14bc68b8f8f275 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 18:30:54 -0700 Subject: [PATCH 40/57] cleanup --- buildSrc/src/main/groovy/nostr-java.java-conventions.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle index 1e0901069..217a085ad 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle @@ -22,9 +22,6 @@ repositories { maven { url = 'https://plugins.gradle.org/m2/' } - maven { - url = 'https://plugins.gradle.org/m2/' - } } //// TODO: commented placeholder as eric may want to provide custom publishing specs From 3cc76b5a4ec4a89215ce93747fa8ef67f972eb21 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Tue, 18 Mar 2025 23:49:20 -0700 Subject: [PATCH 41/57] unit test / integration test filename differentiation --- .../{APINIP09EventTest.java => APINIP09EventIT.java} | 2 +- .../api/integration/{ApiEventTest.java => ApiEventIT.java} | 2 +- ...t.java => ApiEventTestUsingSpringWebSocketClientIT.java} | 6 +++--- .../{ApiNIP52EventTest.java => ApiNIP52EventIT.java} | 4 ++-- .../{ApiNIP52RequestTest.java => ApiNIP52RequestIT.java} | 2 +- .../{ApiNIP99EventTest.java => ApiNIP99EventIT.java} | 4 ++-- .../{ApiNIP99RequestTest.java => ApiNIP99RequestIT.java} | 2 +- .../java/nostr/api/{integration => unit}/NIP52ImplTest.java | 2 +- .../java/nostr/api/{integration => unit}/NIP60Test.java | 2 +- .../java/nostr/api/{integration => unit}/NIP61Test.java | 2 +- nostr-java-client/build.gradle | 5 +++++ nostr-java-encryption/build.gradle | 5 +++++ nostr-java-util/build.gradle | 5 +++++ 13 files changed, 29 insertions(+), 14 deletions(-) rename nostr-java-api/src/test/java/nostr/api/integration/{APINIP09EventTest.java => APINIP09EventIT.java} (99%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiEventTest.java => ApiEventIT.java} (99%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiEventTestUsingSpringWebSocketClientTest.java => ApiEventTestUsingSpringWebSocketClientIT.java} (94%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiNIP52EventTest.java => ApiNIP52EventIT.java} (97%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiNIP52RequestTest.java => ApiNIP52RequestIT.java} (99%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiNIP99EventTest.java => ApiNIP99EventIT.java} (98%) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiNIP99RequestTest.java => ApiNIP99RequestIT.java} (99%) rename nostr-java-api/src/test/java/nostr/api/{integration => unit}/NIP52ImplTest.java (99%) rename nostr-java-api/src/test/java/nostr/api/{integration => unit}/NIP60Test.java (99%) rename nostr-java-api/src/test/java/nostr/api/{integration => unit}/NIP61Test.java (99%) diff --git a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java index b29cb90fd..60a7fd704 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java @@ -39,7 +39,7 @@ @ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") -public class APINIP09EventTest { +public class APINIP09EventIT { @Autowired private Map relays; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java index 5e5840dd7..ba4eb7a85 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java @@ -64,7 +64,7 @@ @ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") -public class ApiEventTest { +public class ApiEventIT { @Autowired private Map relays; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java similarity index 94% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java index 008b008d6..27e550b35 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java @@ -18,14 +18,14 @@ import java.util.List; import java.util.Map; -import static nostr.api.integration.ApiEventTest.createProduct; -import static nostr.api.integration.ApiEventTest.createStall; +import static nostr.api.integration.ApiEventIT.createProduct; +import static nostr.api.integration.ApiEventIT.createStall; import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") -class ApiEventTestUsingSpringWebSocketClientTest { +class ApiEventTestUsingSpringWebSocketClientIT { private SpringWebSocketClient springWebSocketClient; @Autowired diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java similarity index 97% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java index 3b9db8e87..a44c5830c 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java @@ -21,11 +21,11 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -class ApiNIP52EventTest { +class ApiNIP52EventIT { private static final String RELAY_URI = "ws://localhost:5555"; private final SpringWebSocketClient springWebSocketClient; - public ApiNIP52EventTest() { + public ApiNIP52EventIT() { springWebSocketClient = new SpringWebSocketClient(RELAY_URI); } diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java index 4c70ee2f2..55dd1334a 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java @@ -26,7 +26,7 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -class ApiNIP52RequestTest { +class ApiNIP52RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; private static final String SUBSCRIBER_ID = "ApiNIP52RequestTest-subscriber_001"; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java similarity index 98% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java index 560bb22be..c2ee18707 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java @@ -26,7 +26,7 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -class ApiNIP99EventTest { +class ApiNIP99EventIT { private static final String RELAY_URI = "ws://localhost:5555"; public static final String CLASSIFIED_LISTING_CONTENT = "classified listing content"; @@ -53,7 +53,7 @@ class ApiNIP99EventTest { public static final String LOCATION_CODE = "location"; private final SpringWebSocketClient springWebSocketClient; - public ApiNIP99EventTest() { + public ApiNIP99EventIT() { springWebSocketClient = new SpringWebSocketClient(RELAY_URI); } diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java index 78d759f63..8509354ea 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestTest.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java @@ -27,7 +27,7 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -class ApiNIP99RequestTest { +class ApiNIP99RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; public static final String PUBLISHED_AT_CODE = "published_at"; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java rename to nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java index 44c433d33..9db1e284a 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/NIP52ImplTest.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java @@ -1,4 +1,4 @@ -package nostr.api.integration; +package nostr.api.unit; import java.util.ArrayList; import java.util.List; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java rename to nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java index 3235061a2..d24fc641c 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/NIP60Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java @@ -1,4 +1,4 @@ -package nostr.api.integration; +package nostr.api.unit; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.NonNull; diff --git a/nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java rename to nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java index 1fe3f73cf..c30e826f8 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/NIP61Test.java +++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java @@ -1,4 +1,4 @@ -package nostr.api.integration; +package nostr.api.unit; import java.util.Arrays; import java.util.List; diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index df98b3b45..1da7af808 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -7,3 +7,8 @@ description = 'nostr-java-client' dependencies { api project(':nostr-java-id') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 6917bde48..5f23dfb74 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -8,3 +8,8 @@ dependencies { api project(':nostr-java-crypto') api project(':nostr-java-util') } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index 9592ce67b..767d1d245 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -8,3 +8,8 @@ tasks.named('test') { systemProperty("spring.profiles.active", "test") useJUnitPlatform() } + +tasks.named('test') { + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() +} From c888550289bd84d72052bff089fa54a17858726e Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 13:03:24 -0700 Subject: [PATCH 42/57] comments/cleanup --- buildSrc/build.gradle | 7 +++++++ ...ventions.gradle => nostr-java.conventions.gradle} | 12 +++++++----- nostr-java-api/build.gradle | 2 +- nostr-java-base/build.gradle | 9 +-------- nostr-java-client/build.gradle | 2 +- nostr-java-crypto/build.gradle | 2 +- nostr-java-encryption/build.gradle | 2 +- nostr-java-event/build.gradle | 2 +- nostr-java-examples/build.gradle | 2 +- nostr-java-id/build.gradle | 2 +- nostr-java-util/build.gradle | 7 +------ 11 files changed, 23 insertions(+), 26 deletions(-) rename buildSrc/src/main/groovy/{nostr-java.java-conventions.gradle => nostr-java.conventions.gradle} (94%) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index be30e2850..75830dea2 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,3 +1,10 @@ +/* +gradle project-build tools configuration file + +nostr-java specific configs can be found in: + buildSrc/src/main/groovy/nostr-java.conventions.gradle +*/ + plugins { id 'java' id 'groovy-gradle-plugin' diff --git a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle similarity index 94% rename from buildSrc/src/main/groovy/nostr-java.java-conventions.gradle rename to buildSrc/src/main/groovy/nostr-java.conventions.gradle index 217a085ad..fbc7766bc 100644 --- a/buildSrc/src/main/groovy/nostr-java.java-conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -1,3 +1,10 @@ +/* +nostr-java application/library dependencies & configuration file + +gradle project-build tools specific configs can be found in: + buildSrc/build.gradle +*/ + plugins { id 'java' id 'java-library' @@ -19,9 +26,6 @@ repositories { gradlePluginPortal() mavenLocal() mavenCentral() - maven { - url = 'https://plugins.gradle.org/m2/' - } } //// TODO: commented placeholder as eric may want to provide custom publishing specs @@ -43,8 +47,6 @@ dependencies { def googleGuava = '33.2.1-jre' def bouncyCastle = '1.80' def awaitility = '4.2.0' -// TODO: save below/Modulith for multi-module integration testing - def springModulithVersion = '1.3.3' def lombok = '1.18.36' implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index 9b9095426..071d24706 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-api' diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index e8d8e105f..611fbfafb 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -1,6 +1,5 @@ plugins { - id 'nostr-java.java-conventions' - id 'com.adarshr.test-logger' + id 'nostr-java.conventions' } description = 'nostr-java-base' @@ -8,12 +7,6 @@ description = 'nostr-java-base' dependencies { api project(':nostr-java-util') api project(':nostr-java-crypto') - -// TODO: save below/Modulith for multi-module integration testing -// testRuntimeOnly 'org.springframework.modulith:spring-modulith-core:1.3.3' -// testCompileOnly 'org.springframework.modulith:spring-modulith-api:1.3.3' -// testCompileOnly 'org.springframework.modulith:spring-modulith-apt:1.3.3' -// testCompileOnly 'org.springframework.modulith:spring-modulith-moments:1.3.3' } tasks.named('test') { diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index 1da7af808..c10e34293 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-client' diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index 14c3029a8..182bfc48f 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-crypto' diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 5f23dfb74..2a7330940 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-encryption' diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index 2259e2ea3..577f71f11 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-event' diff --git a/nostr-java-examples/build.gradle b/nostr-java-examples/build.gradle index 5d0ab1650..1900922d1 100644 --- a/nostr-java-examples/build.gradle +++ b/nostr-java-examples/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-examples' diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index c9b4be127..fe382889e 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-id' diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index 767d1d245..bac6ec2b6 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nostr-java.java-conventions' + id 'nostr-java.conventions' } description = 'nostr-java-util' @@ -8,8 +8,3 @@ tasks.named('test') { systemProperty("spring.profiles.active", "test") useJUnitPlatform() } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} From 75885eca49c17edc150027f488c3721608854708 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 15:10:13 -0700 Subject: [PATCH 43/57] working snapshot --- .../main/groovy/nostr-java.conventions.gradle | 27 +++++++++---------- gradle.properties | 14 ++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index fbc7766bc..11334caf2 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -15,12 +15,9 @@ plugins { id 'io.spring.dependency-management' } -group = 'xyz.tcheeric' -version = '0.6.5-SNAPSHOT' -description = 'nostr-java' - -java.sourceCompatibility = JavaVersion.VERSION_21 -java.targetCompatibility = JavaVersion.VERSION_21 +group = version = rootProject.property("nostr-java.group") +version = rootProject.property("nostr-java.version") +description = rootProject.property("nostr-java.description") repositories { gradlePluginPortal() @@ -41,13 +38,13 @@ repositories { //} dependencies { - def springBootVersion = '3.4.3' - def apacheCommonsLang3 = '3.17.0' - def jacksonModuleAfterburner = '2.18.3' - def googleGuava = '33.2.1-jre' - def bouncyCastle = '1.80' - def awaitility = '4.2.0' - def lombok = '1.18.36' + def springBootVersion = rootProject.property("nostr-java.springBootVersion") + def apacheCommonsLang3 = rootProject.property("nostr-java.apacheCommonsLang3") + def jacksonModuleAfterburner = rootProject.property("nostr-java.jacksonModuleAfterburner") + def googleGuava = rootProject.property("nostr-java.googleGuava") + def bouncyCastle = rootProject.property("nostr-java.bouncyCastle") + def awaitility = rootProject.property("nostr-java.awaitility") + def lombok = rootProject.property("nostr-java.lombok") implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion implementation 'org.springframework.boot:spring-boot-devtools:' + springBootVersion @@ -96,9 +93,11 @@ tasks.jar { archiveClassifier = '' } +java.sourceCompatibility = JavaVersion.toVersion(rootProject.property("nostr-java.java-version")) +java.targetCompatibility = JavaVersion.toVersion(rootProject.property("nostr-java.java-version")) java { toolchain { - languageVersion = JavaLanguageVersion.of(21) + languageVersion = JavaLanguageVersion.of(rootProject.property("nostr-java.java-version").toString()) } } diff --git a/gradle.properties b/gradle.properties index cd889ee94..ad6214092 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,3 +3,17 @@ org.gradle.daemon=true org.gradle.caching=true org.gradle.parallel=true #createReports=true + +nostr-java.group=xyz.tcheeric +nostr-java.version=0.6.5-SNAPSHOT +nostr-java.description=nostr-java + +nostr-java.springBootVersion=3.4.3 +nostr-java.apacheCommonsLang3=3.17.0 +nostr-java.jacksonModuleAfterburner=2.18.3 +nostr-java.googleGuava=33.2.1-jre +nostr-java.bouncyCastle=1.80 +nostr-java.awaitility=4.2.0 +nostr-java.lombok=1.18.36 + +nostr-java.java-version=21 From ef5c87b93b2c99dd7ba1936406e6bf8a0c6fc827 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 18:25:57 -0700 Subject: [PATCH 44/57] add test-retry options --- .mvn/wrapper/maven-wrapper.jar | Bin 58727 -> 0 bytes buildSrc/build.gradle | 8 ++++-- .../main/groovy/nostr-java.conventions.gradle | 26 ++++++++++++------ gradle.properties | 5 ++-- nostr-java-api/build.gradle | 5 ---- 5 files changed, 26 insertions(+), 18 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.jar diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index c1dd12f17644411d6e840bd5a10c6ecda0175f18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58727 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%0ANsA|A3-jj|r`KAo%oTajX3>^E` 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 YM{}PByk10KD_nuQ4E7Du?}+~TKh4V)`~Uy| diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 75830dea2..53c70a4ad 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -16,16 +16,18 @@ version = '0.6.5-SNAPSHOT' repositories { gradlePluginPortal() mavenCentral() - maven { - url = 'https://repo.maven.apache.org/maven2/' - } + gradlePluginPortal { + url = 'https://plugins.gradle.org/m2/' + } } dependencies { def springBootVersion = '3.4.3' + def retry = '1.6.2' implementation 'org.springframework.boot:spring-boot:' + springBootVersion implementation 'org.springframework.boot:spring-boot-gradle-plugin:' + springBootVersion + implementation 'org.gradle.test-retry:org.gradle.test-retry.gradle.plugin:' + retry } configurations { diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index 11334caf2..26a49c0d5 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -11,8 +11,9 @@ plugins { id 'maven-publish' id 'groovy-gradle-plugin' id 'org.springframework.boot' - id 'com.adarshr.test-logger' id 'io.spring.dependency-management' + id 'com.adarshr.test-logger' + id 'org.gradle.test-retry' } group = version = rootProject.property("nostr-java.group") @@ -45,6 +46,7 @@ dependencies { def bouncyCastle = rootProject.property("nostr-java.bouncyCastle") def awaitility = rootProject.property("nostr-java.awaitility") def lombok = rootProject.property("nostr-java.lombok") + def logger = rootProject.property("nostr-java.adarshrGradleTestLoggerPlugin") implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion implementation 'org.springframework.boot:spring-boot-devtools:' + springBootVersion @@ -56,24 +58,23 @@ dependencies { implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:' + jacksonModuleAfterburner implementation 'org.bouncycastle:bcprov-jdk18on:' + bouncyCastle - + implementation 'org.apache.commons:commons-lang3:' + apacheCommonsLang3 implementation 'com.google.guava:guava:' + googleGuava implementation 'org.awaitility:awaitility:' + awaitility - annotationProcessor 'org.awaitility:awaitility:' + awaitility implementation 'org.projectlombok:lombok:' + lombok + annotationProcessor 'org.awaitility:awaitility:' + awaitility annotationProcessor 'org.projectlombok:lombok:' + lombok testImplementation 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion testImplementation 'org.projectlombok:lombok:' + lombok testImplementation 'org.awaitility:awaitility:' + awaitility - testImplementation 'com.adarshr:gradle-test-logger-plugin:4.0.0' - testAnnotationProcessor 'org.projectlombok:lombok:' + lombok + testImplementation 'com.adarshr:gradle-test-logger-plugin:' + logger + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testAnnotationProcessor 'org.projectlombok:lombok:' + lombok } -subprojects { apply plugin: 'com.adarshr.test-logger' } - configurations { compileOnly { extendsFrom annotationProcessor @@ -81,10 +82,19 @@ configurations { } tasks.test { -// systemProperty("spring.profiles.active", "test") + systemProperty("spring.profiles.active", "test") useJUnitPlatform() } +test { + retry { + maxRetries.set(2) +// maxFailures.set(20) + failOnPassedAfterRetry.set(false) +// failOnSkippedAfterRetry.set(true) + } +} + tasks.bootJar { enabled = false } diff --git a/gradle.properties b/gradle.properties index ad6214092..129650918 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,7 @@ nostr-java.group=xyz.tcheeric nostr-java.version=0.6.5-SNAPSHOT nostr-java.description=nostr-java +nostr-java.java-version=21 nostr-java.springBootVersion=3.4.3 nostr-java.apacheCommonsLang3=3.17.0 nostr-java.jacksonModuleAfterburner=2.18.3 @@ -15,5 +16,5 @@ nostr-java.googleGuava=33.2.1-jre nostr-java.bouncyCastle=1.80 nostr-java.awaitility=4.2.0 nostr-java.lombok=1.18.36 - -nostr-java.java-version=21 +nostr-java.adarshrGradleTestLoggerPlugin=4.0.0 +nostr-java.gradleTestRetry=1.6.2 diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index 071d24706..c07288efb 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -8,8 +8,3 @@ dependencies { api project(':nostr-java-client') api project(':nostr-java-encryption') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} From 09618788a61668962998d14d9c53662001b1a48b Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 21:52:29 -0700 Subject: [PATCH 45/57] config sequential execution for api tests --- .../src/main/groovy/nostr-java.conventions.gradle | 15 ++++++--------- .../java/nostr/api/integration/ApiEventIT.java | 4 ---- .../ApiEventTestUsingSpringWebSocketClientIT.java | 3 +++ ...{APINIP09EventIT.java => ApiNIP09EventIT.java} | 2 +- .../nostr/api/integration/ApiNIP52EventIT.java | 7 ++++++- .../nostr/api/integration/ApiNIP52RequestIT.java | 5 +++++ .../nostr/api/integration/ApiNIP99EventIT.java | 5 +++++ .../nostr/api/integration/ApiNIP99RequestIT.java | 5 +++++ .../src/test/resources/junit-platform.properties | 4 +++- 9 files changed, 34 insertions(+), 16 deletions(-) rename nostr-java-api/src/test/java/nostr/api/integration/{APINIP09EventIT.java => ApiNIP09EventIT.java} (99%) diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index 26a49c0d5..5f7cbef43 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -84,15 +84,12 @@ configurations { tasks.test { systemProperty("spring.profiles.active", "test") useJUnitPlatform() -} - -test { - retry { - maxRetries.set(2) -// maxFailures.set(20) - failOnPassedAfterRetry.set(false) -// failOnSkippedAfterRetry.set(true) - } +// retry { +// maxRetries.set(1) +//// maxFailures.set(20) +//// failOnPassedAfterRetry.set(false) +//// failOnSkippedAfterRetry.set(true) +// } } tasks.bootJar { 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 ba4eb7a85..f2d343cc8 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 @@ -57,10 +57,6 @@ import static org.awaitility.Awaitility.await; import static org.junit.jupiter.api.Assertions.*; - -/** - * @author eric - */ @ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") 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 27e550b35..56c3fd3e6 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 @@ -9,8 +9,10 @@ import nostr.id.Identity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -23,6 +25,7 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; +@ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientIT { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java index 60a7fd704..7f1395480 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/APINIP09EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java @@ -39,7 +39,7 @@ @ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") -public class APINIP09EventIT { +public class ApiNIP09EventIT { @Autowired private Map relays; 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 a44c5830c..a5389c379 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 @@ -13,6 +13,9 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.util.ArrayList; @@ -21,6 +24,8 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(SpringExtension.class) +@ActiveProfiles("test") class ApiNIP52EventIT { private static final String RELAY_URI = "ws://localhost:5555"; private final SpringWebSocketClient springWebSocketClient; @@ -47,7 +52,7 @@ void testNIP52CalendarTimeBasedEventEventUsingSpringWebSocketClient() throws IOE EventMessage message = new EventMessage(event); var expectedJson = MAPPER_AFTERBURNER.readTree(expectedResponseJson(event.getId())); - var actualJson = MAPPER_AFTERBURNER.readTree(springWebSocketClient.send(message).stream().findFirst().get()); + var actualJson = MAPPER_AFTERBURNER.readTree(springWebSocketClient.send(message).stream().findFirst().orElseThrow()); // Compare only first 3 elements of the JSON arrays assertTrue( 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 55dd1334a..4442ede62 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 @@ -17,6 +17,9 @@ import nostr.id.Identity; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.net.URI; @@ -26,6 +29,8 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(SpringExtension.class) +@ActiveProfiles("test") class ApiNIP52RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; 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 c2ee18707..d0c043b56 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 @@ -17,6 +17,9 @@ import nostr.event.tag.SubjectTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.math.BigDecimal; @@ -26,6 +29,8 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(SpringExtension.class) +@ActiveProfiles("test") class ApiNIP99EventIT { private static final String RELAY_URI = "ws://localhost:5555"; 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 8509354ea..4fa1ccb65 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 @@ -18,6 +18,9 @@ import nostr.id.Identity; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.math.BigDecimal; @@ -27,6 +30,8 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(SpringExtension.class) +@ActiveProfiles("test") class ApiNIP99RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; diff --git a/nostr-java-api/src/test/resources/junit-platform.properties b/nostr-java-api/src/test/resources/junit-platform.properties index a413a5904..efcd342d7 100644 --- a/nostr-java-api/src/test/resources/junit-platform.properties +++ b/nostr-java-api/src/test/resources/junit-platform.properties @@ -1,7 +1,9 @@ # junit-platform.properties -junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.enabled=false junit.jupiter.execution.parallel.config.strategy=dynamic junit.jupiter.execution.parallel.mode.default=same_thread #junit.jupiter.execution.parallel.mode.default=concurrent #junit.jupiter.execution.parallel.mode.classes.default=concurrent + +#junit.jupiter.testclass.order.default=org.junit.jupiter.api.ClassOrderer$ClassName From 1fc0b42784fe7e14b0f4482ec4765890f884f800 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 22:21:11 -0700 Subject: [PATCH 46/57] test-method calls to close socket introduce race-condition with test thread execution/completion. since explicit socket closes are irrelevant to the purpose of these specific tests and since relays should handle socket disconnects themselves, calls to close socket are superfluous here- and therefore- removed --- .../nostr/api/integration/ApiEventIT.java | 31 +++++------ ...EventTestUsingSpringWebSocketClientIT.java | 26 +++++----- .../api/integration/ApiNIP09EventIT.java | 52 ++++++++----------- .../api/integration/ApiNIP52EventIT.java | 5 +- .../api/integration/ApiNIP52RequestIT.java | 7 +-- .../api/integration/ApiNIP99EventIT.java | 5 +- .../api/integration/ApiNIP99RequestIT.java | 7 +-- 7 files changed, 53 insertions(+), 80 deletions(-) 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 f2d343cc8..531a32c21 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 @@ -39,10 +39,8 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -57,7 +55,6 @@ import static org.awaitility.Awaitility.await; import static org.junit.jupiter.api.Assertions.*; -@ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") public class ApiEventIT { @@ -97,7 +94,7 @@ public void testNIP01SendTextNoteEvent() throws IOException { assertTrue(response instanceof OkMessage); assertEquals(nip01.getEvent().getId(), ((OkMessage) response).getEventId()); - nip01.close(); +// nip01.close(); } @Test @@ -117,7 +114,7 @@ public void testNIP04SendDirectMessage() throws IOException { var response = instance.setRelays(relays).send(); assertTrue(response instanceof OkMessage); assertEquals(nip04.getEvent().getId(), ((OkMessage) response).getEventId()); - nip04.close(); +// nip04.close(); } @Test @@ -134,7 +131,7 @@ public void testNIP44SendDirectMessage() throws IOException { var response = instance.setRelays(relays).send(); assertTrue(response instanceof OkMessage); assertEquals(nip44.getEvent().getId(), ((OkMessage) response).getEventId()); - nip44.close(); +// nip44.close(); } @Test @@ -156,7 +153,7 @@ public void testNIP01SendTextNoteEventGeoHashTag() throws IOException { assertEquals(2, result.size()); assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); - nip01.close(); +// nip01.close(); } @Test @@ -178,7 +175,7 @@ public void testNIP01SendTextNoteEventHashtagTag() throws IOException { assertEquals(2, result.size()); assertTrue(result.stream().anyMatch(s -> s.contains(targetString))); - nip01.close(); +// nip01.close(); } @Test @@ -204,7 +201,7 @@ public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException { assertTrue(result.stream().anyMatch(s -> s.contains(matcher))); - nip01.close(); +// nip01.close(); } @Test @@ -232,7 +229,7 @@ public void testFiltersListReturnSameSingularEvent() throws IOException { assertEquals(2, result.size()); assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); - nip01.close(); +// nip01.close(); } @Test @@ -268,8 +265,8 @@ public void testFiltersListReturnTwoDifferentEvents() throws IOException { assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget1))); assertTrue(result.stream().anyMatch(s -> s.contains(genericTagTarget2))); - nip01_1.close(); - nip01_2.close(); +// nip01_1.close(); +// nip01_2.close(); } @Test @@ -295,7 +292,7 @@ public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOExceptio assertEquals(2, result.size()); assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget))); - nip01.close(); +// nip01.close(); } @Test @@ -371,7 +368,7 @@ public void testNIP15UpdateStallEvent() throws IOException { assertTrue(response instanceof OkMessage); assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - nip15.close(); +// nip15.close(); } @Test @@ -395,7 +392,7 @@ public void testNIP15CreateProductEvent() throws IOException { assertTrue(response instanceof OkMessage); assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - nip15.close(); +// nip15.close(); } @Test @@ -427,7 +424,7 @@ public void testNIP15UpdateProductEvent() throws IOException { assertTrue(response instanceof OkMessage); assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId()); - nip15.close(); +// nip15.close(); } @Test @@ -500,7 +497,7 @@ public void testNIP52CalendarTimeBasedEventEvent() throws IOException { assertTrue(response instanceof OkMessage); assertEquals(nip52.getEvent().getId(), ((OkMessage) response).getEventId()); - nip52.close(); +// nip52.close(); } @Test 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 56c3fd3e6..b6b38c8da 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,21 +1,18 @@ package nostr.api.integration; +import lombok.SneakyThrows; import nostr.api.NIP15; -import nostr.config.RelayProperties; import nostr.base.PrivateKey; import nostr.client.springwebsocket.SpringWebSocketClient; +import nostr.config.RelayProperties; import nostr.event.impl.GenericEvent; import nostr.event.message.EventMessage; import nostr.id.Identity; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -25,22 +22,23 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertEquals; -@ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") class ApiEventTestUsingSpringWebSocketClientIT { - private SpringWebSocketClient springWebSocketClient; + private final List springWebSocketClients; @Autowired - Map relays; - - @BeforeEach - void setupBeforeEach() { - relays.forEach((key, value) -> springWebSocketClient = new SpringWebSocketClient(value)); + public ApiEventTestUsingSpringWebSocketClientIT(Map relays) { + this.springWebSocketClients = relays.values().stream().map(SpringWebSocketClient::new).toList(); } @Test - void testNIP15SendProductEventUsingSpringWebSocketClient() throws IOException { + void doForEach() { + springWebSocketClients.forEach(this::testNIP15SendProductEventUsingSpringWebSocketClient); + } + + @SneakyThrows + void testNIP15SendProductEventUsingSpringWebSocketClient(SpringWebSocketClient springWebSocketClient) { System.out.println("testNIP15CreateProductEventUsingSpringWebSocketClient"); var product = createProduct(createStall()); @@ -68,7 +66,7 @@ void testNIP15SendProductEventUsingSpringWebSocketClient() throws IOException { assertEquals(expectedSubscriptionId, actualSubscriptionId, "Subscription ID should match"); assertEquals(expectedSuccess, actualSuccess, "Success flag should match"); - springWebSocketClient.closeSocket(); +// springWebSocketClient.closeSocket(); } private String expectedResponseJson(String sha256) { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java index 7f1395480..22f32d6b1 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java @@ -2,8 +2,8 @@ import nostr.api.NIP01; import nostr.api.NIP09; -import nostr.config.RelayProperties; import nostr.base.Relay; +import nostr.config.RelayProperties; import nostr.event.BaseMessage; import nostr.event.BaseTag; import nostr.event.Kind; @@ -19,10 +19,8 @@ import nostr.event.tag.IdentifierTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.io.IOException; @@ -31,18 +29,14 @@ import java.util.UUID; import java.util.stream.Collectors; -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; +import static org.junit.jupiter.api.Assertions.*; -@ExtendWith(SpringExtension.class) @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") public class ApiNIP09EventIT { @Autowired private Map relays; - + @Test public void deleteEvent() throws IOException { @@ -53,8 +47,8 @@ public void deleteEvent() throws IOException { nip01.createTextNoteEvent("Delete me!").signAndSend(relays); Filters filters = new Filters( - new KindFilter<>(Kind.TEXT_NOTE), - new AuthorFilter<>(identity.getPublicKey())); + new KindFilter<>(Kind.TEXT_NOTE), + new AuthorFilter<>(identity.getPublicKey())); List result = nip01.sendRequest(filters, UUID.randomUUID().toString()); @@ -68,8 +62,8 @@ public void deleteEvent() throws IOException { assertFalse(result.isEmpty()); assertEquals(1, result.size()); - nip01.close(); - nip09.close(); +// nip01.close(); +// nip09.close(); } @@ -89,10 +83,10 @@ public void deleteEventWithRef() throws IOException { NIP01 nip01 = new NIP01<>(identity); nip01 - .createTextNoteEvent("Reference me!") - .getEvent() - .addTag(nip01.createAddressTag(10_001, identity.getPublicKey(), identifierTag, new Relay(RELAY_URI))); - + .createTextNoteEvent("Reference me!") + .getEvent() + .addTag(nip01.createAddressTag(10_001, identity.getPublicKey(), identifierTag, new Relay(RELAY_URI))); + BaseMessage message = nip01.signAndSend(relays); assertNotNull(message); @@ -106,9 +100,9 @@ public void deleteEventWithRef() throws IOException { assertEquals(4, deletedEvent.getTags().size()); List eventTags = deletedEvent.getTags() - .stream() - .filter(t -> "e".equals(t.getCode())) - .collect(Collectors.toList()); + .stream() + .filter(t -> "e".equals(t.getCode())) + .collect(Collectors.toList()); assertEquals(1, eventTags.size()); @@ -116,9 +110,9 @@ public void deleteEventWithRef() throws IOException { assertEquals(event.getId(), eventTag.getIdEvent()); List addressTags = deletedEvent.getTags() - .stream() - .filter(t -> "a".equals(t.getCode())) - .collect(Collectors.toList()); + .stream() + .filter(t -> "a".equals(t.getCode())) + .collect(Collectors.toList()); assertEquals(1, addressTags.size()); @@ -128,16 +122,16 @@ public void deleteEventWithRef() throws IOException { assertEquals(identity.getPublicKey(), addressTag.getPublicKey()); List kindTags = deletedEvent.getTags() - .stream() - .filter(t -> "k".equals(t.getCode())) - .collect(Collectors.toList()); + .stream() + .filter(t -> "k".equals(t.getCode())) + .collect(Collectors.toList()); assertEquals(2, kindTags.size()); nip09.signAndSend(relays); - nip01.close(); - nip011.close(); - nip09.close(); +// nip01.close(); +// nip011.close(); +// nip09.close(); } } 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 a5389c379..a06da9197 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 @@ -13,9 +13,7 @@ import nostr.event.tag.PubKeyTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.util.ArrayList; @@ -24,7 +22,6 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) @ActiveProfiles("test") class ApiNIP52EventIT { private static final String RELAY_URI = "ws://localhost:5555"; @@ -66,7 +63,7 @@ void testNIP52CalendarTimeBasedEventEventUsingSpringWebSocketClient() throws IOE .add(actualJson.get(1)) .add(actualJson.get(2)))); - springWebSocketClient.closeSocket(); +// springWebSocketClient.closeSocket(); } private String expectedResponseJson(String sha256) { 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 4442ede62..ffc8c1c2b 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 @@ -15,11 +15,8 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.ReferenceTag; import nostr.id.Identity; -import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.net.URI; @@ -29,7 +26,6 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) @ActiveProfiles("test") class ApiNIP52RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; @@ -81,7 +77,6 @@ class ApiNIP52RequestIT { public String eventPubKey; public String signature; - @Order(1) @Test void testNIP99CalendarContentPreRequest() throws IOException { System.out.println("testNIP52CalendarContentEvent"); @@ -131,7 +126,7 @@ void testNIP99CalendarContentPreRequest() throws IOException { assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); //assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); -- This test is not required. The relay will always return false because we resending the same event, causing duplicates. - springWebSocketEventClient.closeSocket(); +// springWebSocketEventClient.closeSocket(); // TODO - This assertion fails with superdonductor and nostr-rs-relay 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 d0c043b56..a7249751d 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 @@ -17,9 +17,7 @@ import nostr.event.tag.SubjectTag; import nostr.id.Identity; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.math.BigDecimal; @@ -29,7 +27,6 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) @ActiveProfiles("test") class ApiNIP99EventIT { private static final String RELAY_URI = "ws://localhost:5555"; @@ -101,7 +98,7 @@ void testNIP99ClassifiedListingEvent() throws IOException { assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); - springWebSocketClient.closeSocket(); +// springWebSocketClient.closeSocket(); } private String expectedResponseJson(String sha256) { 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 4fa1ccb65..262a3b15a 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 @@ -16,11 +16,8 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.SubjectTag; import nostr.id.Identity; -import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; import java.math.BigDecimal; @@ -30,7 +27,6 @@ import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) @ActiveProfiles("test") class ApiNIP99RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; @@ -68,7 +64,6 @@ class ApiNIP99RequestIT { public String eventPubKey; public String signature; - @Order(1) @Test void testNIP99ClassifiedListingPreRequest() throws IOException { System.out.println("testNIP99ClassifiedListingEvent"); @@ -116,7 +111,7 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); - springWebSocketEventClient.closeSocket(); +// springWebSocketEventClient.closeSocket(); // TODO - Investigate why EOSE, instead of EVENT, is returned from nostr-rs-relay, and not superconductor From 65876785f5d941f4e27bdb4452ab7c6c7ec22073 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 22:35:48 -0700 Subject: [PATCH 47/57] parallel tests for api --- nostr-java-api/src/test/resources/junit-platform.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostr-java-api/src/test/resources/junit-platform.properties b/nostr-java-api/src/test/resources/junit-platform.properties index efcd342d7..beae0cf29 100644 --- a/nostr-java-api/src/test/resources/junit-platform.properties +++ b/nostr-java-api/src/test/resources/junit-platform.properties @@ -1,6 +1,6 @@ # junit-platform.properties -junit.jupiter.execution.parallel.enabled=false +junit.jupiter.execution.parallel.enabled=true junit.jupiter.execution.parallel.config.strategy=dynamic junit.jupiter.execution.parallel.mode.default=same_thread #junit.jupiter.execution.parallel.mode.default=concurrent From 2aafacca897551bf3a4b50b97c6ce1e43579fda1 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 23:28:58 -0700 Subject: [PATCH 48/57] commented out tested fixed --- .../api/integration/ApiNIP52RequestIT.java | 26 +++--- .../api/integration/ApiNIP99RequestIT.java | 28 +++--- ...entIT.java => ZDoLastApiNIP09EventIT.java} | 2 +- .../java/nostr/event/unit/RelaysTagTest.java | 86 +++++++++---------- 4 files changed, 74 insertions(+), 68 deletions(-) rename nostr-java-api/src/test/java/nostr/api/integration/{ApiNIP09EventIT.java => ZDoLastApiNIP09EventIT.java} (99%) 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 ffc8c1c2b..281bdaa8a 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,6 +1,7 @@ package nostr.api.integration; import nostr.api.NIP52; +import nostr.api.util.JsonComparator; import nostr.base.PublicKey; import nostr.client.springwebsocket.SpringWebSocketClient; import nostr.event.BaseTag; @@ -22,6 +23,7 @@ import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import static nostr.base.IEvent.MAPPER_AFTERBURNER; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -30,7 +32,6 @@ class ApiNIP52RequestIT { private static final String PRV_KEY_VALUE = "23c011c4c02de9aa98d48c3646c70bb0e7ae30bdae1dfed4d251cbceadaeeb7b"; private static final String RELAY_URI = "ws://localhost:5555"; - private static final String SUBSCRIBER_ID = "ApiNIP52RequestTest-subscriber_001"; private static final String UUID_CALENDAR_TIME_BASED_EVENT_TEST = "UUID-CalendarTimeBasedEventTest"; public static final String ID = "299ab85049a7923e9cd82329c0fa489ca6fd6d21feeeac33543b1237e14a9e07"; @@ -106,12 +107,13 @@ void testNIP99CalendarContentPreRequest() throws IOException { GenericEvent event = nip52.createCalendarTimeBasedEvent(tags, CALENDAR_CONTENT, calendarContent).sign().getEvent(); event.setCreatedAt(Long.valueOf(CREATED_AT)); + eventId = event.getId(); signature = event.getSignature().toString(); eventPubKey = event.getPubKey().toString(); EventMessage eventMessage = new EventMessage(event); SpringWebSocketClient springWebSocketEventClient = new SpringWebSocketClient(RELAY_URI); - String eventResponse = springWebSocketEventClient.send(eventMessage).stream().findFirst().get(); + String eventResponse = springWebSocketEventClient.send(eventMessage).stream().findFirst().orElseThrow(); // Extract and compare only first 3 elements of the JSON array var expectedArray = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); @@ -130,18 +132,20 @@ void testNIP99CalendarContentPreRequest() throws IOException { // TODO - This assertion fails with superdonductor and nostr-rs-relay -/* +///* SpringWebSocketClient springWebSocketRequestClient = new SpringWebSocketClient(RELAY_URI); - String reqJson = createReqJson(SUBSCRIBER_ID, eventId); - String reqResponse = springWebSocketRequestClient.send(reqJson).stream().findFirst().get(); + String subscriberId = UUID.randomUUID().toString(); + String reqJson = createReqJson(subscriberId, eventId); + String reqResponse = springWebSocketRequestClient.send(reqJson).stream().findFirst().orElseThrow(); + String expected = expectedRequestResponseJson(subscriberId); assertTrue( JsonComparator.isEquivalentJson( - MAPPER_AFTERBURNER.readTree(expectedRequestResponseJson()), + MAPPER_AFTERBURNER.readTree(expected), MAPPER_AFTERBURNER.readTree(reqResponse))); - springWebSocketRequestClient.closeSocket(); -*/ +// springWebSocketRequestClient.closeSocket(); +//*/ } private String expectedEventResponseJson(String subscriptionId) { @@ -152,15 +156,15 @@ private String createReqJson(String subscriberId, String id) { return "[\"REQ\",\"" + subscriberId + "\",{\"ids\":[\"" + id + "\"]}]"; } - private String expectedRequestResponseJson() { - return " [\"EVENT\",\"" + SUBSCRIBER_ID + "\",\n" + + private String expectedRequestResponseJson(String subscriberId) { + return " [\"EVENT\",\"" + subscriberId + "\",\n" + " {\"id\": \"" + eventId + "\",\n" + " \"kind\": " + KIND + ",\n" + " \"content\": \"" + CALENDAR_CONTENT + "\",\n" + " \"pubkey\": \"" + eventPubKey + "\",\n" + " \"created_at\": " + CREATED_AT + ",\n" + " \"tags\": [\n" + - " [ \"e\", \"" + E_TAG.getIdEvent() + "\", \"" + E_TAG.getMarker() + "\" ],\n" + + " [ \"e\", \"" + E_TAG.getIdEvent() + "\" ],\n" + " [ \"g\", \"" + G_TAG.getLocation() + "\" ],\n" + " [ \"t\", \"" + T_TAG.getHashTag() + "\" ],\n" + " [ \"d\", \"" + UUID_CALENDAR_TIME_BASED_EVENT_TEST + "\" ],\n" + 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 262a3b15a..bf3908c68 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 @@ -23,8 +23,10 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import static nostr.base.IEvent.MAPPER_AFTERBURNER; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @ActiveProfiles("test") @@ -96,39 +98,39 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { SpringWebSocketClient springWebSocketEventClient = new SpringWebSocketClient(RELAY_URI); List eventResponses = springWebSocketEventClient.send(eventMessage); - assertTrue(eventResponses.size() == 1, "Expected 1 event response, but got " + eventResponses.size()); + assertEquals(1, eventResponses.size(), "Expected 1 event response, but got " + eventResponses.size()); // Extract and compare only first 3 elements of the JSON array var expectedArray = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(0).asText(); var expectedSubscriptionId = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(1).asText(); var expectedSuccess = MAPPER_AFTERBURNER.readTree(expectedEventResponseJson(event.getId())).get(2).asBoolean(); - var actualArray = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(0).asText(); - var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(1).asText(); - var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponses.get(0)).get(2).asBoolean(); + var actualArray = MAPPER_AFTERBURNER.readTree(eventResponses.getFirst()).get(0).asText(); + var actualSubscriptionId = MAPPER_AFTERBURNER.readTree(eventResponses.getFirst()).get(1).asText(); + var actualSuccess = MAPPER_AFTERBURNER.readTree(eventResponses.getFirst()).get(2).asBoolean(); - assertTrue(expectedArray.equals(actualArray), "First element should match"); - assertTrue(expectedSubscriptionId.equals(actualSubscriptionId), "Subscription ID should match"); - assertTrue(expectedSuccess == actualSuccess, "Success flag should match"); + assertEquals(expectedArray, actualArray, "First element should match"); + assertEquals(expectedSubscriptionId, actualSubscriptionId, "Subscription ID should match"); + assertEquals(expectedSuccess, actualSuccess, "Success flag should match"); // springWebSocketEventClient.closeSocket(); // TODO - Investigate why EOSE, instead of EVENT, is returned from nostr-rs-relay, and not superconductor -/* +///* SpringWebSocketClient springWebSocketRequestClient = new SpringWebSocketClient(RELAY_URI); - String reqJson = createReqJson(SUBSCRIBER_ID, eventId); + String reqJson = createReqJson(UUID.randomUUID().toString(), eventId); List reqResponses = springWebSocketRequestClient.send(reqJson).stream().toList(); - springWebSocketRequestClient.closeSocket(); +// springWebSocketRequestClient.closeSocket(); var actualJson = MAPPER_AFTERBURNER.readTree(reqResponses.getFirst()); var expectedJson = MAPPER_AFTERBURNER.readTree(expectedRequestResponseJson()); // Verify you receive the event - assertTrue(actualJson.get(0).asText().equals("EVENT"), "Event should be received, and not " + actualJson.get(0).asText()); + assertEquals("EVENT", actualJson.get(0).asText(), "Event should be received, and not " + actualJson.get(0).asText()); // Verify only required fields - assertTrue(actualJson.size() == 3, "Expected 3 elements in the array, but got " + actualJson.size()); + assertEquals(3, actualJson.size(), "Expected 3 elements in the array, but got " + actualJson.size()); assertTrue(actualJson.get(2).get("id").asText().equals(expectedJson.get(2).get("id").asText()), "ID should match"); assertTrue(actualJson.get(2).get("kind").asInt() == expectedJson.get(2).get("kind").asInt(), "Kind should match"); @@ -137,7 +139,7 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { assertTrue(hasRequiredTag(actualTags, "price", NUMBER.toString()), "Price tag should be present"); assertTrue(hasRequiredTag(actualTags, "title", TITLE), "Title tag should be present"); assertTrue(hasRequiredTag(actualTags, "summary", SUMMARY), "Summary tag should be present"); -*/ +//*/ } private String expectedEventResponseJson(String subscriptionId) { diff --git a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java similarity index 99% rename from nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java rename to nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java index 22f32d6b1..95857593d 100644 --- a/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP09EventIT.java +++ b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java @@ -33,7 +33,7 @@ @SpringJUnitConfig(RelayProperties.class) @ActiveProfiles("test") -public class ApiNIP09EventIT { +public class ZDoLastApiNIP09EventIT { @Autowired private Map relays; 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 afb681970..87dddb67f 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,43 +1,43 @@ -package nostr.event.unit; - -import com.fasterxml.jackson.databind.JsonNode; -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.IEvent.MAPPER_AFTERBURNER; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class RelaysTagTest { - - public final static String RELAYS_KEY = "relays"; - public final static String HOST_VALUE = "ws://localhost:5555"; - public final static String HOST_VALUE2 = "ws://anotherlocalhost:5432"; - - @Test - void testSerialize() { - final String expected = "[\"relays\",\"ws://localhost:5555\",\"ws://anotherlocalhost:5432\"]"; - RelaysTag relaysTag = new RelaysTag(List.of(new Relay(HOST_VALUE), new Relay(HOST_VALUE2))); - BaseTagEncoder baseTagEncoder = new BaseTagEncoder(relaysTag); - assertDoesNotThrow(() -> { - assertEquals(expected, baseTagEncoder.encode()); - }); - } - - @Test - void testDeserialize() { - final String EXPECTED = "[\"relays\",\"ws://localhost:5555\"]"; - assertDoesNotThrow(() -> { - JsonNode node = MAPPER_AFTERBURNER.readTree(EXPECTED); - BaseTag deserialize = RelaysTag.deserialize(node); - assertEquals(RELAYS_KEY, deserialize.getCode()); - assertEquals(HOST_VALUE, ((RelaysTag) deserialize).getRelays().get(0).getUri()); - }); - } - -} +package nostr.event.unit; + +import com.fasterxml.jackson.databind.JsonNode; +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.IEvent.MAPPER_AFTERBURNER; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class RelaysTagTest { + + public final static String RELAYS_KEY = "relays"; + public final static String HOST_VALUE = "ws://localhost:5555"; + public final static String HOST_VALUE2 = "ws://anotherlocalhost:5432"; + + @Test + void testSerialize() { + final String expected = "[\"relays\",\"ws://localhost:5555\",\"ws://anotherlocalhost:5432\"]"; + RelaysTag relaysTag = new RelaysTag(List.of(new Relay(HOST_VALUE), new Relay(HOST_VALUE2))); + BaseTagEncoder baseTagEncoder = new BaseTagEncoder(relaysTag); + assertDoesNotThrow(() -> { + assertEquals(expected, baseTagEncoder.encode()); + }); + } + + @Test + void testDeserialize() { + final String EXPECTED = "[\"relays\",\"ws://localhost:5555\"]"; + assertDoesNotThrow(() -> { + JsonNode node = MAPPER_AFTERBURNER.readTree(EXPECTED); + BaseTag deserialize = RelaysTag.deserialize(node); + assertEquals(RELAYS_KEY, deserialize.getCode()); + assertEquals(HOST_VALUE, ((RelaysTag) deserialize).getRelays().getFirst().getUri()); + }); + } + +} From b9a6d5d22396e9b0c8f0ca86a5e5c45d4c510a55 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 23:42:29 -0700 Subject: [PATCH 49/57] conventions does not need gradle plugin --- buildSrc/src/main/groovy/nostr-java.conventions.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index 5f7cbef43..a5d091e19 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -9,7 +9,6 @@ plugins { id 'java' id 'java-library' id 'maven-publish' - id 'groovy-gradle-plugin' id 'org.springframework.boot' id 'io.spring.dependency-management' id 'com.adarshr.test-logger' From 12d86cede16dc4a0e945da9f7d209bab750d5260 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 19 Mar 2025 23:47:24 -0700 Subject: [PATCH 50/57] accidental comented --- .../main/groovy/nostr-java.conventions.gradle | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index a5d091e19..cfa437d7a 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -25,17 +25,19 @@ repositories { mavenCentral() } -//// TODO: commented placeholder as eric may want to provide custom publishing specs -//publishing { -// publications { -// nostrjava(MavenPublication) { -// from components.java -// } -// } -// repositories { +publishing { + publications { + nostrjava(MavenPublication) { + from components.java + } + } + repositories { + mavenLocal() +//// TODO: below placeholder for eric // someRemoteRepo() -// } -//} + } +} + dependencies { def springBootVersion = rootProject.property("nostr-java.springBootVersion") From c362a2ae12147f2de0b4b1bcff4eb389803ef4c3 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 20 Mar 2025 12:05:57 -0700 Subject: [PATCH 51/57] removed superfluous nip (& subsequent null use/abuse) from ElementAttribute and downstream dependents --- .../src/main/java/nostr/api/NIP57.java | 16 ++++--- .../nostr/api/factory/impl/NIP42Impl.java | 2 +- .../java/nostr/base/ElementAttribute.java | 6 --- .../main/java/nostr/base/IGenericElement.java | 9 +--- .../src/main/java/nostr/event/BaseTag.java | 15 +++--- .../impl/CanonicalAuthenticationEvent.java | 8 ++-- .../java/nostr/event/impl/GenericEvent.java | 13 ++++-- .../java/nostr/event/impl/GenericMessage.java | 13 +++--- .../java/nostr/event/impl/GenericTag.java | 46 +++++++++---------- .../event/json/codec/GenericTagDecoder.java | 33 ++++++------- .../src/test/java/nostr/id/EntityFactory.java | 6 +-- .../src/test/java/nostr/id/EventTest.java | 4 -- 12 files changed, 82 insertions(+), 89 deletions(-) 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 c85f7195a..c3c0cb1e4 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP57.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP57.java @@ -11,7 +11,11 @@ import nostr.event.impl.GenericEvent; import nostr.event.impl.GenericTag; import nostr.event.impl.ZapRequest; -import nostr.event.tag.*; +import nostr.event.tag.AddressTag; +import nostr.event.tag.EventTag; +import nostr.event.tag.IdentifierTag; +import nostr.event.tag.PubKeyTag; +import nostr.event.tag.RelaysTag; import nostr.id.Identity; import java.util.ArrayList; @@ -54,7 +58,7 @@ public NIP57 createZapRequestEvent(@NonNull PublicKey recipientPubKey, @NonNu } public NIP57 createZapReceiptEvent(@NonNull PubKeyTag zapRequestPubKeyTag, List baseTags, EventTag zapRequestEventTag, AddressTag zapRequestAddressTag, @NonNull String bolt11, - @NonNull String descriptionSha256, @NonNull String preimage) { + @NonNull String descriptionSha256, @NonNull String preimage) { setEvent((T) new ZapReceiptEventFactory(getSender(), baseTags, zapRequestPubKeyTag, zapRequestEventTag, zapRequestAddressTag, bolt11, descriptionSha256, preimage).create()); return this; } @@ -169,16 +173,16 @@ public static GenericTag createAmountTag(@NonNull Integer amount) { */ public static GenericTag createZapTag(@NonNull PublicKey receiver, @NonNull List relays, Integer weight) { List attributes = new ArrayList<>(); - var receiverAttr = new ElementAttribute("receiver", receiver.toString(), 57); - var relayAttrs = relays.stream().map(relay -> new ElementAttribute("relay", relay.getUri(), 57)).toList(); + var receiverAttr = new ElementAttribute("receiver", receiver.toString()); + var relayAttrs = relays.stream().map(relay -> new ElementAttribute("relay", relay.getUri())).toList(); if (weight != null) { - var weightAttr = new ElementAttribute("weight", weight, 57); + var weightAttr = new ElementAttribute("weight", weight); attributes.add(weightAttr); } attributes.add(receiverAttr); attributes.addAll(relayAttrs); - return new GenericTag(ZAP_TAG_NAME, 57, attributes); + return new GenericTag(ZAP_TAG_NAME, attributes); } /** diff --git a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP42Impl.java b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP42Impl.java index d5c46d91b..35b2f739e 100644 --- a/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP42Impl.java +++ b/nostr-java-api/src/main/java/nostr/api/factory/impl/NIP42Impl.java @@ -93,7 +93,7 @@ public static class RelayAuthenticationMessageFactory extends MessageFactory attributes = new ArrayList<>(); - final var attr = new ElementAttribute("challenge", challenge, 42); + final var attr = new ElementAttribute("challenge", challenge); attributes.add(attr); return new GenericMessage(Command.AUTH.name(), attributes, 42); } diff --git a/nostr-java-base/src/main/java/nostr/base/ElementAttribute.java b/nostr-java-base/src/main/java/nostr/base/ElementAttribute.java index 804a58682..4ce02a995 100644 --- a/nostr-java-base/src/main/java/nostr/base/ElementAttribute.java +++ b/nostr-java-base/src/main/java/nostr/base/ElementAttribute.java @@ -29,10 +29,4 @@ public class ElementAttribute { @JsonProperty @EqualsAndHashCode.Include private final Object value; - - @JsonProperty - @JsonInclude(JsonInclude.Include.NON_NULL) - @EqualsAndHashCode.Exclude - private final Integer nip; - } diff --git a/nostr-java-base/src/main/java/nostr/base/IGenericElement.java b/nostr-java-base/src/main/java/nostr/base/IGenericElement.java index 3f38b028a..93a83f393 100644 --- a/nostr-java-base/src/main/java/nostr/base/IGenericElement.java +++ b/nostr-java-base/src/main/java/nostr/base/IGenericElement.java @@ -2,13 +2,8 @@ import java.util.List; -/** - * - * @author squirrel - */ public interface IGenericElement extends IElement { - List getAttributes(); - - void addAttribute(ElementAttribute attribute); + void addAttribute(ElementAttribute... attribute); + void addAttributes(List attributes); } 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 f8a7bd2e2..fed63fdf4 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import lombok.NonNull; import lombok.ToString; import nostr.base.IEvent; import nostr.base.ITag; @@ -34,7 +34,6 @@ @Data @ToString @EqualsAndHashCode(callSuper = false) -@NoArgsConstructor @JsonDeserialize(using = TagDeserializer.class) @JsonSerialize(using = TagSerializer.class) public abstract class BaseTag implements ITag { @@ -43,7 +42,7 @@ public abstract class BaseTag implements ITag { private IEvent parent; @Override - public void setParent(IEvent event) { + public void setParent(@NonNull IEvent event) { this.parent = event; } @@ -68,11 +67,11 @@ public String getFieldValue(Field field) throws NostrException { public List getSupportedFields() throws NostrException { return new Streams.FailableStream<>(Arrays.stream(this.getClass().getDeclaredFields())) - .filter(f -> - Objects.nonNull(f.getAnnotation(Key.class))) - .filter(f -> - Objects.nonNull(getFieldValue(f))) - .collect(Collectors.toList()); + .filter(f -> + Objects.nonNull(f.getAnnotation(Key.class))) + .filter(f -> + Objects.nonNull(getFieldValue(f))) + .collect(Collectors.toList()); } protected static void setOptionalField(JsonNode node, BiConsumer con, T tag) { 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 7c4fa5f60..d11b6db12 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 @@ -23,16 +23,16 @@ public CanonicalAuthenticationEvent(@NonNull PublicKey pubKey, @NonNull String c // Challenge tag List chAttributes = new ArrayList<>(); - var attribute = ElementAttribute.builder().nip(42).name("challenge").value(challenge).build(); + var attribute = ElementAttribute.builder().name("challenge").value(challenge).build(); chAttributes.add(attribute); - BaseTag challengeTag = new GenericTag("challenge", 42, chAttributes); + BaseTag challengeTag = new GenericTag("challenge", chAttributes); this.addTag(challengeTag); // Relay tag final List relayAttributes = new ArrayList<>(); - final ElementAttribute relayAttribute = ElementAttribute.builder().nip(42).name("uri").value(relay.getUri()).build(); + final ElementAttribute relayAttribute = ElementAttribute.builder().name("uri").value(relay.getUri()).build(); relayAttributes.add(relayAttribute); - final BaseTag relayTag = new GenericTag("relay", 42, relayAttributes); + final BaseTag relayTag = new GenericTag("relay", relayAttributes); this.addTag(relayTag); } } 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 060cb685e..f0939850b 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 @@ -119,12 +119,12 @@ public GenericEvent(@NonNull PublicKey pubKey, @NonNull Kind kind, @NonNull List } public GenericEvent(@NonNull PublicKey pubKey, @NonNull Kind kind, @NonNull List tags, - @NonNull String content) { + @NonNull String content) { this(pubKey, kind.getValue(), tags, content); } public GenericEvent(@NonNull PublicKey pubKey, @NonNull Integer kind, @NonNull List tags, - @NonNull String content) { + @NonNull String content) { this.pubKey = pubKey; this.kind = Kind.valueOf(kind).getValue(); this.tags = tags; @@ -196,8 +196,13 @@ public boolean isSigned() { } @Override - public void addAttribute(ElementAttribute attribute) { - this.attributes.add(attribute); + public void addAttribute(ElementAttribute... attribute) { + addAttributes(List.of(attribute)); + } + + @Override + public void addAttributes(List attributes) { + this.attributes.addAll(attributes); } protected void validate() { diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java index c71a81b2a..c96d40e63 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java @@ -27,9 +27,6 @@ public class GenericMessage extends BaseMessage implements IGenericElement, IEle @JsonIgnore private final List attributes; - @JsonIgnore - private final Integer nip; - public GenericMessage(String command) { this(command, new ArrayList<>(), 1); } @@ -41,12 +38,16 @@ public GenericMessage(String command, Integer nip) { public GenericMessage(String command, List attributes, Integer nip) { super(command); this.attributes = attributes; - this.nip = nip; } @Override - public void addAttribute(ElementAttribute attribute) { - this.attributes.add(attribute); + public void addAttribute(ElementAttribute... attribute) { + addAttributes(List.of(attribute)); + } + + @Override + public void addAttributes(List attributes) { + this.attributes.addAll(attributes); } @Override diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java index f66e09ce1..c78112ab3 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java @@ -1,56 +1,54 @@ package nostr.event.impl; -import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NonNull; import nostr.base.ElementAttribute; import nostr.base.IGenericElement; import nostr.event.BaseTag; -import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; /** * @author squirrel */ @Data @EqualsAndHashCode(callSuper = false) -@AllArgsConstructor public class GenericTag extends BaseTag implements IGenericElement { private final String code; - @JsonIgnore - @EqualsAndHashCode.Exclude - private final Integer nip; - private final List attributes; - public GenericTag(String code) { - this(code, 1); + public GenericTag(@NonNull String code, @NonNull ElementAttribute... attribute) { + this(code, List.of(attribute)); + } + + public GenericTag(@NonNull String code, @NonNull List attributes) { + this.code = code; + this.attributes = attributes; } - public GenericTag(String code, Integer nip) { - this(code, nip, new ArrayList<>()); + @Override + public void addAttribute(@NonNull ElementAttribute... attribute) { + this.addAttributes(List.of(attribute)); } @Override - public void addAttribute(ElementAttribute attribute) { - this.attributes.add(attribute); + public void addAttributes(@NonNull List attributes) { + this.attributes.addAll(attributes); } - public static GenericTag create(String code, Integer nip, String... params) { + public static GenericTag create(@NonNull String code, Integer nip, @NonNull String... params) { return create(code, nip, List.of(params)); } - public static GenericTag create(String code, Integer nip, List params) { - List attributes = new ArrayList<>(); - for (int i = 0; i < params.size(); i++) { - String name = "param" + i; - var p = params.get(i); - attributes.add(i, ElementAttribute.builder().name(name).value(p).build()); - } - return new GenericTag(code, nip, attributes); + public static GenericTag create(@NonNull String code, Integer nip, @NonNull List params) { + return new GenericTag(code, + IntStream.range(0, params.size()) + .mapToObj(i -> + new ElementAttribute("param".concat(String.valueOf(i)), params.get(i))) + .toList()); } -} \ No newline at end of file +} 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 3f6724408..3b8368f0c 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 @@ -2,12 +2,12 @@ import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; +import lombok.NonNull; import nostr.base.ElementAttribute; import nostr.base.IDecoder; import nostr.event.impl.GenericTag; -import java.util.ArrayList; -import java.util.List; +import java.util.stream.IntStream; import static nostr.base.IEvent.MAPPER_AFTERBURNER; @@ -17,25 +17,26 @@ public class GenericTagDecoder implements IDecoder { private final Class clazz; public GenericTagDecoder() { - this.clazz = (Class) GenericTag.class; + this((Class) GenericTag.class); + } + + public GenericTagDecoder(@NonNull Class clazz) { + this.clazz = clazz; } @Override - public T decode(String json) { + public T decode(@NonNull String json) { try { String[] jsonElements = MAPPER_AFTERBURNER.readValue(json, String[].class); - - String code = jsonElements[0]; - - List attributes = new ArrayList<>(); - for (int i = 1; i < jsonElements.length; i++) { - ElementAttribute attribute = new ElementAttribute("param"+(i-1), jsonElements[i], null); - if (!attributes.contains(attribute)) { - attributes.add(attribute); - } - } - - return (T) new GenericTag(code, null, attributes); + GenericTag genericTag = new GenericTag( + jsonElements[0], // index 0 designated as generic tag's "code" + IntStream.of(0, jsonElements.length) + .mapToObj(i -> + new ElementAttribute( + "param".concat(String.valueOf(i)), + jsonElements[i])) + .toList()); + return (T) genericTag; } catch (JsonProcessingException ex) { throw new RuntimeException(ex); } 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 4d1a2f95b..63374589b 100644 --- a/nostr-java-id/src/test/java/nostr/id/EntityFactory.java +++ b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java @@ -121,14 +121,14 @@ public static GenericTag createGenericTag(PublicKey publicKey) { public static GenericTag createGenericTag(PublicKey publicKey, IEvent event) { GenericTag tag = new GenericTag("devil"); - tag.addAttribute(ElementAttribute.builder().name("param0").value("Lucifer").nip(666).build()); + tag.addAttribute(ElementAttribute.builder().name("param0").value("Lucifer").build()); ((GenericEvent) event).addTag(tag); return tag; } public static GenericTag createGenericTag(PublicKey publicKey, IEvent event, Integer tagNip) { - GenericTag tag = new GenericTag("devil", tagNip); - tag.addAttribute(ElementAttribute.builder().name("param0").value("Lucifer").nip(666).build()); + GenericTag tag = new GenericTag("devil"); + tag.addAttribute(ElementAttribute.builder().name("param0").value("Lucifer").build()); ((GenericEvent) event).addTag(tag); return tag; } 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 6bfd93da3..74008d3a4 100644 --- a/nostr-java-id/src/test/java/nostr/id/EventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/EventTest.java @@ -55,10 +55,6 @@ public void testCreateGenericTag() { Relay relay = new Relay("wss://secret.relay.com"); relay.addNipSupport(1); relay.addNipSupport(genericTag.getNip()); - var attrs = genericTag.getAttributes(); - for (var a : attrs) { - relay.addNipSupport(a.getNip()); - } var encoder = new BaseTagEncoder(genericTag, relay); var strJsonEvent = encoder.encode(); From 9575ddaa0539e049e392f1fca086bb9e713fcdd7 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 20 Mar 2025 13:06:51 -0700 Subject: [PATCH 52/57] test spec update --- nostr-java-base/build.gradle | 5 ----- nostr-java-client/build.gradle | 5 ----- nostr-java-crypto/build.gradle | 5 ----- nostr-java-encryption/build.gradle | 5 ----- nostr-java-event/build.gradle | 5 ----- nostr-java-id/build.gradle | 5 ----- nostr-java-util/build.gradle | 5 ----- 7 files changed, 35 deletions(-) diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle index 611fbfafb..03572bb8c 100644 --- a/nostr-java-base/build.gradle +++ b/nostr-java-base/build.gradle @@ -8,8 +8,3 @@ dependencies { api project(':nostr-java-util') api project(':nostr-java-crypto') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-client/build.gradle b/nostr-java-client/build.gradle index c10e34293..95517328c 100644 --- a/nostr-java-client/build.gradle +++ b/nostr-java-client/build.gradle @@ -7,8 +7,3 @@ description = 'nostr-java-client' dependencies { api project(':nostr-java-id') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-crypto/build.gradle b/nostr-java-crypto/build.gradle index 182bfc48f..3e57327eb 100644 --- a/nostr-java-crypto/build.gradle +++ b/nostr-java-crypto/build.gradle @@ -7,8 +7,3 @@ description = 'nostr-java-crypto' dependencies { api project(':nostr-java-util') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-encryption/build.gradle b/nostr-java-encryption/build.gradle index 2a7330940..69bddf914 100644 --- a/nostr-java-encryption/build.gradle +++ b/nostr-java-encryption/build.gradle @@ -8,8 +8,3 @@ dependencies { api project(':nostr-java-crypto') api project(':nostr-java-util') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-event/build.gradle b/nostr-java-event/build.gradle index 577f71f11..2c195373f 100644 --- a/nostr-java-event/build.gradle +++ b/nostr-java-event/build.gradle @@ -7,8 +7,3 @@ description = 'nostr-java-event' dependencies { api project(':nostr-java-base') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-id/build.gradle b/nostr-java-id/build.gradle index fe382889e..1d3aa7720 100644 --- a/nostr-java-id/build.gradle +++ b/nostr-java-id/build.gradle @@ -7,8 +7,3 @@ description = 'nostr-java-id' dependencies { api project(':nostr-java-event') } - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} diff --git a/nostr-java-util/build.gradle b/nostr-java-util/build.gradle index bac6ec2b6..d6be2576a 100644 --- a/nostr-java-util/build.gradle +++ b/nostr-java-util/build.gradle @@ -3,8 +3,3 @@ plugins { } description = 'nostr-java-util' - -tasks.named('test') { - systemProperty("spring.profiles.active", "test") - useJUnitPlatform() -} From e7b49945a53358d667cbf94a5f56a9cab8a32867 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 20 Mar 2025 16:03:37 -0700 Subject: [PATCH 53/57] ongoing, snapshot prior to removing IElement interface dependency --- gradle.properties | 1 + .../nostr/api/integration/ApiEventIT.java | 20 ++++----- .../api/integration/ApiNIP52RequestIT.java | 14 +++---- .../api/integration/ApiNIP99EventIT.java | 4 +- .../api/integration/ApiNIP99RequestIT.java | 4 +- .../api/unit/CalendarTimeBasedEventTest.java | 6 +-- .../java/nostr/api/unit/NIP52ImplTest.java | 18 ++++---- .../java/nostr/api/unit/NIP99ImplTest.java | 4 +- .../src/main/java/nostr/base/IElement.java | 5 ++- .../main/java/nostr/event/BaseMessage.java | 5 --- .../src/main/java/nostr/event/BaseTag.java | 5 --- .../java/nostr/event/impl/GenericEvent.java | 4 +- .../java/nostr/event/impl/GenericTag.java | 42 +++++++++++++++++-- .../event/json/codec/BaseTagEncoder.java | 20 ++++----- .../event/json/codec/GenericTagDecoder.java | 2 +- .../event/json/serializer/TagSerializer.java | 4 +- .../java/nostr/event/unit/BaseTagTest.java | 14 +------ .../nostr/id/ClassifiedListingEventTest.java | 8 ++-- .../src/test/java/nostr/id/EntityFactory.java | 6 +++ .../src/test/java/nostr/id/EventTest.java | 6 +-- 20 files changed, 104 insertions(+), 88 deletions(-) diff --git a/gradle.properties b/gradle.properties index 129650918..40e91dec1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,6 +3,7 @@ org.gradle.daemon=true org.gradle.caching=true org.gradle.parallel=true #createReports=true +org.gradle.warning.mode=none nostr-java.group=xyz.tcheeric nostr-java.version=0.6.5-SNAPSHOT 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 531a32c21..7cc37d63b 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 @@ -183,7 +183,7 @@ public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException { System.out.println("testNIP01SendTextNoteEventCustomGenericTag"); String targetString = "custom-generic-tag-testNIP01SendTextNoteEventCustomGenericTag"; - GenericTag genericTag = GenericTag.create("m", 1, targetString); + GenericTag genericTag = GenericTag.create("m", targetString); NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); nip01.createTextNoteEvent(List.of(genericTag), "Custom Generic Tag Test testNIP01SendTextNoteEventCustomGenericTag").signAndSend(relays); @@ -212,7 +212,7 @@ public void testFiltersListReturnSameSingularEvent() throws IOException { GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); String genericTagTarget = "generic-tag-value_SameSingularEvent"; - GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); + GenericTag genericTag = GenericTag.create("m", genericTagTarget); NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); @@ -240,7 +240,7 @@ public void testFiltersListReturnTwoDifferentEvents() throws IOException { String geoHashTagTarget1 = "geohash_tag-location-1"; GeohashTag geohashTag1 = new GeohashTag(geoHashTagTarget1); String genericTagTarget1 = "generic-tag-value-1"; - GenericTag genericTag1 = GenericTag.create("m", 1, genericTagTarget1); + GenericTag genericTag1 = GenericTag.create("m", genericTagTarget1); NIP01 nip01_1 = new NIP01<>(Identity.generateRandomIdentity()); nip01_1.createTextNoteEvent(List.of(geohashTag1, genericTag1), "Multiple Filters 1").signAndSend(relays); @@ -248,7 +248,7 @@ public void testFiltersListReturnTwoDifferentEvents() throws IOException { String geoHashTagTarget2 = "geohash_tag-location-2"; GeohashTag geohashTag2 = new GeohashTag(geoHashTagTarget2); String genericTagTarget2 = "generic-tag-value-2"; - GenericTag genericTag2 = GenericTag.create("m", 1, genericTagTarget2); + GenericTag genericTag2 = GenericTag.create("m", genericTagTarget2); NIP01 nip01_2 = new NIP01<>(Identity.generateRandomIdentity()); nip01_2.createTextNoteEvent(List.of(geohashTag2, genericTag2), "Multiple Filters 2").signAndSend(relays); @@ -277,7 +277,7 @@ public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOExceptio GeohashTag geohashTag = new GeohashTag(geoHashTagTarget); String genericTagTarget = "generic-tag-value-DifferentTypesReturnSameEvent"; - GenericTag genericTag = GenericTag.create("m", 1, genericTagTarget); + GenericTag genericTag = GenericTag.create("m", genericTagTarget); NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity()); nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays); @@ -448,8 +448,8 @@ public void testNIP32CreateLabel1() { assertEquals("l", label.getCode()); assertEquals(2, label.getAttributes().size()); - assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english"))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages"))); } @Test @@ -463,9 +463,9 @@ public void testNIP32CreateLabel2() { assertEquals("l", label.getCode()); assertEquals(3, label.getAttributes().size()); - assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages", 32))); - assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}", 32)), + assertTrue(label.getAttributes().contains(new ElementAttribute("param0", "english"))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages"))); + assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}")), "{\\\"article\\\":\\\"the\\\"}"); } 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 281bdaa8a..c12167a27 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 @@ -86,13 +86,13 @@ void testNIP99CalendarContentPreRequest() throws IOException { tags.add(E_TAG); tags.add(P1_TAG); tags.add(P2_TAG); - tags.add(GenericTag.create(START_TZID_CODE, 52, START_TZID)); - tags.add(GenericTag.create(END_TZID_CODE, 52, END_TZID)); - tags.add(GenericTag.create(SUMMARY_CODE, 52, SUMMARY)); - tags.add(GenericTag.create(LABEL_CODE, 52, LABEL_1)); - tags.add(GenericTag.create(LABEL_CODE, 52, LABEL_2)); - tags.add(GenericTag.create(LOCATION_CODE, 52, LOCATION)); - tags.add(GenericTag.create(END_CODE, 52, END)); + tags.add(GenericTag.create(START_TZID_CODE, START_TZID)); + tags.add(GenericTag.create(END_TZID_CODE, END_TZID)); + tags.add(GenericTag.create(SUMMARY_CODE, SUMMARY)); + tags.add(GenericTag.create(LABEL_CODE, LABEL_1)); + tags.add(GenericTag.create(LABEL_CODE, LABEL_2)); + tags.add(GenericTag.create(LOCATION_CODE, LOCATION)); + tags.add(GenericTag.create(END_CODE, END)); tags.add(G_TAG); tags.add(T_TAG); tags.add(R_TAG); 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 a7249751d..04197533b 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 @@ -66,8 +66,8 @@ void testNIP99ClassifiedListingEvent() throws IOException { List tags = new ArrayList<>(); tags.add(E_TAG); tags.add(P_TAG); - tags.add(GenericTag.create(PUBLISHED_AT_CODE, 99, CLASSIFIED_LISTING_PUBLISHED_AT)); - tags.add(GenericTag.create(LOCATION_CODE, 99, CLASSIFIED_LISTING_LOCATION)); + tags.add(GenericTag.create(PUBLISHED_AT_CODE, CLASSIFIED_LISTING_PUBLISHED_AT)); + tags.add(GenericTag.create(LOCATION_CODE, CLASSIFIED_LISTING_LOCATION)); tags.add(SUBJECT_TAG); tags.add(G_TAG); tags.add(T_TAG); 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 bf3908c68..70c5255f1 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 @@ -73,8 +73,8 @@ void testNIP99ClassifiedListingPreRequest() throws IOException { List tags = new ArrayList<>(); tags.add(E_TAG); tags.add(P_TAG); - tags.add(GenericTag.create(PUBLISHED_AT_CODE, 99, CREATED_AT)); - tags.add(GenericTag.create(LOCATION_CODE, 99, LOCATION)); + tags.add(GenericTag.create(PUBLISHED_AT_CODE, CREATED_AT)); + tags.add(GenericTag.create(LOCATION_CODE, LOCATION)); tags.add(SUBJECT_TAG); tags.add(G_TAG); tags.add(T_TAG); 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 86b7adc2f..9a2266c30 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 @@ -73,13 +73,13 @@ void setup() throws URISyntaxException { List tags = new ArrayList<>(); tags.add(P_1_TAG); tags.add(P_2_TAG); - tags.add(GenericTag.create(LOCATION_CODE, 52, CALENDAR_TIME_BASED_EVENT_LOCATION)); + tags.add(GenericTag.create(LOCATION_CODE, CALENDAR_TIME_BASED_EVENT_LOCATION)); tags.add(SUBJECT_TAG); tags.add(G_TAG); tags.add(T_TAG); - tags.add(GenericTag.create(START_TZID_CODE, 52, CALENDAR_TIME_BASED_EVENT_START_TZID)); + tags.add(GenericTag.create(START_TZID_CODE, CALENDAR_TIME_BASED_EVENT_START_TZID)); Long l = START + 100L; - tags.add(GenericTag.create(END_CODE, 52, l.toString())); + tags.add(GenericTag.create(END_CODE, l.toString())); CalendarContent calendarContent = CalendarContent.builder(identifierTag, CALENDAR_TIME_BASED_EVENT_TITLE, START) .build(); 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 9db1e284a..034148118 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,14 +1,5 @@ package nostr.api.unit; -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.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - import nostr.api.NIP52; import nostr.base.PublicKey; import nostr.event.BaseTag; @@ -21,6 +12,13 @@ import nostr.event.tag.PubKeyTag; import nostr.event.tag.SubjectTag; import nostr.id.Identity; +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.*; class NIP52ImplTest { public static final String TIME_BASED_EVENT_CONTENT = "CalendarTimeBasedEvent unit test content"; @@ -104,6 +102,6 @@ void testNIP52CreateTimeBasedCalendarCalendarEventWithAllOptionalParameters() { } private GenericTag containsGeneric(String key, String value) { - return GenericTag.create(key, 52, value); + return GenericTag.create(key, value); } } 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 d9ae63031..284e06766 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 @@ -96,7 +96,7 @@ void testNIP99CreateClassifiedListingEventWithDuplicateParameters() { classifiedListing.setLocation(LOCATION); classifiedListing.setPublishedAt(PUBLISHED_AT); - baseTags.add(GenericTag.create("published_at", 99, String.valueOf(PUBLISHED_AT))); + baseTags.add(GenericTag.create("published_at", String.valueOf(PUBLISHED_AT))); ClassifiedListingEvent instance = nip99.createClassifiedListingEvent(baseTags, CONTENT, classifiedListing).getEvent(); instance.update(); @@ -114,6 +114,6 @@ void testNIP99CreateClassifiedListingEventNullParameters() { } private GenericTag containsGeneric(String key, String value) { - return GenericTag.create(key, 99, value); + return GenericTag.create(key, value); } } diff --git a/nostr-java-base/src/main/java/nostr/base/IElement.java b/nostr-java-base/src/main/java/nostr/base/IElement.java index 514ea4556..a2b9daa1b 100644 --- a/nostr-java-base/src/main/java/nostr/base/IElement.java +++ b/nostr-java-base/src/main/java/nostr/base/IElement.java @@ -6,6 +6,7 @@ */ public interface IElement { - Integer getNip(); - + default Integer getNip() { + return 1; + } } diff --git a/nostr-java-event/src/main/java/nostr/event/BaseMessage.java b/nostr-java-event/src/main/java/nostr/event/BaseMessage.java index a78aafcec..681b96178 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseMessage.java @@ -19,10 +19,5 @@ protected BaseMessage(String command) { this.command = command; } - @Override - public Integer getNip() { - return 1; - } - public abstract String encode() throws JsonProcessingException; } 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 fed63fdf4..5c0aaff75 100644 --- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java +++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java @@ -51,11 +51,6 @@ public String getCode() { return this.getClass().getAnnotation(Tag.class).code(); } - @Override - public Integer getNip() { - return 1; - } - public String getFieldValue(Field field) throws NostrException { try { Object f = new PropertyDescriptor(field.getName(), this.getClass()).getReadMethod().invoke(this); 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 f0939850b..59098896d 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 @@ -258,10 +258,10 @@ protected void addStandardTag(BaseTag tag) { } protected void addGenericTag(String key, Integer nip, Object value) { - Optional.ofNullable(value).ifPresent(s -> addTag(GenericTag.create(key, nip, s.toString()))); + Optional.ofNullable(value).ifPresent(s -> addTag(GenericTag.create(key, s.toString()))); } protected void addStringListTag(String label, Integer nip, List tag) { - Optional.ofNullable(tag).ifPresent(tagList -> addGenericTag(label, nip, tagList)); + Optional.ofNullable(tag).ifPresent(tagList -> GenericTag.create(label, tagList)); } } diff --git a/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java index c78112ab3..3148f8a59 100644 --- a/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java +++ b/nostr-java-event/src/main/java/nostr/event/impl/GenericTag.java @@ -7,6 +7,7 @@ import nostr.base.IGenericElement; import nostr.event.BaseTag; +import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -21,6 +22,20 @@ public class GenericTag extends BaseTag implements IGenericElement { private final List attributes; + public GenericTag(String code) { + this(code, new ArrayList<>()); + } + + /** + * nip parameter to be removed + * + * @deprecated use any available proper constructor variant instead + */ + @Deprecated(forRemoval = true) + public GenericTag(String code, Integer nip) { + this(code, new ArrayList<>()); + } + public GenericTag(@NonNull String code, @NonNull ElementAttribute... attribute) { this(code, List.of(attribute)); } @@ -40,11 +55,32 @@ public void addAttributes(@NonNull List attributes) { this.attributes.addAll(attributes); } - public static GenericTag create(@NonNull String code, Integer nip, @NonNull String... params) { - return create(code, nip, List.of(params)); + /** + * nip parameter to be removed + * + * @deprecated use {@link #create(String, String...)} instead. + */ + @Deprecated(forRemoval = true) + public static GenericTag create(String code, Integer nip, String... params) { + return create(code, List.of(params)); + } + + /** + * nip parameter to be removed + * + * @deprecated use {@link #create(String, List)} instead. + */ + + @Deprecated(forRemoval = true) + public static GenericTag create(String code, Integer nip, List params) { + return create(code, params); + } + + public static GenericTag create(@NonNull String code, @NonNull String... params) { + return create(code, List.of(params)); } - public static GenericTag create(@NonNull String code, Integer nip, @NonNull List params) { + public static GenericTag create(@NonNull String code, @NonNull List params) { return new GenericTag(code, IntStream.range(0, params.size()) .mapToObj(i -> diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java index d25a62e85..71eeefce2 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java @@ -1,37 +1,33 @@ package nostr.event.json.codec; -import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; import nostr.base.Encoder; -import nostr.base.Relay; import nostr.event.BaseTag; import nostr.event.json.serializer.TagSerializer; @Data -@AllArgsConstructor public class BaseTagEncoder implements Encoder { + public static final ObjectMapper BASETAGENCODER_MAPPED_AFTERBURNER = + ENCODER_MAPPED_AFTERBURNER.copy() + .registerModule( + new SimpleModule().addSerializer( + new TagSerializer())); private final BaseTag tag; - private final Relay relay; public BaseTagEncoder(@NonNull BaseTag tag) { - this(tag, null); + this.tag = tag; } @Override public String encode() { try { -// TODO: revisit below using afterburner alternative - SimpleModule module = new SimpleModule(); - module.addSerializer(new TagSerializer()); - return (new ObjectMapper()) - .setSerializationInclusion(Include.NON_NULL) - .registerModule(module).writeValueAsString(tag); + String s = BASETAGENCODER_MAPPED_AFTERBURNER.writeValueAsString(tag); + return s; } catch (JsonProcessingException e) { throw new RuntimeException(e); } 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 3b8368f0c..32d8546d7 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 @@ -29,7 +29,7 @@ public T decode(@NonNull String json) { try { String[] jsonElements = MAPPER_AFTERBURNER.readValue(json, String[].class); GenericTag genericTag = new GenericTag( - jsonElements[0], // index 0 designated as generic tag's "code" + jsonElements[0], // value at index 0 designated as generic tag's "code" IntStream.of(0, jsonElements.length) .mapToObj(i -> new ElementAttribute( 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 9c40e03e4..f3619a65f 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 @@ -16,6 +16,8 @@ import java.lang.reflect.Field; import java.util.List; +import static nostr.event.json.codec.BaseTagEncoder.BASETAGENCODER_MAPPED_AFTERBURNER; + /** * @author guilhermegps * @@ -33,7 +35,7 @@ public TagSerializer() { public void serialize(BaseTag value, JsonGenerator gen, SerializerProvider serializers) { try { // -- Create the node - final ObjectNode node = new ObjectNode(JsonNodeFactory.instance); + final ObjectNode node = BASETAGENCODER_MAPPED_AFTERBURNER.getNodeFactory().objectNode(); List fields = value.getSupportedFields(); // Populate the node with the fields data 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 c6d8bb8d8..62563d1d3 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 @@ -8,21 +8,11 @@ class BaseTagTest { - BaseTag genericTag = GenericTag.create("id", 1, "value"); - - @Test - void getNip() { - assertEquals(1, genericTag.getNip()); - } - - @Test - void testHashCode() { - assertEquals(112174237, genericTag.hashCode()); - } + BaseTag genericTag = GenericTag.create("id", "value"); @Test void testToString() { - String result = "GenericTag(code=id, nip=1, attributes=[ElementAttribute(name=param0, value=value, nip=null)])"; + String result = "GenericTag(code=id, nip=1, attributes=[ElementAttribute(name=param0, value=value)])"; assertEquals(result, genericTag.toString()); } 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 f8d65670e..baad1eb9f 100644 --- a/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/ClassifiedListingEventTest.java @@ -58,10 +58,10 @@ void setup() { List tags = new ArrayList<>(); tags.add(E_TAG); tags.add(P_TAG); - tags.add(GenericTag.create(TITLE_CODE, 99, CLASSIFIED_LISTING_TITLE)); - tags.add(GenericTag.create(SUMMARY_CODE, 99, CLASSIFIED_LISTING_SUMMARY)); - tags.add(GenericTag.create(PUBLISHED_AT_CODE, 99, CLASSIFIED_LISTING_PUBLISHED_AT)); - tags.add(GenericTag.create(LOCATION_CODE, 99, CLASSIFIED_LISTING_LOCATION)); + tags.add(GenericTag.create(TITLE_CODE, CLASSIFIED_LISTING_TITLE)); + tags.add(GenericTag.create(SUMMARY_CODE, CLASSIFIED_LISTING_SUMMARY)); + tags.add(GenericTag.create(PUBLISHED_AT_CODE, CLASSIFIED_LISTING_PUBLISHED_AT)); + tags.add(GenericTag.create(LOCATION_CODE, CLASSIFIED_LISTING_LOCATION)); tags.add(SUBJECT_TAG); tags.add(G_TAG); tags.add(T_TAG); 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 63374589b..66173ac1a 100644 --- a/nostr-java-id/src/test/java/nostr/id/EntityFactory.java +++ b/nostr-java-id/src/test/java/nostr/id/EntityFactory.java @@ -126,6 +126,12 @@ public static GenericTag createGenericTag(PublicKey publicKey, IEvent event) { return tag; } + /** + * @param tagNip parameter to be removed + * + * @deprecated use {@link #createGenericTag(PublicKey, IEvent)} instead. + */ + @Deprecated(forRemoval = true) public static GenericTag createGenericTag(PublicKey publicKey, IEvent event, Integer tagNip) { GenericTag tag = new GenericTag("devil"); tag.addAttribute(ElementAttribute.builder().name("param0").value("Lucifer").build()); 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 74008d3a4..9292ba99d 100644 --- a/nostr-java-id/src/test/java/nostr/id/EventTest.java +++ b/nostr-java-id/src/test/java/nostr/id/EventTest.java @@ -52,11 +52,7 @@ public void testCreateGenericTag() { PublicKey publicKey = Identity.generateRandomIdentity().getPublicKey(); GenericTag genericTag = EntityFactory.Events.createGenericTag(publicKey); - Relay relay = new Relay("wss://secret.relay.com"); - relay.addNipSupport(1); - relay.addNipSupport(genericTag.getNip()); - - var encoder = new BaseTagEncoder(genericTag, relay); + var encoder = new BaseTagEncoder(genericTag); var strJsonEvent = encoder.encode(); assertDoesNotThrow(() -> { From b626d5c5114616940909a8bcc0c8015772d3db2a Mon Sep 17 00:00:00 2001 From: nick avlo Date: Thu, 20 Mar 2025 20:03:50 -0700 Subject: [PATCH 54/57] distinct stream for generic tag decoder --- .../event/json/codec/GenericTagDecoder.java | 16 +++++++--------- .../test/java/nostr/event/unit/BaseTagTest.java | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) 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 32d8546d7..d65ba7c22 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 @@ -9,8 +9,6 @@ import java.util.stream.IntStream; -import static nostr.base.IEvent.MAPPER_AFTERBURNER; - @Data public class GenericTagDecoder implements IDecoder { @@ -27,14 +25,14 @@ public GenericTagDecoder(@NonNull Class clazz) { @Override public T decode(@NonNull String json) { try { - String[] jsonElements = MAPPER_AFTERBURNER.readValue(json, String[].class); + String[] jsonElements = I_DECODER_MAPPER_AFTERBURNER.readValue(json, String[].class); GenericTag genericTag = new GenericTag( - jsonElements[0], // value at index 0 designated as generic tag's "code" - IntStream.of(0, jsonElements.length) - .mapToObj(i -> - new ElementAttribute( - "param".concat(String.valueOf(i)), - jsonElements[i])) + jsonElements[0], + IntStream.of(1, jsonElements.length-1) + .mapToObj(i -> new ElementAttribute( + "param".concat(String.valueOf(i - 1)), + jsonElements[i])) + .distinct() .toList()); return (T) genericTag; } catch (JsonProcessingException ex) { 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 62563d1d3..e4548c451 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 @@ -12,7 +12,7 @@ class BaseTagTest { @Test void testToString() { - String result = "GenericTag(code=id, nip=1, attributes=[ElementAttribute(name=param0, value=value)])"; + String result = "GenericTag(code=id, attributes=[ElementAttribute(name=param0, value=value)])"; assertEquals(result, genericTag.toString()); } From 5767829fa72d8cf9ca218cf8a9d0e1d96d22170f Mon Sep 17 00:00:00 2001 From: nick avlo Date: Sat, 22 Mar 2025 23:25:14 -0700 Subject: [PATCH 55/57] add maven retyr --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 59ab17bd1..9f2ae4beb 100644 --- a/pom.xml +++ b/pom.xml @@ -291,6 +291,9 @@ integration-test verify + + 1 + From 9282d44ea61ca92aa5ec58ea61bbaa808c0e9a97 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 26 Mar 2025 01:38:03 -0700 Subject: [PATCH 56/57] differentiate gradle test/check phases. pom maven retry=1 --- .../main/groovy/nostr-java.conventions.gradle | 7 ++- nostr-java-api/build.gradle | 20 ++++++++ pom.xml | 49 +++++++------------ 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle index cfa437d7a..b6e19f20b 100644 --- a/buildSrc/src/main/groovy/nostr-java.conventions.gradle +++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle @@ -72,7 +72,6 @@ dependencies { testImplementation 'org.awaitility:awaitility:' + awaitility testImplementation 'com.adarshr:gradle-test-logger-plugin:' + logger - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testAnnotationProcessor 'org.projectlombok:lombok:' + lombok } @@ -93,6 +92,12 @@ tasks.test { // } } +test { + filter { + excludeTestsMatching("nostr.api.integration.*"); + } +} + tasks.bootJar { enabled = false } diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle index c07288efb..6d8ec99ad 100644 --- a/nostr-java-api/build.gradle +++ b/nostr-java-api/build.gradle @@ -8,3 +8,23 @@ dependencies { api project(':nostr-java-client') api project(':nostr-java-encryption') } + +tasks.register('integrationTest', Test) { + description = 'api integration tests.' + group = 'verification' + systemProperty("spring.profiles.active", "test") + useJUnitPlatform() + filter { + excludeTestsMatching("nostr.api.unit.*"); + includeTestsMatching("nostr.api.integration.*"); + } +} + +integrationTest { + retry { + failOnPassedAfterRetry = false + maxRetries = 1 + } +} + +check.dependsOn integrationTest diff --git a/pom.xml b/pom.xml index 9f2ae4beb..5de38fe04 100644 --- a/pom.xml +++ b/pom.xml @@ -248,11 +248,26 @@ org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} + + + + test + + + org.jacoco jacoco-maven-plugin ${jacoco-maven-plugin.version} + + + + prepare-agent + report + + + org.apache.maven.plugins @@ -264,6 +279,9 @@ integration-test verify + + 1 + @@ -274,49 +292,18 @@ maven-surefire-plugin ${maven-surefire-plugin.version} - - - - test - - - maven-failsafe-plugin ${maven-failsafe-plugin.version} - - - - integration-test - verify - - - 1 - - - org.jacoco jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - - prepare-agent - report - - - org.apache.maven.plugins maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - From d9f402f4aff00c2aeb38c7fae52d408f119369d7 Mon Sep 17 00:00:00 2001 From: nick avlo Date: Wed, 26 Mar 2025 22:49:43 -0700 Subject: [PATCH 57/57] updated repo dependencies --- buildSrc/build.gradle | 1 - settings.gradle | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 53c70a4ad..1ee59078a 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -14,7 +14,6 @@ group = 'xyz.tcheeric' version = '0.6.5-SNAPSHOT' repositories { - gradlePluginPortal() mavenCentral() gradlePluginPortal { url = 'https://plugins.gradle.org/m2/' diff --git a/settings.gradle b/settings.gradle index 8fe1e2175..6f73d74f1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,6 @@ buildscript { repositories { - maven { + gradlePluginPortal { url = 'https://plugins.gradle.org/m2/' } }