diff --git a/.gitignore b/.gitignore
index 9298972c8..b32ca7f82 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
@@ -212,6 +211,14 @@ hs_err_pid*
## ignoring target file
target/
+# Gradle files
+.gradle/
+build/
+gradle/
+gradlew
+gradlew.bat
+buildSrc/build
+
### VisualStudioCode ###
.vscode
.vscode/*
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index c1dd12f17..000000000
Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
new file mode 100644
index 000000000..1ee59078a
--- /dev/null
+++ b/buildSrc/build.gradle
@@ -0,0 +1,36 @@
+/*
+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'
+}
+
+group = 'xyz.tcheeric'
+version = '0.6.5-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+ 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 {
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
+}
diff --git a/buildSrc/src/main/groovy/nostr-java.conventions.gradle b/buildSrc/src/main/groovy/nostr-java.conventions.gradle
new file mode 100644
index 000000000..b6e19f20b
--- /dev/null
+++ b/buildSrc/src/main/groovy/nostr-java.conventions.gradle
@@ -0,0 +1,123 @@
+/*
+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'
+ id 'maven-publish'
+ id 'org.springframework.boot'
+ id 'io.spring.dependency-management'
+ id 'com.adarshr.test-logger'
+ id 'org.gradle.test-retry'
+}
+
+group = version = rootProject.property("nostr-java.group")
+version = rootProject.property("nostr-java.version")
+description = rootProject.property("nostr-java.description")
+
+repositories {
+ gradlePluginPortal()
+ mavenLocal()
+ mavenCentral()
+}
+
+publishing {
+ publications {
+ nostrjava(MavenPublication) {
+ from components.java
+ }
+ }
+ repositories {
+ mavenLocal()
+//// TODO: below placeholder for eric
+// someRemoteRepo()
+ }
+}
+
+
+dependencies {
+ 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")
+ def logger = rootProject.property("nostr-java.adarshrGradleTestLoggerPlugin")
+
+ implementation 'org.springframework.boot:spring-boot-starter:' + springBootVersion
+ implementation 'org.springframework.boot:spring-boot-devtools:' + 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
+ implementation '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:' + logger
+
+ testAnnotationProcessor 'org.projectlombok:lombok:' + lombok
+}
+
+configurations {
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
+}
+
+tasks.test {
+ systemProperty("spring.profiles.active", "test")
+ useJUnitPlatform()
+// retry {
+// maxRetries.set(1)
+//// maxFailures.set(20)
+//// failOnPassedAfterRetry.set(false)
+//// failOnSkippedAfterRetry.set(true)
+// }
+}
+
+test {
+ filter {
+ excludeTestsMatching("nostr.api.integration.*");
+ }
+}
+
+tasks.bootJar {
+ enabled = false
+}
+
+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(rootProject.property("nostr-java.java-version").toString())
+ }
+}
+
+tasks.withType(JavaCompile).configureEach {
+ options.encoding = 'UTF-8'
+}
+
+tasks.withType(Javadoc).configureEach {
+ options.encoding = 'UTF-8'
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 000000000..40e91dec1
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+org.gradle.configuration-cache=false
+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
+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
+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.adarshrGradleTestLoggerPlugin=4.0.0
+nostr-java.gradleTestRetry=1.6.2
diff --git a/metrics.md b/metrics.md
new file mode 100644
index 000000000..49ccce034
--- /dev/null
+++ b/metrics.md
@@ -0,0 +1,232 @@
+### 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
+
+###### 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'
+```
diff --git a/nostr-java-api/build.gradle b/nostr-java-api/build.gradle
new file mode 100644
index 000000000..6d8ec99ad
--- /dev/null
+++ b/nostr-java-api/build.gradle
@@ -0,0 +1,30 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-api'
+
+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/nostr-java-api/pom.xml b/nostr-java-api/pom.xml
index 21777ec5e..b60f18204 100644
--- a/nostr-java-api/pom.xml
+++ b/nostr-java-api/pom.xml
@@ -1,56 +1,26 @@
-
4.0.0
+
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
+
nostr-java-api
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
- ${project.version}
+ ${nostr-java.version}
${project.groupId}
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
- ${commons-lang3.version}
+ ${nostr-java.version}
-
- nostr.java.api.NostrJavaApi
-
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 5238893c9..000000000
--- a/nostr-java-api/src/main/java/module-info.java
+++ /dev/null
@@ -1,19 +0,0 @@
-module nostr.api {
- requires nostr.base;
- requires nostr.util;
- requires nostr.event;
- requires nostr.id;
- requires nostr.client;
- requires nostr.encryption;
- requires nostr.encryption.nip04dm;
- requires nostr.encryption.nip44dm;
-
- requires com.fasterxml.jackson.databind;
-
- requires lombok;
- requires java.logging;
- requires nostr.crypto;
- requires org.apache.commons.lang3;
-
- exports nostr.api;
-}
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..564839acb 100644
--- a/nostr-java-api/src/main/java/nostr/api/EventNostr.java
+++ b/nostr-java-api/src/main/java/nostr/api/EventNostr.java
@@ -39,7 +39,6 @@ public EventNostr(@NonNull Identity sender) {
public EventNostr sign() {
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/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..ec5c50f66 100644
--- a/nostr-java-api/src/main/java/nostr/api/NIP44.java
+++ b/nostr-java-api/src/main/java/nostr/api/NIP44.java
@@ -6,8 +6,9 @@
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.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/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/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/NIP60.java b/nostr-java-api/src/main/java/nostr/api/NIP60.java
index e6a3135c3..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;
@@ -30,6 +29,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 +190,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/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 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-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-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..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;
@@ -14,6 +13,7 @@
import java.util.Map;
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
import static nostr.util.NostrUtil.escapeJsonString;
/**
@@ -65,7 +65,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-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-api/src/main/java/nostr/config/RelayProperties.java b/nostr-java-api/src/main/java/nostr/config/RelayProperties.java
new file mode 100644
index 000000000..ae8d4f066
--- /dev/null
+++ b/nostr-java-api/src/main/java/nostr/config/RelayProperties.java
@@ -0,0 +1,21 @@
+package nostr.config;
+
+import org.springframework.context.annotation.Bean;
+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;
+
+@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));
+ }
+}
diff --git a/nostr-java-test/src/test/resources/relays.properties b/nostr-java-api/src/main/resources/relays.properties
similarity index 100%
rename from nostr-java-test/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/ApiEventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java
new file mode 100644
index 000000000..7cc37d63b
--- /dev/null
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventIT.java
@@ -0,0 +1,620 @@
+package nostr.api.integration;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import nostr.api.EventNostr;
+import nostr.api.NIP01;
+import nostr.api.NIP04;
+import nostr.api.NIP15;
+import nostr.api.NIP32;
+import nostr.api.NIP44;
+import nostr.api.NIP52;
+import nostr.api.NIP57;
+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;
+import nostr.event.NIP01Event;
+import nostr.event.filter.Filters;
+import nostr.event.filter.GenericTagQueryFilter;
+import nostr.event.filter.GeohashTagFilter;
+import nostr.event.filter.HashtagTagFilter;
+import nostr.event.impl.CalendarContent;
+import nostr.event.impl.CreateOrUpdateStallEvent;
+import nostr.event.impl.CreateOrUpdateStallEvent.Stall;
+import nostr.event.impl.DirectMessageEvent;
+import nostr.event.impl.EncryptedPayloadEvent;
+import nostr.event.impl.GenericTag;
+import nostr.event.impl.NostrMarketplaceEvent;
+import nostr.event.impl.NostrMarketplaceEvent.Product.Spec;
+import nostr.event.impl.TextNoteEvent;
+import nostr.event.impl.ZapReceiptEvent;
+import nostr.event.impl.ZapRequestEvent;
+import nostr.event.message.OkMessage;
+import nostr.event.tag.GeohashTag;
+import nostr.event.tag.HashtagTag;
+import nostr.event.tag.IdentifierTag;
+import nostr.event.tag.PubKeyTag;
+import nostr.id.Identity;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringJUnitConfig(RelayProperties.class)
+@ActiveProfiles("test")
+public class ApiEventIT {
+ @Autowired
+ private Map relays;
+
+ @Test
+ public void testNIP01CreateTextNoteEvent() throws Exception {
+ 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));
+ }
+
+ @Test
+ public void testNIP01SendTextNoteEvent() throws IOException {
+ System.out.println("testNIP01SendTextNoteEvent");
+
+ var nip01 = new NIP01(Identity.generateRandomIdentity());
+ var instance = nip01.createTextNoteEvent("Hello simplified nostr-java!").sign();
+
+ var response = instance.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip01.getEvent().getId(), ((OkMessage) response).getEventId());
+
+// nip01.close();
+ }
+
+ @Test
+ public void testNIP04SendDirectMessage() throws IOException {
+ System.out.println("testNIP04SendDirectMessage");
+
+ var nip04 = new NIP04(
+ 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();
+
+ 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();
+ }
+
+ @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 testNIP01SendTextNoteEventGeoHashTag() throws IOException {
+ System.out.println("testNIP01SendTextNoteEventGeoHashTag");
+
+ String targetString = "geohash_tag-location-testNIP01SendTextNoteEventGeoHashTag";
+ GeohashTag geohashTag = new GeohashTag(targetString);
+
+ NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity());
+ nip01.createTextNoteEvent(List.of(geohashTag), "GeohashTag Test location testNIP01SendTextNoteEventGeoHashTag").signAndSend(relays);
+
+ Filters filters = new Filters(
+ new GeohashTagFilter<>(new GeohashTag(targetString)));
+
+ List result = nip01.sendRequest(filters, UUID.randomUUID().toString());
+
+ assertFalse(result.isEmpty());
+ assertEquals(2, result.size());
+ assertTrue(result.stream().anyMatch(s -> s.contains(targetString)));
+
+// nip01.close();
+ }
+
+ @Test
+ public void testNIP01SendTextNoteEventHashtagTag() throws IOException {
+ System.out.println("testNIP01SendTextNoteEventHashtagTag");
+
+ String targetString = "hashtag-tag-value-testNIP01SendTextNoteEventHashtagTag";
+ HashtagTag hashtagTag = new HashtagTag(targetString);
+
+ NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity());
+ nip01.createTextNoteEvent(List.of(hashtagTag), "Hashtag Tag Test value testNIP01SendTextNoteEventHashtagTag").signAndSend(relays);
+
+ Filters filters = new Filters(
+ new HashtagTagFilter<>(new HashtagTag(targetString)));
+
+ List result = nip01.sendRequest(filters, UUID.randomUUID().toString());
+
+ assertFalse(result.isEmpty());
+ assertEquals(2, result.size());
+ assertTrue(result.stream().anyMatch(s -> s.contains(targetString)));
+
+// nip01.close();
+ }
+
+ @Test
+ public void testNIP01SendTextNoteEventCustomGenericTag() throws IOException {
+ System.out.println("testNIP01SendTextNoteEventCustomGenericTag");
+
+ String targetString = "custom-generic-tag-testNIP01SendTextNoteEventCustomGenericTag";
+ GenericTag genericTag = GenericTag.create("m", targetString);
+
+ NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity());
+ nip01.createTextNoteEvent(List.of(genericTag), "Custom Generic Tag Test testNIP01SendTextNoteEventCustomGenericTag").signAndSend(relays);
+
+ Filters filters = new Filters(
+ new GenericTagQueryFilter<>(new GenericTagQuery("#m", targetString)));
+
+ List result = nip01.sendRequest(filters, UUID.randomUUID().toString());
+
+ assertFalse(result.isEmpty());
+ assertEquals(2, result.size());
+
+ String matcher = """
+ ["m","custom-generic-tag-testNIP01SendTextNoteEventCustomGenericTag"]""";
+
+ assertTrue(result.stream().anyMatch(s -> s.contains(matcher)));
+
+// nip01.close();
+ }
+
+ @Test
+ public void testFiltersListReturnSameSingularEvent() throws IOException {
+ System.out.println("testFiltersListReturnSameSingularEvent");
+
+ String geoHashTagTarget = "geohash_tag-location_SameSingularEvent";
+ GeohashTag geohashTag = new GeohashTag(geoHashTagTarget);
+
+ String genericTagTarget = "generic-tag-value_SameSingularEvent";
+ GenericTag genericTag = GenericTag.create("m", genericTagTarget);
+
+ NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity());
+
+ nip01.createTextNoteEvent(List.of(geohashTag, genericTag), "Multiple Filters").signAndSend(relays);
+
+ Filters filters1 = new Filters(
+ new GeohashTagFilter<>(new GeohashTag(geoHashTagTarget)));
+ Filters filters2 = new Filters(
+ new GenericTagQueryFilter<>(new GenericTagQuery("#m", genericTagTarget)));
+
+ List result = nip01.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString());
+
+ assertFalse(result.isEmpty());
+ assertEquals(2, result.size());
+ assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget)));
+
+// nip01.close();
+ }
+
+ @Test
+ public void testFiltersListReturnTwoDifferentEvents() throws IOException {
+ System.out.println("testFiltersListReturnTwoDifferentEvents");
+
+// first event
+ String geoHashTagTarget1 = "geohash_tag-location-1";
+ GeohashTag geohashTag1 = new GeohashTag(geoHashTagTarget1);
+ String genericTagTarget1 = "generic-tag-value-1";
+ 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);
+
+// second event
+ String geoHashTagTarget2 = "geohash_tag-location-2";
+ GeohashTag geohashTag2 = new GeohashTag(geoHashTagTarget2);
+ String genericTagTarget2 = "generic-tag-value-2";
+ 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);
+
+ Filters filters1 = new Filters(
+ 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
+
+ List result = nip01_1.sendRequest(List.of(filters1, filters2), UUID.randomUUID().toString());
+
+ assertFalse(result.isEmpty());
+ assertEquals(3, result.size());
+ assertTrue(result.stream().anyMatch(s -> s.contains(geoHashTagTarget1)));
+ assertTrue(result.stream().anyMatch(s -> s.contains(genericTagTarget2)));
+
+// nip01_1.close();
+// nip01_2.close();
+ }
+
+ @Test
+ public void testMultipleFiltersDifferentTypesReturnSameEvent() throws IOException {
+ System.out.println("testMultipleFilters");
+
+ String geoHashTagTarget = "geohash_tag-location-DifferentTypesReturnSameEvent";
+ GeohashTag geohashTag = new GeohashTag(geoHashTagTarget);
+
+ String genericTagTarget = "generic-tag-value-DifferentTypesReturnSameEvent";
+ GenericTag genericTag = GenericTag.create("m", genericTagTarget);
+
+ NIP01 nip01 = new NIP01<>(Identity.generateRandomIdentity());
+ 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)));
+
+ 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");
+
+ 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();
+
+ var message = NIP04.decrypt(identity, instance.getEvent());
+
+ assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message);
+ }
+
+ @Test
+ public void testNIP44EncryptDecrypt() {
+ System.out.println("testNIP44EncryptDecrypt");
+
+ Identity identity = Identity.generateRandomIdentity();
+ 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();
+ var message = NIP44.decrypt(identity, instance.getEvent());
+
+ assertEquals("Quand on n'a que l'amour pour tracer un chemin et forcer le destin...", message);
+ }
+
+ @Test
+ public void testNIP15CreateStallEvent() throws JsonProcessingException {
+ System.out.println("testNIP15CreateStallEvent");
+
+ Stall stall = createStall();
+ var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ // Create and send the nostr event
+ var instance = nip15.createCreateOrUpdateStallEvent(stall).sign();
+ var signature = instance.getEvent().getSignature();
+ assertNotNull(signature);
+
+ // Fetch the content and compare with the above original
+ var content = instance.getEvent().getContent();
+ var expected = MAPPER_AFTERBURNER.readValue(content, Stall.class);
+
+ assertEquals(expected, stall);
+ }
+
+ @Test
+ public void testNIP15UpdateStallEvent() throws IOException {
+ System.out.println("testNIP15UpdateStallEvent");
+
+ var stall = createStall();
+ var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ // Create and send the nostr event
+ var instance = nip15.createCreateOrUpdateStallEvent(stall).sign();
+ var signature = instance.getEvent().getSignature();
+ assertNotNull(signature);
+
+ var response = instance.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId());
+
+ // Update the shipping
+ var shipping = stall.getShipping();
+ shipping.setCost(20.00f);
+
+ EventNostr event = nip15.createCreateOrUpdateStallEvent(stall).sign();
+ response = event.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId());
+
+// nip15.close();
+ }
+
+ @Test
+ public void testNIP15CreateProductEvent() throws IOException {
+
+ System.out.println("testNIP15CreateProductEvent");
+
+ // Create the stall object
+ var stall = createStall();
+ var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ // Create the product
+ var product = createProduct(stall);
+
+ List categories = new ArrayList<>();
+ categories.add("bijoux");
+ categories.add("Hommes");
+
+ EventNostr event = nip15.createCreateOrUpdateProductEvent(product, categories).sign();
+ var response = event.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId());
+
+// nip15.close();
+ }
+
+ @Test
+ public void testNIP15UpdateProductEvent() throws IOException {
+
+ System.out.println("testNIP15UpdateProductEvent");
+
+ // Create the stall object
+ var stall = createStall();
+ var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ // Create the product
+ var product = createProduct(stall);
+
+ List categories = new ArrayList<>();
+ categories.add("bijoux");
+ categories.add("Hommes");
+
+ EventNostr event1 = nip15.createCreateOrUpdateProductEvent(product, categories).sign();
+ var response = event1.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId());
+
+ product.setDescription("Un nouveau bijou en or");
+ categories.add("bagues");
+
+ EventNostr event2 = nip15.createCreateOrUpdateProductEvent(product, categories).sign();
+ response = event2.setRelays(relays).send();
+ assertTrue(response instanceof OkMessage);
+ assertEquals(nip15.getEvent().getId(), ((OkMessage) response).getEventId());
+
+// nip15.close();
+ }
+
+ @Test
+ public void testNIP32CreateNameSpace() {
+
+ System.out.println("testNIP32CreateNameSpace");
+
+ var langNS = NIP32.createNameSpaceTag("Languages");
+
+ assertEquals("L", langNS.getCode());
+ assertEquals(1, langNS.getAttributes().size());
+ assertEquals("Languages", langNS.getAttributes().iterator().next().getValue());
+ }
+
+ @Test
+ public void testNIP32CreateLabel1() {
+
+ 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")));
+ assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages")));
+ }
+
+ @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")));
+ assertTrue(label.getAttributes().contains(new ElementAttribute("param1", "Languages")));
+ assertTrue(label.getAttributes().contains(new ElementAttribute("param2", "{\\\"article\\\":\\\"the\\\"}")),
+ "{\\\"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(Identity.generateRandomIdentity().getPublicKey(),
+ "ws://localhost:5555",
+ "ISSUER"));
+ tags.add(new PubKeyTag(Identity.generateRandomIdentity().getPublicKey(),
+ "",
+ "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 Exception {
+ 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 Exception {
+ 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();
+ }
+
+ 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;
+ }
+}
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
new file mode 100644
index 000000000..b6b38c8da
--- /dev/null
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiEventTestUsingSpringWebSocketClientIT.java
@@ -0,0 +1,75 @@
+package nostr.api.integration;
+
+import lombok.SneakyThrows;
+import nostr.api.NIP15;
+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.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static nostr.api.integration.ApiEventIT.createProduct;
+import static nostr.api.integration.ApiEventIT.createStall;
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringJUnitConfig(RelayProperties.class)
+@ActiveProfiles("test")
+class ApiEventTestUsingSpringWebSocketClientIT {
+ private final List springWebSocketClients;
+
+ @Autowired
+ public ApiEventTestUsingSpringWebSocketClientIT(Map relays) {
+ this.springWebSocketClients = relays.values().stream().map(SpringWebSocketClient::new).toList();
+ }
+
+ @Test
+ void doForEach() {
+ springWebSocketClients.forEach(this::testNIP15SendProductEventUsingSpringWebSocketClient);
+ }
+
+ @SneakyThrows
+ void testNIP15SendProductEventUsingSpringWebSocketClient(SpringWebSocketClient springWebSocketClient) {
+ System.out.println("testNIP15CreateProductEventUsingSpringWebSocketClient");
+ var product = createProduct(createStall());
+
+ List categories = new ArrayList<>();
+ categories.add("bijoux");
+ categories.add("Hommes");
+
+ var nip15 = new NIP15<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ GenericEvent event = nip15.createCreateOrUpdateProductEvent(product, categories).sign().getEvent();
+ EventMessage message = new EventMessage(event);
+
+ 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();
+
+ 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");
+
+// springWebSocketClient.closeSocket();
+ }
+
+ private String expectedResponseJson(String sha256) {
+ return "[\"OK\",\"" + sha256 + "\",true,\"success: request processed\"]";
+ }
+}
diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java
similarity index 79%
rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java
rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java
index fa0e7186b..a06da9197 100644
--- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52EventTest.java
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52EventIT.java
@@ -1,15 +1,7 @@
-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;
+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;
@@ -20,13 +12,22 @@
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 org.springframework.test.context.ActiveProfiles;
+
+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 {
+@ActiveProfiles("test")
+class ApiNIP52EventIT {
private static final String RELAY_URI = "ws://localhost:5555";
private final SpringWebSocketClient springWebSocketClient;
- public ApiNIP52EventTest() {
+ public ApiNIP52EventIT() {
springWebSocketClient = new SpringWebSocketClient(RELAY_URI);
}
@@ -47,24 +48,22 @@ 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().orElseThrow());
- 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))));
- springWebSocketClient.closeSocket();
+// springWebSocketClient.closeSocket();
}
private String expectedResponseJson(String sha256) {
diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java
similarity index 78%
rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java
rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java
index 6baba40fa..c12167a27 100644
--- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP52RequestTest.java
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP52RequestIT.java
@@ -1,7 +1,7 @@
-package nostr.test.event;
+package nostr.api.integration;
-import com.fasterxml.jackson.databind.ObjectMapper;
import nostr.api.NIP52;
+import nostr.api.util.JsonComparator;
import nostr.base.PublicKey;
import nostr.client.springwebsocket.SpringWebSocketClient;
import nostr.event.BaseTag;
@@ -16,20 +16,22 @@
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.springframework.test.context.ActiveProfiles;
import java.io.IOException;
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;
-class ApiNIP52RequestTest {
+@ActiveProfiles("test")
+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";
@@ -76,7 +78,6 @@ class ApiNIP52RequestTest {
public String eventPubKey;
public String signature;
- @Order(1)
@Test
void testNIP99CalendarContentPreRequest() throws IOException {
System.out.println("testNIP52CalendarContentEvent");
@@ -85,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);
@@ -106,44 +107,45 @@ 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();
-
- ObjectMapper mapper = new ObjectMapper();
+ String eventResponse = springWebSocketEventClient.send(eventMessage).stream().findFirst().orElseThrow();
// 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");
//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
-/*
+///*
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.readTree(expectedRequestResponseJson()),
- mapper.readTree(reqResponse)));
+ MAPPER_AFTERBURNER.readTree(expected),
+ MAPPER_AFTERBURNER.readTree(reqResponse)));
- springWebSocketRequestClient.closeSocket();
-*/
+// springWebSocketRequestClient.closeSocket();
+//*/
}
private String expectedEventResponseJson(String subscriptionId) {
@@ -154,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/ApiNIP99EventIT.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java
new file mode 100644
index 000000000..04197533b
--- /dev/null
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99EventIT.java
@@ -0,0 +1,107 @@
+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 org.springframework.test.context.ActiveProfiles;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ActiveProfiles("test")
+class ApiNIP99EventIT {
+ 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 ApiNIP99EventIT() {
+ springWebSocketClient = new SpringWebSocketClient(RELAY_URI);
+ }
+
+ @Test
+ void testNIP99ClassifiedListingEvent() throws IOException {
+ System.out.println("testNIP99ClassifiedListingEvent");
+
+ List tags = new ArrayList<>();
+ tags.add(E_TAG);
+ tags.add(P_TAG);
+ 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);
+
+ PriceTag priceTag = new PriceTag(NUMBER, CURRENCY, FREQUENCY);
+ ClassifiedListing classifiedListing = ClassifiedListing.builder(
+ TITLE_CODE,
+ SUMMARY_CODE,
+ priceTag)
+ .build();
+
+ var nip99 = new NIP99<>(Identity.create(PrivateKey.generateRandomPrivKey()));
+
+ GenericEvent event = nip99.createClassifiedListingEvent(tags, CLASSIFIED_LISTING_CONTENT, classifiedListing).sign().getEvent();
+ EventMessage message = new EventMessage(event);
+
+ // 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();
+
+ String eventResponse = springWebSocketClient.send(message).stream().findFirst().get();
+ 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();
+ }
+
+ private String expectedResponseJson(String sha256) {
+ return "[\"OK\",\"" + sha256 + "\",true,\"success: request processed\"]";
+ }
+}
diff --git a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java
similarity index 74%
rename from nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java
rename to nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java
index 10b9017b0..70c5255f1 100644
--- a/nostr-java-test/src/test/java/nostr/test/event/ApiNIP99RequestTest.java
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ApiNIP99RequestIT.java
@@ -1,7 +1,6 @@
-package nostr.test.event;
+package nostr.api.integration;
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;
@@ -17,22 +16,25 @@
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.springframework.test.context.ActiveProfiles;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
-import static nostr.test.event.ClassifiedListingEventTest.LOCATION_CODE;
-import static nostr.test.event.ClassifiedListingEventTest.PUBLISHED_AT_CODE;
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-class ApiNIP99RequestTest {
+@ActiveProfiles("test")
+class ApiNIP99RequestIT {
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";
@@ -64,7 +66,6 @@ class ApiNIP99RequestTest {
public String eventPubKey;
public String signature;
- @Order(1)
@Test
void testNIP99ClassifiedListingPreRequest() throws IOException {
System.out.println("testNIP99ClassifiedListingEvent");
@@ -72,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);
@@ -97,41 +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());
-
- ObjectMapper mapper = new ObjectMapper();
+ 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.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.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();
+// 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.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());
+ 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");
@@ -140,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-test/src/test/java/nostr/test/event/APINIP09EventTest.java b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java
similarity index 66%
rename from nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java
rename to nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java
index f44849bbf..95857593d 100644
--- a/nostr-java-test/src/test/java/nostr/test/event/APINIP09EventTest.java
+++ b/nostr-java-api/src/test/java/nostr/api/integration/ZDoLastApiNIP09EventIT.java
@@ -1,8 +1,9 @@
-package nostr.test.event;
+package nostr.api.integration;
import nostr.api.NIP01;
import nostr.api.NIP09;
import nostr.base.Relay;
+import nostr.config.RelayProperties;
import nostr.event.BaseMessage;
import nostr.event.BaseTag;
import nostr.event.Kind;
@@ -18,6 +19,9 @@
import nostr.event.tag.IdentifierTag;
import nostr.id.Identity;
import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.io.IOException;
import java.util.List;
@@ -25,14 +29,13 @@
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.*;
-public class APINIP09EventTest {
-
- private static final String RELAY_URI = "ws://localhost:5555";
+@SpringJUnitConfig(RelayProperties.class)
+@ActiveProfiles("test")
+public class ZDoLastApiNIP09EventIT {
+ @Autowired
+ private Map relays;
@Test
public void deleteEvent() throws IOException {
@@ -41,35 +44,36 @@ 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),
- new AuthorFilter<>(identity.getPublicKey()));
+ new KindFilter<>(Kind.TEXT_NOTE),
+ new AuthorFilter<>(identity.getPublicKey()));
List result = nip01.sendRequest(filters, UUID.randomUUID().toString());
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());
assertFalse(result.isEmpty());
assertEquals(1, result.size());
- nip01.close();
- nip09.close();
+// nip01.close();
+// nip09.close();
}
@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);
@@ -79,11 +83,11 @@ 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(Map.of("local", RELAY_URI));
+ BaseMessage message = nip01.signAndSend(relays);
assertNotNull(message);
assertTrue(message instanceof OkMessage);
@@ -96,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());
@@ -106,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());
@@ -118,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(Map.of("local", RELAY_URI));
+ nip09.signAndSend(relays);
- nip01.close();
- nip011.close();
- nip09.close();
+// nip01.close();
+// nip011.close();
+// nip09.close();
}
}
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 63%
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 e35652e07..9a2266c30 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,8 +1,7 @@
-package nostr.test.event;
+package nostr.api.unit;
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)
@@ -73,16 +73,16 @@ 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();
+ .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/json/JsonParseTest.java b/nostr-java-api/src/test/java/nostr/api/unit/JsonParseTest.java
similarity index 97%
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 1041ac5e1..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,9 +1,9 @@
-package nostr.test.json;
+package nostr.api.unit;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
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;
@@ -43,27 +43,19 @@
import nostr.event.tag.PriceTag;
import nostr.event.tag.PubKeyTag;
import nostr.id.Identity;
-import nostr.test.util.JsonComparator;
-import nostr.util.NostrException;
import org.junit.jupiter.api.Test;
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");
@@ -334,7 +326,7 @@ public void testClassifiedListingTagSerializer() throws JsonProcessingException
}
@Test
- public void testDeserializeTag() throws NostrException {
+ public void testDeserializeTag() throws Exception {
log.info("testDeserializeTag");
String npubHex = new PublicKey(Bech32.fromBech32("npub1clk6vc9xhjp8q5cws262wuf2eh4zuvwupft03hy4ttqqnm7e0jrq3upup9")).toString();
@@ -350,7 +342,7 @@ public void testDeserializeTag() throws NostrException {
}
@Test
- public void testDeserializeGenericTag() throws NostrException {
+ 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\"]";
@@ -653,11 +645,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/nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java
similarity index 95%
rename from nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java
rename to nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java
index e4400f76f..034148118 100644
--- a/nostr-java-test/src/test/java/nostr/test/event/NIP52ImplTest.java
+++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP52ImplTest.java
@@ -1,13 +1,4 @@
-package nostr.test.event;
-
-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;
+package nostr.api.unit;
import nostr.api.NIP52;
import nostr.base.PublicKey;
@@ -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-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/api/NIP60Test.java b/nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java
similarity index 93%
rename from nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java
rename to nostr-java-api/src/test/java/nostr/api/unit/NIP60Test.java
index db697af1e..d24fc641c 100644
--- a/nostr-java-test/src/test/java/nostr/test/api/NIP60Test.java
+++ b/nostr-java-api/src/test/java/nostr/api/unit/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;
+package nostr.api.unit;
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/api/NIP61Test.java b/nostr-java-api/src/test/java/nostr/api/unit/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/unit/NIP61Test.java
index 79ddabf46..c30e826f8 100644
--- a/nostr-java-test/src/test/java/nostr/test/api/NIP61Test.java
+++ b/nostr-java-api/src/test/java/nostr/api/unit/NIP61Test.java
@@ -1,4 +1,4 @@
-package nostr.test.api;
+package nostr.api.unit;
import java.util.Arrays;
import java.util.List;
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 96%
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..284e06766 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;
@@ -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-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-api/src/test/resources/junit-platform.properties b/nostr-java-api/src/test/resources/junit-platform.properties
new file mode 100644
index 000000000..beae0cf29
--- /dev/null
+++ b/nostr-java-api/src/test/resources/junit-platform.properties
@@ -0,0 +1,9 @@
+# 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
+
+#junit.jupiter.testclass.order.default=org.junit.jupiter.api.ClassOrderer$ClassName
diff --git a/nostr-java-base/build.gradle b/nostr-java-base/build.gradle
new file mode 100644
index 000000000..03572bb8c
--- /dev/null
+++ b/nostr-java-base/build.gradle
@@ -0,0 +1,10 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-base'
+
+dependencies {
+ api project(':nostr-java-util')
+ api project(':nostr-java-crypto')
+}
diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml
index acf2f5122..103219fe7 100644
--- a/nostr-java-base/pom.xml
+++ b/nostr-java-base/pom.xml
@@ -1,38 +1,26 @@
-
-
+
4.0.0
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
-
+
nostr-java-base
jar
-
-
- org.projectlombok
- lombok
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
-
${project.groupId}
nostr-java-util
- ${project.version}
+ ${nostr-java.version}
${project.groupId}
nostr-java-crypto
- ${project.version}
+ ${nostr-java.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
deleted file mode 100644
index 8e935de14..000000000
--- a/nostr-java-base/src/main/java/module-info.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-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;
-}
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..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.NostrException;
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 (NostrException ex) {
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
}
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/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/Encoder.java b/nostr-java-base/src/main/java/nostr/base/Encoder.java
new file mode 100644
index 000000000..326177d98
--- /dev/null
+++ b/nostr-java-base/src/main/java/nostr/base/Encoder.java
@@ -0,0 +1,14 @@
+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;
+
+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/FEncoder.java b/nostr-java-base/src/main/java/nostr/base/FEncoder.java
deleted file mode 100644
index 1304d0f17..000000000
--- a/nostr-java-base/src/main/java/nostr/base/FEncoder.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package nostr.base;
-
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public interface FEncoder {
- ObjectMapper MAPPER = new ObjectMapper().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/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-base/src/main/java/nostr/base/IEncoder.java b/nostr-java-base/src/main/java/nostr/base/IEncoder.java
deleted file mode 100644
index 631fd3fca..000000000
--- a/nostr-java-base/src/main/java/nostr/base/IEncoder.java
+++ /dev/null
@@ -1,17 +0,0 @@
-
-package nostr.base;
-
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-
-/**
- *
- * @author squirrel
- * @param
- */
-public interface IEncoder {
- ObjectMapper MAPPER = new ObjectMapper().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/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-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/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/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-base/src/main/java/nostr/base/Relay.java b/nostr-java-base/src/main/java/nostr/base/Relay.java
index 20dc5f8fa..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,236 +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;
-
- @ToString.Exclude
- @EqualsAndHashCode.Exclude
- 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/UserProfile.java b/nostr-java-base/src/main/java/nostr/base/UserProfile.java
index 998519766..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.NostrException;
/**
*
@@ -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 (NostrException ex) {
+ } catch (Exception ex) {
log.log(Level.SEVERE, null, ex);
throw new RuntimeException(ex);
}
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-base/src/test/java/nostr/base/BaseKeyTest.java b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java
new file mode 100644
index 000000000..bfd85e403
--- /dev/null
+++ b/nostr-java-base/src/test/java/nostr/base/BaseKeyTest.java
@@ -0,0 +1,79 @@
+package nostr.base;
+
+import org.junit.jupiter.api.Test;
+
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.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";
+
+ @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 testInValidNullPublicKeyString() {
+ System.out.println("testInValidNullPublicKeyString");
+ assertThrows(AssertionError.class, () -> new PublicKey(""));
+ }
+
+ @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(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_LENGTH_TOO_SHORT));
+ }
+
+ @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 testValidPublicKeyAllFF() {
+ System.out.println("testValidPublicKeyAllFF");
+ assertDoesNotThrow(() -> new PublicKey(VALID_HEXPUBKEY_ALL_FF));
+ }
+
+ @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(AssertionError.class, () -> new PublicKey(INVALID_HEXPUBKEY_HAS_SINGLE_UPPERCASE));
+ }
+}
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/nostr-java-client/build.gradle b/nostr-java-client/build.gradle
new file mode 100644
index 000000000..95517328c
--- /dev/null
+++ b/nostr-java-client/build.gradle
@@ -0,0 +1,9 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-client'
+
+dependencies {
+ api project(':nostr-java-id')
+}
diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml
index f2911d6ec..405a337fe 100644
--- a/nostr-java-client/pom.xml
+++ b/nostr-java-client/pom.xml
@@ -1,61 +1,66 @@
-
4.0.0
+
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
+
nostr-java-client
jar
+
+
+ 4.2.2
+ 2.2.0
+ 1.1.20
+ 6.1.10
+ 6.1.10
+
+
${project.groupId}
- nostr-java-event
- ${project.version}
+ nostr-java-id
+ ${nostr-java.version}
+
- ${project.groupId}
- nostr-java-base
- ${project.version}
+ org.springframework.boot
+ spring-boot-starter-websocket
+ ${spring-boot.version}
- ${project.groupId}
- nostr-java-id
- ${project.version}
+ org.springframework
+ spring-websocket
+ ${spring-websocket.version}
org.springframework
- spring-websocket
- 6.1.10
+ spring-webflux
+ ${spring-webflux.version}
+
+
+ io.projectreactor.netty
+ reactor-netty-http
+ ${reactor-netty-http.version}
-
jakarta.websocket
jakarta.websocket-api
- 2.2.0
+ ${jakarta.websocket-api.version}
-
jakarta.websocket
jakarta.websocket-client-api
- 2.2.0
-
-
-
- org.springframework
- spring-webflux
- 6.1.10
-
-
- io.projectreactor.netty
- reactor-netty-http
- 1.1.20
+
+ ${jakarta.websocket-api.version}
org.awaitility
awaitility
- 4.2.2
+ ${awaitility.version}
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-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-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/build.gradle b/nostr-java-crypto/build.gradle
new file mode 100644
index 000000000..3e57327eb
--- /dev/null
+++ b/nostr-java-crypto/build.gradle
@@ -0,0 +1,9 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-crypto'
+
+dependencies {
+ api project(':nostr-java-util')
+}
diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml
index b0022724f..b60d82e4e 100644
--- a/nostr-java-crypto/pom.xml
+++ b/nostr-java-crypto/pom.xml
@@ -1,14 +1,13 @@
-
-
+
4.0.0
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
-
+
nostr-java-crypto
jar
@@ -20,21 +19,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}
+ ${nostr-java.version}
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-crypto/src/main/java/nostr/crypto/bech32/Bech32.java b/nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java
index 896ab5b06..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.NostrException;
import nostr.util.NostrUtil;
/**
@@ -61,21 +60,21 @@ 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);
+ 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 NostrException {
- var data = NostrUtil.hexToBytes(hexKey);
+ 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 NostrException {
- var data = Bech32.decode(strBech32).data;
+ 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 NostrException {
*
* @param bech32
* @return
- * @throws nostr.util.NostrException
+ * @throws nostr.util.Exception
*/
- public static String encode(final Bech32Data bech32) throws NostrException {
+ 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 NostrException {
* @param hrp
* @param values
* @return
- * @throws nostr.util.NostrException
+ * @throws nostr.util.Exception
*/
- // Modified to throw NostrExceptions
- public static String encode(Encoding encoding, String hrp, final byte[] values) throws NostrException {
+ // Modified to throw Exceptions
+ public static String encode(Encoding encoding, String hrp, final byte[] values) throws Exception {
if (hrp.isEmpty()) {
- throw new NostrException("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 nostr.util.NostrException
+ * @throws nostr.util.Exception
*/
- // Modified to throw NostrExceptions
- public static Bech32Data decode(final String str) throws NostrException {
+ // Modified to throw Exceptions
+ public static Bech32Data decode(final String str) throws Exception {
boolean lower = false, upper = false;
if (str.length() < 8) {
- throw new NostrException("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 NostrException(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 NostrException(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 NostrException(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 NostrException("Missing human-readable part");
+ throw new Exception("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 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 NostrException(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 NostrException("InvalidChecksum");
+ throw new Exception("InvalidChecksum");
}
return new Bech32Data(encoding, hrp, Arrays.copyOfRange(values, 0, values.length - 6));
}
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-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-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/build.gradle b/nostr-java-encryption/build.gradle
new file mode 100644
index 000000000..69bddf914
--- /dev/null
+++ b/nostr-java-encryption/build.gradle
@@ -0,0 +1,10 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-encryption'
+
+dependencies {
+ api project(':nostr-java-crypto')
+ api project(':nostr-java-util')
+}
diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml
index bc81e01bc..5a7734cf5 100644
--- a/nostr-java-encryption/pom.xml
+++ b/nostr-java-encryption/pom.xml
@@ -1,12 +1,13 @@
-
+
4.0.0
+
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
-
+
nostr-java-encryption
jar
@@ -16,4 +17,12 @@
UTF-8
+
+
+
+ ${project.groupId}
+ nostr-java-crypto
+ ${nostr-java.version}
+
+
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 94ad056bd..000000000
--- a/nostr-java-encryption/src/main/java/module-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-module nostr.encryption {
-
- 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/nostr-java-event/build.gradle b/nostr-java-event/build.gradle
new file mode 100644
index 000000000..2c195373f
--- /dev/null
+++ b/nostr-java-event/build.gradle
@@ -0,0 +1,9 @@
+plugins {
+ id 'nostr-java.conventions'
+}
+
+description = 'nostr-java-event'
+
+dependencies {
+ api project(':nostr-java-base')
+}
diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml
index 44581be69..00c84a67c 100644
--- a/nostr-java-event/pom.xml
+++ b/nostr-java-event/pom.xml
@@ -1,34 +1,22 @@
-
-
+
4.0.0
xyz.tcheeric
nostr-java
0.6.5-SNAPSHOT
+ ../pom.xml
-
+
nostr-java-event
jar
-
-
- org.projectlombok
- lombok
-
-
${project.groupId}
nostr-java-base
- ${project.version}
-
-
- ${project.groupId}
- nostr-java-util
- ${project.version}
+ ${nostr-java.version}
-
\ No newline at end of file
+
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 60e80d4b3..000000000
--- a/nostr-java-event/src/main/java/module-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-
-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;
-
- 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/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 c3a50a909..5c0aaff75 100644
--- a/nostr-java-event/src/main/java/nostr/event/BaseTag.java
+++ b/nostr-java-event/src/main/java/nostr/event/BaseTag.java
@@ -1,11 +1,12 @@
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;
import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
+import lombok.NonNull;
import lombok.ToString;
import nostr.base.IEvent;
import nostr.base.ITag;
@@ -14,22 +15,25 @@
import nostr.event.json.deserializer.TagDeserializer;
import nostr.event.json.serializer.TagSerializer;
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;
/**
- *
* @author squirrel
*/
@Data
@ToString
@EqualsAndHashCode(callSuper = false)
-@NoArgsConstructor
@JsonDeserialize(using = TagDeserializer.class)
@JsonSerialize(using = TagSerializer.class)
public abstract class BaseTag implements ITag {
@@ -38,19 +42,13 @@ public abstract class BaseTag implements ITag {
private IEvent parent;
@Override
- public void setParent(IEvent event) {
+ public void setParent(@NonNull IEvent event) {
this.parent = event;
}
@Override
public String getCode() {
- var tag = this.getClass().getAnnotation(Tag.class);
- return tag.code();
- }
-
- @Override
- public Integer getNip() {
- return 1;
+ return this.getClass().getAnnotation(Tag.class).code();
}
public String getFieldValue(Field field) throws NostrException {
@@ -63,14 +61,19 @@ 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 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 setOptionalField(JsonNode node, BiConsumer con, T tag) {
+ Optional.ofNullable(node).ifPresent(n -> con.accept(n, tag));
+ }
- return fieldList;
+ 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/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 70654ee32..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
@@ -1,8 +1,8 @@
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 lombok.NonNull;
import nostr.event.BaseTag;
import nostr.event.impl.GenericEvent;
@@ -10,15 +10,15 @@
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();
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)
@@ -26,7 +26,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 +39,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/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/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/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/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..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;
@@ -74,7 +73,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/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/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..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
@@ -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;
@@ -39,8 +28,21 @@
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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
- *
* @author squirrel
*/
@Log
@@ -117,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;
@@ -146,8 +148,8 @@ public String toBech32() {
try {
return Bech32.toBech32(Bech32Prefix.NOTE, this.getId());
- } catch (NostrException ex) {
- throw new RuntimeException(ex);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
}
@@ -194,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() {
@@ -203,7 +210,7 @@ protected void validate() {
}
private String serialize() throws NostrException {
- var mapper = IEncoder.MAPPER;
+ var mapper = ENCODER_MAPPED_AFTERBURNER;
var arrayNode = JsonNodeFactory.instance.arrayNode();
try {
@@ -220,6 +227,20 @@ private String serialize() throws NostrException {
}
}
+ @Transient
+ @Override
+ public Consumer getSignatureConsumer() {
+ return this::setSignature;
+ }
+
+ @Transient
+ @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 extends BaseTag> tagList) {
if (tagList != null && !tagList.isEmpty()) {
for (ITag t : tagList) {
@@ -237,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/GenericMessage.java b/nostr-java-event/src/main/java/nostr/event/impl/GenericMessage.java
index ee06ffeaf..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
@@ -7,13 +7,14 @@
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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author squirrel
@@ -26,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);
}
@@ -40,19 +38,23 @@ 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
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 ENCODER_MAPPED_AFTERBURNER.writeValueAsString(getArrayNode());
}
public static T decode(@NonNull Object[] msgArr) {
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..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
@@ -1,56 +1,90 @@
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);
+ 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, nip, new ArrayList<>());
+ this(code, new ArrayList<>());
+ }
+
+ 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;
}
@Override
- public void addAttribute(ElementAttribute attribute) {
- this.attributes.add(attribute);
+ public void addAttribute(@NonNull ElementAttribute... attribute) {
+ this.addAttributes(List.of(attribute));
}
+ @Override
+ public void addAttributes(@NonNull List attributes) {
+ this.attributes.addAll(attributes);
+ }
+
+ /**
+ * 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, nip, List.of(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) {
- 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);
- }
-}
\ No newline at end of file
+ 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, @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());
+ }
+}
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..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;
@@ -45,8 +43,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..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,6 +16,8 @@
import nostr.event.Kind;
import nostr.event.NIP01Event;
+import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author squirrel
@@ -59,7 +60,7 @@ public void update() {
}
private void setContent() {
- var mapper = IEncoder.MAPPER;
+ 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 8c47e017f..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 IEncoder.MAPPER.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/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/BaseTagEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagEncoder.java
index 9dc9dc6f8..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,43 +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.IEncoder;
-import nostr.base.Relay;
+import nostr.base.Encoder;
import nostr.event.BaseTag;
import nostr.event.json.serializer.TagSerializer;
-/**
- * @author guilhermegps
- *
- */
@Data
-@AllArgsConstructor
-public class BaseTagEncoder implements IEncoder {
+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 {
- SimpleModule module = new SimpleModule();
- module.addSerializer(new TagSerializer());
- var mapper = (new ObjectMapper())
- .setSerializationInclusion(Include.NON_NULL)
- .registerModule(module);
-
- return mapper.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/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..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 = MAPPER.createObjectNode();
+ ObjectNode root = ENCODER_MAPPED_AFTERBURNER.createObjectNode();
filters.getFiltersMap().forEach((key, filterableList) -> {
- final ObjectNode objectNode = MAPPER.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/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/GenericTagDecoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java
index e8658a779..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
@@ -1,42 +1,40 @@
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 lombok.NonNull;
import nostr.base.ElementAttribute;
import nostr.base.IDecoder;
import nostr.event.impl.GenericTag;
+import java.util.stream.IntStream;
+
@Data
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 {
- ObjectMapper objectMapper = new ObjectMapper();
- String[] jsonElements = objectMapper.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);
+ String[] jsonElements = I_DECODER_MAPPER_AFTERBURNER.readValue(json, String[].class);
+ GenericTag genericTag = new GenericTag(
+ 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) {
throw new RuntimeException(ex);
}
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 006b13c19..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 FEncoder.MAPPER.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..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,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.Nip05Content;
+import static nostr.base.IEvent.MAPPER_AFTERBURNER;
+
/**
*
* @author eric
@@ -22,7 +23,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
deleted file mode 100644
index 91b3a581c..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 = IEncoder.MAPPER.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")));
- });
-
- return IEncoder.MAPPER.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 2d3ba9b02..000000000
--- a/nostr-java-event/src/main/java/nostr/event/json/serializer/CustomBaseListSerializer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package nostr.event.json.serializer;
-
-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 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;
-
-/**
- * @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 = IEncoder.MAPPER;
- 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/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/main/java/nostr/event/message/CanonicalAuthenticationMessage.java b/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java
index 3599a1a10..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;
@@ -20,6 +18,9 @@
import java.util.List;
import java.util.Map;
+import static nostr.base.IDecoder.I_DECODER_MAPPER_AFTERBURNER;
+import static nostr.base.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
* @author eric
*/
@@ -36,16 +37,16 @@ public CanonicalAuthenticationMessage(CanonicalAuthenticationEvent event) {
}
@Override
public String encode() throws JsonProcessingException {
- return IEncoder.MAPPER.writeValueAsString(
+ return ENCODER_MAPPED_AFTERBURNER.writeValueAsString(
getArrayNode()
.add(getCommand())
- .add(IEncoder.MAPPER.readTree(
+ .add(ENCODER_MAPPED_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)
@@ -62,7 +63,8 @@ public static T decode(@NonNull Map map, ObjectMapper ma
}
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();
}
-}
\ 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..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author squirrel
@@ -31,7 +32,7 @@ public CloseMessage(String subscriptionId) {
@Override
public String encode() throws JsonProcessingException {
- return IEncoder.MAPPER.writeValueAsString(
+ return ENCODER_MAPPED_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
deleted file mode 100644
index 628c7adbf..000000000
--- a/nostr-java-event/src/main/java/nostr/event/message/ClosedMessage.java
+++ /dev/null
@@ -1,35 +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.base.IEncoder;
-import nostr.event.BaseMessage;
-
-@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 IEncoder.MAPPER.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/EoseMessage.java b/nostr-java-event/src/main/java/nostr/event/message/EoseMessage.java
index d00b57cf9..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author squirrel
@@ -31,7 +32,7 @@ public EoseMessage(String subId) {
@Override
public String encode() throws JsonProcessingException {
- return IEncoder.MAPPER.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 7caf29d7d..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
@Setter
@Getter
public class EventMessage extends BaseMessage {
@@ -43,11 +44,12 @@ public String encode() throws JsonProcessingException {
var arrayNode = getArrayNode().add(getCommand());
Optional.ofNullable(getSubscriptionId())
.ifPresent(arrayNode::add);
- arrayNode.add(IEncoder.MAPPER.readTree(
+ arrayNode.add(ENCODER_MAPPED_AFTERBURNER.readTree(
new BaseEventEncoder<>((BaseEvent)getEvent()).encode()));
- return IEncoder.MAPPER.writeValueAsString(arrayNode);
+ return ENCODER_MAPPED_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/NoticeMessage.java b/nostr-java-event/src/main/java/nostr/event/message/NoticeMessage.java
index 745e33510..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author squirrel
@@ -27,7 +28,7 @@ public NoticeMessage(@NonNull String message) {
@Override
public String encode() throws JsonProcessingException {
- return IEncoder.MAPPER.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 9245ba1e1..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
@@ -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.Encoder.ENCODER_MAPPED_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 ENCODER_MAPPED_AFTERBURNER.writeValueAsString(
getArrayNode()
.add(getCommand())
.add(getEventId())
@@ -43,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/message/RelayAuthenticationMessage.java b/nostr-java-event/src/main/java/nostr/event/message/RelayAuthenticationMessage.java
index bbd894428..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
*
* @author eric
@@ -27,7 +28,7 @@ public RelayAuthenticationMessage(String challenge) {
@Override
public String encode() throws JsonProcessingException {
- return IEncoder.MAPPER.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 f3f2d1491..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
@@ -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.Encoder.ENCODER_MAPPED_AFTERBURNER;
+
/**
* @author squirrel
*/
@@ -31,7 +32,6 @@ public class ReqMessage extends BaseMessage {
private final List