-
Notifications
You must be signed in to change notification settings - Fork 27
Add Nostr Java API reference documentation #384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,184 @@ | ||||||||||
| # Nostr Java API Reference | ||||||||||
|
|
||||||||||
| This document provides an overview of the public API exposed by the `nostr-java` modules. It lists the major classes, configuration objects and their key method signatures, and shows brief examples of how to use them. Where applicable, links to related [Nostr Improvement Proposals (NIPs)](https://github.com/nostr-protocol/nips) are provided. | ||||||||||
|
|
||||||||||
| ## Identity (`nostr-java-id`) | ||||||||||
|
|
||||||||||
| ### `Identity` | ||||||||||
| Represents a Nostr identity backed by a private key. It can derive a public key and sign `ISignable` objects. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| public static Identity create(PrivateKey privateKey) | ||||||||||
| public static Identity create(String privateKey) | ||||||||||
| public static Identity generateRandomIdentity() | ||||||||||
| public PublicKey getPublicKey() | ||||||||||
| public Signature sign(ISignable signable) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Usage:** | ||||||||||
| ```java | ||||||||||
| Identity id = Identity.generateRandomIdentity(); | ||||||||||
| PublicKey pub = id.getPublicKey(); | ||||||||||
| Signature sig = id.sign(event); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Event Model (`nostr-java-event`) | ||||||||||
|
|
||||||||||
| ### Core Types | ||||||||||
| - `BaseMessage` – base class for all relay messages. | ||||||||||
| - `BaseEvent` – root class for Nostr events. | ||||||||||
| - `BaseTag` – helper for tag encoding and decoding. | ||||||||||
|
|
||||||||||
| ### Predefined Events | ||||||||||
| The `nostr.event` package provides event implementations for many NIPs: | ||||||||||
|
|
||||||||||
| | Class | NIP | | ||||||||||
| |-------|-----| | ||||||||||
| | `NIP01Event` | [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md) – standard text notes. | | ||||||||||
| | `NIP04Event` | [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md) – encrypted direct messages. | | ||||||||||
| | `NIP05Event` | [NIP-05](https://github.com/nostr-protocol/nips/blob/master/05.md) – DNS identifiers. | | ||||||||||
| | `NIP09Event` | [NIP-09](https://github.com/nostr-protocol/nips/blob/master/09.md) – event deletion. | | ||||||||||
| | `NIP25Event` | [NIP-25](https://github.com/nostr-protocol/nips/blob/master/25.md) – reactions. | | ||||||||||
| | `NIP52Event` | [NIP-52](https://github.com/nostr-protocol/nips/blob/master/52.md) – calendar events. | | ||||||||||
| | `NIP99Event` | [NIP-99](https://github.com/nostr-protocol/nips/blob/master/99.md) – classified listings. | | ||||||||||
|
|
||||||||||
| ### Filters | ||||||||||
| `Filters` and related `Filterable` implementations help build subscription requests. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| new Filters(Filterable... filterables) | ||||||||||
| List<Filterable> getFilterByType(String type) | ||||||||||
| void setLimit(Integer limit) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Usage:** | ||||||||||
| ```java | ||||||||||
| Filters filters = new Filters(new AuthorFilter(pubKey)); | ||||||||||
| filters.setLimit(100); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## WebSocket Clients (`nostr-java-client`, `nostr-java-api`) | ||||||||||
|
|
||||||||||
| ### `WebSocketClientIF` | ||||||||||
| Abstraction over a WebSocket connection to a relay. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| <T extends BaseMessage> List<String> send(T eventMessage) throws IOException | ||||||||||
| List<String> send(String json) throws IOException | ||||||||||
| void close() throws IOException | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### `StandardWebSocketClient` | ||||||||||
| Spring `TextWebSocketHandler` based implementation of `WebSocketClientIF`. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| public StandardWebSocketClient(String relayUri) | ||||||||||
| public <T extends BaseMessage> List<String> send(T eventMessage) throws IOException | ||||||||||
| public List<String> send(String json) throws IOException | ||||||||||
| public void close() throws IOException | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### `SpringWebSocketClient` | ||||||||||
| Wrapper that adds retry logic around a `WebSocketClientIF`. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| public List<String> send(BaseMessage eventMessage) throws IOException | ||||||||||
| public List<String> send(String json) throws IOException | ||||||||||
| public List<String> recover(IOException ex, String json) throws IOException | ||||||||||
| public void close() throws IOException | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### `NostrSpringWebSocketClient` | ||||||||||
| High level client coordinating multiple relay connections and signing. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| public NostrIF setRelays(Map<String,String> relays) | ||||||||||
| public List<String> sendEvent(IEvent event) | ||||||||||
| public List<String> sendRequest(List<Filters> filters, String subscriptionId) | ||||||||||
| public NostrIF sign(Identity identity, ISignable signable) | ||||||||||
| public boolean verify(GenericEvent event) | ||||||||||
| public Map<String,String> getRelays() | ||||||||||
| public void close() | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### Configuration | ||||||||||
| - `RetryConfig` – enables Spring Retry support. | ||||||||||
| - `RelaysProperties` – maps relay names to URLs via configuration properties. | ||||||||||
| - `RelayConfig` – loads `relays.properties` and exposes a `Map<String,String>` bean. | ||||||||||
|
|
||||||||||
| ## Encryption and Cryptography | ||||||||||
|
|
||||||||||
| ### `MessageCipher` | ||||||||||
| Strategy interface for message encryption. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| String encrypt(String message) | ||||||||||
| String decrypt(String message) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Implementations: | ||||||||||
| - `MessageCipher04` – NIP-04 direct message encryption. | ||||||||||
| - `MessageCipher44` – NIP-44 payload encryption. | ||||||||||
|
|
||||||||||
| ### `Schnorr` | ||||||||||
| Utility for Schnorr signatures (BIP-340). | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| static byte[] sign(byte[] msg, byte[] secKey, byte[] auxRand) | ||||||||||
| static boolean verify(byte[] msg, byte[] pubKey, byte[] sig) | ||||||||||
| static byte[] generatePrivateKey() | ||||||||||
| static byte[] genPubKey(byte[] secKey) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### `Bech32` | ||||||||||
| Utility for Bech32/Bech32m encoding used by [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md). | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| static String toBech32(Bech32Prefix hrp, byte[] hexKey) | ||||||||||
| static String fromBech32(String str) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Utilities (`nostr-java-util`) | ||||||||||
|
|
||||||||||
| ### `NostrUtil` | ||||||||||
| General helper functions. | ||||||||||
|
|
||||||||||
| ```java | ||||||||||
| static String bytesToHex(byte[] bytes) | ||||||||||
| static byte[] hexToBytes(String hex) | ||||||||||
| static byte[] sha256(byte[] data) | ||||||||||
| static byte[] createRandomByteArray(int len) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### `NostrException` | ||||||||||
| Base checked exception for utility methods. | ||||||||||
|
|
||||||||||
| ## Examples | ||||||||||
|
|
||||||||||
| ### Send a Text Note (NIP-01) | ||||||||||
| ```java | ||||||||||
| Identity id = Identity.generateRandomIdentity(); | ||||||||||
| NIP01 nip01 = new NIP01(id).createTextNoteEvent("Hello Nostr"); | ||||||||||
| NostrIF client = NostrSpringWebSocketClient.getInstance(id) | ||||||||||
| .setRelays(Map.of("relay","wss://relay.example")); | ||||||||||
| client.sendEvent(nip01.getEvent()); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### Encrypted Direct Message (NIP-04) | ||||||||||
| ```java | ||||||||||
| Identity alice = Identity.generateRandomIdentity(); | ||||||||||
| Identity bob = Identity.generateRandomIdentity(); | ||||||||||
| NIP04 dm = new NIP04(alice, bob.getPublicKey()) | ||||||||||
| .createDirectMessageEvent("secret"); | ||||||||||
| String plaintext = NIP04.decrypt(bob, dm.getEvent()); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### Subscription with Filters | ||||||||||
| ```java | ||||||||||
|
||||||||||
| ```java | |
| ```java | |
| PublicKey pubKey = id.getPublicKey(); |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example shows sendRequest returning List<String> events, but based on the method signature at line 97, it should return List<String> representing request IDs, not events. The variable name 'events' is misleading and should be something like 'requestIds' or 'responses'.
| List<String> events = client.sendRequest(filters, "sub-id"); | |
| List<String> requestIds = client.sendRequest(filters, "sub-id"); |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sendRequest method expects List<Filters> as the first parameter according to line 97, but the example passes a single Filters object. This should be Arrays.asList(filters) or List.of(filters).
| List<String> events = client.sendRequest(filters, "sub-id"); | |
| List<String> events = client.sendRequest(List.of(filters), "sub-id"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
signmethod documentation suggests it returns aNostrIFbut the method signature indicates it modifies state and returns the client instance. This pattern could be confusing - consider clarifying if this is a fluent interface or if the method actually performs signing internally.