Intial commit

This commit is contained in:
Willem Cazander 2023-09-24 12:41:43 +02:00
parent 7329fb8dea
commit 73f201bdac
268 changed files with 11220 additions and 5 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@
# #
# Ignore project resources # Ignore project resources
no2all-zerofungus/logs
# Ignore maven resources # Ignore maven resources
target target

View file

@ -1,9 +1,10 @@
# No2All # No2All
THIS WIP AND NEVER BEEN RUN. WIP-NOTE; Never been started as only 20% is done.
Send signed notes to all, is a java library to work with the nostr protocol. Send signed notes to all, no2all-nostr is a POJO library to work
And zerofungus moves all packages managers over two blockchains. with the nostr protocol. And no2all-zerofungus is experimental server
to move all package managers content in DAT and signed in nostr..
TODO: With java webstart example over DAT protocol. TODO: With java webstart example over DAT protocol.
This wowk though dewey of UwU is done in toe toe twailing chains. This wowk though dewey of UwU is done in toe toe twailing chains.
@ -28,8 +29,9 @@ todo
- NIP-X: Add "nsecpw" password protected private key in bech32 TLV format - NIP-X: Add "nsecpw" password protected private key in bech32 TLV format
- NIP-X: Add "nssurl" bech32 TLV for encoded url+pubkey+pubvals+?sockey - NIP-X: Add "nssurl" bech32 TLV for encoded url+pubkey+pubvals+?sockey
- NIP-X: Add "nsseed" web of trust voting(plus/min) + policy tree trust for revoke, like running npkg apps - NIP-X: Add "nsseed" web of trust voting(plus/min) + policy tree trust for revoke, like running npkg apps
- NIP-X: Add "npkgurl" Universal pkg, seed msg type to relay + upkeep + replopt - NIP-X: Add "npkgurl" Universal pkg(+refs) of mime types, seed msg type to relay + upkeep + replopt
- NIP-X: Redo/Clone NIP-89 appurl handlers - NIP-X: Add new WS messages for relay managed writable dat streams (after client auth)
- NIP-X: Redo/Rm/Clone NIP-89 appurl handlers
## ZeroFunGus ## ZeroFunGus
@ -59,3 +61,4 @@ This will run;
- Optional create native OS menu entry for application - Optional create native OS menu entry for application
- Run jvm with jars and parameters from jnlp file - Run jvm with jars and parameters from jnlp file
- Welcome to a js free world over 2 blockchains - Welcome to a js free world over 2 blockchains
- Also called "The red sea file system" to boot an TempleOS instance

20
no2all-nostr/pom.xml Normal file
View file

@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>love.distributedrebirth.no2all</groupId>
<artifactId>no2all</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>no2all-nostr</artifactId>
<name>No2All-NoStr</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>no2all-octo</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,25 @@
package love.distributedrebirth.no2all.nostr;
import java.util.function.Consumer;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireWaterBoiler;
import love.distributedrebirth.no2all.nostr.fire.NoStrFirePipe;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentity;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClient;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelay;
public enum NoStr {
FACTORY;
public NoStrFireWaterBoiler boiler(NoStrIdentity identity) {
return new NoStrFireWaterBoiler(identity);
}
public NoStrFirePipe pipeReaderClient(Consumer<String> errHandler, Consumer<NoStrMsgToClient> msgHandler) {
return new NoStrFirePipe(errHandler, null, msgHandler);
}
public NoStrFirePipe pipeReaderRelay(Consumer<String> errHandler, Consumer<NoStrMsgToRelay> msgHandler) {
return new NoStrFirePipe(errHandler, msgHandler, null);
}
}

View file

@ -0,0 +1,9 @@
package love.distributedrebirth.no2all.nostr;
import jakarta.json.JsonValue;
public interface NoStrGospel {
// slow version, add perf test, rewrite to streaming mode
JsonValue toBible();
}

View file

@ -0,0 +1,72 @@
package love.distributedrebirth.no2all.nostr.fire;
import java.io.StringReader;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClient;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelay;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrFirePipe {
private static final String ERROR_INVALID_JSON = "Invalid json; "; // on json parse
private static final String ERROR_INVALID_ROOT = "Invalid root; "; // on none array root
private static final String ERROR_TYPE_UNKNOWN = "Unknown type; "; // on not in values()
private static final String ERROR_TYPE_ILLEGAL = "Illegal type"; // on null mapper
private static final int MSG_TYPE_INDEX = 0;
private final Consumer<String> errHandler;
private final Consumer<NoStrMsgToRelay> msgHandlerToRelay;
private final Consumer<NoStrMsgToClient> msgHandlerToClient;
public NoStrFirePipe(Consumer<String> errHandler, Consumer<NoStrMsgToRelay> msgHandlerToRelay,
Consumer<NoStrMsgToClient> msgHandlerToClient) {
this.errHandler = Objects.requireNonNull(errHandler);
this.msgHandlerToRelay = msgHandlerToRelay;
this.msgHandlerToClient = msgHandlerToClient;
if (msgHandlerToRelay != null && msgHandlerToClient != null) {
throw new IllegalArgumentException("Only use one message handler");
}
if (msgHandlerToRelay == null && msgHandlerToClient == null) {
throw new NullPointerException("Need one message handler");
}
}
public void onFire(String msgStr) {
JsonValue msgJson = null;
try (JsonReader jsonReader = Json.createReader(new StringReader(msgStr))) {
msgJson = jsonReader.readValue();
} catch (Exception e) {
errHandler.accept(ERROR_INVALID_JSON + e.getMessage());
return;
}
if (!JsonValue.ValueType.ARRAY.equals(msgJson.getValueType())) {
errHandler.accept(ERROR_INVALID_ROOT + msgJson.getValueType().name());
return;
}
JsonArray msgPacket = msgJson.asJsonArray();
String msgTypeRaw = msgPacket.getString(MSG_TYPE_INDEX);
if (!NoStrImplMessageType.valueOfValid(msgTypeRaw)) {
errHandler.accept(ERROR_TYPE_UNKNOWN + msgTypeRaw);
return;
}
NoStrImplMessageType msgType = NoStrImplMessageType.valueOf(msgTypeRaw);
if (msgHandlerToClient != null) {
acceptType(msgType.getMapperToClient(), v -> msgHandlerToClient.accept(v.apply(msgPacket))); // on relay
} else {
acceptType(msgType.getMapperToRelay(), v -> msgHandlerToRelay.accept(v.apply(msgPacket))); // on client
}
}
private <T> void acceptType(Optional<T> mapper, Consumer<T> messageHandler) {
if (mapper.isEmpty()) {
errHandler.accept(ERROR_TYPE_ILLEGAL);
return;
}
messageHandler.accept(mapper.get());
}
}

View file

@ -0,0 +1,8 @@
package love.distributedrebirth.no2all.nostr.fire;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTag;
public interface NoStrFireStackFishWelder {
NoStrFireStackWelder tag(NoStrEventTag eventTag);
}

View file

@ -0,0 +1,76 @@
package love.distributedrebirth.no2all.nostr.fire;
import java.util.List;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTag;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagMeta;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagA;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagAlt;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagClient;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagContentWarning;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagD;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagDescription;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagE;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagI;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagImage;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagName;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagNonce;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagP;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagPublishedAt;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagR;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagSubject;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagSummary;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagT;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagThumb;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagTitle;
public class NoStrFireStackWelder implements NoStrFireStackFishWelder,
NoStrTagA.FishWelder,
NoStrTagAlt.FishWelder,
NoStrTagClient.FishWelder,
NoStrTagContentWarning.FishWelder,
NoStrTagD.FishWelder,
NoStrTagDescription.FishWelder,
NoStrTagE.FishWelder,
NoStrTagI.FishWelder,
NoStrTagImage.FishWelder,
NoStrTagName.FishWelder,
NoStrTagNonce.FishWelder,
NoStrTagP.FishWelder,
NoStrTagPublishedAt.FishWelder,
NoStrTagR.FishWelder,
NoStrTagSubject.FishWelder,
NoStrTagSummary.FishWelder,
NoStrTagT.FishWelder,
NoStrTagThumb.FishWelder,
NoStrTagTitle.FishWelder
{
private final NoStrFireWaterWelder welder;
protected NoStrFireStackWelder(NoStrFireWaterWelder welder) {
this.welder = welder;
}
public NoStrFireWaterWelder burn() {
return welder;
}
@Override
public NoStrFireStackWelder tag(NoStrEventTag eventTag) {
welder.smokeTag(eventTag);
return this;
}
public NoStrFireStackWelder tags(List<NoStrEventTag> eventTags) {
eventTags.forEach(v -> welder.smokeTag(v));
return this;
}
public NoStrFireStackWelder tag(NoStrEventTagMeta tag, String... args) {
return tag(NoStrEventTag.valueOf(tag, args));
}
public NoStrFireStackWelder tag(String tag, String... args) {
return tag(NoStrEventTagMeta.valueOf(tag), args);
}
}

View file

@ -0,0 +1,62 @@
package love.distributedrebirth.no2all.nostr.fire;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentity;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.NoStrProfileMetaData;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagP;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrFireWaterBoiler {
private final NoStrIdentity identity;
public NoStrFireWaterBoiler(NoStrIdentity identity) {
this.identity = Objects.requireNonNull(identity);
}
public NoStrFireWaterWelder burn() {
return new NoStrFireWaterWelder(identity);
}
public NoStrFireStackWelder smoker() {
return new NoStrFireStackWelder(burn());
}
public NoStrEvent boilProfileMetaData(NoStrProfileMetaData profileData) {
return burn().water(NoStrImplEventKind.METADATA, profileData.toBible().toString());
}
public NoStrEvent boilClientAuth(String relay, String challenge) {
return smoker()
.tag(NoStrImplEventTag.RELAY, relay)
.tag(NoStrImplEventTag.CHALLENGE, challenge)
.burn()
.water(NoStrImplEventKind.CLIENT_AUTH);
}
public NoStrEvent boilRecommendRelay(String relayUrl) {
return burn().water(NoStrImplEventKind.RECOMMEND_RELAY, relayUrl);
}
public NoStrEvent boilTextNote(String content, String subject, List<NoStrIdentityPublicKey> pubs) {
return smoker()
.tagSubject(subject)
.tags(pubs.stream().map(v -> new NoStrTagP(v, Optional.empty(), Optional.empty())).collect(Collectors.toList()))
.burn()
.water(NoStrImplEventKind.TEXT_NOTE, content);
}
// public NoStrEvent waterTextNote(String content, List<Object> eTags, List<NoStrIdentityPublicKey> pubs) {
// return smoker()
// .tag(NoStrImplEventTag.P, pubs.stream().map(v -> v.getHex()).collect(Collectors.toList()))
// .weld()
// .water(NoStrImplEventKind.TEXT_NOTE, content);
// }
}

View file

@ -0,0 +1,70 @@
package love.distributedrebirth.no2all.nostr.fire;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentity;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventPayload;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventSignature;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTag;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagMeta;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagClient;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public class NoStrFireWaterWelder {
private final List<NoStrEventTag> smokeTags = new ArrayList<>();
private final NoStrIdentity identity;
public NoStrFireWaterWelder(NoStrIdentity identity) {
this.identity = Objects.requireNonNull(identity);
}
public NoStrFireWaterWelder smokeTag(NoStrEventTag tag) {
smokeTags.add(Objects.requireNonNull(tag));
return this;
}
private List<NoStrEventTag> findByMeta(NoStrEventTagMeta meta) {
List<NoStrEventTag> result = new ArrayList<>();
for (NoStrEventTag tag : smokeTags) {
if (tag.getMeta().getQName().equals(meta.getQName())) {
result.add(tag);
}
}
return result;
}
private void waterFishNet(NoStrEventKind kind) {
// TODO: here ? and on which kinds ALL ?
if (NoStrImplEventKind.TEXT_NOTE.equals(kind)) {
if (findByMeta(NoStrImplEventTag.CLIENT).isEmpty()) {
smokeTags.add(new NoStrTagClient("No2All", Optional.empty()));
}
}
// validate per kind minimal required tags here ?
}
public NoStrEvent water(NoStrEventKind kind, String content) {
waterFishNet(kind);
Instant wave = Instant.now();
NoStrEventPayload payload = new NoStrEventPayload(identity.getPublicKey(), wave, kind, smokeTags, content);
return NoStrEventSignature.sign(payload, identity.getPrivateKey());
}
public NoStrEvent water(NoStrEventKind kind) {
return water(kind, "");
}
public NoStrEvent water(NoStrEventKind kind, String content, List<NoStrEventTag> tags) {
this.smokeTags.addAll(tags);
return water(kind, content);
}
}

View file

@ -0,0 +1,22 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.Objects;
public final class NoStrIdentity {
private final NoStrIdentityPrivateKey privateKey;
private final NoStrIdentityPublicKey publicKey;
public NoStrIdentity(NoStrIdentityPrivateKey privateKey) {
this.privateKey = Objects.requireNonNull(privateKey);
this.publicKey = NoStrIdentityPublicKey.of(privateKey);
}
public NoStrIdentityPrivateKey getPrivateKey() {
return privateKey;
}
public NoStrIdentityPublicKey getPublicKey() {
return publicKey;
}
}

View file

@ -0,0 +1,24 @@
package love.distributedrebirth.no2all.nostr.model;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplBinHexAdapter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
import love.distributedrebirth.no2all.octo.trust.OctoTrust;
import love.distributedrebirth.no2all.octo.trust.OctoTrustException;
public final class NoStrIdentityPrivateKey extends NoStrImplBinHexAdapter {
public NoStrIdentityPrivateKey(byte[] keyBytes) {
super(keyBytes);
if (keyBytes.length != OctoTrust.KEY_LENGTH) {
throw new OctoTrustException("Key length is not: " + OctoTrust.KEY_LENGTH);
}
}
public static NoStrIdentityPrivateKey ofRandom() {
return new NoStrIdentityPrivateKey(OctoTrust.generateSecretKey());
}
public static NoStrIdentityPrivateKey ofHex(String keyHex) {
return new NoStrIdentityPrivateKey(OctoBitFormat.HEX.toBytes(keyHex));
}
}

View file

@ -0,0 +1,25 @@
package love.distributedrebirth.no2all.nostr.model;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplBinHexAdapter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
import love.distributedrebirth.no2all.octo.trust.OctoTrust;
import love.distributedrebirth.no2all.octo.trust.OctoTrustException;
import love.distributedrebirth.no2all.octo.trust.OctoTrustSchnorr;
public final class NoStrIdentityPublicKey extends NoStrImplBinHexAdapter {
public NoStrIdentityPublicKey(byte[] keyBytes) {
super(keyBytes);
if (keyBytes.length != OctoTrust.KEY_LENGTH) {
throw new OctoTrustException("Key length is not: " + OctoTrust.KEY_LENGTH);
}
}
public static NoStrIdentityPublicKey ofHex(String keyHex) {
return new NoStrIdentityPublicKey(OctoBitFormat.HEX.toBytes(keyHex));
}
public static NoStrIdentityPublicKey of(NoStrIdentityPrivateKey privateKey) {
return new NoStrIdentityPublicKey(OctoTrustSchnorr.extractPublicKey(privateKey.getBytes()));
}
}

View file

@ -0,0 +1,77 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.List;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrKindValue {
private final int kind;
private final int kindStopRange;
public NoStrKindValue(int kind) {
this(kind, -1);
}
public NoStrKindValue(int kind, int kindStopRange) {
this.kind = kind;
this.kindStopRange = kindStopRange;
}
public int getKind() {
return kind;
}
public int getKindStopRange() {
return kindStopRange;
}
public boolean isRange() {
return kindStopRange != -1;
}
public static void readArrayKinds(JsonObject json, NoStrImplQName jsonName, List<NoStrKindValue> data) {
readArrayKinds(json, jsonName.getQName(), data);
}
public static void readArrayKinds(JsonObject json, String jsonName, List<NoStrKindValue> data) {
if (!json.containsKey(jsonName)) {
return;
}
JsonArray values = json.getJsonArray(jsonName);
for (int i = 0; i < values.size(); i++) {
JsonValue value = values.get(i);
if (JsonValue.ValueType.ARRAY.equals(value.getValueType())) {
JsonArray arr = value.asJsonArray();
int v1 = arr.getInt(0);
int v2 = arr.getInt(1);
data.add(new NoStrKindValue(v1, v2));
} else {
data.add(new NoStrKindValue(values.getInt(i)));
}
}
}
public static void writeArrayKinds(JsonObjectBuilder json, NoStrImplQName jsonName, List<NoStrKindValue> data) {
writeArrayKinds(json, jsonName.getQName(), data);
}
public static void writeArrayKinds(JsonObjectBuilder json, String jsonName, List<NoStrKindValue> data) {
NoStrImplChuch.writeArray(json, jsonName, data, (r, v) -> {
if (v.isRange()) {
r.add(Json.createArrayBuilder()
.add(v.getKind())
.add(v.getKindStopRange())
.build());
} else {
r.add(v.getKind());
}
});
}
}

View file

@ -0,0 +1,121 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.HashMap;
import java.util.Map;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrProfileMetaData implements NoStrGospel {
private final Map<String, String> fields = new HashMap<>();
public NoStrProfileMetaData() {
}
public NoStrProfileMetaData(JsonObject value) {
for (String fieldName : value.keySet()) {
JsonValue fieldValue = value.get(fieldName);
if (fieldValue instanceof JsonString) {
fields.put(fieldName, ((JsonString)fieldValue).getString());
}
}
}
@Override
public JsonValue toBible() {
return Json.createObjectBuilder(fields).build();
}
private enum QName implements NoStrImplQName {
NAME,
DISPLAY_NAME,
ABOUT,
WEBSITE,
PICTURE,
BANNER,
NIP05,
LUD16
;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public String getName() {
return fields.get(QName.NAME.getQName());
}
public void setName(String name) {
this.fields.put(QName.NAME.getQName(), name);
}
public String getDisplayName() {
return fields.get(QName.DISPLAY_NAME.getQName());
}
public void setDisplayName(String displayName) {
this.fields.put(QName.DISPLAY_NAME.getQName(), displayName);
}
public String getAbout() {
return fields.get(QName.ABOUT.getQName());
}
public void setAbout(String about) {
this.fields.put(QName.ABOUT.getQName(), about);
}
public String getWebsite() {
return fields.get(QName.WEBSITE.getQName());
}
public void setWebsite(String website) {
this.fields.put(QName.WEBSITE.getQName(), website);
}
public String getPicture() {
return fields.get(QName.PICTURE.getQName());
}
public void setPicture(String picture) {
this.fields.put(QName.PICTURE.getQName(), picture);
}
public String getBanner() {
return fields.get(QName.BANNER.getQName());
}
public void setBanner(String banner) {
this.fields.put(QName.BANNER.getQName(), banner);
}
public String getNip05() {
return fields.get(QName.NIP05.getQName());
}
public void setNip05(String nip05) {
this.fields.put(QName.NIP05.getQName(), nip05);
}
public String getLud16() {
return fields.get(QName.LUD16.getQName());
}
public void setLud16(String lud16) {
this.fields.put(QName.LUD16.getQName(), lud16);
}
}

View file

@ -0,0 +1,250 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.ArrayList;
import java.util.List;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrRelayInfo implements NoStrGospel {
private String id;
private String name;
private String description;
private String publicKey;
private String contact;
private final List<Integer> supportedNips = new ArrayList<>();
private String software;
private String version;
private NoStrRelayInfoLimitation limitation;
private final List<NoStrRelayInfoRetention> retentions = new ArrayList<>();
private final List<String> relayCountries = new ArrayList<>();
private final List<String> languageTags = new ArrayList<>();
private final List<String> tags = new ArrayList<>();
private String postingPolicy;
private String paymentUrl;
private final List<NoStrRelayInfoPayment> feesAdmission = new ArrayList<>();
private final List<NoStrRelayInfoPayment> feesSubscription = new ArrayList<>();
private final List<NoStrRelayInfoPayment> feesPublication = new ArrayList<>();
public NoStrRelayInfo() {
}
public NoStrRelayInfo(JsonObject json) {
id = NoStrImplChuch.readString(json, QName.ID);
name = NoStrImplChuch.readString(json, QName.NAME);
description = NoStrImplChuch.readString(json, QName.DESCRIPTION);
publicKey = NoStrImplChuch.readString(json, QName.PUBKEY);
contact = NoStrImplChuch.readString(json, QName.CONTACT);
if (json.containsKey(QName.SUPPORTED_NIPS.getQName())) {
JsonArray values = json.getJsonArray(QName.SUPPORTED_NIPS.getQName());
for (int i = 0; i < values.size(); i++) {
supportedNips.add(values.getInt(i));
}
}
software = NoStrImplChuch.readString(json, QName.SOFTWARE);
version = NoStrImplChuch.readString(json, QName.VERSION);
JsonValue limitationJson = json.get(QName.LIMITATION.getQName());
if (limitationJson != null && JsonValue.ValueType.OBJECT.equals(limitationJson.getValueType())) {
limitation = new NoStrRelayInfoLimitation(limitationJson.asJsonObject());
}
NoStrImplChuch.readArray(json, QName.RETENTION, v -> retentions.add(new NoStrRelayInfoRetention(v.asJsonObject())));
NoStrImplChuch.readArrayString(json, QName.RELAY_COUNTRIES, relayCountries);
NoStrImplChuch.readArrayString(json, QName.LANGUAGE_TAGS, languageTags);
NoStrImplChuch.readArrayString(json, QName.TAGS, tags);
postingPolicy = NoStrImplChuch.readString(json, QName.POSTING_POLICY);
paymentUrl = NoStrImplChuch.readString(json, QName.PAYMENT_URL);
JsonValue feesJson = json.get(QName.FEES.getQName());
if (feesJson != null && JsonValue.ValueType.OBJECT.equals(feesJson.getValueType())) {
JsonObject feesObject = feesJson.asJsonObject();
NoStrImplChuch.readArray(feesObject, QName.ADMISSION, v -> feesAdmission.add(new NoStrRelayInfoPayment(v.asJsonObject())));
NoStrImplChuch.readArray(feesObject, QName.SUBSCRIPTION, v -> feesSubscription.add(new NoStrRelayInfoPayment(v.asJsonObject())));
NoStrImplChuch.readArray(feesObject, QName.PUBLICATION, v -> feesPublication.add(new NoStrRelayInfoPayment(v.asJsonObject())));
}
}
@Override
public JsonValue toBible() {
JsonObjectBuilder result = Json.createObjectBuilder();
NoStrImplChuch.writeString(result, QName.ID, id);
NoStrImplChuch.writeString(result, QName.NAME, name);
NoStrImplChuch.writeString(result, QName.DESCRIPTION, description);
NoStrImplChuch.writeString(result, QName.PUBKEY, publicKey);
NoStrImplChuch.writeString(result, QName.CONTACT, contact);
NoStrImplChuch.writeArray(result, QName.SUPPORTED_NIPS, supportedNips, (r, v) -> r.add(v));
NoStrImplChuch.writeString(result, QName.SOFTWARE, software);
NoStrImplChuch.writeString(result, QName.VERSION, version);
if (limitation != null) {
result.add(QName.LIMITATION.getQName(), limitation.toBible());
}
NoStrImplChuch.writeArrayWriter(result, QName.RETENTION, retentions);
NoStrImplChuch.writeArrayString(result, QName.RELAY_COUNTRIES, relayCountries);
NoStrImplChuch.writeArrayString(result, QName.LANGUAGE_TAGS, languageTags);
NoStrImplChuch.writeArrayString(result, QName.TAGS, tags);
NoStrImplChuch.writeString(result, QName.POSTING_POLICY, postingPolicy);
NoStrImplChuch.writeString(result, QName.PAYMENT_URL, paymentUrl);
JsonObjectBuilder feesObject = Json.createObjectBuilder();
NoStrImplChuch.writeArrayWriter(feesObject, QName.ADMISSION, feesAdmission);
NoStrImplChuch.writeArrayWriter(feesObject, QName.SUBSCRIPTION, feesSubscription);
NoStrImplChuch.writeArrayWriter(feesObject, QName.PUBLICATION, feesPublication);
result.add(QName.FEES.getQName(), feesObject);
return result.build();
}
private enum QName implements NoStrImplQName {
ID,
NAME,
DESCRIPTION,
PUBKEY,
CONTACT,
SUPPORTED_NIPS,
SOFTWARE,
VERSION,
LIMITATION,
RETENTION,
RELAY_COUNTRIES,
LANGUAGE_TAGS,
TAGS,
POSTING_POLICY,
PAYMENT_URL,
ADMISSION,
SUBSCRIPTION,
PUBLICATION,
FEES,
;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getSoftware() {
return software;
}
public void setSoftware(String software) {
this.software = software;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public NoStrRelayInfoLimitation getLimitation() {
return limitation;
}
public void setLimitation(NoStrRelayInfoLimitation limitation) {
this.limitation = limitation;
}
public String getPostingPolicy() {
return postingPolicy;
}
public void setPostingPolicy(String postingPolicy) {
this.postingPolicy = postingPolicy;
}
public String getPaymentUrl() {
return paymentUrl;
}
public void setPaymentUrl(String paymentUrl) {
this.paymentUrl = paymentUrl;
}
public List<Integer> getSupportedNips() {
return supportedNips;
}
public List<NoStrRelayInfoRetention> getRetentions() {
return retentions;
}
public List<String> getRelayCountries() {
return relayCountries;
}
public List<String> getLanguageTags() {
return languageTags;
}
public List<String> getTags() {
return tags;
}
public List<NoStrRelayInfoPayment> getFeesAdmission() {
return feesAdmission;
}
public List<NoStrRelayInfoPayment> getFeesSubscription() {
return feesSubscription;
}
public List<NoStrRelayInfoPayment> getFeesPublication() {
return feesPublication;
}
}

View file

@ -0,0 +1,173 @@
package love.distributedrebirth.no2all.nostr.model;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrRelayInfoLimitation implements NoStrGospel {
private Integer maxMessageLength;
private Integer maxSubscriptions;
private Integer maxFilters;
private Integer maxLimit;
private Integer maxSubIdLength;
private Integer minPrefix;
private Integer maxEventTags;
private Integer maxContentLength;
private Integer minPowDifficulty;
private Boolean authRequired;
private Boolean paymentRequired;
public NoStrRelayInfoLimitation() {
}
public NoStrRelayInfoLimitation(JsonObject json) {
maxMessageLength = NoStrImplChuch.readInteger(json, QName.MAX_MESSAGE_LENGTH);
maxSubscriptions = NoStrImplChuch.readInteger(json, QName.MAX_SUBSCRIPTIONS);
maxFilters = NoStrImplChuch.readInteger(json, QName.MAX_FILTERS);
maxLimit = NoStrImplChuch.readInteger(json, QName.MAX_LIMIT);
maxSubIdLength = NoStrImplChuch.readInteger(json, QName.MAX_SUBID_LENGTH);
minPrefix = NoStrImplChuch.readInteger(json, QName.MIN_PREFIX);
maxEventTags = NoStrImplChuch.readInteger(json, QName.MAX_EVENT_TAGS);
maxContentLength = NoStrImplChuch.readInteger(json, QName.MAX_CONTENT_LENGTH);
minPowDifficulty = NoStrImplChuch.readInteger(json, QName.MIN_POW_DIFFICULTY);
authRequired = NoStrImplChuch.readBoolean(json, QName.AUTH_REQUIRED);
paymentRequired = NoStrImplChuch.readBoolean(json, QName.PAYMENT_REQUIRED);
}
@Override
public JsonValue toBible() {
JsonObjectBuilder result = Json.createObjectBuilder();
NoStrImplChuch.writeInteger(result, QName.MAX_MESSAGE_LENGTH, maxMessageLength);
NoStrImplChuch.writeInteger(result, QName.MAX_SUBSCRIPTIONS, maxSubscriptions);
NoStrImplChuch.writeInteger(result, QName.MAX_FILTERS, maxFilters);
NoStrImplChuch.writeInteger(result, QName.MAX_LIMIT, maxLimit);
NoStrImplChuch.writeInteger(result, QName.MAX_SUBID_LENGTH, maxSubIdLength);
NoStrImplChuch.writeInteger(result, QName.MIN_PREFIX, minPrefix);
NoStrImplChuch.writeInteger(result, QName.MAX_EVENT_TAGS, maxEventTags);
NoStrImplChuch.writeInteger(result, QName.MAX_CONTENT_LENGTH, maxContentLength);
NoStrImplChuch.writeInteger(result, QName.MIN_POW_DIFFICULTY, minPowDifficulty);
NoStrImplChuch.writeBoolean(result, QName.AUTH_REQUIRED, authRequired);
NoStrImplChuch.writeBoolean(result, QName.PAYMENT_REQUIRED, paymentRequired);
return result.build();
}
private enum QName implements NoStrImplQName {
MAX_MESSAGE_LENGTH,
MAX_SUBSCRIPTIONS,
MAX_FILTERS,
MAX_LIMIT,
MAX_SUBID_LENGTH,
MIN_PREFIX,
MAX_EVENT_TAGS,
MAX_CONTENT_LENGTH,
MIN_POW_DIFFICULTY,
AUTH_REQUIRED,
PAYMENT_REQUIRED,
;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public Integer getMaxMessageLength() {
return maxMessageLength;
}
public void setMaxMessageLength(Integer maxMessageLength) {
this.maxMessageLength = maxMessageLength;
}
public Integer getMaxSubscriptions() {
return maxSubscriptions;
}
public void setMaxSubscriptions(Integer maxSubscriptions) {
this.maxSubscriptions = maxSubscriptions;
}
public Integer getMaxFilters() {
return maxFilters;
}
public void setMaxFilters(Integer maxFilters) {
this.maxFilters = maxFilters;
}
public Integer getMaxLimit() {
return maxLimit;
}
public void setMaxLimit(Integer maxLimit) {
this.maxLimit = maxLimit;
}
public Integer getMaxSubIdLength() {
return maxSubIdLength;
}
public void setMaxSubIdLength(Integer maxSubIdLength) {
this.maxSubIdLength = maxSubIdLength;
}
public Integer getMinPrefix() {
return minPrefix;
}
public void setMinPrefix(Integer minPrefix) {
this.minPrefix = minPrefix;
}
public Integer getMaxEventTags() {
return maxEventTags;
}
public void setMaxEventTags(Integer maxEventTags) {
this.maxEventTags = maxEventTags;
}
public Integer getMaxContentLength() {
return maxContentLength;
}
public void setMaxContentLength(Integer maxContentLength) {
this.maxContentLength = maxContentLength;
}
public Integer getMinPowDifficulty() {
return minPowDifficulty;
}
public void setMinPowDifficulty(Integer minPowDifficulty) {
this.minPowDifficulty = minPowDifficulty;
}
public Boolean getAuthRequired() {
return authRequired;
}
public void setAuthRequired(Boolean authRequired) {
this.authRequired = authRequired;
}
public Boolean getPaymentRequired() {
return paymentRequired;
}
public void setPaymentRequired(Boolean paymentRequired) {
this.paymentRequired = paymentRequired;
}
}

View file

@ -0,0 +1,78 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.ArrayList;
import java.util.List;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrRelayInfoPayment implements NoStrGospel {
private final List<NoStrKindValue> kinds = new ArrayList<>();
private Integer amount;
private String unit;
public NoStrRelayInfoPayment(int amount, String unit) {
this.amount = amount;
this.unit = unit;
}
public NoStrRelayInfoPayment(JsonObject json) {
NoStrKindValue.readArrayKinds(json, QName.KINDS, kinds);
amount = NoStrImplChuch.readInteger(json, QName.AMOUNT);
unit = NoStrImplChuch.readString(json, QName.UNIT);
}
@Override
public JsonValue toBible() {
JsonObjectBuilder result = Json.createObjectBuilder();
NoStrKindValue.writeArrayKinds(result, QName.KINDS, kinds);
NoStrImplChuch.writeInteger(result, QName.AMOUNT, amount);
NoStrImplChuch.writeString(result, QName.UNIT, unit);
return result.build();
}
private enum QName implements NoStrImplQName {
KINDS,
AMOUNT,
UNIT,
;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public List<NoStrKindValue> getKinds() {
return kinds;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}

View file

@ -0,0 +1,81 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.ArrayList;
import java.util.List;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrRelayInfoRetention implements NoStrGospel {
private final List<NoStrKindValue> kinds = new ArrayList<>();
private Integer time;
private Integer count;
public NoStrRelayInfoRetention() {
}
public NoStrRelayInfoRetention(Integer time, Integer count) {
this.time = time;
this.count = count;
}
public NoStrRelayInfoRetention(JsonObject json) {
NoStrKindValue.readArrayKinds(json, QName.KINDS, kinds);
time = NoStrImplChuch.readInteger(json, QName.TIME);
count = NoStrImplChuch.readInteger(json, QName.COUNT);
}
@Override
public JsonValue toBible() {
JsonObjectBuilder result = Json.createObjectBuilder();
NoStrKindValue.writeArrayKinds(result, QName.KINDS, kinds);
NoStrImplChuch.writeInteger(result, QName.TIME, time);
NoStrImplChuch.writeInteger(result, QName.COUNT, count);
return result.build();
}
private enum QName implements NoStrImplQName {
KINDS,
TIME,
COUNT,
;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public List<NoStrKindValue> getKinds() {
return kinds;
}
public Integer getTime() {
return time;
}
public void setTime(Integer time) {
this.time = time;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}

View file

@ -0,0 +1,133 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagMeta;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplChuch;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public class NoStrSubscriptionFilter implements NoStrGospel {
private final static String TAG_FILTER_PREFIX = "#";
private final List<String> ids = new ArrayList<>();
private final List<String> authors = new ArrayList<>();
private final List<NoStrKindValue> kinds = new ArrayList<>();
private final Map<String, NoStrSubscriptionFilterTag> tags = new HashMap<>();
private Integer since;
private Integer until;
private Integer limit;
private enum QName implements NoStrImplQName {
IDS, AUTHORS, KINDS, SINCE, UNTIL, LIMIT;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public NoStrSubscriptionFilter() {
}
public NoStrSubscriptionFilter(JsonObject json) {
NoStrImplChuch.readArrayString(json, QName.IDS, ids);
NoStrImplChuch.readArrayString(json, QName.AUTHORS, authors);
NoStrKindValue.readArrayKinds(json, QName.KINDS, kinds);
for (String jsonName : json.keySet()) {
if (!jsonName.startsWith(TAG_FILTER_PREFIX)) {
continue;
}
String jsonNameKey = jsonName.substring(0, 1);
if (tags.containsKey(jsonNameKey)) {
continue;
}
JsonValue arrayJson = json.get(jsonNameKey);
if (!JsonValue.ValueType.ARRAY.equals(arrayJson.getValueType())) {
continue;
}
Stream<JsonValue> tagFilterValues = arrayJson.asJsonArray().stream();
List<String> tagFilters = tagFilterValues.map(v -> ((JsonString)v).getString()).collect(Collectors.toList());
NoStrEventTagMeta eventTag = NoStrEventTagMeta.valueOf(jsonNameKey);
tags.put(jsonNameKey, new NoStrSubscriptionFilterTag(eventTag, tagFilters));
}
since = NoStrImplChuch.readInteger(json, QName.SINCE);
until = NoStrImplChuch.readInteger(json, QName.UNTIL);
limit = NoStrImplChuch.readInteger(json, QName.LIMIT);
}
@Override
public JsonValue toBible() {
JsonObjectBuilder result = Json.createObjectBuilder();
NoStrImplChuch.writeArrayString(result, QName.IDS, ids);
NoStrImplChuch.writeArrayString(result, QName.AUTHORS, authors);
NoStrKindValue.writeArrayKinds(result, QName.KINDS, kinds);
for (String tagKey : tags.keySet()) {
if (tagKey.length() != 1) {
continue;
}
NoStrSubscriptionFilterTag tag = tags.get(tagKey);
result.add(TAG_FILTER_PREFIX + tagKey, Json.createArrayBuilder(tag.getKeywords()));
}
NoStrImplChuch.writeInteger(result, QName.SINCE, since);
NoStrImplChuch.writeInteger(result, QName.UNTIL, until);
NoStrImplChuch.writeInteger(result, QName.LIMIT, limit);
return result.build();
}
public Integer getSince() {
return since;
}
public void setSince(Integer since) {
this.since = since;
}
public Integer getUntil() {
return until;
}
public void setUntil(Integer until) {
this.until = until;
}
public Integer getLimit() {
return limit;
}
public void setLimit(Integer limit) {
this.limit = limit;
}
public List<String> getIds() {
return ids;
}
public List<String> getAuthors() {
return authors;
}
public List<NoStrKindValue> getKinds() {
return kinds;
}
public Map<String, NoStrSubscriptionFilterTag> getTags() {
return tags;
}
}

View file

@ -0,0 +1,25 @@
package love.distributedrebirth.no2all.nostr.model;
import java.util.ArrayList;
import java.util.List;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagMeta;
public final class NoStrSubscriptionFilterTag {
private final NoStrEventTagMeta eventTag;
private final List<String> keywords = new ArrayList<>();
public NoStrSubscriptionFilterTag(NoStrEventTagMeta eventTag, List<String> keywords) {
this.eventTag = eventTag;
this.keywords.addAll(keywords);
}
public NoStrEventTagMeta getEventTag() {
return eventTag;
}
public List<String> getKeywords() {
return keywords;
}
}

View file

@ -0,0 +1,100 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public final class NoStrEvent implements NoStrGospel {
private final NoStrEventId id;
private final NoStrEventPayload payload;
private final NoStrEventSignature signature;
private enum QName implements NoStrImplQName {
ID, PUBKEY, CREATED_AT, KIND, TAGS, CONTENT, SIG;
private final String jsonQName;
private QName() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
}
public NoStrEvent(NoStrEventId id, NoStrEventPayload payload, NoStrEventSignature signature) {
this.id = Objects.requireNonNull(id);
this.payload = Objects.requireNonNull(payload);
this.signature = Objects.requireNonNull(signature);
}
public NoStrEvent(JsonObject event) {
List<NoStrEventTag> eventTags = new ArrayList<>();
JsonArray jsonTags = event.getJsonArray(QName.TAGS.getQName());
for (JsonValue jsonTag : jsonTags) {
Iterator<JsonValue> i = jsonTag.asJsonArray().iterator();
if (!i.hasNext()) {
throw new IllegalArgumentException("Empty tag");
}
String tagStr = ((JsonString)i.next()).getString();
NoStrEventTagMeta tagMeta = NoStrEventTagMeta.valueOf(tagStr);
List<String> args = new ArrayList<>();
while (i.hasNext()) {
args.add(((JsonString)i.next()).getString());
}
eventTags.add(NoStrEventTag.valueOf(tagMeta, args.toArray(new String[] {})));
}
long createdAtLong = event.getJsonNumber(QName.CREATED_AT.getQName()).longValue();
int kindNumber = event.getInt(QName.KIND.getQName());
String idStr = event.getString(QName.ID.getQName());
String signatureStr = event.getString(QName.SIG.getQName());
String pubkeyStr = event.getString(QName.PUBKEY.getQName());
String content = event.getString(QName.CONTENT.getQName());
NoStrIdentityPublicKey pubkey = NoStrIdentityPublicKey.ofHex(pubkeyStr);
Instant createdAt = Instant.ofEpochSecond(createdAtLong);
NoStrEventKind kind = NoStrEventKind.valueOf(kindNumber);
this.id = NoStrEventId.ofHex(idStr);
this.payload = new NoStrEventPayload(pubkey, createdAt, kind, eventTags, content);
this.signature = NoStrEventSignature.ofHex(signatureStr);
}
@Override
public JsonValue toBible() {
return Json.createObjectBuilder()
.add(QName.ID.getQName(), id.getHex())
.add(QName.PUBKEY.getQName(), payload.getPublicKey().getHex())
.add(QName.CREATED_AT.getQName(), payload.getCreatedAt().getEpochSecond())
.add(QName.KIND.getQName(), payload.getKind().getNumber())
.add(QName.TAGS.getQName(), NoStrEventTag.toJsonArray(payload.getTags()))
.add(QName.CONTENT.getQName(), payload.getContent())
.add(QName.SIG.getQName(), signature.getHex())
.build();
}
public NoStrEventId getId() {
return id;
}
public NoStrEventPayload getPayload() {
return payload;
}
public NoStrEventSignature getSignature() {
return signature;
}
}

View file

@ -0,0 +1,15 @@
package love.distributedrebirth.no2all.nostr.model.event;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplBinHexAdapter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public final class NoStrEventId extends NoStrImplBinHexAdapter {
public NoStrEventId(byte[] valueBytes) {
super(valueBytes);
}
public static NoStrEventId ofHex(String valueHex) {
return new NoStrEventId(OctoBitFormat.HEX.toBytes(valueHex));
}
}

View file

@ -0,0 +1,22 @@
package love.distributedrebirth.no2all.nostr.model.event;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplPossibility;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQFlag;
public interface NoStrEventKind extends NoStrImplQFlag {
int getNumber();
NoStrImplPossibility getNip();
NoStrEventKindRange getRange();
static NoStrEventKind valueOf(int number) {
if (NoStrImplEventKind.valueOfKindValid(number)) {
return NoStrImplEventKind.valueOfKind(number);
} else {
return new NoStrEventKindCustom(number);
}
}
}

View file

@ -0,0 +1,37 @@
package love.distributedrebirth.no2all.nostr.model.event;
import love.distributedrebirth.no2all.nostr.nip.NoStrImpl;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventKindRange;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplPossibility;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQFlag;
public final class NoStrEventKindCustom implements NoStrEventKind {
private final int number;
private final NoStrEventKindRange range;
public NoStrEventKindCustom(int number) {
this.number = number;
this.range = NoStrImplEventKindRange.valueOfKind(number);
}
@Override
public int getNumber() {
return number;
}
@Override
public String getQFlag() {
return NoStrImplQFlag.CUSTOM_INDICATOR;
}
@Override
public NoStrImplPossibility getNip() {
return NoStrImpl.NIP_0_UNKNOWN;
}
@Override
public NoStrEventKindRange getRange() {
return range;
}
}

View file

@ -0,0 +1,12 @@
package love.distributedrebirth.no2all.nostr.model.event;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQFlag;
public interface NoStrEventKindRange extends NoStrImplQFlag {
int getNumberStart();
int getNumberstop();
boolean isReplaceable(int number);
}

View file

@ -0,0 +1,80 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
public final class NoStrEventPayload {
private final NoStrIdentityPublicKey publicKey;
private Instant createdAt;
private final NoStrEventKind kind;
private final List<NoStrEventTag> tags;
private final String content;
public NoStrEventPayload(NoStrIdentityPublicKey publicKey, Instant createdAt, NoStrEventKind kind, List<NoStrEventTag> tags,
String content) {
this.publicKey = Objects.requireNonNull(publicKey);
this.createdAt = Objects.requireNonNull(createdAt);
this.kind = Objects.requireNonNull(kind);
this.tags = Objects.requireNonNull(tags);
this.content = Objects.requireNonNull(content);
}
public NoStrIdentityPublicKey getPublicKey() {
return publicKey;
}
public Instant getCreatedAt() {
return createdAt;
}
public NoStrEventKind getKind() {
return kind;
}
public List<NoStrEventTag> getTags() {
return tags;
}
public String getContent() {
return content;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = Objects.requireNonNull(createdAt);
}
public List<NoStrEventTag> findByQName(String tagQName) {
List<NoStrEventTag> result = new ArrayList<>();
for (int i=0; i < tags.size(); i++) {
NoStrEventTag tag = tags.get(i);
if (tag.getMeta().getQName().equals(tagQName)) {
result.add(tag);
}
}
return result;
}
public List<NoStrEventTag> findByQName(NoStrEventTagMeta tagQName) {
return findByQName(tagQName.getQName());
}
public Optional<NoStrEventTag> findFirstByQName(String tagQName) {
for (int i=0; i < tags.size(); i++) {
NoStrEventTag tag = tags.get(i);
if (tag.getMeta().getQName().equals(tagQName)) {
return Optional.of(tag);
}
}
return Optional.empty();
}
public Optional<NoStrEventTag> findFirstByQName(NoStrEventTagMeta tagQName) {
return findFirstByQName(tagQName.getQName());
}
}

View file

@ -0,0 +1,68 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonWriter;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPrivateKey;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplBinHexAdapter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
import love.distributedrebirth.no2all.octo.trust.OctoTrust;
import love.distributedrebirth.no2all.octo.trust.OctoTrustHash;
import love.distributedrebirth.no2all.octo.trust.OctoTrustSchnorr;
public final class NoStrEventSignature extends NoStrImplBinHexAdapter {
public NoStrEventSignature(byte[] valueBytes) {
super(valueBytes);
}
public static NoStrEventSignature ofHex(String valueHex) {
return new NoStrEventSignature(OctoBitFormat.HEX.toBytes(valueHex));
}
public static NoStrEvent sign(NoStrEventPayload payload, NoStrIdentityPrivateKey privateKey, byte[] eventId) {
byte[] signRandom = OctoTrust.createRandomByteArray(OctoTrust.KEY_LENGTH);
byte[] signHash = OctoTrustSchnorr.sign(eventId, privateKey.getBytes(), signRandom);
NoStrEventSignature signature = new NoStrEventSignature(signHash);
return new NoStrEvent(new NoStrEventId(eventId), payload, signature);
}
public static NoStrEvent sign(NoStrEventPayload payload, NoStrIdentityPrivateKey privateKey) {
return sign(payload, privateKey, generateEventId(payload));
}
public static boolean verify(NoStrEvent event) {
byte[] eventId = generateEventId(event.getPayload());
byte[] pubkey = event.getPayload().getPublicKey().getBytes();
byte[] sig = event.getSignature().getBytes();
boolean result = OctoTrustSchnorr.verify(eventId, pubkey, sig);
return result;
}
public static String generateEventIdJsonString(NoStrEventPayload payload) {
JsonArray eventAsJson = Json.createArrayBuilder()
.add(0)
.add(payload.getPublicKey().getHex())
.add(payload.getCreatedAt().getEpochSecond())
.add(payload.getKind().getNumber())
.add(NoStrEventTag.toJsonArray(payload.getTags()))
.add(payload.getContent())
.build();
StringWriter eventAsString = new StringWriter();
try (JsonWriter writer = Json.createWriter(eventAsString)) {
writer.write(eventAsJson);
}
return eventAsString.getBuffer().toString();
}
public static byte[] generateEventIdHash(String eventIdJsonString) {
return OctoTrustHash.sha256(eventIdJsonString.getBytes(StandardCharsets.UTF_8));
}
public static byte[] generateEventId(NoStrEventPayload payload) {
return generateEventIdHash(generateEventIdJsonString(payload));
}
}

View file

@ -0,0 +1,83 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagE;
import love.distributedrebirth.no2all.nostr.model.tag.NoStrTagNonce;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
public interface NoStrEventTag extends NoStrGospel {
NoStrEventTagMeta getMeta();
String[] getMetaArguments();
default Optional<String> getMetaArgument(int idx) {
if (idx >= getMetaArguments().length || idx < 0) {
return Optional.empty();
}
return Optional.ofNullable(getMetaArguments()[idx]);
}
default Optional<String> getMetaArgument(NoStrImplEventTagArgument idx) {
return getMetaArgument(idx.ordinal());
}
default List<String> getMetaSafeArguments() {
List<String> result = new ArrayList<>();
int idxLastValue = 0;
String[] values = getMetaArguments();
for (int i = 0; i < values.length; i++) {
String str = values[i];
if (str == null) {
result.add(""); // optional
} else {
result.add(str);
idxLastValue = i;
}
}
if (idxLastValue < result.size()) {
result = result.subList(0, idxLastValue + 1);
}
return result;
}
@Override
default JsonValue toBible() {
return Json.createArrayBuilder()
.add(getMeta().getQName())
.addAll(Json.createArrayBuilder(getMetaSafeArguments()))
.build();
}
static JsonArray toJsonArray(List<NoStrEventTag> tags) {
return Json.createArrayBuilder(
tags.stream().map(v -> v.toBible()).collect(Collectors.toList())
).build();
}
static NoStrEventTag valueOfArgs(NoStrEventTagMeta meta, String... args) {
return valueOf(meta, args);
}
static NoStrEventTag valueOf(NoStrEventTagMeta meta, String[] args) {
Objects.requireNonNull(meta);
Objects.requireNonNull(args);
if (NoStrImplEventTag.E.equals(meta)) {
return new NoStrTagE(args);
}
if (NoStrImplEventTag.NONCE.equals(meta)) {
return new NoStrTagNonce(args);
}
return new NoStrEventTagCustom(meta, args);
}
}

View file

@ -0,0 +1,65 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public class NoStrEventTagBase<T extends NoStrImplEventTagArgument> implements NoStrEventTag {
private final NoStrEventTagMeta meta;
private String[] args;
public NoStrEventTagBase(NoStrEventTagMeta meta) {
this(meta, new String[4]); // limit autoGrow to zero in 99% of tags
}
public NoStrEventTagBase(NoStrEventTagMeta meta, String[] args) {
this.meta = Objects.requireNonNull(meta);
this.args = Objects.requireNonNull(args);
}
@Override
public NoStrEventTagMeta getMeta() {
return meta;
}
@Override
public String[] getMetaArguments() {
return args;
}
private int autoGrow(int index) {
if (index < args.length) {
return index;
}
String[] result = new String[index];
System.arraycopy(args, 0, result, 0, args.length);
args = result;
return index;
}
// public Optional<String> getMetaArgument(T arg) {
// return NoStrEventTag.super.getMetaArgument(arg.ordinal());
// }
protected void setMetaArgumentStr(T arg, String value) {
int index = autoGrow(arg.ordinal());
args[index] = value;
}
protected void setMetaArgumentOptStr(T arg, Optional<String> value) {
if (value.isEmpty()) {
return;
}
setMetaArgumentStr(arg, value.get());
}
protected void setMetaArgumentOptQName(T arg, Optional<? extends NoStrImplQName> value) {
if (value.isEmpty()) {
return;
}
setMetaArgumentStr(arg, value.get().getQName());
}
}

View file

@ -0,0 +1,53 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public class NoStrEventTagBaseMono implements NoStrEventTag {
private final NoStrEventTagMeta meta;
private String[] args;
public NoStrEventTagBaseMono(NoStrEventTagMeta meta) {
this(meta, new String[1]);
}
public NoStrEventTagBaseMono(NoStrEventTagMeta meta, String[] args) {
this.meta = Objects.requireNonNull(meta);
this.args = Objects.requireNonNull(args);
}
@Override
public NoStrEventTagMeta getMeta() {
return meta;
}
@Override
public String[] getMetaArguments() {
return args;
}
public Optional<String> getMetaArgument() {
return NoStrEventTag.super.getMetaArgument(0);
}
protected void setMetaArgumentStr(String value) {
args[0] = value;
}
protected void setMetaArgumentOptStr(Optional<String> value) {
if (value.isEmpty()) {
return;
}
setMetaArgumentStr(value.get());
}
protected void setMetaArgumentOptQName(Optional<? extends NoStrImplQName> value) {
if (value.isEmpty()) {
return;
}
setMetaArgumentStr(value.get().getQName());
}
}

View file

@ -0,0 +1,24 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.util.Objects;
public final class NoStrEventTagCustom implements NoStrEventTag {
private final NoStrEventTagMeta meta;
private final String[] args;
public NoStrEventTagCustom(NoStrEventTagMeta meta, String[] args) {
this.meta = Objects.requireNonNull(meta);
this.args = Objects.requireNonNull(args);
}
@Override
public NoStrEventTagMeta getMeta() {
return meta;
}
@Override
public String[] getMetaArguments() {
return args;
}
}

View file

@ -0,0 +1,23 @@
package love.distributedrebirth.no2all.nostr.model.event;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplPossibility;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQFlag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public interface NoStrEventTagMeta extends NoStrImplQName, NoStrImplQFlag {
boolean isQuariable();
boolean isSinglton();
NoStrImplPossibility[] getNips();
static NoStrEventTagMeta valueOf(String qName) {
if (NoStrImplEventTag.valueOfWireValid(qName)) {
return NoStrImplEventTag.valueOfWire(qName);
} else {
return new NoStrEventTagMetaCustom(qName);
}
}
}

View file

@ -0,0 +1,45 @@
package love.distributedrebirth.no2all.nostr.model.event;
import java.util.Objects;
import love.distributedrebirth.no2all.nostr.nip.NoStrImpl;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplPossibility;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQFlag;
public class NoStrEventTagMetaCustom implements NoStrEventTagMeta {
private static final NoStrImplPossibility[] UNKNOWN_NIPS = new NoStrImplPossibility[] { NoStrImpl.NIP_0_UNKNOWN };
private final String qName;
private final boolean quariable;
public NoStrEventTagMetaCustom(String qName) {
this.qName = Objects.requireNonNull(qName);
this.quariable = NoStrImplEventTag.isQuariable(qName);
}
@Override
public String getQName() {
return qName;
}
@Override
public String getQFlag() {
return NoStrImplQFlag.CUSTOM_INDICATOR;
}
@Override
public NoStrImplPossibility[] getNips() {
return UNKNOWN_NIPS;
}
@Override
public boolean isQuariable() {
return quariable;
}
@Override
public boolean isSinglton() {
return false;
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.nostr.model.message;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
public interface NoStrMsgToClient extends NoStrGospel {
// marker
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientAuth implements NoStrMsgToClient {
private final String challenge;
public NoStrMsgToClientAuth(String challenge) {
this.challenge = Objects.requireNonNull(challenge);
}
public NoStrMsgToClientAuth(JsonArray json) {
this.challenge = ((JsonString)json.get(1)).getString();
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.AUTH.getQName())
.add(challenge)
.build();
}
public String getChallenge() {
return challenge;
}
}

View file

@ -0,0 +1,43 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientCount implements NoStrMsgToClient {
private final String QNAME_COUNT = "count";
private final String subscriptionId;
private final int count;
public NoStrMsgToClientCount(String subscriptionId, int count) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
this.count = count;
}
public NoStrMsgToClientCount(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
this.count = json.get(2).asJsonObject().getInt(QNAME_COUNT);
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.COUNT.getQName())
.add(subscriptionId)
.add(Json.createObjectBuilder().add(QNAME_COUNT, count))
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
public int getCount() {
return count;
}
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientEose implements NoStrMsgToClient {
private final String subscriptionId;
public NoStrMsgToClientEose(String subscriptionId) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
}
public NoStrMsgToClientEose(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.EOSE.getQName())
.add(subscriptionId)
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
}

View file

@ -0,0 +1,43 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientEvent implements NoStrMsgToClient {
private final String subscriptionId;
private final NoStrEvent event;
public NoStrMsgToClientEvent(String subscriptionId, NoStrEvent event) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
this.event = Objects.requireNonNull(event);
}
public NoStrMsgToClientEvent(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
this.event = new NoStrEvent(json.get(2).asJsonObject());
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.EVENT.getQName())
.add(subscriptionId)
.add(event.toBible())
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
public NoStrEvent getEvent() {
return event;
}
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientNotice implements NoStrMsgToClient {
private final String message;
public NoStrMsgToClientNotice(String message) {
this.message = Objects.requireNonNull(message);
}
public NoStrMsgToClientNotice(JsonArray json) {
this.message = ((JsonString)json.get(1)).getString();
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.NOTICE.getQName())
.add(message)
.build();
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,66 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventId;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageOkReason;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToClientOk implements NoStrMsgToClient {
private final NoStrEventId eventId;
private final boolean saved;
private final String message;
private final NoStrImplMessageOkReason reason;
public NoStrMsgToClientOk(NoStrEventId eventId, boolean saved, NoStrImplMessageOkReason reason, String message) {
this.eventId = Objects.requireNonNull(eventId);
this.saved = saved;
this.reason = Objects.requireNonNull(reason);
this.message = reason.getPrefix() + " " + message;
}
public NoStrMsgToClientOk(NoStrEventId eventId, boolean saved, String message) {
this.eventId = Objects.requireNonNull(eventId);
this.saved = saved;
this.message = Objects.requireNonNull(message);
this.reason = NoStrImplMessageOkReason.valueOfPrefix(message);
}
public NoStrMsgToClientOk(JsonArray json) {
this.eventId = NoStrEventId.ofHex(((JsonString)json.get(1)).getString());
this.saved = JsonValue.TRUE.equals(json.get(2));
this.message = ((JsonString)json.get(3)).getString();
this.reason = NoStrImplMessageOkReason.valueOfPrefix(message);
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.OK.getQName())
.add(eventId.getHex())
.add(saved)
.add(message)
.build();
}
public NoStrEventId getEventId() {
return eventId;
}
public boolean isSaved() {
return saved;
}
public String getMessage() {
return message;
}
public NoStrImplMessageOkReason getReason() {
return reason;
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.nostr.model.message;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
public interface NoStrMsgToRelay extends NoStrGospel {
// marker
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToRelayAuth implements NoStrMsgToRelay {
private final NoStrEvent event;
public NoStrMsgToRelayAuth(NoStrEvent event) {
this.event = Objects.requireNonNull(event);
}
public NoStrMsgToRelayAuth(JsonArray json) {
this.event = new NoStrEvent(json.get(1).asJsonObject());
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.AUTH.getQName())
.add(event.toBible())
.build();
}
public NoStrEvent getEvent() {
return event;
}
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToRelayClose implements NoStrMsgToRelay {
private final String subscriptionId;
public NoStrMsgToRelayClose(String subscriptionId) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
}
public NoStrMsgToRelayClose(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.CLOSE.getQName())
.add(subscriptionId)
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
}

View file

@ -0,0 +1,49 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.NoStrSubscriptionFilter;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToRelayCount implements NoStrMsgToRelay {
private final String subscriptionId;
private final List<NoStrSubscriptionFilter> filters = new ArrayList<>();
public NoStrMsgToRelayCount(String subscriptionId, NoStrSubscriptionFilter... filters) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
this.filters.addAll(Arrays.asList(filters));
}
public NoStrMsgToRelayCount(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
for (int i = 2; i < json.size(); i++) {
filters.add(new NoStrSubscriptionFilter(json.get(i).asJsonObject()));
}
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.COUNT.getQName())
.add(subscriptionId)
.addAll(Json.createArrayBuilder(filters.stream().map(v -> v.toBible()).collect(Collectors.toList())))
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
public List<NoStrSubscriptionFilter> getFilters() {
return filters;
}
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.Objects;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToRelayEvent implements NoStrMsgToRelay {
private final NoStrEvent event;
public NoStrMsgToRelayEvent(NoStrEvent event) {
this.event = Objects.requireNonNull(event);
}
public NoStrMsgToRelayEvent(JsonArray json) {
this.event = new NoStrEvent(json.get(1).asJsonObject());
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.EVENT.getQName())
.add(event.toBible())
.build();
}
public NoStrEvent getEvent() {
return event;
}
}

View file

@ -0,0 +1,49 @@
package love.distributedrebirth.no2all.nostr.model.message;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.model.NoStrSubscriptionFilter;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageType;
public final class NoStrMsgToRelayReq implements NoStrMsgToRelay {
private final String subscriptionId;
private final List<NoStrSubscriptionFilter> filters = new ArrayList<>();
public NoStrMsgToRelayReq(String subscriptionId, NoStrSubscriptionFilter... filters) {
this.subscriptionId = Objects.requireNonNull(subscriptionId);
this.filters.addAll(Arrays.asList(filters));
}
public NoStrMsgToRelayReq(JsonArray json) {
this.subscriptionId = ((JsonString)json.get(1)).getString();
for (int i = 2; i < json.size(); i++) {
filters.add(new NoStrSubscriptionFilter(json.get(i).asJsonObject()));
}
}
@Override
public JsonValue toBible() {
return Json.createArrayBuilder()
.add(NoStrImplMessageType.REQ.getQName())
.add(subscriptionId)
.addAll(Json.createArrayBuilder(filters.stream().map(v -> v.toBible()).collect(Collectors.toList())))
.build();
}
public String getSubscriptionId() {
return subscriptionId;
}
public List<NoStrSubscriptionFilter> getFilters() {
return filters;
}
}

View file

@ -0,0 +1,32 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.Objects;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public abstract class NoStrShareB32LinkBare implements NoStrShareLink {
private final String shareLink;
private final byte[] bareValue;
public NoStrShareB32LinkBare(NoStrImplShareLink linkType, OctoBech32String link) {
this(linkType, OctoBech32.fromBech32(linkType.validate(link)).getData());
}
public NoStrShareB32LinkBare(NoStrImplShareLink linkType, byte[] bareValue) {
Objects.requireNonNull(bareValue);
this.shareLink = OctoBech32.toBech32(linkType.getPrefix(), bareValue).getValue();
this.bareValue = bareValue;
}
@Override
public final String toShareLink() {
return shareLink;
}
protected byte[] getBareValue() {
return bareValue;
}
}

View file

@ -0,0 +1,49 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.Optional;
import java.util.function.Consumer;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareTLV;
import love.distributedrebirth.no2all.octo.OctoBech32;
import love.distributedrebirth.no2all.octo.OctoBech32Bucket;
import love.distributedrebirth.no2all.octo.OctoBech32String;
import love.distributedrebirth.no2all.octo.OctoBitChain;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public abstract class NoStrShareB32LinkTLV implements NoStrShareLink {
private final NoStrShareBitChainTapeDeck tapeDeck;
private final String shareLink;
public NoStrShareB32LinkTLV(NoStrImplShareLink linkType, OctoBech32String link) {
OctoBech32Bucket shareB32 = OctoBech32.fromBech32(linkType.validate(link));
OctoBitChain chain = new OctoBitChain(shareB32.getData());
this.tapeDeck = new NoStrShareBitChainTapeDeck(chain);
this.shareLink = createShareLink(chain, linkType);
}
public NoStrShareB32LinkTLV(NoStrImplShareLink linkType, Consumer<NoStrShareBitChainTapeStudio> tapeStudio) {
OctoBitChain chain = new OctoBitChain();
tapeStudio.accept(new NoStrShareBitChainTapeStudio(chain));
this.tapeDeck = new NoStrShareBitChainTapeDeck(chain);
this.shareLink = createShareLink(chain, linkType);
}
private static String createShareLink(OctoBitChain chain, NoStrImplShareLink linkType) {
return OctoBech32.toBech32(linkType.getPrefix(), chain.toByteArray()).getValue();
}
protected NoStrShareBitChainTapeDeck getTapeDeck() {
return tapeDeck;
}
public Optional<String> getClient() {
return getTapeDeck().playBitFormatOf(NoStrImplShareTLV.CLIENT, OctoBitFormat.UTF8);
}
@Override
public final String toShareLink() {
return shareLink;
}
}

View file

@ -0,0 +1,94 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareTLV;
import love.distributedrebirth.no2all.octo.OctoBitChain;
import love.distributedrebirth.no2all.octo.OctoBitChainFrame;
import love.distributedrebirth.no2all.octo.OctoBitConverter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public class NoStrShareBitChainTapeDeck {
protected final OctoBitChain chain;
public NoStrShareBitChainTapeDeck(OctoBitChain chain) {
this.chain = Objects.requireNonNull(chain);
}
public int getFrameCount() {
return chain.getFrameCount();
}
public Optional<ByteBuffer> playByteBufferOf(NoStrImplShareTLV tlv) {
byte[] data = chain.getFirstDataOfType(tlv);
if (data == null) {
return Optional.empty();
}
if (data.length == 0) {
return Optional.empty();
}
return Optional.of(ByteBuffer.wrap(data));
}
public Optional<ByteBuffer> playSpecial() {
return playByteBufferOf(NoStrImplShareTLV.SPECIAL);
}
public <T> Optional<T> playSpecial(OctoBitConverter<T> type) {
Optional<ByteBuffer> data = playSpecial();
if (data.isEmpty()) {
return Optional.empty();
}
return Optional.of(type.fromBytes(data.get().array()));
}
public List<String> playRelays() {
List<String> result = new ArrayList<>();
for (OctoBitChainFrame frame : chain.getFramesByType(NoStrImplShareTLV.RELAY)) {
result.add(OctoBitFormat.IDN.fromBytes(frame.getData()));
}
return result;
}
public Optional<NoStrIdentityPublicKey> playAuthor() {
byte[] data = chain.getFirstDataOfType(NoStrImplShareTLV.AUTHOR);
if (data == null) {
return Optional.empty();
}
return Optional.of(new NoStrIdentityPublicKey(data));
}
public Optional<NoStrEventKind> playKind() {
byte[] data = chain.getFirstDataOfType(NoStrImplShareTLV.KIND);
if (data == null) {
return Optional.empty();
}
return Optional.of(NoStrEventKind.valueOf(OctoBitFormat.BI_UI32.fromBytes(data).intValue()));
}
public Optional<Byte> playByteOf(NoStrImplShareTLV tlv) {
byte[] data = chain.getFirstDataOfType(tlv);
if (data == null) {
return Optional.empty();
}
if (data.length == 0) {
return Optional.empty();
}
return Optional.of(data[0]);
}
public <T> Optional<T> playBitFormatOf(NoStrImplShareTLV tlv, OctoBitConverter<T> type) {
byte[] data = chain.getFirstDataOfType(tlv);
if (data == null) {
return Optional.empty();
}
return Optional.of(type.fromBytes(data));
}
}

View file

@ -0,0 +1,85 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareTLV;
import love.distributedrebirth.no2all.octo.OctoBitChain;
import love.distributedrebirth.no2all.octo.OctoBitConverter;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public class NoStrShareBitChainTapeStudio extends NoStrShareBitChainTapeDeck {
public NoStrShareBitChainTapeStudio(OctoBitChain chain) {
super(chain);
}
public void clear() {
chain.clear();
}
public void recordClient(String client) {
if (client == null) {
return;
}
chain.addFrame(NoStrImplShareTLV.CLIENT, OctoBitFormat.UTF8.toBytes(client));
}
public void recordByteArrayFor(byte[] value, NoStrImplShareTLV tlv) {
if (value == null) {
return;
}
chain.addFrame(tlv, value);
}
public void recordSpecial(byte[] value) {
recordByteArrayFor(Objects.requireNonNull(value), NoStrImplShareTLV.SPECIAL);
}
public <T> void recordSpecial(T value, OctoBitConverter<T> type) {
recordSpecial(type.toBytes(Objects.requireNonNull(value)));
}
public void recordRelays(List<String> relays) {
if (relays == null) {
return;
}
for (String relay : relays) {
chain.addFrame(NoStrImplShareTLV.RELAY, OctoBitFormat.IDN.toBytes(relay));
}
}
public void recordAuthor(Optional<NoStrIdentityPublicKey> value) {
if (value.isEmpty()) {
return;
}
recordAuthor(value.get());
}
public void recordAuthor(NoStrIdentityPublicKey value) {
recordByteArrayFor(value.getBytes(), NoStrImplShareTLV.AUTHOR);
}
public void recordKind(Optional<NoStrEventKind> value) {
if (value.isEmpty()) {
return;
}
recordKind(value.get());
}
public void recordKind(NoStrEventKind value) {
if (value == null) {
return;
}
chain.addFrame(NoStrImplShareTLV.KIND, OctoBitFormat.BI_UI32.toBytes((long)value.getNumber()));
}
public void recordByteFor(byte value, NoStrImplShareTLV tlv) {
byte[] data = new byte[1];
data[0] = value;
chain.addFrame(tlv, data);
}
}

View file

@ -0,0 +1,6 @@
package love.distributedrebirth.no2all.nostr.model.share;
public interface NoStrShareLink {
String toShareLink();
}

View file

@ -0,0 +1,50 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.List;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventId;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkEvent extends NoStrShareB32LinkTLV {
public NoStrShareLinkEvent(OctoBech32String link) {
super(NoStrImplShareLink.EVENT, link);
}
public NoStrShareLinkEvent(NoStrEventId eventId) {
this(eventId, List.of(), Optional.empty(), Optional.empty());
}
public NoStrShareLinkEvent(NoStrEventId eventId, List<String> relays, Optional<NoStrIdentityPublicKey> author, Optional<NoStrEventKind> kind) {
super(NoStrImplShareLink.EVENT, tapeStudio -> {
tapeStudio.recordSpecial(eventId.getBytes());
tapeStudio.recordRelays(relays);
tapeStudio.recordAuthor(author);
tapeStudio.recordKind(kind);
});
}
public NoStrEventId getEventId() {
return new NoStrEventId(getTapeDeck().playSpecial().get().array());
}
public List<String> getRelays() {
return getTapeDeck().playRelays();
}
public Optional<NoStrIdentityPublicKey> getAuthorId() {
return getTapeDeck().playAuthor();
}
public Optional<NoStrEventKind> getKind() {
return getTapeDeck().playKind();
}
public static NoStrShareLinkEvent ofB32(String linkB32) {
return new NoStrShareLinkEvent(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,46 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.List;
import java.util.Objects;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public final class NoStrShareLinkEventReference extends NoStrShareB32LinkTLV {
public NoStrShareLinkEventReference(OctoBech32String link) {
super(NoStrImplShareLink.EVENT_REFERENCE, link);
}
public NoStrShareLinkEventReference(String refDValue, List<String> relays, NoStrIdentityPublicKey author, NoStrEventKind kind) {
super(NoStrImplShareLink.EVENT_REFERENCE, tapeStudio -> {
tapeStudio.recordSpecial(refDValue, OctoBitFormat.UTF8);
tapeStudio.recordRelays(relays);
tapeStudio.recordAuthor(author);
tapeStudio.recordKind(Objects.requireNonNull(kind));
});
}
public String getReferenceDValue() {
return getTapeDeck().playSpecial(OctoBitFormat.UTF8).get();
}
public List<String> getRelays() {
return getTapeDeck().playRelays();
}
public NoStrIdentityPublicKey getAuthorId() {
return getTapeDeck().playAuthor().get();
}
public NoStrEventKind getKind() {
return getTapeDeck().playKind().get();
}
public static NoStrShareLinkEventReference ofB32(String linkB32) {
return new NoStrShareLinkEventReference(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,24 @@
package love.distributedrebirth.no2all.nostr.model.share;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventId;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkNote extends NoStrShareB32LinkBare {
public NoStrShareLinkNote(OctoBech32String link) {
super(NoStrImplShareLink.NOTE, link);
}
public NoStrShareLinkNote(NoStrEventId eventId) {
super(NoStrImplShareLink.NOTE, eventId.getBytes());
}
public NoStrEventId getEventId() {
return new NoStrEventId(getBareValue());
}
public static NoStrShareLinkNote ofB32(String linkB32) {
return new NoStrShareLinkNote(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,24 @@
package love.distributedrebirth.no2all.nostr.model.share;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPrivateKey;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkPrivateKey extends NoStrShareB32LinkBare {
public NoStrShareLinkPrivateKey(OctoBech32String link) {
super(NoStrImplShareLink.PRIVATE_KEY, link);
}
public NoStrShareLinkPrivateKey(NoStrIdentityPrivateKey privateKey) {
super(NoStrImplShareLink.PRIVATE_KEY, privateKey.getBytes());
}
public NoStrIdentityPrivateKey getPrivateKey() {
return new NoStrIdentityPrivateKey(getBareValue());
}
public static NoStrShareLinkPrivateKey ofB32(String linkB32) {
return new NoStrShareLinkPrivateKey(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,51 @@
package love.distributedrebirth.no2all.nostr.model.share;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareTLV;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkPrivateKeySecure extends NoStrShareB32LinkTLV {
public NoStrShareLinkPrivateKeySecure(OctoBech32String link) {
super(NoStrImplShareLink.PRIVATE_KEY_SECURE, link);
}
public NoStrShareLinkPrivateKeySecure(byte[] cryptKey, byte version, byte logN, byte[] salt, byte[] nonce, byte level) {
super(NoStrImplShareLink.PRIVATE_KEY_SECURE, tapeStudio -> {
tapeStudio.recordSpecial(cryptKey);
tapeStudio.recordByteFor(version, NoStrImplShareTLV.VERSION);
tapeStudio.recordByteFor(logN, NoStrImplShareTLV.LOG_N);
tapeStudio.recordByteArrayFor(salt, NoStrImplShareTLV.SALT);
tapeStudio.recordByteArrayFor(nonce, NoStrImplShareTLV.NONCE);
tapeStudio.recordByteFor(level, NoStrImplShareTLV.LEVEL);
});
}
public byte[] getCryptKey() {
return getTapeDeck().playSpecial().get().array();
}
public byte getVersion() {
return getTapeDeck().playByteOf(NoStrImplShareTLV.VERSION).get();
}
public byte getLogN() {
return getTapeDeck().playByteOf(NoStrImplShareTLV.LOG_N).get();
}
public byte[] getSalt() {
return getTapeDeck().playByteBufferOf(NoStrImplShareTLV.SALT).get().array();
}
public byte[] getNonce() {
return getTapeDeck().playByteBufferOf(NoStrImplShareTLV.NONCE).get().array();
}
public byte getSecurityLevel() {
return getTapeDeck().playByteOf(NoStrImplShareTLV.LEVEL).get();
}
public static NoStrShareLinkPrivateKeySecure ofB32(String linkB32) {
return new NoStrShareLinkPrivateKeySecure(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,33 @@
package love.distributedrebirth.no2all.nostr.model.share;
import java.util.List;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkProfile extends NoStrShareB32LinkTLV {
public NoStrShareLinkProfile(OctoBech32String link) {
super(NoStrImplShareLink.PROFILE, link);
}
public NoStrShareLinkProfile(NoStrIdentityPublicKey publicKey, List<String> relays) {
super(NoStrImplShareLink.PROFILE, tapeStudio -> {
tapeStudio.recordSpecial(publicKey.getBytes());
tapeStudio.recordRelays(relays);
});
}
public NoStrIdentityPublicKey getPublicKey() {
return new NoStrIdentityPublicKey(getTapeDeck().playSpecial().get().array());
}
public List<String> getRelays() {
return getTapeDeck().playRelays();
}
public static NoStrShareLinkProfile ofB32(String linkB32) {
return new NoStrShareLinkProfile(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,24 @@
package love.distributedrebirth.no2all.nostr.model.share;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public final class NoStrShareLinkPublicKey extends NoStrShareB32LinkBare {
public NoStrShareLinkPublicKey(OctoBech32String link) {
super(NoStrImplShareLink.PUBLIC_KEY, link);
}
public NoStrShareLinkPublicKey(NoStrIdentityPublicKey publicKey) {
super(NoStrImplShareLink.PUBLIC_KEY, publicKey.getBytes());
}
public NoStrIdentityPublicKey getPublicKey() {
return new NoStrIdentityPublicKey(getBareValue());
}
public static NoStrShareLinkPublicKey ofB32(String linkB32) {
return new NoStrShareLinkPublicKey(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,26 @@
package love.distributedrebirth.no2all.nostr.model.share;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplShareLink;
import love.distributedrebirth.no2all.octo.OctoBech32String;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public final class NoStrShareLinkRelay extends NoStrShareB32LinkTLV {
public NoStrShareLinkRelay(OctoBech32String link) {
super(NoStrImplShareLink.RELAY, link);
}
public NoStrShareLinkRelay(String relayUrl) {
super(NoStrImplShareLink.RELAY, tapeStudio -> {
tapeStudio.recordSpecial(relayUrl, OctoBitFormat.UTF8);
});
}
public String getRelayUrl() {
return getTapeDeck().playSpecial(OctoBitFormat.UTF8).get();
}
public static NoStrShareLinkRelay ofB32(String linkB32) {
return new NoStrShareLinkRelay(OctoBech32String.of(linkB32));
}
}

View file

@ -0,0 +1,76 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagA;
public final class NoStrTagA extends NoStrEventTagBase<NoStrImplTagA> {
public NoStrTagA(String address, String relayUrl, Optional<String> platform) {
super(NoStrImplEventTag.A);
setMetaArgumentStr(NoStrImplTagA.ADDRESS, address);
setMetaArgumentStr(NoStrImplTagA.RELAY_URL, relayUrl);
setMetaArgumentOptStr(NoStrImplTagA.PLATFORM, platform);
}
public NoStrTagA(String[] args) {
super(NoStrImplEventTag.A, args);
}
public String getAddress() {
return getMetaArgument(NoStrImplTagA.ADDRESS).get();
}
public String getRelayUrl() {
return getMetaArgument(NoStrImplTagA.RELAY_URL).get();
}
public Optional<String> getPlatform() {
return getMetaArgument(NoStrImplTagA.PLATFORM);
}
public NoStrEventKind getAddressKind() {
return NoStrEventKind.valueOf(NoStrImplTagA.splitToKind(getAddress()));
}
public NoStrIdentityPublicKey getAddressPublicKey() {
return NoStrIdentityPublicKey.ofHex(NoStrImplTagA.splitToPublicKey(getAddress()));
}
public String getAddressParameter() {
return NoStrImplTagA.splitToParameter(getAddress());
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagA(String address, String relayUrl, Optional<String> platform) {
return tag(new NoStrTagA(address, relayUrl, platform));
}
default NoStrFireStackWelder tagA(String address, String relayUrl, String platform) {
return tagA(address, relayUrl, Optional.of(platform));
}
default NoStrFireStackWelder tagA(String address, String relayUrl) {
return tagA(address, relayUrl, Optional.empty());
}
default NoStrFireStackWelder tagA(NoStrEventKind kind, NoStrIdentityPublicKey publicKey, String parameter, String relayUrl, Optional<String> platform) {
return tagA(kind.getNumber() + NoStrImplTagA.SEPERATOR + publicKey.getHex() + NoStrImplTagA.SEPERATOR + parameter, relayUrl, platform);
}
default NoStrFireStackWelder tagA(NoStrEventKind kind, NoStrIdentityPublicKey publicKey, String parameter, String relayUrl, String platform) {
return tagA(kind, publicKey, parameter, relayUrl, Optional.of(platform));
}
default NoStrFireStackWelder tagA(NoStrEventKind kind, NoStrIdentityPublicKey publicKey, String parameter, String relayUrl) {
return tagA(kind, publicKey, parameter, relayUrl, Optional.empty());
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagAlt extends NoStrEventTagBaseMono {
public NoStrTagAlt(String altDescription) {
super(NoStrImplEventTag.ALT);
setMetaArgumentStr(altDescription);
}
public NoStrTagAlt(String[] args) {
super(NoStrImplEventTag.ALT, args);
}
public String getAltDescription() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagAlt(String altDescription) {
return tag(new NoStrTagAlt(altDescription));
}
}
}

View file

@ -0,0 +1,45 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagClient;
public final class NoStrTagClient extends NoStrEventTagBase<NoStrImplTagClient> {
public NoStrTagClient(String userAgent, Optional<String> version) {
super(NoStrImplEventTag.CLIENT);
setMetaArgumentStr(NoStrImplTagClient.USER_AGENT, userAgent);
setMetaArgumentOptStr(NoStrImplTagClient.VERSION, version);
}
public NoStrTagClient(String[] args) {
super(NoStrImplEventTag.CLIENT, args);
}
public String getUserAgent() {
return getMetaArgument(NoStrImplTagClient.USER_AGENT).get();
}
public Optional<String> getVersion() {
return getMetaArgument(NoStrImplTagClient.VERSION);
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagClient(String userAgent, Optional<String> version) {
return tag(new NoStrTagClient(userAgent, version));
}
default NoStrFireStackWelder tagClient(String userAgent, String version) {
return tagClient(userAgent, Optional.of(version));
}
default NoStrFireStackWelder tagClient(String userAgent) {
return tagClient(userAgent, Optional.empty());
}
}
}

View file

@ -0,0 +1,50 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagContentWarning;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagContentWarningRGroup;
public final class NoStrTagContentWarning extends NoStrEventTagBase<NoStrImplTagContentWarning> {
public NoStrTagContentWarning(Optional<String> reason, Optional<NoStrImplTagContentWarningRGroup> rateGroup) {
super(NoStrImplEventTag.CONTENT_WARNING);
setMetaArgumentOptStr(NoStrImplTagContentWarning.REASON, reason);
setMetaArgumentOptQName(NoStrImplTagContentWarning.RATE_GROUP, rateGroup);
}
public NoStrTagContentWarning(String[] args) {
super(NoStrImplEventTag.CONTENT_WARNING, args);
}
public Optional<String> getReason() {
return getMetaArgument(NoStrImplTagContentWarning.REASON);
}
public Optional<NoStrImplTagContentWarningRGroup> getRateGroup() {
return getMetaArgument(NoStrImplTagContentWarning.RATE_GROUP).flatMap(v -> NoStrImplTagContentWarningRGroup.valueOfQName(v));
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagContentWarning(Optional<String> reason, Optional<NoStrImplTagContentWarningRGroup> rateGroup) {
return tag(new NoStrTagContentWarning(reason, rateGroup));
}
default NoStrFireStackWelder tagContentWarning(String reason, NoStrImplTagContentWarningRGroup rateGroup) {
return tagContentWarning(Optional.of(reason), Optional.of(rateGroup));
}
default NoStrFireStackWelder tagContentWarning(String reason) {
return tagContentWarning(Optional.of(reason), Optional.empty());
}
default NoStrFireStackWelder tagContentWarning() {
return tagContentWarning(Optional.empty(), Optional.empty());
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagD extends NoStrEventTagBaseMono {
public NoStrTagD(String parameter) {
super(NoStrImplEventTag.D);
setMetaArgumentStr(parameter);
}
public NoStrTagD(String[] args) {
super(NoStrImplEventTag.D, args);
}
public String getParameter() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagD(String parameter) {
return tag(new NoStrTagD(parameter));
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagDescription extends NoStrEventTagBaseMono {
public NoStrTagDescription(String description) {
super(NoStrImplEventTag.DESCRIPTION);
setMetaArgumentStr(description);
}
public NoStrTagDescription(String[] args) {
super(NoStrImplEventTag.DESCRIPTION, args);
}
public String getDescription() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagDescription(String description) {
return tag(new NoStrTagDescription(description));
}
}
}

View file

@ -0,0 +1,56 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventId;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagE;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagEMarker;
public final class NoStrTagE extends NoStrEventTagBase<NoStrImplTagE> {
public NoStrTagE(NoStrEventId eventId, Optional<String> relayUrl, Optional<NoStrImplTagEMarker> marker) {
super(NoStrImplEventTag.E);
setMetaArgumentStr(NoStrImplTagE.EVENT_ID, eventId.getHex());
setMetaArgumentOptStr(NoStrImplTagE.RELAY_URL, relayUrl);
setMetaArgumentOptQName(NoStrImplTagE.MARKER, marker);
}
public NoStrTagE(String[] args) {
super(NoStrImplEventTag.E, args);
}
public NoStrEventId getEventId() {
return NoStrEventId.ofHex(getMetaArgument(NoStrImplTagE.EVENT_ID).get());
}
public Optional<String> getRelayUrl() {
return getMetaArgument(NoStrImplTagE.RELAY_URL);
}
public Optional<NoStrImplTagEMarker> getMarker() {
return getMetaArgument(NoStrImplTagE.MARKER).flatMap(v -> NoStrImplTagEMarker.valueOfQName(v));
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagE(NoStrEventId eventId, Optional<String> relayUrl, Optional<NoStrImplTagEMarker> marker) {
return tag(new NoStrTagE(eventId, relayUrl, marker));
}
default NoStrFireStackWelder tagE(NoStrEventId eventId, String relayUrl, NoStrImplTagEMarker marker) {
return tagE(eventId, Optional.of(relayUrl), Optional.of(marker));
}
default NoStrFireStackWelder tagERelayUrl(NoStrEventId eventId, String relayUrl) {
return tagE(eventId, Optional.of(relayUrl), Optional.empty());
}
default NoStrFireStackWelder tagEMarker(NoStrEventId eventId, NoStrImplTagEMarker marker) {
return tagE(eventId, Optional.empty(), Optional.of(marker));
}
}
}

View file

@ -0,0 +1,50 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagI;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagIClaim;
public final class NoStrTagI extends NoStrEventTagBase<NoStrImplTagI> {
public NoStrTagI(String platformIdentity, String proof) {
super(NoStrImplEventTag.I);
setMetaArgumentStr(NoStrImplTagI.PLATFORM_IDENTITY, platformIdentity);
setMetaArgumentStr(NoStrImplTagI.PROOF, proof);
}
public NoStrTagI(String[] args) {
super(NoStrImplEventTag.I, args);
}
public String getPlatformIdentity() {
return getMetaArgument(NoStrImplTagI.PLATFORM_IDENTITY).get();
}
public String getProof() {
return getMetaArgument(NoStrImplTagI.PROOF).get();
}
public String getIdentityName() {
return NoStrImplTagIClaim.splitFromPlatformIdentity(getPlatformIdentity());
}
public Optional<NoStrImplTagIClaim> getIdentityClaim() {
return NoStrImplTagIClaim.valueOfPlatformIdentity(getPlatformIdentity());
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagI(String platformIdentity, String proof) {
return tag(new NoStrTagI(platformIdentity, proof));
}
default NoStrFireStackWelder tagI(NoStrImplTagIClaim claimPlatform, String claimIdentity, String proof) {
return tagI(claimPlatform.getQName() + NoStrImplTagIClaim.SEPERATOR + claimIdentity, proof);
}
}
}

View file

@ -0,0 +1,57 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagImage;
public final class NoStrTagImage extends NoStrEventTagBase<NoStrImplTagImage> {
public NoStrTagImage(String url, Optional<String> dimension) {
super(NoStrImplEventTag.IMAGE);
setMetaArgumentStr(NoStrImplTagImage.URL, url);
setMetaArgumentOptStr(NoStrImplTagImage.DIMENSION, dimension);
}
public NoStrTagImage(String[] args) {
super(NoStrImplEventTag.IMAGE, args);
}
public String getUrl() {
return getMetaArgument(NoStrImplTagImage.URL).get();
}
public Optional<String> getDimension() {
return getMetaArgument(NoStrImplTagImage.DIMENSION);
}
public Optional<Integer> getDimensionWidth() {
return getDimension().map(v -> NoStrImplTagImage.splitDimensionToWidth(v));
}
public Optional<Integer> getDimensionHeight() {
return getDimension().map(v -> NoStrImplTagImage.splitDimensionToHeight(v));
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagImage(String url, Optional<String> dimension) {
return tag(new NoStrTagImage(url, dimension));
}
default NoStrFireStackWelder tagImage(String url) {
return tagImage(url, Optional.empty());
}
default NoStrFireStackWelder tagImage(String url, String dimension) {
return tagImage(url, Optional.of(dimension));
}
default NoStrFireStackWelder tagImage(String url, int width, int height) {
return tagImage(url, Optional.of(NoStrImplTagImage.createDimension(width, height)));
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagName extends NoStrEventTagBaseMono {
public NoStrTagName(String name) {
super(NoStrImplEventTag.NAME);
setMetaArgumentStr(name);
}
public NoStrTagName(String[] args) {
super(NoStrImplEventTag.NAME, args);
}
public String getName() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagName(String name) {
return tag(new NoStrTagName(name));
}
}
}

View file

@ -0,0 +1,39 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagNonce;
public final class NoStrTagNonce extends NoStrEventTagBase<NoStrImplTagNonce> {
public NoStrTagNonce(int difficulty) {
super(NoStrImplEventTag.NONCE);
setMetaArgumentStr(NoStrImplTagNonce.BEARER_PROOF, Integer.toString(NoStrImplTagNonce.DEFAULT_BEARER_PROOF));
setMetaArgumentStr(NoStrImplTagNonce.DIFFICULTY, Integer.toString(difficulty));
}
public NoStrTagNonce(String[] args) {
super(NoStrImplEventTag.NONCE, args);
}
public void setBearerProof(int bearerProof) {
setMetaArgumentStr(NoStrImplTagNonce.BEARER_PROOF, Integer.toString(bearerProof));
}
public int getBearerProof() {
return Integer.valueOf(getMetaArgument(NoStrImplTagNonce.BEARER_PROOF).get());
}
public int getDifficulty() {
return Integer.valueOf(getMetaArgument(NoStrImplTagNonce.DIFFICULTY).get());
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagNonce(int difficulty) {
return tag(new NoStrTagNonce(difficulty));
}
}
}

View file

@ -0,0 +1,54 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPublicKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagP;
public final class NoStrTagP extends NoStrEventTagBase<NoStrImplTagP> {
public NoStrTagP(NoStrIdentityPublicKey publicKey, Optional<String> relayUrl, Optional<String> petName) {
super(NoStrImplEventTag.P);
setMetaArgumentStr(NoStrImplTagP.PUBLIC_KEY, publicKey.getHex());
setMetaArgumentOptStr(NoStrImplTagP.PET_NAME, petName);
}
public NoStrTagP(String[] args) {
super(NoStrImplEventTag.E, args);
}
public NoStrIdentityPublicKey getPublicKey() {
return NoStrIdentityPublicKey.ofHex(getMetaArgument(NoStrImplTagP.PUBLIC_KEY).get());
}
public Optional<String> getPetName() {
return getMetaArgument(NoStrImplTagP.PET_NAME);
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagP(NoStrIdentityPublicKey publicKey, Optional<String> relayUrl, Optional<String> petName) {
return tag(new NoStrTagP(publicKey, relayUrl, petName));
}
default NoStrFireStackWelder tagP(NoStrIdentityPublicKey publicKey, String relayUrl, String petName) {
return tagP(publicKey, Optional.of(relayUrl), Optional.of(petName));
}
default NoStrFireStackWelder tagP(NoStrIdentityPublicKey publicKey) {
return tagP(publicKey, Optional.empty(), Optional.empty());
}
default NoStrFireStackWelder tagPRelayUrl(NoStrIdentityPublicKey publicKey, String relayUrl) {
return tagP(publicKey, Optional.of(relayUrl), Optional.empty());
}
default NoStrFireStackWelder tagPPetName(NoStrIdentityPublicKey publicKey, String petName) {
return tagP(publicKey, Optional.empty(), Optional.of(petName));
}
}
}

View file

@ -0,0 +1,35 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.time.Instant;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagPublishedAt extends NoStrEventTagBaseMono {
public NoStrTagPublishedAt(Instant publishedAt) {
super(NoStrImplEventTag.PUBLISHED_AT);
setMetaArgumentStr(Long.toString(publishedAt.getEpochSecond()));
}
public NoStrTagPublishedAt(String[] args) {
super(NoStrImplEventTag.PUBLISHED_AT, args);
}
public Instant getPublishedAt() {
return Instant.ofEpochSecond(Long.valueOf(getMetaArgument().get()));
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagPublishedAt(Instant publishedAt) {
return tag(new NoStrTagPublishedAt(publishedAt));
}
default NoStrFireStackWelder tagPublishedAtNow() {
return tagPublishedAt(Instant.now());
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagR extends NoStrEventTagBaseMono {
public NoStrTagR(String reference) {
super(NoStrImplEventTag.R);
setMetaArgumentStr(reference);
}
public NoStrTagR(String[] args) {
super(NoStrImplEventTag.R, args);
}
public String getReference() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagR(String reference) {
return tag(new NoStrTagR(reference));
}
}
}

View file

@ -0,0 +1,45 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagSubject;
public final class NoStrTagSubject extends NoStrEventTagBase<NoStrImplTagSubject> {
public NoStrTagSubject(String subject) {
super(NoStrImplEventTag.SUBJECT);
setMetaArgumentStr(NoStrImplTagSubject.SUBJECT, subject);
}
public NoStrTagSubject(String[] args) {
super(NoStrImplEventTag.SUBJECT, args);
}
public String getSubject() {
return getMetaArgument(NoStrImplTagSubject.SUBJECT).get();
}
public boolean hasReplyPrefix() {
return NoStrImplTagSubject.hasReplyPrefix(getSubject());
}
public boolean hasChoppedPostfix() {
return NoStrImplTagSubject.hasChoppedPostfix(getSubject());
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagSubject(String subject) {
return tag(new NoStrTagSubject(NoStrImplTagSubject.limitLength(subject)));
}
default NoStrFireStackWelder tagSubjectReply(String subject) {
if (NoStrImplTagSubject.hasReplyPrefix(subject)) {
return tagSubject(subject);
}
return tagSubject(NoStrImplTagSubject.prefixSubject(subject));
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagSummary extends NoStrEventTagBaseMono {
public NoStrTagSummary(String summary) {
super(NoStrImplEventTag.SUMMARY);
setMetaArgumentStr(summary);
}
public NoStrTagSummary(String[] args) {
super(NoStrImplEventTag.SUMMARY, args);
}
public String getSummary() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagSummary(String summary) {
return tag(new NoStrTagSummary(summary));
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBaseMono;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
public final class NoStrTagT extends NoStrEventTagBaseMono {
public NoStrTagT(String hashTag) {
super(NoStrImplEventTag.T);
setMetaArgumentStr(hashTag);
}
public NoStrTagT(String[] args) {
super(NoStrImplEventTag.T, args);
}
public String getHashTag() {
return getMetaArgument().get();
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagT(String hashTag) {
return tag(new NoStrTagT(hashTag));
}
}
}

View file

@ -0,0 +1,57 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagThumb;
public final class NoStrTagThumb extends NoStrEventTagBase<NoStrImplTagThumb> {
public NoStrTagThumb(String url, Optional<String> dimension) {
super(NoStrImplEventTag.THUMB);
setMetaArgumentStr(NoStrImplTagThumb.URL, url);
setMetaArgumentOptStr(NoStrImplTagThumb.DIMENSION, dimension);
}
public NoStrTagThumb(String[] args) {
super(NoStrImplEventTag.THUMB, args);
}
public String getUrl() {
return getMetaArgument(NoStrImplTagThumb.URL).get();
}
public Optional<String> getDimension() {
return getMetaArgument(NoStrImplTagThumb.DIMENSION);
}
public Optional<Integer> getDimensionWidth() {
return getDimension().map(v -> NoStrImplTagThumb.splitDimensionToWidth(v));
}
public Optional<Integer> getDimensionHeight() {
return getDimension().map(v -> NoStrImplTagThumb.splitDimensionToHeight(v));
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagThumb(String url, Optional<String> dimension) {
return tag(new NoStrTagThumb(url, dimension));
}
default NoStrFireStackWelder tagThumb(String url) {
return tagThumb(url, Optional.empty());
}
default NoStrFireStackWelder tagThumb(String url, String dimension) {
return tagThumb(url, Optional.of(dimension));
}
default NoStrFireStackWelder tagThumb(String url, int width, int height) {
return tagThumb(url, Optional.of(NoStrImplTagThumb.createDimension(width, height)));
}
}
}

View file

@ -0,0 +1,34 @@
package love.distributedrebirth.no2all.nostr.model.tag;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackFishWelder;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireStackWelder;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagBase;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTag;
import love.distributedrebirth.no2all.nostr.nip.tag.NoStrImplTagTitle;
public final class NoStrTagTitle extends NoStrEventTagBase<NoStrImplTagTitle> {
public NoStrTagTitle(String title) {
super(NoStrImplEventTag.TITLE);
setMetaArgumentStr(NoStrImplTagTitle.TITLE, title);
}
public NoStrTagTitle(String[] args) {
super(NoStrImplEventTag.TITLE, args);
}
public String getTitle() {
return getMetaArgument(NoStrImplTagTitle.TITLE).get();
}
public boolean hasChoppedPostfix() {
return NoStrImplTagTitle.hasChoppedPostfix(getTitle());
}
public interface FishWelder extends NoStrFireStackFishWelder {
default NoStrFireStackWelder tagTitle(String title) {
return tag(new NoStrTagTitle(NoStrImplTagTitle.limitLength(title)));
}
}
}

View file

@ -0,0 +1,89 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
public enum NoStrImpl implements NoStrImplPossibility {
NIP_0_UNKNOWN,
NIP_1_BASE_PROTOCOL,
NIP_2_CONTACTS,
NIP_3_OPEN_TIMESTAMPS,
NIP_4_CRYTE_DIRECT_MSG,
NIP_5_NOSTR_TO_DNS,
NIP_6_KEY_FROM_MNEMONIC_SEED,
NIP_7_BROWSER_WINDOW_NOSTR,
NIP_9_EVENT_DELETION,
NIP_10_CORRECT_BASE_TAGS,
NIP_11_RELAY_INFO_DOC,
NIP_12_GENERIC_TAG_QUERY,
NIP_13_PROOF_OF_WORK,
NIP_14_TEXT_SUBJECT,
NIP_15_MARKETPLACE,
NIP_16_EVENT_TREATMENT,
NIP_18_REPOSTS,
NIP_19_BECH32_ENCODED,
NIP_20_COMMAND_RESULT,
NIP_21_NOSTR_URL_SCHEMA,
NIP_22_EVENT_AT_LIMITS,
NIP_23_LONG_FORM_CONTENT,
NIP_25_REACTIONS,
NIP_26_DELEGATED_EVENT_SIGN,
NIP_27_TEXT_NOTE_REFERENCE,
NIP_28_PUBLIC_CHAT,
NIP_30_CUSTOM_EMOJI,
NIP_31_ALT_FOR_UNKNOWN,
NIP_33_PARA_REPLACEABLE_EVENTS,
NIP_36_SENSITIVE_CONTENT,
NIP_39_EXT_INDENTITIES_IN_PROFILE,
NIP_40_EXPIRATION_TIMESTAMP,
NIP_42_AUTH_RELAY,
NIP_45_COUNTING_RESULTS,
NIP_46_NOSTR_CONNECT,
NIP_47_WALLET_CONNECT,
NIP_50_KEYWORD_FILTER,
NIP_51_LISTS,
NIP_56_REPORTING,
NIP_57_LIGHTING_ZAPS,
NIP_58_BADGES,
NIP_65_RELAY_LIST_METADATA,
NIP_78_APP_CUSTOM_DATA,
@Deprecated
NIP_89_RECOMMENDED_APP_HANDLERS, // used dyna hash tags so client will a cancer disconnect if a mongool send this packet.
NIP_94_FILE_METADATA,
;
private static final char PREFIX_SPLIT = '_';
private static final int PREFIX_LENGTH = 4;
private static final Map<Integer, NoStrImpl> MAP_NUMBER = Collections.unmodifiableMap(
Arrays.asList(values()).stream().collect(Collectors.toMap(v -> v.getNumber(), v -> v)));
private final int number;
private final String qFlag;
private NoStrImpl() {
int secondSplitIdx = name().indexOf(PREFIX_SPLIT, PREFIX_LENGTH);
String numberStr = name().substring(PREFIX_LENGTH, secondSplitIdx);
this.number = Integer.valueOf(numberStr);
this.qFlag = name();
}
@Override
public int getNumber() {
return number;
}
@Override
public String getQFlag() {
return qFlag;
}
public static boolean valueOfNIPValid(int nip) {
return MAP_NUMBER.containsKey(nip);
}
public static NoStrImpl valueOfNIP(int nip) {
return MAP_NUMBER.get(nip);
}
}

View file

@ -0,0 +1,10 @@
package love.distributedrebirth.no2all.nostr.nip;
public interface NoStrImplBinHex {
byte[] getBytes();
String getHex();
String getHexDipavali();
}

View file

@ -0,0 +1,33 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Objects;
import love.distributedrebirth.no2all.octo.OctoBitFormat;
public class NoStrImplBinHexAdapter implements NoStrImplBinHex {
private final byte[] valueBytes;
private final String valueHex;
private final String valueHexDipavali;
public NoStrImplBinHexAdapter(byte[] value) {
this.valueBytes = Objects.requireNonNull(value);
this.valueHex = OctoBitFormat.HEX.fromBytes(value);
this.valueHexDipavali = OctoBitFormat.HEX_DIPAVALI.fromBytes(value);
}
@Override
public final byte[] getBytes() {
return valueBytes;
}
@Override
public final String getHex() {
return valueHex;
}
@Override
public String getHexDipavali() {
return valueHexDipavali;
}
}

View file

@ -0,0 +1,133 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import love.distributedrebirth.no2all.nostr.NoStrGospel;
public final class NoStrImplChuch {
public static void readArrayString(JsonObject json, NoStrImplQName jsonName, List<String> data) {
readArrayString(json, jsonName.getQName(), data);
}
public static void readArrayString(JsonObject json, String jsonName, List<String> data) {
readArray(json, jsonName, v -> data.add(((JsonString)v).getString()));
}
public static void readArray(JsonObject json, NoStrImplQName jsonName, Consumer<JsonValue> arrayValue) {
readArray(json, jsonName.getQName(), arrayValue);
}
public static void readArray(JsonObject json, String jsonName, Consumer<JsonValue> arrayValue) {
if (!json.containsKey(jsonName)) {
return;
}
JsonArray values = json.getJsonArray(jsonName);
for (JsonValue valueJson : values) {
arrayValue.accept(valueJson);
}
}
public static String readString(JsonObject json, NoStrImplQName jsonName) {
return readString(json, jsonName.getQName());
}
public static String readString(JsonObject json, String jsonName) {
return json.getString(jsonName, null);
}
public static Integer readInteger(JsonObject json, NoStrImplQName jsonName) {
return readInteger(json, jsonName.getQName());
}
public static Integer readInteger(JsonObject json, String jsonName) {
if (json.containsKey(jsonName)) {
return json.getInt(jsonName);
}
return null;
}
public static Boolean readBoolean(JsonObject json, NoStrImplQName jsonName) {
return readBoolean(json, jsonName.getQName());
}
public static Boolean readBoolean(JsonObject json, String jsonName) {
if (json.containsKey(jsonName)) {
return json.getBoolean(jsonName);
}
return null;
}
public static void writeArrayWriter(JsonObjectBuilder json, NoStrImplQName jsonName, List<? extends NoStrGospel> data) {
writeArrayWriter(json, jsonName.getQName(), data);
}
public static void writeArrayWriter(JsonObjectBuilder json, String jsonName, List<? extends NoStrGospel> data) {
writeArray(json, jsonName, data, (r, v) -> r.add(v.toBible()));
}
public static void writeArrayString(JsonObjectBuilder json, NoStrImplQName jsonName, List<String> data) {
writeArrayString(json, jsonName.getQName(), data);
}
public static void writeArrayString(JsonObjectBuilder json, String jsonName, List<String> data) {
writeArray(json, jsonName, data, (r, v) -> r.add(v));
}
public static <T> void writeArray(JsonObjectBuilder json, NoStrImplQName jsonName, List<T> data, BiConsumer<JsonArrayBuilder, T> addFn) {
writeArray(json, jsonName.getQName(), data, addFn);
}
public static <T> void writeArray(JsonObjectBuilder json, String jsonName, List<T> data, BiConsumer<JsonArrayBuilder, T> addFn) {
JsonArrayBuilder builder = Json.createArrayBuilder();
for (T value : data) {
addFn.accept(builder, value);
}
JsonArray result = builder.build();
if (!result.isEmpty()) {
json.add(jsonName, result);
}
}
public static void writeString(JsonObjectBuilder json, NoStrImplQName jsonName, String data) {
writeString(json, jsonName.getQName(), data);
}
public static void writeString(JsonObjectBuilder json, String jsonName, String data) {
if (data == null) {
return;
}
json.add(jsonName, data);
}
public static void writeInteger(JsonObjectBuilder json, NoStrImplQName jsonName, Integer data) {
writeInteger(json, jsonName.getQName(), data);
}
public static void writeInteger(JsonObjectBuilder json, String jsonName, Integer data) {
if (data == null) {
return;
}
json.add(jsonName, data);
}
public static void writeBoolean(JsonObjectBuilder json, NoStrImplQName jsonName, Boolean data) {
writeBoolean(json, jsonName.getQName(), data);
}
public static void writeBoolean(JsonObjectBuilder json, String jsonName, Boolean data) {
if (data == null) {
return;
}
json.add(jsonName, data);
}
}

View file

@ -0,0 +1,93 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKind;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKindRange;
public enum NoStrImplEventKind implements NoStrEventKind {
METADATA (0, NoStrImpl.NIP_1_BASE_PROTOCOL),
TEXT_NOTE (1, NoStrImpl.NIP_1_BASE_PROTOCOL),
RECOMMEND_RELAY (2, NoStrImpl.NIP_1_BASE_PROTOCOL),
CONTACTS (3, NoStrImpl.NIP_2_CONTACTS),
CRYPT_DIRECT_MSG (4, NoStrImpl.NIP_4_CRYTE_DIRECT_MSG),
EVENT_DELETION (5, NoStrImpl.NIP_9_EVENT_DELETION),
REPOSTS (6, NoStrImpl.NIP_18_REPOSTS),
REACTION (7, NoStrImpl.NIP_25_REACTIONS),
BADGE_AWARD (8, NoStrImpl.NIP_58_BADGES),
CHANNEL_CREATION (40, NoStrImpl.NIP_28_PUBLIC_CHAT),
CHANNEL_METADATA (41, NoStrImpl.NIP_28_PUBLIC_CHAT),
CHANNEL_SEND_MSG (42, NoStrImpl.NIP_28_PUBLIC_CHAT),
CHANNEL_HIDE_MSG (43, NoStrImpl.NIP_28_PUBLIC_CHAT),
CHANNEL_MUTE_USER (44, NoStrImpl.NIP_28_PUBLIC_CHAT),
FILE_METADATA (1063, NoStrImpl.NIP_94_FILE_METADATA),
REPORTING (1984, NoStrImpl.NIP_56_REPORTING),
ZAP_REQUEST (9734, NoStrImpl.NIP_57_LIGHTING_ZAPS),
ZAP_TX (9735, NoStrImpl.NIP_57_LIGHTING_ZAPS),
MUTE_LIST (10000, NoStrImpl.NIP_51_LISTS),
PIN_LIST (10001, NoStrImpl.NIP_51_LISTS),
RELAY_LIST_METADATA (10002, NoStrImpl.NIP_65_RELAY_LIST_METADATA),
WALLET_INFO (13194, NoStrImpl.NIP_47_WALLET_CONNECT),
CLIENT_AUTH (22242, NoStrImpl.NIP_42_AUTH_RELAY),
WALLET_REQUEST (23194, NoStrImpl.NIP_47_WALLET_CONNECT),
WALLET_RESPONSE (23195, NoStrImpl.NIP_47_WALLET_CONNECT),
NOSTR_CONNECT (24133, NoStrImpl.NIP_46_NOSTR_CONNECT),
CAT_PEOPLE_LIST (30000, NoStrImpl.NIP_51_LISTS),
CAT_BOOKMARK_LIST (30001, NoStrImpl.NIP_51_LISTS),
PROFILE_BADGES (30008, NoStrImpl.NIP_58_BADGES),
BADGE_DEFINITION (30009, NoStrImpl.NIP_58_BADGES),
MARKET_STALL (30017, NoStrImpl.NIP_15_MARKETPLACE),
MARKET_PRODUCT (30018, NoStrImpl.NIP_15_MARKETPLACE),
LONG_FORM_CONTENT (30023, NoStrImpl.NIP_23_LONG_FORM_CONTENT),
APP_CUSTOM_DATA (30078, NoStrImpl.NIP_78_APP_CUSTOM_DATA),
;
private static final Map<Integer, NoStrImplEventKind> MAP_NUMBER = Collections.unmodifiableMap(
Arrays.asList(values()).stream().collect(Collectors.toMap(v -> v.getNumber(), v -> v)));
private final int number;
private final NoStrImplPossibility nip;
private final NoStrEventKindRange range;
private NoStrImplEventKind(int number, NoStrImpl nip) {
this.number = number;
this.nip = nip;
this.range = NoStrImplEventKindRange.valueOfKind(number);
}
@Override
public int getNumber() {
return number;
}
@Override
public String getQFlag() {
return name();
}
@Override
public NoStrImplPossibility getNip() {
return nip;
}
@Override
public NoStrEventKindRange getRange() {
return range;
}
public static boolean valueOfKindValid(int kind) {
return MAP_NUMBER.containsKey(kind);
}
public static NoStrImplEventKind valueOfKind(int kind) {
return MAP_NUMBER.get(kind);
}
}

View file

@ -0,0 +1,63 @@
package love.distributedrebirth.no2all.nostr.nip;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventKindRange;
public enum NoStrImplEventKindRange implements NoStrEventKindRange {
// Internal Nips
UNKNOWN ( -1, -1),
CHAT ( 0, 999),
REGULAR ( 1000, 9999),
REGULAR_REPL (10000, 19999),
EPHEMERAL (20000, 29999),
PARAM_REPL (30000, 39999),
// External Apps
NOSTROCKET (640000,649999),
;
private final int numberStart;
private final int numberstop;
private NoStrImplEventKindRange(int numberStart, int numberstop) {
this.numberStart = numberStart;
this.numberstop = numberstop;
}
@Override
public String getQFlag() {
return name();
}
@Override
public int getNumberStart() {
return numberStart;
}
@Override
public int getNumberstop() {
return numberstop;
}
@Override
public boolean isReplaceable(int number) {
if (number == 0 || number == 3 || number == 41) {
return true;
}
if (this == REGULAR_REPL) {
return true;
}
if (this == PARAM_REPL) {
return true;
}
return false;
}
public static NoStrImplEventKindRange valueOfKind(int number) {
for (NoStrImplEventKindRange range : values()) {
if (number >= range.getNumberStart() && number <= range.getNumberstop()) {
return range;
}
}
return NoStrImplEventKindRange.UNKNOWN;
}
}

View file

@ -0,0 +1,112 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventTagMeta;
public enum NoStrImplEventTag implements NoStrEventTagMeta {
// the "p" tag is used for referencing public keys
P (NoStrImpl.NIP_1_BASE_PROTOCOL),
// the "e" tag for referencing event ids
E (NoStrImpl.NIP_1_BASE_PROTOCOL, NoStrImpl.NIP_10_CORRECT_BASE_TAGS),
// ["a", "<kind>:<pubkey>:<d-identifier>", "<relay url>"]
A (NoStrImpl.NIP_23_LONG_FORM_CONTENT, NoStrImpl.NIP_33_PARA_REPLACEABLE_EVENTS),
I (NoStrImpl.NIP_39_EXT_INDENTITIES_IN_PROFILE),
// the "d" tag is a delete slug key for "pubkey:kind:d" + time, empty is def key
D (NoStrImpl.NIP_33_PARA_REPLACEABLE_EVENTS), // TODO: add single tag info + check
T (NoStrImpl.NIP_12_GENERIC_TAG_QUERY),
R (NoStrImpl.NIP_12_GENERIC_TAG_QUERY),
G (NoStrImpl.NIP_12_GENERIC_TAG_QUERY),
CHALLENGE (NoStrImpl.NIP_42_AUTH_RELAY),
RELAY (NoStrImpl.NIP_42_AUTH_RELAY),
TITLE (NoStrImpl.NIP_23_LONG_FORM_CONTENT),
SUMMARY (NoStrImpl.NIP_23_LONG_FORM_CONTENT),
PUBLISHED_AT (NoStrImpl.NIP_23_LONG_FORM_CONTENT),
IMAGE (NoStrImpl.NIP_23_LONG_FORM_CONTENT, NoStrImpl.NIP_58_BADGES),
ZAP (NoStrImpl.NIP_57_LIGHTING_ZAPS),
LNURL (NoStrImpl.NIP_57_LIGHTING_ZAPS),
AMOUNT (NoStrImpl.NIP_57_LIGHTING_ZAPS),
BOLT11 (NoStrImpl.NIP_57_LIGHTING_ZAPS),
PREIMAGE (NoStrImpl.NIP_57_LIGHTING_ZAPS),
DESCRIPTION (NoStrImpl.NIP_57_LIGHTING_ZAPS, NoStrImpl.NIP_58_BADGES),
RELAYS (NoStrImpl.NIP_57_LIGHTING_ZAPS),
CLIENT (true, NoStrImpl.NIP_0_UNKNOWN),
NONCE (true, NoStrImpl.NIP_13_PROOF_OF_WORK),
SUBJECT (NoStrImpl.NIP_14_TEXT_SUBJECT),
DELEGATION (NoStrImpl.NIP_26_DELEGATED_EVENT_SIGN),
EMOJI (NoStrImpl.NIP_30_CUSTOM_EMOJI),
CONTENT_WARNING (NoStrImpl.NIP_36_SENSITIVE_CONTENT),
EXPIRATION (NoStrImpl.NIP_40_EXPIRATION_TIMESTAMP),
ALT (NoStrImpl.NIP_31_ALT_FOR_UNKNOWN),
NAME (NoStrImpl.NIP_58_BADGES),
THUMB (NoStrImpl.NIP_58_BADGES),
// Dat Package extensions
DPFH (NoStrImpl.NIP_0_UNKNOWN), // "DAT Package File Hash" with event content = maven://ndaturl+versionhash
;
private static final Map<String, NoStrEventTagMeta> MAP_QNAME = Collections.unmodifiableMap(
Arrays.asList(values()).stream().collect(Collectors.toMap(v -> v.getQName(), v -> v)));
private final String jsonQName;
private final NoStrImplPossibility[] nips;
private final boolean quariable;
private final boolean singleton;
private NoStrImplEventTag(NoStrImpl... nips) {
this(false, nips); // TODO: add info on all needed tags
}
private NoStrImplEventTag(boolean singleton, NoStrImpl... nips) {
this.jsonQName = name().toLowerCase().replaceAll("_", "-");
this.nips = nips;
this.quariable = isQuariable(name());
this.singleton = singleton;
}
@Override
public String getQName() {
return jsonQName;
}
@Override
public String getQFlag() {
return name();
}
@Override
public NoStrImplPossibility[] getNips() {
return nips;
}
@Override
public boolean isQuariable() {
return quariable;
}
@Override
public boolean isSinglton() {
return singleton;
}
public static boolean isQuariable(String qName) {
return qName != null && qName.length() == 1;
}
public static boolean valueOfWireValid(String tag) {
return MAP_QNAME.containsKey(Objects.requireNonNull(tag));
}
public static NoStrEventTagMeta valueOfWire(String tag) {
return MAP_QNAME.get(Objects.requireNonNull(tag));
}
}

View file

@ -0,0 +1,6 @@
package love.distributedrebirth.no2all.nostr.nip;
public interface NoStrImplEventTagArgument {
int ordinal();
}

View file

@ -0,0 +1,43 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Objects;
public enum NoStrImplMessageOkReason {
DEFAULT (""),
BLOCKED ("blocked:"),
INVALID ("invalid:"),
POW ("pow:"),
RATE_LIMITED ("rate-limited:"),
ERROR ("error:"),
;
private final String prefix;
private final String prefixFormat;
private NoStrImplMessageOkReason(String prefix) {
this.prefix = prefix;
this.prefixFormat = prefix + (prefix.isEmpty()?"":" ");
}
public String getPrefix() {
return prefix;
}
public String format(String message) {
return prefixFormat + Objects.requireNonNull(message);
}
public static NoStrImplMessageOkReason valueOfPrefix(String message) {
Objects.requireNonNull(message);
for (NoStrImplMessageOkReason reason : values()) {
if (reason == DEFAULT) {
continue;
}
if (message.startsWith(reason.getPrefix())) {
return reason;
}
}
return NoStrImplMessageOkReason.DEFAULT;
}
}

View file

@ -0,0 +1,70 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import jakarta.json.JsonArray;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClient;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelay;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientNotice;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientOk;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayClose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayReq;
public enum NoStrImplMessageType implements NoStrImplQName {
EVENT (NoStrImpl.NIP_1_BASE_PROTOCOL, v -> new NoStrMsgToRelayEvent(v), v -> new NoStrMsgToClientEvent(v)),
REQ (NoStrImpl.NIP_1_BASE_PROTOCOL, v -> new NoStrMsgToRelayReq(v), null),
CLOSE (NoStrImpl.NIP_1_BASE_PROTOCOL, v -> new NoStrMsgToRelayClose(v), null),
EOSE (NoStrImpl.NIP_1_BASE_PROTOCOL, null, v -> new NoStrMsgToClientEose(v)),
NOTICE (NoStrImpl.NIP_1_BASE_PROTOCOL, null, v -> new NoStrMsgToClientNotice(v)),
OK (NoStrImpl.NIP_20_COMMAND_RESULT, null, v -> new NoStrMsgToClientOk(v)),
AUTH (NoStrImpl.NIP_42_AUTH_RELAY, v -> new NoStrMsgToRelayAuth(v), v -> new NoStrMsgToClientAuth(v)),
COUNT (NoStrImpl.NIP_45_COUNTING_RESULTS, v -> new NoStrMsgToRelayCount(v), v -> new NoStrMsgToClientCount(v)),
;
private static final Set<String> MAP_NAME = Arrays.asList(values()).stream().map(v -> v.name()).collect(Collectors.toSet());
private final NoStrImplPossibility requireNip;
private final Optional<Function<JsonArray, NoStrMsgToRelay>> mapperToRelay;
private final Optional<Function<JsonArray, NoStrMsgToClient>> mapperToClient;
private NoStrImplMessageType(NoStrImpl requireNip,
Function<JsonArray, NoStrMsgToRelay> mapperToRelay,
Function<JsonArray, NoStrMsgToClient> mapperToClient) {
this.requireNip = requireNip;
this.mapperToRelay = Optional.ofNullable(mapperToRelay);
this.mapperToClient = Optional.ofNullable(mapperToClient);
}
public NoStrImplPossibility getFeatureNip() {
return requireNip;
}
public String getQName() {
return name();
}
public Optional<Function<JsonArray, NoStrMsgToRelay>> getMapperToRelay() {
return mapperToRelay;
}
public Optional<Function<JsonArray, NoStrMsgToClient>> getMapperToClient() {
return mapperToClient;
}
public static boolean valueOfValid(String name) {
return MAP_NAME.contains(Objects.requireNonNull(name));
}
}

View file

@ -0,0 +1,6 @@
package love.distributedrebirth.no2all.nostr.nip;
public interface NoStrImplPossibility extends NoStrImplQFlag {
int getNumber();
}

View file

@ -0,0 +1,8 @@
package love.distributedrebirth.no2all.nostr.nip;
public interface NoStrImplQFlag {
String CUSTOM_INDICATOR = "CUSTOM";
String getQFlag(); // for part of i18n key slug
}

View file

@ -0,0 +1,17 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Optional;
public interface NoStrImplQName {
String getQName(); // for gospel church bible
static <T extends NoStrImplQName> Optional<T> valueOfQName(T[] values, String qName) {
for (T value : values) {
if (value.getQName().equals(qName)) {
return Optional.of(value);
}
}
return Optional.empty();
}
}

View file

@ -0,0 +1,52 @@
package love.distributedrebirth.no2all.nostr.nip;
import java.util.Objects;
import love.distributedrebirth.no2all.octo.OctoBech32;
import love.distributedrebirth.no2all.octo.OctoBech32String;
public enum NoStrImplShareLink { // TODO: add NIP dep
// bare value bach32
PRIVATE_KEY("nsec"),
PUBLIC_KEY("npub"),
NOTE("note"),
// TLV values bach32
PROFILE("nprofile"),
EVENT("nevent"),
RELAY("nrelay"),
EVENT_REFERENCE("naddr"),
//CHANNEL("nchannel"), //todo find docs
PRIVATE_KEY_SECURE("ncryptsec"), // bip 49
// PRIVATE_KEY_SECURE("nsecpw"),
// SECURE_URL("nsurl"),
;
private final String prefix;
private NoStrImplShareLink(String prefix) {
this.prefix = prefix;
}
public String getPrefix() {
return prefix;
}
public OctoBech32String validate(OctoBech32String link) {
Objects.requireNonNull(link);
Objects.requireNonNull(link.getValue());
if (link.getValue().startsWith(getPrefix())) {
return link;
}
throw new IllegalArgumentException("Wrong prefix; wanted " + getPrefix() + " got " + link.getValue());
}
public byte[] fromBech32(OctoBech32String link) {
return OctoBech32.fromBech32(validate(link)).getData();
}
public String toBech32(byte[] data) {
return OctoBech32.toBech32(getPrefix(), data).getValue();
}
}

View file

@ -0,0 +1,41 @@
package love.distributedrebirth.no2all.nostr.nip;
import love.distributedrebirth.no2all.octo.OctoBitChainFrameType;
public enum NoStrImplShareTLV implements OctoBitChainFrameType {
SPECIAL(0), // pubkey/eventId/payload/etc
RELAY(1),
AUTHOR(2),
KIND(3),
// new
CLIENT(4), // for appId
// for "ncryptsec" ChaCha20-Poly1305 CIPHERTEXT is in SPECIAL
VERSION(5), // one byte
LOG_N(6), // one byte
SALT(7), // 16 bytes random
NONCE(8), // 24 bytes from ChaCha20-Poly1305
LEVEL(9), // 1 byte to indicate security level of private key
// for "nsecpw" (simple AES)
//SALT,
//IV
// for "nsurl"
//SURL,
//PKCS_8, // (full ASN.1 DER packet)
;
private final byte typeByte;
private NoStrImplShareTLV(int typeByte) {
this.typeByte = (byte)typeByte;
}
@Override
public byte getTypeByte() {
return typeByte;
}
}

View file

@ -0,0 +1,32 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
public enum NoStrImplTagA implements NoStrImplEventTagArgument {
ADDRESS,
RELAY_URL,
PLATFORM,
;
public static final String SEPERATOR = ":";
public static int splitToKind(String address) {
int idxSep = address.indexOf(SEPERATOR);
String result = address.substring(0, idxSep);
return Integer.valueOf(result);
}
public static String splitToPublicKey(String address) {
int idxSep = address.indexOf(SEPERATOR);
int idxSepEnd = address.indexOf(SEPERATOR, idxSep + 1);
String result = address.substring(idxSep + 1, idxSepEnd);
return result;
}
public static String splitToParameter(String address) {
int idxSep = address.indexOf(SEPERATOR);
int idxSepEnd = address.indexOf(SEPERATOR, idxSep + 1);
String result = address.substring(idxSepEnd + 1, address.length());
return result;
}
}

View file

@ -0,0 +1,9 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
public enum NoStrImplTagClient implements NoStrImplEventTagArgument {
USER_AGENT,
VERSION,
;
}

View file

@ -0,0 +1,9 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
public enum NoStrImplTagContentWarning implements NoStrImplEventTagArgument {
REASON,
RATE_GROUP
;
}

View file

@ -0,0 +1,30 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public enum NoStrImplTagContentWarningRGroup implements NoStrImplQName {
// from: https://en.wikipedia.org/wiki/Motion_Picture_Association_film_rating_system#Rating_components
VIOLENCE,
LANGUAGE,
SUBSTANCE,
NUDITY,
SEX,
;
private final String jsonQName;
private NoStrImplTagContentWarningRGroup() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
public static Optional<NoStrImplTagContentWarningRGroup> valueOfQName(String qName) {
return NoStrImplQName.valueOfQName(values(), qName);
}
}

View file

@ -0,0 +1,10 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventTagArgument;
public enum NoStrImplTagE implements NoStrImplEventTagArgument {
EVENT_ID,
RELAY_URL,
MARKER,
;
}

View file

@ -0,0 +1,25 @@
package love.distributedrebirth.no2all.nostr.nip.tag;
import java.util.Optional;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplQName;
public enum NoStrImplTagEMarker implements NoStrImplQName {
REPLAY, ROOT, MENTION;
private final String jsonQName;
private NoStrImplTagEMarker() {
jsonQName = name().toLowerCase();
}
@Override
public String getQName() {
return jsonQName;
}
public static Optional<NoStrImplTagEMarker> valueOfQName(String qName) {
return NoStrImplQName.valueOfQName(values(), qName);
}
}

Some files were not shown because too many files have changed in this diff Show more