From 4cb59a4ebd6fcc98129f10fa88a99bdfb6a208c0 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 21 Dec 2024 18:57:44 +0000 Subject: [PATCH 1/8] Version 0.6.4-SNAPSHOT --- nostr-java-api/pom.xml | 2 +- .../src/main/java/nostr/api/NIP60.java | 1 - nostr-java-base/pom.xml | 2 +- nostr-java-client/pom.xml | 2 +- .../client/{Client.java => AsyncClient.java} | 8 +++--- nostr-java-command-interface/pom.xml | 2 +- nostr-java-command-provider/pom.xml | 2 +- nostr-java-connection/pom.xml | 2 +- nostr-java-context-interface/pom.xml | 2 +- nostr-java-context/pom.xml | 3 +-- nostr-java-controller/pom.xml | 2 +- nostr-java-crypto/pom.xml | 2 +- nostr-java-encryption-nip04/pom.xml | 2 +- nostr-java-encryption-nip44/pom.xml | 2 +- nostr-java-encryption/pom.xml | 2 +- nostr-java-event/pom.xml | 2 +- .../src/main/java/nostr/event/Kind.java | 13 ++++++++++ nostr-java-examples/pom.xml | 2 +- nostr-java-id/pom.xml | 3 +-- nostr-java-test/pom.xml | 3 +-- nostr-java-util/pom.xml | 2 +- pom.xml | 25 +++++++++++++++++-- 22 files changed, 58 insertions(+), 28 deletions(-) rename nostr-java-client/src/main/java/nostr/client/{Client.java => AsyncClient.java} (94%) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index 1277c3224..e26afd4eb 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-api jar 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 c013d5cf0..b6cf6b802 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP60.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP60.java @@ -27,7 +27,6 @@ import nostr.event.impl.GenericEvent; import nostr.event.impl.GenericTag; import nostr.event.json.codec.BaseTagEncoder; -import nostr.event.json.codec.GenericTagEncoder; import nostr.event.tag.EventTag; import nostr.id.Identity; diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 6ff5f6659..7a1f2e4b6 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-base diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 56164f1c3..7b8100c3a 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-client jar diff --git a/nostr-java-client/src/main/java/nostr/client/Client.java b/nostr-java-client/src/main/java/nostr/client/AsyncClient.java similarity index 94% rename from nostr-java-client/src/main/java/nostr/client/Client.java rename to nostr-java-client/src/main/java/nostr/client/AsyncClient.java index d1cc550f2..a7dcc4d4e 100644 --- a/nostr-java-client/src/main/java/nostr/client/Client.java +++ b/nostr-java-client/src/main/java/nostr/client/AsyncClient.java @@ -21,21 +21,21 @@ @Log @NoArgsConstructor -public class Client { +public class AsyncClient { private static class Holder { - private static final Client INSTANCE = new Client(); + private static final AsyncClient INSTANCE = new AsyncClient(); } private RequestContext context; private ConnectionPool connectionPool; - public static Client getInstance() { + public static AsyncClient getInstance() { return Holder.INSTANCE; } - public Client connect(@NonNull RequestContext context) throws TimeoutException { + public AsyncClient connect(@NonNull RequestContext context) throws TimeoutException { if (context instanceof DefaultRequestContext defaultRequestContext) { Holder.INSTANCE.context = context; connectionPool = ConnectionPool.getInstance(defaultRequestContext); diff --git a/nostr-java-command-interface/pom.xml b/nostr-java-command-interface/pom.xml index a42859beb..4de9c2ef1 100644 --- a/nostr-java-command-interface/pom.xml +++ b/nostr-java-command-interface/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-command-interface diff --git a/nostr-java-command-provider/pom.xml b/nostr-java-command-provider/pom.xml index 8ab9e4a0d..8215a7d5c 100644 --- a/nostr-java-command-provider/pom.xml +++ b/nostr-java-command-provider/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-command-provider diff --git a/nostr-java-connection/pom.xml b/nostr-java-connection/pom.xml index f27b6bfd8..1cb63adcd 100644 --- a/nostr-java-connection/pom.xml +++ b/nostr-java-connection/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-connection diff --git a/nostr-java-context-interface/pom.xml b/nostr-java-context-interface/pom.xml index f4393d987..b0ab878d8 100644 --- a/nostr-java-context-interface/pom.xml +++ b/nostr-java-context-interface/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-context-interface diff --git a/nostr-java-context/pom.xml b/nostr-java-context/pom.xml index 7204a1877..f76682f03 100644 --- a/nostr-java-context/pom.xml +++ b/nostr-java-context/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-context @@ -21,7 +21,6 @@ org.projectlombok lombok - ${lombok.version} ${project.groupId} diff --git a/nostr-java-controller/pom.xml b/nostr-java-controller/pom.xml index c5de9dd59..74ab632aa 100644 --- a/nostr-java-controller/pom.xml +++ b/nostr-java-controller/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-controller diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index bade534fb..3a022a345 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-crypto diff --git a/nostr-java-encryption-nip04/pom.xml b/nostr-java-encryption-nip04/pom.xml index c2dcce47a..ced97d6bf 100644 --- a/nostr-java-encryption-nip04/pom.xml +++ b/nostr-java-encryption-nip04/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-encryption-nip04 diff --git a/nostr-java-encryption-nip44/pom.xml b/nostr-java-encryption-nip44/pom.xml index aa83e53f4..bb95d4948 100644 --- a/nostr-java-encryption-nip44/pom.xml +++ b/nostr-java-encryption-nip44/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-encryption-nip44 diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index a236f3f18..169f58443 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-encryption diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 300bd9933..425b20931 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-event diff --git a/nostr-java-event/src/main/java/nostr/event/Kind.java b/nostr-java-event/src/main/java/nostr/event/Kind.java index a707003c4..2e1567ccf 100644 --- a/nostr-java-event/src/main/java/nostr/event/Kind.java +++ b/nostr-java-event/src/main/java/nostr/event/Kind.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; + import lombok.AllArgsConstructor; import lombok.Getter; @@ -35,6 +36,18 @@ public enum Kind { CLASSIFIED_LISTING(30_402, "classified_listing_active"), CLASSIFIED_LISTING_INACTIVE(30_403, "classified_listing_inactive"), CLASSIFIED_LISTING_DRAFT(30_403, "classified_listing_draft"), + + // NIP-60 + WALLET(37_375, "wallet"), + WALLET_UNSPENT_PROOF(7_375, "wallet_unspent_proof"), + WALLET_SPENDING_HISTORY(7_376, "wallet_spending_history"), + + // NIP-61 + NUTZAP_RECEIPT(7_376, "nutzap_receipt"), + NUTZAP(9_321, "nutzap"), + NUTZAP_INFO(10_019, "nutzap_info"), + + // Default UNDEFINED(-1, "undefined"); @JsonValue diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index a3a9b808f..ad1dfcf4d 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-examples diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 91d14cf86..f6dd1719b 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-id @@ -41,7 +41,6 @@ org.bouncycastle bcprov-jdk18on - ${bcprov-jdk18on.version} ${project.groupId} diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml index 97ed07e2c..dde59d4fa 100644 --- a/nostr-java-test/pom.xml +++ b/nostr-java-test/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-test @@ -106,7 +106,6 @@ org.jacoco jacoco-maven-plugin - ${jacoco-maven-plugin.version} one diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 96b8fe48e..055036fd6 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT nostr-java-util diff --git a/pom.xml b/pom.xml index 64aecdae2..a819b3d89 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT pom ${project.artifactId} @@ -21,7 +21,28 @@ - npub1llfht66qadyxv44q9rkmequztav07r2ufgd6ytl8w3wjs3ffa5yqy398ja + @tcheeric + + + @avlo + + + @guilhermegps + + + @devinbileck + + + @Memory-of-Snow + + + @austenjt + + + @maxbrito500 + + + @KoalaSat From 87a8661fdf2aa3ec3265df961e059d737562d9ac Mon Sep 17 00:00:00 2001 From: erict875 Date: Fri, 3 Jan 2025 18:07:14 +0000 Subject: [PATCH 2/8] Change the nip09 implementation to match the updates in the NIP --- .../src/main/java/nostr/api/NIP01.java | 78 ++++++---- .../src/main/java/nostr/api/NIP09.java | 69 ++++++--- .../src/main/java/nostr/api/NIP25.java | 68 +++++---- .../src/main/java/nostr/event/Deleteable.java | 6 + .../java/nostr/event/impl/GenericEvent.java | 31 ++-- .../main/java/nostr/event/tag/EventTag.java | 4 +- .../nostr/test/event/APINIP09EventTest.java | 140 ++++++++++++++++++ 7 files changed, 303 insertions(+), 93 deletions(-) create mode 100644 nostr-java-event/src/main/java/nostr/event/Deleteable.java create mode 100644 nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java diff --git a/nostr-java-api/src/main/java/nostr/api/NIP01.java b/nostr-java-api/src/main/java/nostr/api/NIP01.java index d0819dfc3..c91ccf304 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP01.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP01.java @@ -67,6 +67,7 @@ public NIP01 createTextNoteEvent(@NonNull String content) { return this; } + @Deprecated public NIP01 createTextNoteEvent(@NonNull Identity sender, @NonNull String content) { var event = new TextNoteEventFactory(sender, content).create(); this.setEvent((T) event); @@ -77,7 +78,7 @@ public NIP01 createTextNoteEvent(@NonNull Identity sender, @NonNull String co /** * Create a NIP01 text note event with tags * - * @param tags the note tags + * @param tags the note tags * @param content the content of the note * @return a text note event */ @@ -88,7 +89,8 @@ public NIP01 createTextNoteEvent(@NonNull List tags, @NonNull String public NIP01 createMetadataEvent(@NonNull UserProfile profile) { var sender = getSender(); - var event = (sender!=null) ? new MetadataEventFactory(sender, profile).create() : new MetadataEventFactory(profile).create(); + var event = (sender != null) ? new MetadataEventFactory(sender, profile).create() + : new MetadataEventFactory(profile).create(); this.setEvent((T) event); return this; @@ -96,7 +98,8 @@ public NIP01 createMetadataEvent(@NonNull UserProfile profile) { /** * Create a replaceable event - * @param kind the kind (10000 <= kind < 20000 || kind == 0 || kind == 3) + * + * @param kind the kind (10000 <= kind < 20000 || kind == 0 || kind == 3) * @param content the content */ public NIP01 createReplaceableEvent(@NonNull Integer kind, String content) { @@ -108,8 +111,9 @@ public NIP01 createReplaceableEvent(@NonNull Integer kind, String content) { /** * Create a replaceable event - * @param tags the note's tags - * @param kind the kind (10000 <= kind < 20000 || kind == 0 || kind == 3) + * + * @param tags the note's tags + * @param kind the kind (10000 <= kind < 20000 || kind == 0 || kind == 3) * @param content the note's content */ public NIP01 createReplaceableEvent(@NonNull List tags, @NonNull Integer kind, String content) { @@ -121,7 +125,8 @@ public NIP01 createReplaceableEvent(@NonNull List tags, @NonNull Int /** * Create an ephemeral event - * @param kind the kind (20000 <= n < 30000) + * + * @param kind the kind (20000 <= n < 30000) * @param content the note's content */ public NIP01 createEphemeralEvent(@NonNull Integer kind, String content) { @@ -144,11 +149,11 @@ public static EventTag createEventTag(@NonNull String relateEventId) { /** * Create a NIP01 event tag with additional recommended relay and marker * - * @param relateEventId the related event id + * @param relateEventId the related event id * @param recommendedRelayUrl the recommended relay - * @param marker the marker + * @param marker the marker * @return an event tag with the id of the related event and optional - * recommended relay and marker + * recommended relay and marker */ public static EventTag createEventTag(@NonNull String relateEventId, String recommendedRelayUrl, Marker marker) { var result = new EventTagFactory(relateEventId).create(); @@ -162,7 +167,7 @@ public static EventTag createEventTag(@NonNull String relateEventId, String reco * * @param publicKey the associated public key * @return a pubkey tag with the hex representation of the associated public - * key + * key */ public static PubKeyTag createPubKeyTag(@NonNull PublicKey publicKey) { return new PubKeyTagFactory(publicKey).create(); @@ -172,11 +177,11 @@ public static PubKeyTag createPubKeyTag(@NonNull PublicKey publicKey) { * Create a NIP01 pubkey tag with additional recommended relay and petname * (as defined in NIP02) * - * @param publicKey the associated public key + * @param publicKey the associated public key * @param mainRelayUrl the recommended relay - * @param petName the petname + * @param petName the petname * @return a pubkey tag with the hex representation of the associated public - * key and the optional recommended relay and petname + * key and the optional recommended relay and petname */ public static PubKeyTag createPubKeyTag(@NonNull PublicKey publicKey, String mainRelayUrl, String petName) { var result = new PubKeyTagFactory(publicKey).create(); @@ -188,24 +193,30 @@ public static PubKeyTag createPubKeyTag(@NonNull PublicKey publicKey, String mai /** * Create a NIP01 filters object (all parameters are optional) * - * @param events a list of event - * @param authors a list of pubkeys or prefixes, the pubkey of an event must - * be one of these - * @param kinds a list of a kind numbers + * @param events a list of event + * @param authors a list of pubkeys or prefixes, the pubkey of an event + * must + * be one of these + * @param kinds a list of a kind numbers * @param referencedEvents a list of event ids that are referenced in an "e" - * tag + * tag * @param referencePubKeys a list of pubkeys that are referenced in a "p" - * tag - * @param since an integer unix timestamp in seconds, events must be newer - * than this to pass - * @param until an integer unix timestamp in seconds, events must be older - * than this to pass - * @param limit maximum number of events to be returned in the initial query - * @param genericTagQuery a generic tag query + * tag + * @param since an integer unix timestamp in seconds, events must be + * newer + * than this to pass + * @param until an integer unix timestamp in seconds, events must be + * older + * than this to pass + * @param limit maximum number of events to be returned in the + * initial query + * @param genericTagQuery a generic tag query * @return a filters object */ @Deprecated(forRemoval = true) - public static Filters createFilters(List events, List authors, List kinds, List referencedEvents, List referencePubKeys, Long since, Long until, Integer limit, GenericTagQuery genericTagQuery) { + public static Filters createFilters(List events, List authors, List kinds, + List referencedEvents, List referencePubKeys, Long since, Long until, + Integer limit, GenericTagQuery genericTagQuery) { return Filters.builder() .authors(authors) .events(events) @@ -221,11 +232,10 @@ public static Filters createFilters(List events, List a .build(); } - /** * Create an event message to send events requested by clients * - * @param event the related event + * @param event the related event * @param subscriptionId the related subscription id * @return an event message */ @@ -237,7 +247,7 @@ public static EventMessage createEventMessage(@NonNull IEvent event, @NonNull St * Create a REQ message to request events and subscribe to new updates * * @param subscriptionId the subscription id - * @param filtersList the filters list + * @param filtersList the filters list * @return a REQ message */ public static ReqMessage createReqMessage(@NonNull String subscriptionId, @NonNull List filtersList) { @@ -294,7 +304,8 @@ public NIP01 createParameterizedReplaceableEvent(@NonNull Integer kind, Strin * @param comment * @return */ - public NIP01 createParameterizedReplaceableEvent(@NonNull List tags, @NonNull Integer kind, String comment) { + public NIP01 createParameterizedReplaceableEvent(@NonNull List tags, @NonNull Integer kind, + String comment) { var event = new ParameterizedReplaceableEventFactory(getSender(), tags, kind, comment).create(); this.setEvent((T) event); @@ -318,9 +329,12 @@ public static IdentifierTag createIdentifierTag(@NonNull String id) { * @param relay * @return */ - public static AddressTag createAddressTag(@NonNull Integer kind, @NonNull PublicKey publicKey, @NonNull IdentifierTag idTag, Relay relay) { + public static AddressTag createAddressTag(@NonNull Integer kind, @NonNull PublicKey publicKey, + IdentifierTag idTag, Relay relay) { var result = new AddressTagFactory(publicKey).create(); - result.setIdentifierTag(idTag); + if(idTag != null) { + result.setIdentifierTag(idTag); + } result.setKind(kind); result.setRelay(relay); return result; diff --git a/nostr-java-api/src/main/java/nostr/api/NIP09.java b/nostr-java-api/src/main/java/nostr/api/NIP09.java index c1859c7ff..1b0a69d8c 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP09.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP09.java @@ -1,15 +1,16 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package nostr.api; import lombok.NonNull; import nostr.api.factory.impl.NIP09Impl.DeletionEventFactory; import nostr.event.BaseTag; +import nostr.event.Deleteable; import nostr.event.NIP09Event; +import nostr.event.impl.GenericEvent; +import nostr.event.tag.AddressTag; +import nostr.event.tag.EventTag; import nostr.id.Identity; +import java.util.ArrayList; import java.util.List; /** @@ -17,21 +18,47 @@ * @author eric */ public class NIP09 extends EventNostr { - - public NIP09(@NonNull Identity sender) { - setSender(sender); - } - - /** - * Create a NIP09 Deletion Event - * - * @param tags list of event or address tags to be deleted - * @return the deletion event - */ - public NIP09 createDeletionEvent(@NonNull List tags) { - var event = new DeletionEventFactory(getSender(), tags).create(); - this.setEvent((T) event); - - return this; - } + + public NIP09(@NonNull Identity sender) { + setSender(sender); + } + + public NIP09 createDeletionEvent(@NonNull Deleteable deleteable) { + return this.createDeletionEvent(List.of(deleteable)); + } + + /** + * Create a NIP09 Deletion Event + * + * @param deleteables list of event or address tags to be deleted + * @return the deletion event + */ + public NIP09 createDeletionEvent(@NonNull List deleteables) { + List tags = new ArrayList<>(); + + // Handle GenericEvents + deleteables.stream() + .filter(d -> d instanceof GenericEvent) + .map(d -> (GenericEvent) d) + .forEach(event -> tags.add(new EventTag(event.getId()))); + + // Handle AddressTags + deleteables.stream() + .filter(d -> d instanceof GenericEvent) + .map(d -> (GenericEvent) d) + .map(GenericEvent::getTags) + .forEach(t -> t.stream() + .filter(tag -> "a".equals(tag.getCode())) + .forEach(addressTag -> { + tags.add(addressTag); + tags.add(NIP25.createKindTag(((AddressTag)addressTag).getKind())); + })); + + // Add kind tags for all deleteables + deleteables.forEach(d -> tags.add(NIP25.createKindTag(d.getKind()))); + + var event = new DeletionEventFactory(getSender(), tags).create(); + this.setEvent((T) event); + return this; + } } diff --git a/nostr-java-api/src/main/java/nostr/api/NIP25.java b/nostr-java-api/src/main/java/nostr/api/NIP25.java index 75488df69..c687d5c01 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP25.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP25.java @@ -5,11 +5,14 @@ package nostr.api; import lombok.NonNull; +import nostr.api.factory.TagFactory; import nostr.api.factory.impl.NIP25Impl.ReactionEventFactory; import nostr.event.BaseTag; import nostr.event.NIP25Event; import nostr.event.Reaction; import nostr.event.impl.GenericEvent; +import nostr.event.impl.GenericTag; +import nostr.event.impl.GenericTag; import nostr.event.tag.EmojiTag; import nostr.id.Identity; @@ -17,58 +20,71 @@ import java.util.List; public class NIP25 extends EventNostr { - - public NIP25(@NonNull Identity sender) { - setSender(sender); - } + + public NIP25(@NonNull Identity sender) { + setSender(sender); + } /** * Create a Reaction event - * @param event the related event to react to + * + * @param event the related event to react to * @param reaction */ public NIP25 createReactionEvent(@NonNull GenericEvent event, @NonNull Reaction reaction) { var e = new ReactionEventFactory(getSender(), event, reaction).create(); - this.setEvent((T) e); + this.setEvent((T) e); - return this; + return this; } - + /** * Create a NIP25 Reaction event to react to a specific event - * @param event the related event to react to + * + * @param event the related event to react to * @param content MAY be an emoji */ public NIP25 createReactionEvent(@NonNull GenericEvent event, @NonNull String content) { - var e = new ReactionEventFactory(getSender(), event, content).create(); - this.setEvent((T) e); + var e = new ReactionEventFactory(getSender(), event, content).create(); + this.setEvent((T) e); - return this; + return this; } /** * Create a NIP25 Reaction event to react to a specific event - * @param event the related event to react to + * + * @param event the related event to react to * @param emojiTag MUST be an costum emoji (NIP30) */ - public EventNostr createReactionEvent(@NonNull GenericEvent event,@NonNull EmojiTag emojiTag) { - var content = String.format(":%s:", emojiTag.getShortcode()); - var e = new ReactionEventFactory(getSender(), new ArrayList<>(List.of(emojiTag)), event, content).create(); - this.setEvent((T) e); + public EventNostr createReactionEvent(@NonNull GenericEvent event, @NonNull EmojiTag emojiTag) { + var content = String.format(":%s:", emojiTag.getShortcode()); + var e = new ReactionEventFactory(getSender(), new ArrayList<>(List.of(emojiTag)), event, content).create(); + this.setEvent((T) e); - return this; - } + return this; + } /** * Create a NIP25 Reaction event to react to several event and/or pubkeys - * @param tags the list of events or pubkeys to react to + * + * @param tags the list of events or pubkeys to react to * @param content MAY be an emoji */ public NIP25 createReactionEvent(@NonNull List tags, @NonNull String content) { - var e = new ReactionEventFactory(getSender(), tags, content).create(); - this.setEvent((T) e); + var e = new ReactionEventFactory(getSender(), tags, content).create(); + this.setEvent((T) e); - return this; + return this; + } + + /** + * Create the kind tag + * + * @param kind the kind + */ + public static GenericTag createKindTag(@NonNull Integer kind) { + return new TagFactory("k", 25, kind.toString()).create(); } /** @@ -86,7 +102,7 @@ public void like(@NonNull GenericEvent event) { public void dislike(@NonNull GenericEvent event) { react(event, Reaction.DISLIKE.getEmoji()); } - + /** * * @param event @@ -95,7 +111,7 @@ public void dislike(@NonNull GenericEvent event) { public void react(@NonNull GenericEvent event, @NonNull String reaction) { var e = new ReactionEventFactory(getSender(), event, reaction).create(); - this.setEvent((T) e); - this.sign().send(); + this.setEvent((T) e); + this.sign().send(); } } diff --git a/nostr-java-event/src/main/java/nostr/event/Deleteable.java b/nostr-java-event/src/main/java/nostr/event/Deleteable.java new file mode 100644 index 000000000..30dd9a611 --- /dev/null +++ b/nostr-java-event/src/main/java/nostr/event/Deleteable.java @@ -0,0 +1,6 @@ +package nostr.event; + +public interface Deleteable { + + Integer getKind(); +} 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 3e73b99bf..8dff22f9c 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,10 +1,20 @@ 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; @@ -21,21 +31,13 @@ import nostr.crypto.bech32.Bech32Prefix; import nostr.event.BaseEvent; import nostr.event.BaseTag; +import nostr.event.Deleteable; import nostr.event.Kind; import nostr.event.json.deserializer.PublicKeyDeserializer; import nostr.event.json.deserializer.SignatureDeserializer; import nostr.util.NostrException; import nostr.util.NostrUtil; -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; - /** * * @author squirrel @@ -43,7 +45,7 @@ @Log @Data @EqualsAndHashCode(callSuper = false) -public class GenericEvent extends BaseEvent implements ISignable, IGenericElement { +public class GenericEvent extends BaseEvent implements ISignable, IGenericElement, Deleteable { @Key @EqualsAndHashCode.Include @@ -113,11 +115,13 @@ public GenericEvent(@NonNull PublicKey pubKey, @NonNull Kind kind, @NonNull List this(pubKey, kind, tags, ""); } - public GenericEvent(@NonNull PublicKey pubKey, @NonNull Kind kind, @NonNull List tags, @NonNull String content) { + public GenericEvent(@NonNull PublicKey pubKey, @NonNull Kind kind, @NonNull List tags, + @NonNull String content) { this(pubKey, kind.getValue(), tags, content); } - public GenericEvent(@NonNull PublicKey pubKey, @NonNull Integer kind, @NonNull List tags, @NonNull String content) { + public GenericEvent(@NonNull PublicKey pubKey, @NonNull Integer kind, @NonNull List tags, + @NonNull String content) { this.pubKey = pubKey; this.kind = kind; this.tags = tags; @@ -151,7 +155,8 @@ public void setTags(List tags) { } public void addTag(BaseTag tag) { - if(tags==null) tags = new ArrayList<>(); + if (tags == null) + tags = new ArrayList<>(); if (!tags.contains(tag)) { tag.setParent(this); 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 220dfa939..ea42f1094 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 @@ -50,7 +50,9 @@ public class EventTag extends BaseTag { public EventTag(String idEvent) { this.recommendedRelayUrl = null; this.idEvent = idEvent; - this.marker = this.idEvent == null ? Marker.ROOT : Marker.REPLY; + + // TODO: This is a bug. The marker should not be set, or at least not like this. + //this.marker = this.idEvent == null ? Marker.ROOT : Marker.REPLY; } public static T deserialize(@NonNull JsonNode node) { 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 new file mode 100644 index 000000000..0c11089a6 --- /dev/null +++ b/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java @@ -0,0 +1,140 @@ +package nostr.test.event; + +import nostr.api.NIP01; +import nostr.api.NIP09; +import nostr.base.Relay; +import nostr.client.springwebsocket.SpringWebSocketClient; +import nostr.event.BaseMessage; +import nostr.event.BaseTag; +import nostr.event.Kind; +import nostr.event.impl.Filters; +import nostr.event.impl.GenericEvent; +import nostr.event.impl.ReplaceableEvent; +import nostr.event.impl.TextNoteEvent; +import nostr.event.message.OkMessage; +import nostr.event.tag.AddressTag; +import nostr.event.tag.EventTag; +import nostr.event.tag.IdentifierTag; +import nostr.id.Identity; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +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; + +public class APINIP09EventTest { + + private static final String RELAY_URI = "ws://localhost:5555"; + private final SpringWebSocketClient springWebSocketClient; + + public APINIP09EventTest() { + springWebSocketClient = new SpringWebSocketClient(RELAY_URI); + } + + @Test + public void deleteEvent() throws IOException { + + Identity identity = Identity.generateRandomIdentity(); + NIP09 nip09 = new NIP09<>(identity); + + NIP01 nip01 = new NIP01<>(identity); + nip01.createTextNoteEvent("Delete me!").signAndSend(Map.of("local", RELAY_URI)); + + + Filters filters = Filters + .builder() + .kinds(List.of(Kind.TEXT_NOTE)) + .authors(List.of(identity.getPublicKey())) + .build(); + + List result = nip01.send(filters, UUID.randomUUID().toString()); + + assertFalse(result.isEmpty()); + assertEquals(2, result.size()); + + nip09.createDeletionEvent(nip01.getEvent()).signAndSend(Map.of("local", RELAY_URI)); + + result = nip01.send(filters, UUID.randomUUID().toString()); + + assertFalse(result.isEmpty()); + assertEquals(1, result.size()); + + nip01.close(); + nip09.close(); + } + + + @Test + public void deleteEventWithRef() throws IOException { + Identity identity = Identity.generateRandomIdentity(); + + NIP01 nip011 = new NIP01<>(identity); + BaseMessage replaceableMessage = nip011.createReplaceableEvent(10_001, "replaceable event").signAndSend(Map.of("local", RELAY_URI)); + + assertNotNull(replaceableMessage); + assertTrue(replaceableMessage instanceof OkMessage); + + GenericEvent replaceableEvent = nip011.getEvent(); + IdentifierTag identifierTag = new IdentifierTag(replaceableEvent.getId()); + + NIP01 nip01 = new NIP01<>(identity); + nip01 + .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)); + + assertNotNull(message); + assertTrue(message instanceof OkMessage); + + GenericEvent event = nip01.getEvent(); + + NIP09 nip09 = new NIP09<>(identity); + GenericEvent deletedEvent = nip09.createDeletionEvent(event).getEvent(); + + assertEquals(4, deletedEvent.getTags().size()); + + List eventTags = deletedEvent.getTags() + .stream() + .filter(t -> "e".equals(t.getCode())) + .collect(Collectors.toList()); + + assertEquals(1, eventTags.size()); + + EventTag eventTag = (EventTag) eventTags.get(0); + assertEquals(event.getId(), eventTag.getIdEvent()); + + List addressTags = deletedEvent.getTags() + .stream() + .filter(t -> "a".equals(t.getCode())) + .collect(Collectors.toList()); + + assertEquals(1, addressTags.size()); + + AddressTag addressTag = (AddressTag) addressTags.get(0); + assertEquals(10_001, addressTag.getKind()); + assertEquals(replaceableEvent.getId(), addressTag.getIdentifierTag().getId()); + assertEquals(identity.getPublicKey(), addressTag.getPublicKey()); + + List kindTags = deletedEvent.getTags() + .stream() + .filter(t -> "k".equals(t.getCode())) + .collect(Collectors.toList()); + + assertEquals(2, kindTags.size()); + + nip09.signAndSend(Map.of("local", RELAY_URI)); + + nip01.close(); + nip011.close(); + nip09.close(); + } +} From 86039113bde25e8b150d2c55385c874d7196643f Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 4 Jan 2025 20:46:18 +0000 Subject: [PATCH 3/8] NIP09 updates --- .../src/main/java/nostr/examples/NostrApiExamples.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f75e384d9..0a3117e6a 100644 --- a/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java +++ b/nostr-java-examples/src/main/java/nostr/examples/NostrApiExamples.java @@ -223,7 +223,7 @@ private static void deletionEvent() { List tags = new ArrayList<>(List.of(new EventTag(event.getId()))); var nip09 = new NIP09(SENDER); - nip09.createDeletionEvent(tags) + nip09.createDeletionEvent(event) .sign() .send(); } From c59a8b5b3137f0b5dcbcd65a25daed01963b7f89 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 4 Jan 2025 20:46:36 +0000 Subject: [PATCH 4/8] Reverting class name change --- .../java/nostr/client/{AsyncClient.java => Client.java} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename nostr-java-client/src/main/java/nostr/client/{AsyncClient.java => Client.java} (94%) diff --git a/nostr-java-client/src/main/java/nostr/client/AsyncClient.java b/nostr-java-client/src/main/java/nostr/client/Client.java similarity index 94% rename from nostr-java-client/src/main/java/nostr/client/AsyncClient.java rename to nostr-java-client/src/main/java/nostr/client/Client.java index a7dcc4d4e..d1cc550f2 100644 --- a/nostr-java-client/src/main/java/nostr/client/AsyncClient.java +++ b/nostr-java-client/src/main/java/nostr/client/Client.java @@ -21,21 +21,21 @@ @Log @NoArgsConstructor -public class AsyncClient { +public class Client { private static class Holder { - private static final AsyncClient INSTANCE = new AsyncClient(); + private static final Client INSTANCE = new Client(); } private RequestContext context; private ConnectionPool connectionPool; - public static AsyncClient getInstance() { + public static Client getInstance() { return Holder.INSTANCE; } - public AsyncClient connect(@NonNull RequestContext context) throws TimeoutException { + public Client connect(@NonNull RequestContext context) throws TimeoutException { if (context instanceof DefaultRequestContext defaultRequestContext) { Holder.INSTANCE.context = context; connectionPool = ConnectionPool.getInstance(defaultRequestContext); From 440c38cef1586db365b945aee1d886a4381b20f9 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 4 Jan 2025 20:46:52 +0000 Subject: [PATCH 5/8] Add NIP60/61 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bc43e4344..e1c354428 100644 --- a/README.md +++ b/README.md @@ -66,4 +66,6 @@ The following NIPs are supported by the API out-of-the-box: - [NIP-44](https://github.com/nostr-protocol/nips/blob/master/44.md) - [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md) - [NIP-57](https://github.com/nostr-protocol/nips/blob/master/57.md) +- [NIP-60](https://github.com/nostr-protocol/nips/blob/master/60.md) +- [NIP-61](https://github.com/nostr-protocol/nips/blob/master/61.md) - [NIP-99](https://github.com/nostr-protocol/nips/blob/master/99.md) \ No newline at end of file From c0d2ecd1cbc354bbdde6c62d6863729e868628c8 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 4 Jan 2025 20:50:45 +0000 Subject: [PATCH 6/8] Reverting version upgrade. --- nostr-java-api/pom.xml | 2 +- nostr-java-base/pom.xml | 2 +- nostr-java-client/pom.xml | 2 +- nostr-java-command-interface/pom.xml | 2 +- nostr-java-command-provider/pom.xml | 2 +- nostr-java-connection/pom.xml | 2 +- nostr-java-context-interface/pom.xml | 2 +- nostr-java-context/pom.xml | 2 +- nostr-java-controller/pom.xml | 2 +- nostr-java-crypto/pom.xml | 2 +- nostr-java-encryption-nip04/pom.xml | 2 +- nostr-java-encryption-nip44/pom.xml | 2 +- nostr-java-encryption/pom.xml | 2 +- nostr-java-event/pom.xml | 2 +- nostr-java-examples/pom.xml | 2 +- nostr-java-test/pom.xml | 2 +- nostr-java-util/pom.xml | 2 +- pom.xml | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index d91981977..3c3ab98db 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-api jar diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 7a1f2e4b6..6ff5f6659 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-base diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index b0c563d45..2ad124eea 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-client jar diff --git a/nostr-java-command-interface/pom.xml b/nostr-java-command-interface/pom.xml index 4de9c2ef1..a42859beb 100644 --- a/nostr-java-command-interface/pom.xml +++ b/nostr-java-command-interface/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-command-interface diff --git a/nostr-java-command-provider/pom.xml b/nostr-java-command-provider/pom.xml index 8215a7d5c..8ab9e4a0d 100644 --- a/nostr-java-command-provider/pom.xml +++ b/nostr-java-command-provider/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-command-provider diff --git a/nostr-java-connection/pom.xml b/nostr-java-connection/pom.xml index 1cb63adcd..f27b6bfd8 100644 --- a/nostr-java-connection/pom.xml +++ b/nostr-java-connection/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-connection diff --git a/nostr-java-context-interface/pom.xml b/nostr-java-context-interface/pom.xml index b0ab878d8..f4393d987 100644 --- a/nostr-java-context-interface/pom.xml +++ b/nostr-java-context-interface/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-context-interface diff --git a/nostr-java-context/pom.xml b/nostr-java-context/pom.xml index f76682f03..6c30861e0 100644 --- a/nostr-java-context/pom.xml +++ b/nostr-java-context/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-context diff --git a/nostr-java-controller/pom.xml b/nostr-java-controller/pom.xml index 74ab632aa..c5de9dd59 100644 --- a/nostr-java-controller/pom.xml +++ b/nostr-java-controller/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-controller diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index 3a022a345..bade534fb 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-crypto diff --git a/nostr-java-encryption-nip04/pom.xml b/nostr-java-encryption-nip04/pom.xml index ced97d6bf..c2dcce47a 100644 --- a/nostr-java-encryption-nip04/pom.xml +++ b/nostr-java-encryption-nip04/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-encryption-nip04 diff --git a/nostr-java-encryption-nip44/pom.xml b/nostr-java-encryption-nip44/pom.xml index bb95d4948..aa83e53f4 100644 --- a/nostr-java-encryption-nip44/pom.xml +++ b/nostr-java-encryption-nip44/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-encryption-nip44 diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 169f58443..a236f3f18 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-encryption diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 8a7b7c9c5..6e8893ef4 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-event diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index ad1dfcf4d..a3a9b808f 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-examples diff --git a/nostr-java-test/pom.xml b/nostr-java-test/pom.xml index 80e6dec6a..15e049822 100644 --- a/nostr-java-test/pom.xml +++ b/nostr-java-test/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-test diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 055036fd6..96b8fe48e 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -6,7 +6,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT nostr-java-util diff --git a/pom.xml b/pom.xml index 4022ab720..5940f3cc5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ xyz.tcheeric nostr-java - 0.6.4-SNAPSHOT + 0.6.3-SNAPSHOT pom ${project.artifactId} From d0df51db44adf2c6eafba7e7d08abf64527cc397 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sat, 4 Jan 2025 21:25:26 +0000 Subject: [PATCH 7/8] NIP60 fixes --- nostr-java-api/src/main/java/nostr/api/NIP60.java | 4 ++-- .../src/main/java/nostr/base/Wallet.java | 15 ++++++++++++++- .../src/main/java/nostr/event/Kind.java | 3 +++ .../src/test/java/nostr/test/api/NIP60Test.java | 4 ++-- 4 files changed, 21 insertions(+), 5 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 b6cf6b802..e6a3135c3 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP60.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP60.java @@ -230,8 +230,8 @@ private List getWalletEventTags(@NonNull Wallet wallet) { tags.add(NIP60.createPrivKeyTag(wallet.getPrivateKey())); tags.add(NIP60.createBalanceTag(wallet.getBalance(), wallet.getUnit())); - if (wallet.getMint() != null) { - wallet.getMint().forEach(mint -> tags.add(NIP60.createMintTag(mint))); + if (wallet.getMints() != null) { + wallet.getMints().forEach(mint -> tags.add(NIP60.createMintTag(mint))); } if (wallet.getRelays() != null) { diff --git a/nostr-java-base/src/main/java/nostr/base/Wallet.java b/nostr-java-base/src/main/java/nostr/base/Wallet.java index f31d9b08b..34fa3b8fd 100644 --- a/nostr-java-base/src/main/java/nostr/base/Wallet.java +++ b/nostr-java-base/src/main/java/nostr/base/Wallet.java @@ -19,6 +19,19 @@ public class Wallet { private Integer balance; private String privateKey; private String unit; - private List mint; + private List mints; private List relays; + private List tokens; + + public void resetBalance() { + this.balance = 0; + } + + public void increaseBalance(Integer amount) { + this.balance += amount; + } + + public void decreaseBalance(Integer amount) { + this.balance -= amount; + } } diff --git a/nostr-java-event/src/main/java/nostr/event/Kind.java b/nostr-java-event/src/main/java/nostr/event/Kind.java index 415d39f3d..f51c15658 100644 --- a/nostr-java-event/src/main/java/nostr/event/Kind.java +++ b/nostr-java-event/src/main/java/nostr/event/Kind.java @@ -38,6 +38,9 @@ public enum Kind { CLASSIFIED_LISTING_DRAFT(30_403, "classified_listing_draft"), CALENDAR_DATE_BASED_EVENT(31_922, "calendar_date_based_event"), CALENDAR_TIME_BASED_EVENT(31_923, "calendar_time_based_event"), + WALLET(37_375, "wallet"), + WALLET_UNSPENT_PROOF(7_375, "wallet_unspent_proof"), + WALLET_TX_HISTORY(7_376, "wallet_tx_history"), UNDEFINED(-1, "undefined"); @JsonValue 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 4e5be1068..67cb0df90 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 @@ -51,7 +51,7 @@ public void createWalletEvent() throws JsonProcessingException { wallet.setBalance(100); wallet.setPrivateKey("hexkey"); wallet.setUnit("sat"); - wallet.setMint(Arrays.asList(mint1, mint2, mint3)); + wallet.setMints(Arrays.asList(mint1, mint2, mint3)); wallet.setRelays(Arrays.asList(relay1, relay2)); Identity sender = Identity.generateRandomIdentity(); @@ -115,7 +115,7 @@ public void createTokenEvent() throws JsonProcessingException { wallet.setBalance(100); wallet.setPrivateKey("hexkey"); wallet.setUnit("sat"); - wallet.setMint(Arrays.asList(mint)); + wallet.setMints(Arrays.asList(mint)); Proof proof = new Proof(); proof.setId("005c2502034d4f12"); From 86a5ddfc218b090fef6842ad6de283ed1c5cbd48 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sun, 12 Jan 2025 16:46:22 +0000 Subject: [PATCH 8/8] NIP09 updates --- .../src/main/java/nostr/api/NIP09.java | 105 ++++++++++++------ 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/nostr-java-api/src/main/java/nostr/api/NIP09.java b/nostr-java-api/src/main/java/nostr/api/NIP09.java index 1b0a69d8c..3836077cb 100644 --- a/nostr-java-api/src/main/java/nostr/api/NIP09.java +++ b/nostr-java-api/src/main/java/nostr/api/NIP09.java @@ -2,63 +2,94 @@ import lombok.NonNull; import nostr.api.factory.impl.NIP09Impl.DeletionEventFactory; +import nostr.base.PublicKey; +import nostr.base.Relay; import nostr.event.BaseTag; import nostr.event.Deleteable; import nostr.event.NIP09Event; import nostr.event.impl.GenericEvent; +import nostr.event.impl.GenericTag; import nostr.event.tag.AddressTag; import nostr.event.tag.EventTag; +import nostr.event.tag.IdentifierTag; import nostr.id.Identity; import java.util.ArrayList; import java.util.List; /** - * * @author eric */ public class NIP09 extends EventNostr { - public NIP09(@NonNull Identity sender) { - setSender(sender); - } + public NIP09(@NonNull Identity sender) { + setSender(sender); + } - public NIP09 createDeletionEvent(@NonNull Deleteable deleteable) { - return this.createDeletionEvent(List.of(deleteable)); - } + public NIP09 createDeletionEvent(@NonNull Deleteable deleteable) { + return this.createDeletionEvent(List.of(deleteable)); + } - /** - * Create a NIP09 Deletion Event - * - * @param deleteables list of event or address tags to be deleted - * @return the deletion event - */ - public NIP09 createDeletionEvent(@NonNull List deleteables) { - List tags = new ArrayList<>(); + /** + * Create a NIP09 Deletion Event + * + * @param deleteables list of event or address tags to be deleted + * @return the deletion event + */ + public NIP09 createDeletionEvent(@NonNull List deleteables) { + List tags = new ArrayList<>(); - // Handle GenericEvents - deleteables.stream() - .filter(d -> d instanceof GenericEvent) - .map(d -> (GenericEvent) d) - .forEach(event -> tags.add(new EventTag(event.getId()))); + // Handle GenericEvents + deleteables.stream() + .filter(d -> d instanceof GenericEvent) + .map(d -> (GenericEvent) d) + .forEach(event -> tags.add(new EventTag(event.getId()))); - // Handle AddressTags - deleteables.stream() - .filter(d -> d instanceof GenericEvent) - .map(d -> (GenericEvent) d) - .map(GenericEvent::getTags) - .forEach(t -> t.stream() - .filter(tag -> "a".equals(tag.getCode())) - .forEach(addressTag -> { - tags.add(addressTag); - tags.add(NIP25.createKindTag(((AddressTag)addressTag).getKind())); - })); + // Handle AddressTags + deleteables.stream() + .filter(d -> d instanceof GenericEvent) + .map(d -> (GenericEvent) d) + .map(GenericEvent::getTags) + .forEach(t -> t.stream() + .filter(tag -> "a".equals(tag.getCode())) + .forEach(tag -> { + if (tag instanceof GenericTag) { + AddressTag addressTag = toAddressTag((GenericTag) tag); + tags.add(addressTag); + tags.add(NIP25.createKindTag(addressTag.getKind())); + } else if (tag instanceof AddressTag) { + tags.add(tag); + tags.add(NIP25.createKindTag(((AddressTag) tag).getKind())); + } else { + throw new IllegalArgumentException("Unsupported tag type: " + tag.getClass()); + } + })); - // Add kind tags for all deleteables - deleteables.forEach(d -> tags.add(NIP25.createKindTag(d.getKind()))); + // Add kind tags for all deleteables + deleteables.forEach(d -> tags.add(NIP25.createKindTag(d.getKind()))); - var event = new DeletionEventFactory(getSender(), tags).create(); - this.setEvent((T) event); - return this; - } + var event = new DeletionEventFactory(getSender(), tags).create(); + this.setEvent((T) event); + return this; + } + + private AddressTag toAddressTag(@NonNull GenericTag genericTag) { + IdentifierTag identifierTag = new IdentifierTag(); + identifierTag.setId(genericTag.getAttributes().get(1).getValue().toString()); + + AddressTag addressTag = new AddressTag(); + addressTag.setIdentifierTag(identifierTag); + + String value = genericTag.getAttributes().get(0).getValue().toString(); + String[] parts = value.split(":"); + addressTag.setKind(Integer.decode(parts[0])); + addressTag.setPublicKey(new PublicKey(parts[1])); + if (parts.length == 3) { + addressTag.setRelay(new Relay(parts[2])); + } + + addressTag.setParent(genericTag.getParent()); + + return addressTag; + } }